Squashed commit of the following: committags/3.2e280c2385c
Merge:579039f
87aa9eb
Author: Gang Zhuo <gang.zhuo@gmail.com> Date: Wed Mar 16 04:02:27 2016 -0400 Merge remote-tracking branch 'origin/master' commit579039fe40
Author: Gang Zhuo <gang.zhuo@gmail.com> Date: Fri Mar 4 21:45:23 2016 +0800 log unhandle exception commit8d863f1d5f
Author: Gang Zhuo <gang.zhuo@gmail.com> Date: Fri Mar 4 21:44:54 2016 +0800 fix Availability Statistics commitb3ce1c698a
Author: Gang Zhuo <gang.zhuo@gmail.com> Date: Fri Mar 4 21:07:54 2016 +0800 tiny refactor commit0f7d39e27e
Merge:bd7078a
b01aced
Author: Gang Zhuo <gang.zhuo@gmail.com> Date: Fri Mar 4 20:02:58 2016 +0800 Merge remote-tracking branch 'origin/master' commitbd7078aa4f
Author: Gang Zhuo <gang.zhuo@gmail.com> Date: Fri Mar 4 20:01:58 2016 +0800 tiny refactor commit49adb95b6e
Author: Gang Zhuo <gang.zhuo@gmail.com> Date: Fri Mar 4 03:44:26 2016 -0500 log more Ping information for debug commit2aa0620ddd
Author: Gang Zhuo <gang.zhuo@gmail.com> Date: Fri Mar 4 03:04:10 2016 -0500 reduce 3rd packages [solve conflicts and squash to make history clean] Signed-off-by: Syrone Wong <wong.syrone@gmail.com>
@@ -107,67 +107,30 @@ namespace Shadowsocks.Controller | |||||
var bytes = inbound - lastInbound; | var bytes = inbound - lastInbound; | ||||
_lastInboundCounter[id] = inbound; | _lastInboundCounter[id] = inbound; | ||||
var inboundSpeed = GetSpeedInKiBPerSecond(bytes, _monitorInterval.TotalSeconds); | var inboundSpeed = GetSpeedInKiBPerSecond(bytes, _monitorInterval.TotalSeconds); | ||||
_inboundSpeedRecords.GetOrAdd(id, new List<int> {inboundSpeed}).Add(inboundSpeed); | |||||
_inboundSpeedRecords.GetOrAdd(id, (k) => | |||||
{ | |||||
List<int> records = new List<int>(); | |||||
records.Add(inboundSpeed); | |||||
return records; | |||||
}); | |||||
var lastOutbound = _lastOutboundCounter[id]; | var lastOutbound = _lastOutboundCounter[id]; | ||||
var outbound = _outboundCounter[id]; | var outbound = _outboundCounter[id]; | ||||
bytes = outbound - lastOutbound; | bytes = outbound - lastOutbound; | ||||
_lastOutboundCounter[id] = outbound; | _lastOutboundCounter[id] = outbound; | ||||
var outboundSpeed = GetSpeedInKiBPerSecond(bytes, _monitorInterval.TotalSeconds); | var outboundSpeed = GetSpeedInKiBPerSecond(bytes, _monitorInterval.TotalSeconds); | ||||
_outboundSpeedRecords.GetOrAdd(id, new List<int> {outboundSpeed}).Add(outboundSpeed); | |||||
_outboundSpeedRecords.GetOrAdd(id, (k) => | |||||
{ | |||||
List<int> records = new List<int>(); | |||||
records.Add(outboundSpeed); | |||||
return records; | |||||
}); | |||||
Logging.Debug( | Logging.Debug( | ||||
$"{id}: current/max inbound {inboundSpeed}/{_inboundSpeedRecords[id].Max()} KiB/s, current/max outbound {outboundSpeed}/{_outboundSpeedRecords[id].Max()} KiB/s"); | $"{id}: current/max inbound {inboundSpeed}/{_inboundSpeedRecords[id].Max()} KiB/s, current/max outbound {outboundSpeed}/{_outboundSpeedRecords[id].Max()} KiB/s"); | ||||
} | } | ||||
} | } | ||||
private async Task<ICMPResult> ICMPTest(Server server) | |||||
{ | |||||
Logging.Debug("Ping " + server.FriendlyName()); | |||||
if (server.server == "") return null; | |||||
var result = new ICMPResult(server); | |||||
try | |||||
{ | |||||
var IP = | |||||
Dns.GetHostAddresses(server.server) | |||||
.First( | |||||
ip => | |||||
ip.AddressFamily == AddressFamily.InterNetwork || | |||||
ip.AddressFamily == AddressFamily.InterNetworkV6); | |||||
var ping = new Ping(); | |||||
foreach (var _ in Enumerable.Range(0, Repeat)) | |||||
{ | |||||
try | |||||
{ | |||||
var reply = await ping.SendTaskAsync(IP, TimeoutMilliseconds); | |||||
if (reply.Status.Equals(IPStatus.Success)) | |||||
{ | |||||
result.RoundtripTime.Add((int?) reply.RoundtripTime); | |||||
} | |||||
else | |||||
{ | |||||
result.RoundtripTime.Add(null); | |||||
} | |||||
//Do ICMPTest in a random frequency | |||||
Thread.Sleep(TimeoutMilliseconds + new Random().Next()%TimeoutMilliseconds); | |||||
} | |||||
catch (Exception e) | |||||
{ | |||||
Logging.Error($"An exception occured while eveluating {server.FriendlyName()}"); | |||||
Logging.LogUsefulException(e); | |||||
} | |||||
} | |||||
} | |||||
catch (Exception e) | |||||
{ | |||||
Logging.Error($"An exception occured while eveluating {server.FriendlyName()}"); | |||||
Logging.LogUsefulException(e); | |||||
} | |||||
return result; | |||||
} | |||||
private void Reset() | private void Reset() | ||||
{ | { | ||||
_inboundSpeedRecords.Clear(); | _inboundSpeedRecords.Clear(); | ||||
@@ -178,15 +141,14 @@ namespace Shadowsocks.Controller | |||||
private void Run(object _) | private void Run(object _) | ||||
{ | { | ||||
UpdateRecords(); | UpdateRecords(); | ||||
Save(); | |||||
Reset(); | Reset(); | ||||
FilterRawStatistics(); | |||||
} | } | ||||
private async void UpdateRecords() | |||||
private void UpdateRecords() | |||||
{ | { | ||||
var records = new Dictionary<string, StatisticsRecord>(); | var records = new Dictionary<string, StatisticsRecord>(); | ||||
UpdateRecordsState state = new UpdateRecordsState(); | |||||
state.counter = _controller.GetCurrentConfiguration().configs.Count; | |||||
foreach (var server in _controller.GetCurrentConfiguration().configs) | foreach (var server in _controller.GetCurrentConfiguration().configs) | ||||
{ | { | ||||
var id = server.Identifier(); | var id = server.Identifier(); | ||||
@@ -202,43 +164,80 @@ namespace Shadowsocks.Controller | |||||
records[id] = record; | records[id] = record; | ||||
else | else | ||||
records.Add(id, record); | records.Add(id, record); | ||||
if (Config.Ping) | |||||
{ | |||||
MyPing ping = new MyPing(server, Repeat); | |||||
ping.Completed += ping_Completed; | |||||
ping.Start(new PingState { state = state, record = record }); | |||||
} | |||||
else if (!record.IsEmptyData()) | |||||
{ | |||||
AppendRecord(id, record); | |||||
} | |||||
} | } | ||||
if (Config.Ping) | |||||
if (!Config.Ping) | |||||
{ | { | ||||
var icmpResults = await TaskEx.WhenAll(_controller.GetCurrentConfiguration().configs.Select(ICMPTest)); | |||||
foreach (var result in icmpResults.Where(result => result != null)) | |||||
{ | |||||
records[result.Server.Identifier()].SetResponse(result.RoundtripTime); | |||||
} | |||||
Save(); | |||||
FilterRawStatistics(); | |||||
} | } | ||||
} | |||||
foreach (var kv in records.Where(kv => !kv.Value.IsEmptyData())) | |||||
private void ping_Completed(object sender, MyPing.CompletedEventArgs e) | |||||
{ | |||||
PingState pingState = (PingState)e.UserState; | |||||
UpdateRecordsState state = pingState.state; | |||||
Server server = e.Server; | |||||
StatisticsRecord record = pingState.record; | |||||
record.SetResponse(e.RoundtripTime); | |||||
if (!record.IsEmptyData()) | |||||
{ | { | ||||
AppendRecord(kv.Key, kv.Value); | |||||
AppendRecord(server.Identifier(), record); | |||||
} | |||||
Logging.Debug($"Ping {server.FriendlyName()} {e.RoundtripTime.Count} times, {(100 - record.PackageLoss * 100)}% packages loss, min {record.MinResponse} ms, max {record.MaxResponse} ms, avg {record.AverageResponse} ms"); | |||||
if (Interlocked.Decrement(ref state.counter) == 0) | |||||
{ | |||||
Save(); | |||||
FilterRawStatistics(); | |||||
} | } | ||||
} | } | ||||
private void AppendRecord(string serverIdentifier, StatisticsRecord record) | private void AppendRecord(string serverIdentifier, StatisticsRecord record) | ||||
{ | { | ||||
List<StatisticsRecord> records; | |||||
if (!RawStatistics.TryGetValue(serverIdentifier, out records)) | |||||
try | |||||
{ | |||||
List<StatisticsRecord> records; | |||||
lock (RawStatistics) | |||||
{ | |||||
if (!RawStatistics.TryGetValue(serverIdentifier, out records)) | |||||
{ | |||||
records = new List<StatisticsRecord>(); | |||||
RawStatistics[serverIdentifier] = records; | |||||
} | |||||
} | |||||
records.Add(record); | |||||
} | |||||
catch (Exception e) | |||||
{ | { | ||||
records = new List<StatisticsRecord>(); | |||||
Logging.LogUsefulException(e); | |||||
} | } | ||||
records.Add(record); | |||||
RawStatistics[serverIdentifier] = records; | |||||
} | } | ||||
private void Save() | private void Save() | ||||
{ | { | ||||
Logging.Debug($"save statistics to {AvailabilityStatisticsFile}"); | |||||
if (RawStatistics.Count == 0) | if (RawStatistics.Count == 0) | ||||
{ | { | ||||
return; | return; | ||||
} | } | ||||
try | try | ||||
{ | { | ||||
var content = JsonConvert.SerializeObject(RawStatistics, Formatting.None); | |||||
string content; | |||||
#if DEBUG | |||||
content = JsonConvert.SerializeObject(RawStatistics, Formatting.Indented); | |||||
#else | |||||
content = JsonConvert.SerializeObject(RawStatistics, Formatting.None); | |||||
#endif | |||||
File.WriteAllText(AvailabilityStatisticsFile, content); | File.WriteAllText(AvailabilityStatisticsFile, content); | ||||
} | } | ||||
catch (IOException e) | catch (IOException e) | ||||
@@ -258,17 +257,25 @@ namespace Shadowsocks.Controller | |||||
private void FilterRawStatistics() | private void FilterRawStatistics() | ||||
{ | { | ||||
if (RawStatistics == null) return; | |||||
if (FilteredStatistics == null) | |||||
try | |||||
{ | { | ||||
FilteredStatistics = new Statistics(); | |||||
} | |||||
Logging.Debug("filter raw statistics"); | |||||
if (RawStatistics == null) return; | |||||
if (FilteredStatistics == null) | |||||
{ | |||||
FilteredStatistics = new Statistics(); | |||||
} | |||||
foreach (var serverAndRecords in RawStatistics) | |||||
foreach (var serverAndRecords in RawStatistics) | |||||
{ | |||||
var server = serverAndRecords.Key; | |||||
var filteredRecords = serverAndRecords.Value.FindAll(IsValidRecord); | |||||
FilteredStatistics[server] = filteredRecords; | |||||
} | |||||
} | |||||
catch (Exception e) | |||||
{ | { | ||||
var server = serverAndRecords.Key; | |||||
var filteredRecords = serverAndRecords.Value.FindAll(IsValidRecord); | |||||
FilteredStatistics[server] = filteredRecords; | |||||
Logging.LogUsefulException(e); | |||||
} | } | ||||
} | } | ||||
@@ -298,21 +305,10 @@ namespace Shadowsocks.Controller | |||||
private static int GetSpeedInKiBPerSecond(long bytes, double seconds) | private static int GetSpeedInKiBPerSecond(long bytes, double seconds) | ||||
{ | { | ||||
var result = (int) (bytes/seconds)/1024; | |||||
var result = (int)(bytes / seconds) / 1024; | |||||
return result; | return result; | ||||
} | } | ||||
private class ICMPResult | |||||
{ | |||||
internal readonly List<int?> RoundtripTime = new List<int?>(); | |||||
internal readonly Server Server; | |||||
internal ICMPResult(Server server) | |||||
{ | |||||
Server = server; | |||||
} | |||||
} | |||||
public void Dispose() | public void Dispose() | ||||
{ | { | ||||
_recorder.Dispose(); | _recorder.Dispose(); | ||||
@@ -321,44 +317,158 @@ namespace Shadowsocks.Controller | |||||
public void UpdateLatency(Server server, int latency) | public void UpdateLatency(Server server, int latency) | ||||
{ | { | ||||
List<int> records; | |||||
_latencyRecords.TryGetValue(server.Identifier(), out records); | |||||
if (records == null) | |||||
_latencyRecords.GetOrAdd(server.Identifier(), (k) => | |||||
{ | { | ||||
records = new List<int>(); | |||||
} | |||||
records.Add(latency); | |||||
_latencyRecords[server.Identifier()] = records; | |||||
List<int> records = new List<int>(); | |||||
records.Add(latency); | |||||
return records; | |||||
}); | |||||
} | } | ||||
public void UpdateInboundCounter(Server server, long n) | public void UpdateInboundCounter(Server server, long n) | ||||
{ | { | ||||
long count; | |||||
if (_inboundCounter.TryGetValue(server.Identifier(), out count)) | |||||
_inboundCounter.AddOrUpdate(server.Identifier(), (k) => | |||||
{ | { | ||||
count += n; | |||||
} | |||||
else | |||||
{ | |||||
count = n; | |||||
_lastInboundCounter[server.Identifier()] = 0; | |||||
} | |||||
_inboundCounter[server.Identifier()] = count; | |||||
_lastInboundCounter.GetOrAdd(server.Identifier(), 0); | |||||
return n; | |||||
}, (k, v) => (v + n)); | |||||
} | } | ||||
public void UpdateOutboundCounter(Server server, long n) | public void UpdateOutboundCounter(Server server, long n) | ||||
{ | { | ||||
long count; | |||||
if (_outboundCounter.TryGetValue(server.Identifier(), out count)) | |||||
_outboundCounter.AddOrUpdate(server.Identifier(), (k) => | |||||
{ | |||||
_lastOutboundCounter.GetOrAdd(server.Identifier(), 0); | |||||
return n; | |||||
}, (k, v) => (v + n)); | |||||
} | |||||
class UpdateRecordsState | |||||
{ | |||||
public int counter; | |||||
} | |||||
class PingState | |||||
{ | |||||
public UpdateRecordsState state; | |||||
public StatisticsRecord record; | |||||
} | |||||
class MyPing | |||||
{ | |||||
//arguments for ICMP tests | |||||
public const int TimeoutMilliseconds = 500; | |||||
public EventHandler<CompletedEventArgs> Completed; | |||||
private Server server; | |||||
private int repeat; | |||||
private IPAddress ip; | |||||
private Ping ping; | |||||
private List<int?> RoundtripTime; | |||||
public MyPing(Server server, int repeat) | |||||
{ | { | ||||
count += n; | |||||
this.server = server; | |||||
this.repeat = repeat; | |||||
RoundtripTime = new List<int?>(repeat); | |||||
ping = new Ping(); | |||||
ping.PingCompleted += Ping_PingCompleted; | |||||
} | |||||
public void Start(object userstate) | |||||
{ | |||||
if (server.server == "") | |||||
{ | |||||
FireCompleted(new Exception("Invalid Server"), userstate); | |||||
return; | |||||
} | |||||
new Task(() => ICMPTest(0, userstate)).Start(); | |||||
} | } | ||||
else | |||||
private void ICMPTest(int delay, object userstate) | |||||
{ | { | ||||
count = n; | |||||
_lastOutboundCounter[server.Identifier()] = 0; | |||||
try | |||||
{ | |||||
Logging.Debug($"Ping {server.FriendlyName()}"); | |||||
if (ip == null) | |||||
{ | |||||
ip = Dns.GetHostAddresses(server.server) | |||||
.First( | |||||
ip => | |||||
ip.AddressFamily == AddressFamily.InterNetwork || | |||||
ip.AddressFamily == AddressFamily.InterNetworkV6); | |||||
} | |||||
repeat--; | |||||
if (delay > 0) | |||||
Thread.Sleep(delay); | |||||
ping.SendAsync(ip, TimeoutMilliseconds, userstate); | |||||
} | |||||
catch (Exception e) | |||||
{ | |||||
Logging.Error($"An exception occured while eveluating {server.FriendlyName()}"); | |||||
Logging.LogUsefulException(e); | |||||
FireCompleted(e, userstate); | |||||
} | |||||
} | |||||
private void Ping_PingCompleted(object sender, PingCompletedEventArgs e) | |||||
{ | |||||
try | |||||
{ | |||||
if (e.Reply.Status == IPStatus.Success) | |||||
{ | |||||
Logging.Debug($"Ping {server.FriendlyName()} {e.Reply.RoundtripTime} ms"); | |||||
RoundtripTime.Add((int?)e.Reply.RoundtripTime); | |||||
} | |||||
else | |||||
{ | |||||
Logging.Debug($"Ping {server.FriendlyName()} timeout"); | |||||
RoundtripTime.Add(null); | |||||
} | |||||
TestNext(e.UserState); | |||||
} | |||||
catch (Exception ex) | |||||
{ | |||||
Logging.Error($"An exception occured while eveluating {server.FriendlyName()}"); | |||||
Logging.LogUsefulException(ex); | |||||
FireCompleted(ex, e.UserState); | |||||
} | |||||
} | |||||
private void TestNext(object userstate) | |||||
{ | |||||
if (repeat > 0) | |||||
{ | |||||
//Do ICMPTest in a random frequency | |||||
int delay = TimeoutMilliseconds + new Random().Next() % TimeoutMilliseconds; | |||||
new Task(() => ICMPTest(delay, userstate)).Start(); | |||||
} | |||||
else | |||||
{ | |||||
FireCompleted(null, userstate); | |||||
} | |||||
} | |||||
private void FireCompleted(Exception error, object userstate) | |||||
{ | |||||
Completed?.Invoke(this, new CompletedEventArgs | |||||
{ | |||||
Error = error, | |||||
Server = server, | |||||
RoundtripTime = RoundtripTime, | |||||
UserState = userstate | |||||
}); | |||||
} | |||||
public class CompletedEventArgs : EventArgs | |||||
{ | |||||
public Exception Error; | |||||
public Server Server; | |||||
public List<int?> RoundtripTime; | |||||
public object UserState; | |||||
} | } | ||||
_outboundCounter[server.Identifier()] = count; | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -47,20 +47,7 @@ namespace Shadowsocks.Controller | |||||
Process[] existingPolipo = Process.GetProcessesByName("ss_privoxy"); | Process[] existingPolipo = Process.GetProcessesByName("ss_privoxy"); | ||||
foreach (Process p in existingPolipo) | foreach (Process p in existingPolipo) | ||||
{ | { | ||||
try | |||||
{ | |||||
p.CloseMainWindow(); | |||||
p.WaitForExit(100); | |||||
if (!p.HasExited) | |||||
{ | |||||
p.Kill(); | |||||
p.WaitForExit(); | |||||
} | |||||
} | |||||
catch (Exception e) | |||||
{ | |||||
Logging.LogUsefulException(e); | |||||
} | |||||
KillProcess(p); | |||||
} | } | ||||
string polipoConfig = Resources.privoxy_conf; | string polipoConfig = Resources.privoxy_conf; | ||||
_runningPort = this.GetFreePort(); | _runningPort = this.GetFreePort(); | ||||
@@ -86,20 +73,30 @@ namespace Shadowsocks.Controller | |||||
{ | { | ||||
if (_process != null) | if (_process != null) | ||||
{ | { | ||||
try | |||||
{ | |||||
_process.Kill(); | |||||
_process.WaitForExit(); | |||||
} | |||||
catch (Exception e) | |||||
{ | |||||
Logging.LogUsefulException(e); | |||||
} | |||||
KillProcess(_process); | |||||
_process = null; | _process = null; | ||||
} | } | ||||
RefreshTrayArea(); | RefreshTrayArea(); | ||||
} | } | ||||
private static void KillProcess(Process p) | |||||
{ | |||||
try | |||||
{ | |||||
p.CloseMainWindow(); | |||||
p.WaitForExit(100); | |||||
if (!p.HasExited) | |||||
{ | |||||
p.Kill(); | |||||
p.WaitForExit(); | |||||
} | |||||
} | |||||
catch (Exception e) | |||||
{ | |||||
Logging.LogUsefulException(e); | |||||
} | |||||
} | |||||
private int GetFreePort() | private int GetFreePort() | ||||
{ | { | ||||
int defaultPort = 8123; | int defaultPort = 8123; | ||||
@@ -5,7 +5,6 @@ using System.Net; | |||||
using System.Net.Sockets; | using System.Net.Sockets; | ||||
using System.Text; | using System.Text; | ||||
using System.Threading; | using System.Threading; | ||||
using System.Threading.Tasks; | |||||
using Newtonsoft.Json; | using Newtonsoft.Json; | ||||
using Shadowsocks.Controller.Strategy; | using Shadowsocks.Controller.Strategy; | ||||
@@ -335,7 +334,7 @@ namespace Shadowsocks.Controller | |||||
{ | { | ||||
if (_config.availabilityStatistics) | if (_config.availabilityStatistics) | ||||
{ | { | ||||
new Task(() => availabilityStatistics.UpdateLatency(server, (int)latency.TotalMilliseconds)).Start(); | |||||
availabilityStatistics.UpdateLatency(server, (int)latency.TotalMilliseconds); | |||||
} | } | ||||
} | } | ||||
@@ -344,7 +343,7 @@ namespace Shadowsocks.Controller | |||||
Interlocked.Add(ref inboundCounter, n); | Interlocked.Add(ref inboundCounter, n); | ||||
if (_config.availabilityStatistics) | if (_config.availabilityStatistics) | ||||
{ | { | ||||
new Task(() => availabilityStatistics.UpdateInboundCounter(server, n)).Start(); | |||||
availabilityStatistics.UpdateInboundCounter(server, n); | |||||
} | } | ||||
} | } | ||||
@@ -353,7 +352,7 @@ namespace Shadowsocks.Controller | |||||
Interlocked.Add(ref outboundCounter, n); | Interlocked.Add(ref outboundCounter, n); | ||||
if (_config.availabilityStatistics) | if (_config.availabilityStatistics) | ||||
{ | { | ||||
new Task(() => availabilityStatistics.UpdateOutboundCounter(server, n)).Start(); | |||||
availabilityStatistics.UpdateOutboundCounter(server, n); | |||||
} | } | ||||
} | } | ||||
@@ -101,3 +101,5 @@ Failed to decode QRCode=无法解析二维码 | |||||
Failed to update registry=无法修改注册表 | Failed to update registry=无法修改注册表 | ||||
System Proxy On: =系统代理已启用: | System Proxy On: =系统代理已启用: | ||||
Running: Port {0}=正在运行:端口 {0} | Running: Port {0}=正在运行:端口 {0} | ||||
Unexpect error, shadowsocks will be exit. Please report to=非预期错误,Shadowsocks将退出。请提交此错误到 | |||||
@@ -21,6 +21,7 @@ namespace Shadowsocks | |||||
Utils.ReleaseMemory(true); | Utils.ReleaseMemory(true); | ||||
using (Mutex mutex = new Mutex(false, "Global\\Shadowsocks_" + Application.StartupPath.GetHashCode())) | using (Mutex mutex = new Mutex(false, "Global\\Shadowsocks_" + Application.StartupPath.GetHashCode())) | ||||
{ | { | ||||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; | |||||
Application.EnableVisualStyles(); | Application.EnableVisualStyles(); | ||||
Application.SetCompatibleTextRenderingDefault(false); | Application.SetCompatibleTextRenderingDefault(false); | ||||
@@ -53,5 +54,19 @@ namespace Shadowsocks | |||||
Application.Run(); | Application.Run(); | ||||
} | } | ||||
} | } | ||||
private static int exited = 0; | |||||
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) | |||||
{ | |||||
if (Interlocked.Increment(ref exited) == 1) | |||||
{ | |||||
Logging.Error(e.ExceptionObject?.ToString()); | |||||
MessageBox.Show(I18N.GetString("Unexpect error, shadowsocks will be exit. Please report to") + | |||||
" https://github.com/shadowsocks/shadowsocks-windows/issues " + | |||||
Environment.NewLine + (e.ExceptionObject?.ToString()), | |||||
"Shadowsocks Error", MessageBoxButtons.OK, MessageBoxIcon.Error); | |||||
Application.Exit(); | |||||
} | |||||
} | |||||
} | } | ||||
} | } |
@@ -3,11 +3,6 @@ | |||||
<package id="Caseless.Fody" version="1.4.1" targetFramework="net40-client" developmentDependency="true" /> | <package id="Caseless.Fody" version="1.4.1" targetFramework="net40-client" developmentDependency="true" /> | ||||
<package id="Costura.Fody" version="1.3.3.0" targetFramework="net40-client" developmentDependency="true" /> | <package id="Costura.Fody" version="1.3.3.0" targetFramework="net40-client" developmentDependency="true" /> | ||||
<package id="Fody" version="1.29.4" targetFramework="net40-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="Newtonsoft.Json" version="8.0.2" targetFramework="net40-client" /> | ||||
<package id="StringEx.CS" version="0.2" targetFramework="net40-client" /> | <package id="StringEx.CS" version="0.2" targetFramework="net40-client" /> | ||||
<package id="System.Net.Http" version="2.0.20710.0" targetFramework="net40-client" /> | |||||
</packages> | </packages> |
@@ -66,18 +66,6 @@ | |||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<Reference Include="Microsoft.CSharp" /> | <Reference Include="Microsoft.CSharp" /> | ||||
<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> | |||||
</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> | |||||
</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> | |||||
</Reference> | |||||
<Reference Include="Microsoft.VisualBasic" /> | <Reference Include="Microsoft.VisualBasic" /> | ||||
<Reference Include="Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> | <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> | <HintPath>3rd\Newtonsoft.Json.8.0.2\lib\net40\Newtonsoft.Json.dll</HintPath> | ||||
@@ -88,27 +76,7 @@ | |||||
<Reference Include="System" /> | <Reference Include="System" /> | ||||
<Reference Include="System.Data" /> | <Reference Include="System.Data" /> | ||||
<Reference Include="System.Drawing" /> | <Reference Include="System.Drawing" /> | ||||
<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> | |||||
</Reference> | |||||
<Reference Include="System.Net" /> | <Reference Include="System.Net" /> | ||||
<Reference Include="System.Net.Http, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||||
<HintPath>3rd\Microsoft.Net.Http.2.0.20710.0\lib\net40\System.Net.Http.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="System.Net.Http.WebRequest, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||||
<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.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||||
<HintPath>3rd\Microsoft.Bcl.1.1.10\lib\net40\System.Runtime.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<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> | |||||
</Reference> | |||||
<Reference Include="System.Windows.Forms" /> | <Reference Include="System.Windows.Forms" /> | ||||
<Reference Include="System.Windows.Forms.DataVisualization" /> | <Reference Include="System.Windows.Forms.DataVisualization" /> | ||||
<Reference Include="System.Xaml" /> | <Reference Include="System.Xaml" /> | ||||
@@ -332,10 +300,8 @@ | |||||
<PropertyGroup> | <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> | <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> | </PropertyGroup> | ||||
<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'))" /> | <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> | </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')" /> | <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')" /> | ||||
<UsingTask TaskName="CosturaCleanup" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" TaskFactory="CodeTaskFactory"> | <UsingTask TaskName="CosturaCleanup" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" TaskFactory="CodeTaskFactory"> | ||||
<ParameterGroup> | <ParameterGroup> | ||||
@@ -1,8 +0,0 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<packages> | |||||
<package id="Microsoft.Bcl" version="1.1.10" targetFramework="net45" /> | |||||
<package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net45" /> | |||||
<package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net45" /> | |||||
<package id="Microsoft.Net.Http" version="2.2.29" targetFramework="net45" /> | |||||
<package id="System.Net.Http" version="4.0.0" targetFramework="net45" /> | |||||
</packages> |
@@ -35,29 +35,9 @@ | |||||
<StartupObject /> | <StartupObject /> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<Reference Include="Microsoft.Threading.Tasks, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||||
<HintPath>..\shadowsocks-csharp\3rd\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="Microsoft.Threading.Tasks.Extensions, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||||
<HintPath>..\shadowsocks-csharp\3rd\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="Microsoft.Threading.Tasks.Extensions.Desktop, Version=1.0.168.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||||
<HintPath>..\shadowsocks-csharp\3rd\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="System" /> | <Reference Include="System" /> | ||||
<Reference Include="System.Net" /> | <Reference Include="System.Net" /> | ||||
<Reference Include="System.Net.Http" /> | <Reference Include="System.Net.Http" /> | ||||
<Reference Include="System.Net.Http.Extensions, Version=2.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||||
<HintPath>..\shadowsocks-csharp\3rd\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Extensions.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="System.Net.Http.Primitives, Version=4.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||||
<HintPath>..\shadowsocks-csharp\3rd\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="System.Net.Http.WebRequest" /> | <Reference Include="System.Net.Http.WebRequest" /> | ||||
</ItemGroup> | </ItemGroup> | ||||
<Choose> | <Choose> | ||||
@@ -82,9 +62,6 @@ | |||||
<Name>shadowsocks-csharp</Name> | <Name>shadowsocks-csharp</Name> | ||||
</ProjectReference> | </ProjectReference> | ||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | |||||
<None Include="packages.config" /> | |||||
</ItemGroup> | |||||
<Choose> | <Choose> | ||||
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'"> | <When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'"> | ||||
<ItemGroup> | <ItemGroup> | ||||
@@ -105,13 +82,6 @@ | |||||
</Choose> | </Choose> | ||||
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" /> | <Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" /> | ||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | ||||
<Import Project="..\shadowsocks-csharp\3rd\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\shadowsocks-csharp\3rd\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.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('..\shadowsocks-csharp\3rd\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\shadowsocks-csharp\3rd\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets'))" /> | |||||
</Target> | |||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. | <!-- 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. | Other similar extension points exist, see Microsoft.Common.targets. | ||||
<Target Name="BeforeBuild"> | <Target Name="BeforeBuild"> | ||||