@@ -1,8 +1,6 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.IO; | |||
using System.IO.Compression; | |||
using System.Text; | |||
namespace Shadowsocks.Controller | |||
{ | |||
@@ -12,9 +10,7 @@ namespace Shadowsocks.Controller | |||
{ | |||
try | |||
{ | |||
System.IO.FileStream _FileStream = | |||
new System.IO.FileStream(fileName, System.IO.FileMode.Create, | |||
System.IO.FileAccess.Write); | |||
FileStream _FileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write); | |||
_FileStream.Write(content, 0, content.Length); | |||
_FileStream.Close(); | |||
return true; | |||
@@ -31,7 +27,7 @@ namespace Shadowsocks.Controller | |||
{ | |||
FileStream destinationFile = File.Create(fileName); | |||
// Because the uncompressed size of the file is unknown, | |||
// Because the uncompressed size of the file is unknown, | |||
// we are using an arbitrary buffer size. | |||
byte[] buffer = new byte[4096]; | |||
int n; | |||
@@ -39,17 +35,33 @@ namespace Shadowsocks.Controller | |||
using (GZipStream input = new GZipStream(new MemoryStream(content), | |||
CompressionMode.Decompress, false)) | |||
{ | |||
while (true) | |||
while ((n = input.Read(buffer, 0, buffer.Length)) > 0) | |||
{ | |||
n = input.Read(buffer, 0, buffer.Length); | |||
if (n == 0) | |||
{ | |||
break; | |||
} | |||
destinationFile.Write(buffer, 0, n); | |||
} | |||
} | |||
destinationFile.Close(); | |||
} | |||
public static void CompressFile(string fileName, byte[] content) | |||
{ | |||
FileStream destinationFile = File.Create(fileName); | |||
MemoryStream ms = new MemoryStream(content); | |||
// Because the compressed size of the file is unknown, | |||
// we are using an arbitrary buffer size. | |||
byte[] buffer = new byte[4096]; | |||
int n; | |||
using (GZipStream output = new GZipStream(destinationFile, | |||
CompressionMode.Compress, false)) | |||
{ | |||
while ((n = ms.Read(buffer, 0, buffer.Length)) > 0) | |||
{ | |||
output.Write(buffer, 0, n); | |||
} | |||
} | |||
destinationFile.Close(); | |||
} | |||
} | |||
} |
@@ -9,18 +9,29 @@ namespace Shadowsocks.Controller | |||
{ | |||
public class Logging | |||
{ | |||
public static string LogFile; | |||
public static string LogFilePath; | |||
private static DateTime LogFileCreationTime; | |||
public static bool OpenLogFile() | |||
{ | |||
try | |||
{ | |||
LogFile = Utils.GetTempPath("shadowsocks.log"); | |||
FileStream fs = new FileStream(LogFile, FileMode.Append); | |||
StreamWriterWithTimestamp sw = new StreamWriterWithTimestamp(fs); | |||
sw.AutoFlush = true; | |||
Console.SetOut(sw); | |||
Console.SetError(sw); | |||
LogFilePath = Utils.GetTempPath("shadowsocks.log"); | |||
if (!File.Exists(LogFilePath)) | |||
using (File.Create(LogFilePath)) { } | |||
LogFileCreationTime = File.GetCreationTime(LogFilePath); | |||
if ((DateTime.Now - LogFileCreationTime).Days >= 1) | |||
RollLogFile(); | |||
else | |||
{ | |||
FileStream fs = new FileStream(LogFilePath, FileMode.Append); | |||
StreamWriterWithTimestamp sw = new StreamWriterWithTimestamp(fs); | |||
sw.AutoFlush = true; | |||
Console.SetOut(sw); | |||
Console.SetError(sw); | |||
} | |||
return true; | |||
} | |||
@@ -31,20 +42,53 @@ namespace Shadowsocks.Controller | |||
} | |||
} | |||
private static void RollLogFile() | |||
{ | |||
Console.Out.Close(); | |||
Console.Error.Close(); | |||
MemoryStream ms = new MemoryStream(); | |||
StreamWriterWithTimestamp sw = new StreamWriterWithTimestamp(ms); | |||
sw.AutoFlush = true; | |||
Console.SetOut(sw); | |||
Console.SetError(sw); | |||
byte[] logContents = File.ReadAllBytes(LogFilePath); | |||
string datestr = DateTime.Now.AddDays(-1).ToString("yyyyMMdd"); | |||
string filepath = Utils.GetTempPath($"shadowsocks.{datestr}.log.zip"); | |||
FileManager.CompressFile(filepath, logContents); | |||
File.Delete(LogFilePath); | |||
FileStream fs = new FileStream(LogFilePath, FileMode.CreateNew); | |||
LogFileCreationTime = DateTime.Now; | |||
ms.CopyTo(fs); | |||
StreamWriterWithTimestamp sw2 = new StreamWriterWithTimestamp(fs); | |||
sw2.AutoFlush = true; | |||
Console.SetOut(sw2); | |||
Console.SetError(sw2); | |||
} | |||
private static void WriteToLogFile(object o) | |||
{ | |||
if ((DateTime.Now - LogFileCreationTime).Days >= 1) | |||
RollLogFile(); | |||
Console.WriteLine(o); | |||
} | |||
public static void Error(object o) | |||
{ | |||
Console.WriteLine("[E] " + o); | |||
WriteToLogFile("[E] " + o); | |||
} | |||
public static void Info(object o) | |||
{ | |||
Console.WriteLine(o); | |||
WriteToLogFile(o); | |||
} | |||
public static void Debug(object o) | |||
{ | |||
#if DEBUG | |||
Console.WriteLine("[D] " + o); | |||
WriteToLogFile("[D] " + o); | |||
#endif | |||
} | |||
@@ -147,7 +147,7 @@ Connection: Close | |||
", Encoding.UTF8.GetBytes(pac).Length) + pac; | |||
byte[] response = Encoding.UTF8.GetBytes(text); | |||
socket.BeginSend(response, 0, response.Length, 0, new AsyncCallback(SendCallback), socket); | |||
Util.Utils.ReleaseMemory(true); | |||
Utils.ReleaseMemory(true); | |||
} | |||
catch (Exception e) | |||
{ | |||
@@ -23,7 +23,7 @@ namespace Shadowsocks.Controller | |||
public string LatestVersionLocalName; | |||
public event EventHandler CheckUpdateCompleted; | |||
public const string Version = "2.5.8.1"; | |||
public const string Version = "2.5.8.2"; | |||
private class CheckUpdateTimer : System.Timers.Timer | |||
{ | |||
@@ -63,6 +63,8 @@ namespace Shadowsocks.Controller | |||
public ShadowsocksController() | |||
{ | |||
_config = Configuration.Load(); | |||
inboundCounter = _config.GetCurrentServer().bandwidthIn; | |||
outboundCounter = _config.GetCurrentServer().bandwidthOut; | |||
StatisticsConfiguration = StatisticsStrategyConfiguration.Load(); | |||
_strategyManager = new StrategyManager(this); | |||
StartReleasingMemory(); | |||
@@ -253,7 +255,7 @@ namespace Shadowsocks.Controller | |||
public static string GetQRCode(Server server) | |||
{ | |||
string parts = server.method + ":" + server.password + "@" + server.server + ":" + server.server_port; | |||
string base64 = System.Convert.ToBase64String(Encoding.UTF8.GetBytes(parts)); | |||
string base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(parts)); | |||
return "ss://" + base64; | |||
} | |||
@@ -310,17 +312,21 @@ namespace Shadowsocks.Controller | |||
public void UpdateInboundCounter(long n) | |||
{ | |||
Interlocked.Add(ref inboundCounter, n); | |||
_config.GetCurrentServer().bandwidthIn = inboundCounter; | |||
} | |||
public void UpdateOutboundCounter(long n) | |||
{ | |||
Interlocked.Add(ref outboundCounter, n); | |||
_config.GetCurrentServer().bandwidthOut = outboundCounter; | |||
} | |||
protected void Reload() | |||
{ | |||
// some logic in configuration updated the config when saving, we need to read it again | |||
_config = Configuration.Load(); | |||
inboundCounter = _config.GetCurrentServer().bandwidthIn; | |||
outboundCounter = _config.GetCurrentServer().bandwidthOut; | |||
StatisticsConfiguration = StatisticsStrategyConfiguration.Load(); | |||
if (polipoRunner == null) | |||
@@ -398,7 +404,7 @@ namespace Shadowsocks.Controller | |||
} | |||
UpdateSystemProxy(); | |||
Util.Utils.ReleaseMemory(true); | |||
Utils.ReleaseMemory(true); | |||
} | |||
protected void SaveConfig(Configuration newConfig) | |||
@@ -494,7 +500,7 @@ namespace Shadowsocks.Controller | |||
{ | |||
while (true) | |||
{ | |||
Util.Utils.ReleaseMemory(false); | |||
Utils.ReleaseMemory(false); | |||
Thread.Sleep(30 * 1000); | |||
} | |||
} | |||
@@ -31,13 +31,9 @@ namespace Shadowsocks.Model | |||
public Server GetCurrentServer() | |||
{ | |||
if (index >= 0 && index < configs.Count) | |||
{ | |||
return configs[index]; | |||
} | |||
else | |||
{ | |||
return GetDefaultServer(); | |||
} | |||
} | |||
public static void CheckServer(Server server) | |||
@@ -55,24 +51,15 @@ namespace Shadowsocks.Model | |||
Configuration config = JsonConvert.DeserializeObject<Configuration>(configContent); | |||
config.isDefault = false; | |||
if (config.localPort == 0) | |||
{ | |||
config.localPort = 1080; | |||
} | |||
if (config.index == -1) | |||
{ | |||
if (config.strategy == null) | |||
{ | |||
config.index = 0; | |||
} | |||
} | |||
if (config.index == -1 && config.strategy == null) | |||
config.index = 0; | |||
return config; | |||
} | |||
catch (Exception e) | |||
{ | |||
if (!(e is FileNotFoundException)) | |||
{ | |||
Logging.LogUsefulException(e); | |||
} | |||
return new Configuration | |||
{ | |||
index = 0, | |||
@@ -90,20 +77,11 @@ namespace Shadowsocks.Model | |||
public static void Save(Configuration config) | |||
{ | |||
if (config.index >= config.configs.Count) | |||
{ | |||
config.index = config.configs.Count - 1; | |||
} | |||
if (config.index < -1) | |||
{ | |||
config.index = -1; | |||
} | |||
if (config.index == -1) | |||
{ | |||
if (config.strategy == null) | |||
{ | |||
config.index = 0; | |||
} | |||
} | |||
if (config.index == -1 && config.strategy == null) | |||
config.index = 0; | |||
config.isDefault = false; | |||
try | |||
{ | |||
@@ -128,42 +106,32 @@ namespace Shadowsocks.Model | |||
private static void Assert(bool condition) | |||
{ | |||
if (!condition) | |||
{ | |||
throw new Exception(I18N.GetString("assertion failure")); | |||
} | |||
} | |||
public static void CheckPort(int port) | |||
{ | |||
if (port <= 0 || port > 65535) | |||
{ | |||
throw new ArgumentException(I18N.GetString("Port out of range")); | |||
} | |||
} | |||
public static void CheckLocalPort(int port) | |||
{ | |||
CheckPort(port); | |||
if (port == 8123) | |||
{ | |||
throw new ArgumentException(I18N.GetString("Port can't be 8123")); | |||
} | |||
} | |||
private static void CheckPassword(string password) | |||
{ | |||
if (string.IsNullOrEmpty(password)) | |||
{ | |||
throw new ArgumentException(I18N.GetString("Password can not be blank")); | |||
} | |||
} | |||
private static void CheckServer(string server) | |||
{ | |||
if (string.IsNullOrEmpty(server)) | |||
{ | |||
throw new ArgumentException(I18N.GetString("Server IP can not be blank")); | |||
} | |||
} | |||
} | |||
} |
@@ -15,6 +15,8 @@ namespace Shadowsocks.Model | |||
public string method; | |||
public string remarks; | |||
public bool auth; | |||
public long bandwidthIn; | |||
public long bandwidthOut; | |||
public override int GetHashCode() | |||
{ | |||
@@ -24,7 +26,7 @@ namespace Shadowsocks.Model | |||
public override bool Equals(object obj) | |||
{ | |||
Server o2 = (Server)obj; | |||
return this.server == o2.server && this.server_port == o2.server_port; | |||
return server == o2.server && server_port == o2.server_port; | |||
} | |||
public string FriendlyName() | |||
@@ -45,12 +47,12 @@ namespace Shadowsocks.Model | |||
public Server() | |||
{ | |||
this.server = ""; | |||
this.server_port = 8388; | |||
this.method = "aes-256-cfb"; | |||
this.password = ""; | |||
this.remarks = ""; | |||
this.auth = false; | |||
server = ""; | |||
server_port = 8388; | |||
method = "aes-256-cfb"; | |||
password = ""; | |||
remarks = ""; | |||
auth = false; | |||
} | |||
public Server(string ssURL) : this() | |||
@@ -62,7 +64,7 @@ namespace Shadowsocks.Model | |||
{ | |||
try | |||
{ | |||
bytes = System.Convert.FromBase64String(base64); | |||
bytes = Convert.FromBase64String(base64); | |||
} | |||
catch (FormatException) | |||
{ | |||
@@ -80,16 +82,15 @@ namespace Shadowsocks.Model | |||
string afterAt = data.Substring(indexLastAt + 1); | |||
int indexLastColon = afterAt.LastIndexOf(':'); | |||
this.server_port = int.Parse(afterAt.Substring(indexLastColon + 1)); | |||
this.server = afterAt.Substring(0, indexLastColon); | |||
server_port = int.Parse(afterAt.Substring(indexLastColon + 1)); | |||
server = afterAt.Substring(0, indexLastColon); | |||
string beforeAt = data.Substring(0, indexLastAt); | |||
string[] parts = beforeAt.Split(new[] { ':' }); | |||
this.method = parts[0]; | |||
this.password = parts[1]; | |||
method = parts[0]; | |||
password = parts[1]; | |||
//TODO: read one_time_auth | |||
} | |||
catch (IndexOutOfRangeException) | |||
{ | |||
@@ -11,6 +11,7 @@ using ZXing.QrCode; | |||
using Shadowsocks.Controller; | |||
using Shadowsocks.Model; | |||
using Shadowsocks.Properties; | |||
using Shadowsocks.Util; | |||
namespace Shadowsocks.View | |||
{ | |||
@@ -341,7 +342,6 @@ namespace Shadowsocks.View | |||
{ | |||
item.Checked = true; | |||
} | |||
} | |||
} | |||
@@ -363,7 +363,7 @@ namespace Shadowsocks.View | |||
{ | |||
if (logForms.Count == 0) | |||
{ | |||
LogForm f = new LogForm(controller, Logging.LogFile); | |||
LogForm f = new LogForm(controller, Logging.LogFilePath); | |||
f.Show(); | |||
f.FormClosed += logForm_FormClosed; | |||
@@ -388,7 +388,7 @@ namespace Shadowsocks.View | |||
void configForm_FormClosed(object sender, FormClosedEventArgs e) | |||
{ | |||
configForm = null; | |||
Util.Utils.ReleaseMemory(true); | |||
Utils.ReleaseMemory(true); | |||
ShowFirstTimeBalloon(); | |||
} | |||
@@ -491,7 +491,7 @@ namespace Shadowsocks.View | |||
private void ShowLogItem_Click(object sender, EventArgs e) | |||
{ | |||
LogForm f = new LogForm(controller, Logging.LogFile); | |||
LogForm f = new LogForm(controller, Logging.LogFilePath); | |||
f.Show(); | |||
f.FormClosed += logForm_FormClosed; | |||
@@ -8,11 +8,11 @@ | |||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> | |||
<dependentAssembly> | |||
<assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> | |||
<bindingRedirect oldVersion="0.0.0.0-2.6.8.0" newVersion="2.6.8.0" /> | |||
<bindingRedirect oldVersion="0.0.0.0-2.6.10.0" newVersion="2.6.10.0" /> | |||
</dependentAssembly> | |||
<dependentAssembly> | |||
<assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> | |||
<bindingRedirect oldVersion="0.0.0.0-2.6.8.0" newVersion="2.6.8.0" /> | |||
<bindingRedirect oldVersion="0.0.0.0-2.6.10.0" newVersion="2.6.10.0" /> | |||
</dependentAssembly> | |||
</assemblyBinding> | |||
</runtime> | |||
@@ -1,11 +1,11 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<packages> | |||
<package id="Costura.Fody" version="1.3.3.0" targetFramework="net4-client" developmentDependency="true" /> | |||
<package id="Fody" version="1.29.3" targetFramework="net4-client" developmentDependency="true" /> | |||
<package id="Microsoft.Bcl" version="1.1.8" targetFramework="net4-client" /> | |||
<package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net4-client" /> | |||
<package id="Microsoft.Bcl.Build" version="1.0.14" targetFramework="net4-client" /> | |||
<package id="Microsoft.Net.Http" version="2.0.20710.0" targetFramework="net4-client" /> | |||
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net4-client" /> | |||
<package id="System.Net.Http" version="2.0.20710.0" targetFramework="net4-client" /> | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<packages> | |||
<package id="Costura.Fody" version="1.3.3.0" targetFramework="net4-client" developmentDependency="true" /> | |||
<package id="Fody" version="1.29.4" targetFramework="net40-client" developmentDependency="true" /> | |||
<package id="Microsoft.Bcl" version="1.1.10" targetFramework="net40-client" /> | |||
<package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net40-client" /> | |||
<package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net40-client" /> | |||
<package id="Microsoft.Net.Http" version="2.0.20710.0" targetFramework="net4-client" /> | |||
<package id="Newtonsoft.Json" version="8.0.2" targetFramework="net40-client" /> | |||
<package id="System.Net.Http" version="2.0.20710.0" targetFramework="net40-client" /> | |||
</packages> |
@@ -69,21 +69,18 @@ | |||
<Reference Include="Microsoft.Threading.Tasks, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>3rd\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath> | |||
<Private>True</Private> | |||
<EmbedInteropTypes>False</EmbedInteropTypes> | |||
</Reference> | |||
<Reference Include="Microsoft.Threading.Tasks.Extensions, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>3rd\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll</HintPath> | |||
<Private>True</Private> | |||
<EmbedInteropTypes>False</EmbedInteropTypes> | |||
</Reference> | |||
<Reference Include="Microsoft.Threading.Tasks.Extensions.Desktop, Version=1.0.168.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>3rd\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll</HintPath> | |||
<Private>True</Private> | |||
<EmbedInteropTypes>False</EmbedInteropTypes> | |||
</Reference> | |||
<Reference Include="Microsoft.VisualBasic" /> | |||
<Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> | |||
<HintPath>3rd\Newtonsoft.Json.7.0.1\lib\net40\Newtonsoft.Json.dll</HintPath> | |||
<Reference Include="Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> | |||
<HintPath>3rd\Newtonsoft.Json.8.0.2\lib\net40\Newtonsoft.Json.dll</HintPath> | |||
<Private>True</Private> | |||
</Reference> | |||
<Reference Include="PresentationCore" /> | |||
@@ -91,10 +88,9 @@ | |||
<Reference Include="System" /> | |||
<Reference Include="System.Data" /> | |||
<Reference Include="System.Drawing" /> | |||
<Reference Include="System.IO, Version=2.6.8.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>3rd\Microsoft.Bcl.1.1.8\lib\net40\System.IO.dll</HintPath> | |||
<Reference Include="System.IO, Version=2.6.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>3rd\Microsoft.Bcl.1.1.10\lib\net40\System.IO.dll</HintPath> | |||
<Private>True</Private> | |||
<EmbedInteropTypes>False</EmbedInteropTypes> | |||
</Reference> | |||
<Reference Include="System.Net" /> | |||
<Reference Include="System.Net.Http, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
@@ -105,15 +101,13 @@ | |||
<HintPath>3rd\Microsoft.Net.Http.2.0.20710.0\lib\net40\System.Net.Http.WebRequest.dll</HintPath> | |||
<Private>True</Private> | |||
</Reference> | |||
<Reference Include="System.Runtime, Version=2.6.8.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>3rd\Microsoft.Bcl.1.1.8\lib\net40\System.Runtime.dll</HintPath> | |||
<Reference Include="System.Runtime, Version=2.6.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>3rd\Microsoft.Bcl.1.1.10\lib\net40\System.Runtime.dll</HintPath> | |||
<Private>True</Private> | |||
<EmbedInteropTypes>False</EmbedInteropTypes> | |||
</Reference> | |||
<Reference Include="System.Threading.Tasks, Version=2.6.8.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>3rd\Microsoft.Bcl.1.1.8\lib\net40\System.Threading.Tasks.dll</HintPath> | |||
<Reference Include="System.Threading.Tasks, Version=2.6.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>3rd\Microsoft.Bcl.1.1.10\lib\net40\System.Threading.Tasks.dll</HintPath> | |||
<Private>True</Private> | |||
<EmbedInteropTypes>False</EmbedInteropTypes> | |||
</Reference> | |||
<Reference Include="System.Windows.Forms" /> | |||
<Reference Include="System.Windows.Forms.DataVisualization" /> | |||
@@ -330,18 +324,15 @@ | |||
</BootstrapperPackage> | |||
</ItemGroup> | |||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | |||
<Import Project="3rd\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets" Condition="Exists('3rd\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" /> | |||
<Target Name="EnsureBclBuildImported" BeforeTargets="BeforeBuild" Condition="'$(BclBuildImported)' == ''"> | |||
<Error Condition="!Exists('3rd\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" Text="This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="BCLBUILD2001" /> | |||
<Error Condition="Exists('3rd\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" Text="The build restored NuGet packages. Build the project again to include these packages in the build. For more information, see http://go.microsoft.com/fwlink/?LinkID=317568." HelpKeyword="BCLBUILD2002" /> | |||
</Target> | |||
<Import Project="3rd\Fody.1.29.3\build\portable-net+sl+win+wpa+wp\Fody.targets" Condition="Exists('3rd\Fody.1.29.3\build\portable-net+sl+win+wpa+wp\Fody.targets')" /> | |||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> | |||
<PropertyGroup> | |||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> | |||
</PropertyGroup> | |||
<Error Condition="!Exists('3rd\Fody.1.29.3\build\portable-net+sl+win+wpa+wp\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '3rd\Fody.1.29.3\build\portable-net+sl+win+wpa+wp\Fody.targets'))" /> | |||
<Error Condition="!Exists('3rd\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="$([System.String]::Format('$(ErrorText)', '3rd\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets'))" /> | |||
<Error Condition="!Exists('3rd\Fody.1.29.4\build\portable-net+sl+win+wpa+wp\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '3rd\Fody.1.29.4\build\portable-net+sl+win+wpa+wp\Fody.targets'))" /> | |||
</Target> | |||
<Import Project="3rd\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('3rd\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" /> | |||
<Import Project="3rd\Fody.1.29.4\build\portable-net+sl+win+wpa+wp\Fody.targets" Condition="Exists('3rd\Fody.1.29.4\build\portable-net+sl+win+wpa+wp\Fody.targets')" /> | |||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. | |||
Other similar extension points exist, see Microsoft.Common.targets. | |||
<Target Name="BeforeBuild"> | |||