You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

Program.cs 6.5 kB

10 years ago
10 years ago
10 years ago
12 years ago
12 years ago
10 years ago
12 years ago
12 years ago
10 years ago
10 years ago
10 years ago
10 years ago
12 years ago
12 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. using System;
  2. using System.Diagnostics;
  3. using System.IO;
  4. using System.Threading;
  5. using System.Windows.Forms;
  6. using Microsoft.Win32;
  7. using Shadowsocks.Controller;
  8. using Shadowsocks.Util;
  9. using Shadowsocks.View;
  10. namespace Shadowsocks
  11. {
  12. static class Program
  13. {
  14. private static ShadowsocksController _controller;
  15. // XXX: Don't change this name
  16. private static MenuViewController _viewController;
  17. /// <summary>
  18. /// 应用程序的主入口点。
  19. /// </summary>
  20. [STAThread]
  21. static void Main()
  22. {
  23. // Check OS since we are using dual-mode socket
  24. if (!Utils.IsWinVistaOrHigher())
  25. {
  26. MessageBox.Show(I18N.GetString("Unsupported operating system, use Windows Vista at least."),
  27. "Shadowsocks Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
  28. return;
  29. }
  30. Utils.ReleaseMemory(true);
  31. using (Mutex mutex = new Mutex(false, $"Global\\Shadowsocks_{Application.StartupPath.GetHashCode()}"))
  32. {
  33. Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
  34. // handle UI exceptions
  35. Application.ThreadException += Application_ThreadException;
  36. // handle non-UI exceptions
  37. AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
  38. Application.ApplicationExit += Application_ApplicationExit;
  39. SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
  40. Application.EnableVisualStyles();
  41. Application.SetCompatibleTextRenderingDefault(false);
  42. Application.ApplicationExit += (sender, args) => HotKeys.Destroy();
  43. if (!mutex.WaitOne(0, false))
  44. {
  45. Process[] oldProcesses = Process.GetProcessesByName("Shadowsocks");
  46. if (oldProcesses.Length > 0)
  47. {
  48. Process oldProcess = oldProcesses[0];
  49. }
  50. MessageBox.Show(I18N.GetString("Find Shadowsocks icon in your notify tray.")
  51. + Environment.NewLine
  52. + I18N.GetString("If you want to start multiple Shadowsocks, make a copy in another directory."),
  53. I18N.GetString("Shadowsocks is already running."));
  54. return;
  55. }
  56. Directory.SetCurrentDirectory(Application.StartupPath);
  57. #if DEBUG
  58. Logging.OpenLogFile();
  59. // truncate privoxy log file while debugging
  60. string privoxyLogFilename = Utils.GetTempPath("privoxy.log");
  61. if (File.Exists(privoxyLogFilename))
  62. using (new FileStream(privoxyLogFilename, FileMode.Truncate)) { }
  63. #else
  64. Logging.OpenLogFile();
  65. #endif
  66. _controller = new ShadowsocksController();
  67. _viewController = new MenuViewController(_controller);
  68. HotKeys.Init();
  69. _controller.Start();
  70. Application.Run();
  71. }
  72. }
  73. private static int exited = 0;
  74. private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
  75. {
  76. if (Interlocked.Increment(ref exited) == 1)
  77. {
  78. Logging.Error(e.ExceptionObject?.ToString());
  79. MessageBox.Show(
  80. $"{I18N.GetString("Unexpected error, shadowsocks will exit. Please report to")} https://github.com/shadowsocks/shadowsocks-windows/issues {Environment.NewLine}{(e.ExceptionObject?.ToString())}",
  81. "Shadowsocks Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
  82. Application.Exit();
  83. }
  84. }
  85. private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
  86. {
  87. string errorMsg = $"Exception Type: {e.GetType().Name}{Environment.NewLine}Stack Trace:{Environment.NewLine}{e.Exception.StackTrace}";
  88. Logging.Error(errorMsg);
  89. MessageBox.Show(
  90. $"{I18N.GetString("Unexpected error, shadowsocks will exit. Please report to")} https://github.com/shadowsocks/shadowsocks-windows/issues {Environment.NewLine}{errorMsg}",
  91. "Shadowsocks Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
  92. Application.Exit();
  93. }
  94. private static void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
  95. {
  96. switch (e.Mode)
  97. {
  98. case PowerModes.Resume:
  99. Logging.Info("os wake up");
  100. if (_controller != null)
  101. {
  102. System.Timers.Timer timer = new System.Timers.Timer(5 * 1000);
  103. timer.Elapsed += Timer_Elapsed;
  104. timer.AutoReset = false;
  105. timer.Enabled = true;
  106. timer.Start();
  107. }
  108. break;
  109. case PowerModes.Suspend:
  110. _controller?.Stop();
  111. Logging.Info("os suspend");
  112. break;
  113. }
  114. }
  115. private static void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
  116. {
  117. try
  118. {
  119. _controller?.Start();
  120. }
  121. catch (Exception ex)
  122. {
  123. Logging.LogUsefulException(ex);
  124. }
  125. finally
  126. {
  127. try
  128. {
  129. System.Timers.Timer timer = (System.Timers.Timer)sender;
  130. timer.Enabled = false;
  131. timer.Stop();
  132. timer.Dispose();
  133. }
  134. catch (Exception ex)
  135. {
  136. Logging.LogUsefulException(ex);
  137. }
  138. }
  139. }
  140. private static void Application_ApplicationExit(object sender, EventArgs e)
  141. {
  142. if (_controller != null)
  143. {
  144. _controller.Stop();
  145. _controller = null;
  146. }
  147. }
  148. }
  149. }