@@ -1,27 +1,28 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.IO; | |||
using System.Net.Sockets; | |||
using System.Text; | |||
namespace Shadowsocks.Controller | |||
{ | |||
public class Logging | |||
{ | |||
public static string LogFile; | |||
public static bool OpenLogFile() | |||
private static FileStream _logFileStream; | |||
private static StreamWriter _streamWriter; | |||
public static bool AttatchToConsole() | |||
{ | |||
try | |||
{ | |||
string temppath = Path.GetTempPath(); | |||
LogFile = Path.Combine(temppath, "shadowsocks.log"); | |||
FileStream fs = new FileStream(LogFile, FileMode.Append); | |||
StreamWriterWithTimestamp sw = new StreamWriterWithTimestamp(fs); | |||
sw.AutoFlush = true; | |||
Console.SetOut(sw); | |||
Console.SetError(sw); | |||
if (_logFileStream == null) | |||
{ | |||
_logFileStream = new FileStream(LogFile, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite); | |||
_logFileStream.Seek(_logFileStream.Length, SeekOrigin.Begin); | |||
_streamWriter = new StreamWriterWithTimestamp(_logFileStream) { AutoFlush = true }; | |||
Console.SetOut(_streamWriter); | |||
Console.SetError(_streamWriter); | |||
} | |||
return true; | |||
} | |||
catch (IOException e) | |||
@@ -61,12 +62,33 @@ namespace Shadowsocks.Controller | |||
} | |||
} | |||
/// <summary> | |||
/// Clear the log file | |||
/// </summary> | |||
/// <returns></returns> | |||
public static bool Clear() | |||
{ | |||
if (_logFileStream != null) | |||
{ | |||
try | |||
{ | |||
_logFileStream.SetLength(0); | |||
return true; | |||
} | |||
catch (IOException ioException) | |||
{ | |||
Console.WriteLine(ioException); | |||
} | |||
} | |||
return false; | |||
} | |||
} | |||
// Simply extended System.IO.StreamWriter for adding timestamp workaround | |||
public class StreamWriterWithTimestamp : StreamWriter | |||
{ | |||
public StreamWriterWithTimestamp(Stream stream) : base(stream) | |||
public StreamWriterWithTimestamp(Stream stream) | |||
: base(stream) | |||
{ | |||
} | |||
@@ -20,6 +20,7 @@ Edit User Rule for GFWList...=编辑 GFWList 的用户规则... | |||
Show QRCode...=显示二维码... | |||
Scan QRCode from Screen...=扫描屏幕上的二维码... | |||
Show Logs...=显示日志... | |||
Clear Logs...=清除日志... | |||
About...=关于... | |||
Quit=退出 | |||
Edit Servers=编辑服务器 | |||
@@ -1,12 +1,12 @@ | |||
using Shadowsocks.Controller; | |||
using Shadowsocks.Properties; | |||
using Shadowsocks.View; | |||
using System; | |||
using System.Collections.Generic; | |||
using System; | |||
using System.Diagnostics; | |||
using System.IO; | |||
using System.Threading; | |||
using System.Windows.Forms; | |||
using Shadowsocks.Controller; | |||
using Shadowsocks.Properties; | |||
using Shadowsocks.Util; | |||
using Shadowsocks.View; | |||
namespace Shadowsocks | |||
{ | |||
@@ -18,8 +18,8 @@ namespace Shadowsocks | |||
[STAThread] | |||
static void Main() | |||
{ | |||
Util.Utils.ReleaseMemory(); | |||
using (Mutex mutex = new Mutex(false, "Global\\" + "71981632-A427-497F-AB91-241CD227EC1F")) | |||
Utils.ReleaseMemory(); | |||
using (var mutex = new Mutex(false, "Global\\" + "71981632-A427-497F-AB91-241CD227EC1F")) | |||
{ | |||
Application.EnableVisualStyles(); | |||
Application.SetCompatibleTextRenderingDefault(false); | |||
@@ -29,18 +29,17 @@ namespace Shadowsocks | |||
Process[] oldProcesses = Process.GetProcessesByName("Shadowsocks"); | |||
if (oldProcesses.Length > 0) | |||
{ | |||
Process oldProcess = oldProcesses[0]; | |||
} | |||
MessageBox.Show("Shadowsocks is already running.\n\nFind Shadowsocks icon in your notify tray."); | |||
MessageBox.Show(Resources.MultiProcess); | |||
return; | |||
} | |||
Directory.SetCurrentDirectory(Application.StartupPath); | |||
#if !DEBUG | |||
Logging.OpenLogFile(); | |||
Logging.AttatchToConsole(); | |||
#endif | |||
ShadowsocksController controller = new ShadowsocksController(); | |||
MenuViewController viewController = new MenuViewController(controller); | |||
MenuViewController.AttachMenu(controller); | |||
controller.Start(); | |||
@@ -1,10 +1,10 @@ | |||
//------------------------------------------------------------------------------ | |||
// <auto-generated> | |||
// This code was generated by a tool. | |||
// Runtime Version:4.0.30319.34209 | |||
// 此代码由工具生成。 | |||
// 运行时版本:4.0.30319.0 | |||
// | |||
// Changes to this file may cause incorrect behavior and will be lost if | |||
// the code is regenerated. | |||
// 对此文件的更改可能会导致不正确的行为,并且如果 | |||
// 重新生成代码,这些更改将会丢失。 | |||
// </auto-generated> | |||
//------------------------------------------------------------------------------ | |||
@@ -13,12 +13,12 @@ namespace Shadowsocks.Properties { | |||
/// <summary> | |||
/// A strongly-typed resource class, for looking up localized strings, etc. | |||
/// 一个强类型的资源类,用于查找本地化的字符串等。 | |||
/// </summary> | |||
// This class was auto-generated by the StronglyTypedResourceBuilder | |||
// class via a tool like ResGen or Visual Studio. | |||
// To add or remove a member, edit your .ResX file then rerun ResGen | |||
// with the /str option, or rebuild your VS project. | |||
// 此类是由 StronglyTypedResourceBuilder | |||
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 | |||
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen | |||
// (以 /str 作为命令选项),或重新生成 VS 项目。 | |||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] | |||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] | |||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] | |||
@@ -33,7 +33,7 @@ namespace Shadowsocks.Properties { | |||
} | |||
/// <summary> | |||
/// Returns the cached ResourceManager instance used by this class. | |||
/// 返回此类使用的缓存的 ResourceManager 实例。 | |||
/// </summary> | |||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] | |||
internal static global::System.Resources.ResourceManager ResourceManager { | |||
@@ -47,8 +47,8 @@ namespace Shadowsocks.Properties { | |||
} | |||
/// <summary> | |||
/// Overrides the current thread's CurrentUICulture property for all | |||
/// resource lookups using this strongly typed resource class. | |||
/// 使用此强类型资源类,为所有资源查找 | |||
/// 重写当前线程的 CurrentUICulture 属性。 | |||
/// </summary> | |||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] | |||
internal static global::System.Globalization.CultureInfo Culture { | |||
@@ -61,7 +61,7 @@ namespace Shadowsocks.Properties { | |||
} | |||
/// <summary> | |||
/// Looks up a localized resource of type System.Byte[]. | |||
/// 查找 System.Byte[] 类型的本地化资源。 | |||
/// </summary> | |||
internal static byte[] abp_js { | |||
get { | |||
@@ -71,33 +71,30 @@ namespace Shadowsocks.Properties { | |||
} | |||
/// <summary> | |||
/// Looks up a localized string similar to Shadowsocks=Shadowsocks | |||
///Enable System Proxy=启用系统代理 | |||
///Mode=系统代理模式 | |||
///PAC=PAC 模式 | |||
///Global=全局模式 | |||
///Servers=服务器 | |||
///Edit Servers...=编辑服务器... | |||
///Start on Boot=开机启动 | |||
///Allow Clients from LAN=允许来自局域网的连接 | |||
///Edit PAC File...=编辑 PAC 文件... | |||
///Edit User Rule for GFWList...=编辑 GFWList 的用户规则... | |||
///Show QRCode...=显示二维码... | |||
///Scan QRCode from Screen...=扫描屏幕上的二维码... | |||
///Show Logs...=显示日志... | |||
///About...=关于... | |||
///Quit=退出 | |||
///Edit Servers=编辑服务器 | |||
///&Add=添加(&A) | |||
///&Delete=删除(&D) | |||
///Server=服务器 | |||
///Server IP=服务器 IP | |||
///Server Port=服务器端口 | |||
///Password=密码 | |||
///Encryption=加密 | |||
///Proxy Port=代理端口 | |||
///Remarks=备注 | |||
///OK= [rest of string was truncated]";. | |||
/// 查找类似 # translation for Simplified Chinese | |||
/// | |||
///Shadowsocks=Shadowsocks | |||
/// | |||
///# Menu items | |||
/// | |||
///Enable System Proxy=启用系统代理 | |||
///Mode=系统代理模式 | |||
///PAC=PAC 模式 | |||
///Global=全局模式 | |||
///Servers=服务器 | |||
///Edit Servers...=编辑服务器... | |||
///Start on Boot=开机启动 | |||
///Allow Clients from LAN=允许来自局域网的连接 | |||
///Local PAC=使用本地 PAC | |||
///Online PAC=使用在线 PAC | |||
///Edit Local PAC File...=编辑本地 PAC 文件... | |||
///Update Local PAC from GFWList=从 GFWList 更新本地 PAC | |||
///Edit User Rule for GFWList...=编辑 GFWList 的用户规则... | |||
///Show QRCode...=显示二维码... | |||
///Scan QRCode from Screen...=扫描屏幕上的二维码... | |||
///Show Logs...=显示日志... | |||
///Clear Logs...=清除日志... | |||
/// [字符串的其余部分被截断]"; 的本地化字符串。 | |||
/// </summary> | |||
internal static string cn { | |||
get { | |||
@@ -106,7 +103,7 @@ namespace Shadowsocks.Properties { | |||
} | |||
/// <summary> | |||
/// Looks up a localized resource of type System.Byte[]. | |||
/// 查找 System.Byte[] 类型的本地化资源。 | |||
/// </summary> | |||
internal static byte[] libsscrypto_dll { | |||
get { | |||
@@ -116,16 +113,27 @@ namespace Shadowsocks.Properties { | |||
} | |||
/// <summary> | |||
/// Looks up a localized string similar to proxyAddress = "__POLIPO_BIND_IP__" | |||
///proxyPort = 8123 | |||
/// | |||
///socksParentProxy = "127.0.0.1:__SOCKS_PORT__" | |||
///socksProxyType = socks5 | |||
///diskCacheRoot = "" | |||
///localDocumentRoot = "" | |||
/// | |||
/// 查找类似 Shadowsocks is already running. | |||
/// | |||
///Find Shadowsocks icon in your notify tray. 的本地化字符串。 | |||
/// </summary> | |||
internal static string MultiProcess { | |||
get { | |||
return ResourceManager.GetString("MultiProcess", resourceCulture); | |||
} | |||
} | |||
/// <summary> | |||
/// 查找类似 proxyAddress = "__POLIPO_BIND_IP__" | |||
///proxyPort = 8123 | |||
/// | |||
///socksParentProxy = "127.0.0.1:__SOCKS_PORT__" | |||
///socksProxyType = socks5 | |||
///diskCacheRoot = "" | |||
///localDocumentRoot = "" | |||
/// | |||
///allowedPorts = 1-65535 | |||
///tunnelAllowedPorts = 1-65535. | |||
///tunnelAllowedPorts = 1-65535 的本地化字符串。 | |||
/// </summary> | |||
internal static string polipo_config { | |||
get { | |||
@@ -134,7 +142,7 @@ namespace Shadowsocks.Properties { | |||
} | |||
/// <summary> | |||
/// Looks up a localized resource of type System.Byte[]. | |||
/// 查找 System.Byte[] 类型的本地化资源。 | |||
/// </summary> | |||
internal static byte[] polipo_exe { | |||
get { | |||
@@ -144,7 +152,7 @@ namespace Shadowsocks.Properties { | |||
} | |||
/// <summary> | |||
/// Looks up a localized resource of type System.Byte[]. | |||
/// 查找 System.Byte[] 类型的本地化资源。 | |||
/// </summary> | |||
internal static byte[] proxy_pac_txt { | |||
get { | |||
@@ -154,7 +162,7 @@ namespace Shadowsocks.Properties { | |||
} | |||
/// <summary> | |||
/// Looks up a localized resource of type System.Drawing.Bitmap. | |||
/// 查找 System.Drawing.Bitmap 类型的本地化资源。 | |||
/// </summary> | |||
internal static System.Drawing.Bitmap ss16 { | |||
get { | |||
@@ -164,7 +172,7 @@ namespace Shadowsocks.Properties { | |||
} | |||
/// <summary> | |||
/// Looks up a localized resource of type System.Drawing.Bitmap. | |||
/// 查找 System.Drawing.Bitmap 类型的本地化资源。 | |||
/// </summary> | |||
internal static System.Drawing.Bitmap ss20 { | |||
get { | |||
@@ -174,7 +182,7 @@ namespace Shadowsocks.Properties { | |||
} | |||
/// <summary> | |||
/// Looks up a localized resource of type System.Drawing.Bitmap. | |||
/// 查找 System.Drawing.Bitmap 类型的本地化资源。 | |||
/// </summary> | |||
internal static System.Drawing.Bitmap ss24 { | |||
get { | |||
@@ -184,7 +192,7 @@ namespace Shadowsocks.Properties { | |||
} | |||
/// <summary> | |||
/// Looks up a localized resource of type System.Drawing.Bitmap. | |||
/// 查找 System.Drawing.Bitmap 类型的本地化资源。 | |||
/// </summary> | |||
internal static System.Drawing.Bitmap ssw128 { | |||
get { | |||
@@ -194,9 +202,9 @@ namespace Shadowsocks.Properties { | |||
} | |||
/// <summary> | |||
/// Looks up a localized string similar to ! Put user rules line by line in this file. | |||
/// 查找类似 ! Put user rules line by line in this file. | |||
///! See https://adblockplus.org/en/filter-cheatsheet | |||
///. | |||
/// 的本地化字符串。 | |||
/// </summary> | |||
internal static string user_rule { | |||
get { | |||
@@ -151,4 +151,9 @@ | |||
<data name="user_rule" type="System.Resources.ResXFileRef, System.Windows.Forms"> | |||
<value>..\data\user-rule.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value> | |||
</data> | |||
<data name="MultiProcess" xml:space="preserve"> | |||
<value>Shadowsocks is already running. | |||
Find Shadowsocks icon in your notify tray.</value> | |||
</data> | |||
</root> |
@@ -1,12 +1,13 @@ | |||
using Shadowsocks.Controller; | |||
using Shadowsocks.Model; | |||
using Shadowsocks.Properties; | |||
using System; | |||
using System.Collections.Generic; | |||
using System; | |||
using System.Diagnostics; | |||
using System.Drawing; | |||
using System.Text; | |||
using System.IO; | |||
using System.Windows.Forms; | |||
using Microsoft.VisualBasic; | |||
using Shadowsocks.Controller; | |||
using Shadowsocks.Model; | |||
using Shadowsocks.Properties; | |||
using Shadowsocks.Util; | |||
using ZXing; | |||
using ZXing.Common; | |||
using ZXing.QrCode; | |||
@@ -18,7 +19,7 @@ namespace Shadowsocks.View | |||
// yes this is just a menu view controller | |||
// when config form is closed, it moves away from RAM | |||
// and it should just do anything related to the config form | |||
private ShadowsocksController controller; | |||
private UpdateChecker updateChecker; | |||
@@ -44,7 +45,12 @@ namespace Shadowsocks.View | |||
private ConfigForm configForm; | |||
private string _urlToOpen; | |||
public MenuViewController(ShadowsocksController controller) | |||
public static MenuViewController AttachMenu(ShadowsocksController controller) | |||
{ | |||
return new MenuViewController(controller); | |||
} | |||
private MenuViewController(ShadowsocksController controller) | |||
{ | |||
this.controller = controller; | |||
@@ -80,7 +86,7 @@ namespace Shadowsocks.View | |||
} | |||
} | |||
void controller_Errored(object sender, System.IO.ErrorEventArgs e) | |||
void controller_Errored(object sender, ErrorEventArgs e) | |||
{ | |||
MessageBox.Show(e.GetException().ToString(), String.Format(I18N.GetString("Shadowsocks Error: {0}"), e.GetException().Message)); | |||
} | |||
@@ -171,6 +177,7 @@ namespace Shadowsocks.View | |||
this.ShareOverLANItem = CreateMenuItem("Allow Clients from LAN", new EventHandler(this.ShareOverLANItem_Click)), | |||
new MenuItem("-"), | |||
CreateMenuItem("Show Logs...", new EventHandler(this.ShowLogItem_Click)), | |||
CreateMenuItem("Clear Logs...",ClearLogItem_Click), | |||
CreateMenuItem("About...", new EventHandler(this.AboutItem_Click)), | |||
new MenuItem("-"), | |||
CreateMenuItem("Quit", new EventHandler(this.Quit_Click)) | |||
@@ -204,7 +211,7 @@ namespace Shadowsocks.View | |||
{ | |||
string argument = @"/select, " + e.Path; | |||
System.Diagnostics.Process.Start("explorer.exe", argument); | |||
Process.Start("explorer.exe", argument); | |||
} | |||
void ShowBalloonTip(string title, string content, ToolTipIcon icon, int timeout) | |||
@@ -215,7 +222,7 @@ namespace Shadowsocks.View | |||
_notifyIcon.ShowBalloonTip(timeout); | |||
} | |||
void controller_UpdatePACFromGFWListError(object sender, System.IO.ErrorEventArgs e) | |||
void controller_UpdatePACFromGFWListError(object sender, ErrorEventArgs e) | |||
{ | |||
ShowBalloonTip(I18N.GetString("Failed to update PAC file"), e.GetException().Message, ToolTipIcon.Error, 5000); | |||
Logging.LogUsefulException(e.GetException()); | |||
@@ -236,7 +243,7 @@ namespace Shadowsocks.View | |||
void notifyIcon1_BalloonTipClicked(object sender, EventArgs e) | |||
{ | |||
System.Diagnostics.Process.Start(updateChecker.LatestVersionURL); | |||
Process.Start(updateChecker.LatestVersionURL); | |||
_notifyIcon.BalloonTipClicked -= notifyIcon1_BalloonTipClicked; | |||
} | |||
@@ -297,7 +304,7 @@ namespace Shadowsocks.View | |||
void configForm_FormClosed(object sender, FormClosedEventArgs e) | |||
{ | |||
configForm = null; | |||
Util.Utils.ReleaseMemory(); | |||
Utils.ReleaseMemory(); | |||
ShowFirstTimeBalloon(); | |||
} | |||
@@ -318,7 +325,7 @@ namespace Shadowsocks.View | |||
if (_isFirstRun) | |||
{ | |||
_notifyIcon.BalloonTipTitle = I18N.GetString("Shadowsocks is here"); | |||
_notifyIcon.BalloonTipText = I18N.GetString("You can turn on/off Shadowsocks in the context menu"); | |||
_notifyIcon.BalloonTipText = I18N.GetString("You can turn on/off Shadowsocks in the context menu"); | |||
_notifyIcon.BalloonTipIcon = ToolTipIcon.Info; | |||
_notifyIcon.ShowBalloonTip(0); | |||
_isFirstRun = false; | |||
@@ -384,7 +391,12 @@ namespace Shadowsocks.View | |||
{ | |||
string argument = Logging.LogFile; | |||
System.Diagnostics.Process.Start("notepad.exe", argument); | |||
Process.Start("notepad.exe", argument); | |||
} | |||
private void ClearLogItem_Click(object sender, EventArgs e) | |||
{ | |||
Logging.Clear(); | |||
} | |||
private void QRCodeItem_Click(object sender, EventArgs e) | |||
@@ -489,12 +501,14 @@ namespace Shadowsocks.View | |||
Process.Start(_urlToOpen); | |||
} | |||
private void AutoStartupItem_Click(object sender, EventArgs e) { | |||
AutoStartupItem.Checked = !AutoStartupItem.Checked; | |||
if (!AutoStartup.Set(AutoStartupItem.Checked)) { | |||
MessageBox.Show(I18N.GetString("Failed to update registry")); | |||
} | |||
} | |||
private void AutoStartupItem_Click(object sender, EventArgs e) | |||
{ | |||
AutoStartupItem.Checked = !AutoStartupItem.Checked; | |||
if (!AutoStartup.Set(AutoStartupItem.Checked)) | |||
{ | |||
MessageBox.Show(I18N.GetString("Failed to update registry")); | |||
} | |||
} | |||
private void LocalPACItem_Click(object sender, EventArgs e) | |||
{ | |||
@@ -528,7 +542,7 @@ namespace Shadowsocks.View | |||
private void UpdateOnlinePACURLItem_Click(object sender, EventArgs e) | |||
{ | |||
string origPacUrl = controller.GetConfiguration().pacUrl; | |||
string pacUrl = Microsoft.VisualBasic.Interaction.InputBox( | |||
string pacUrl = Interaction.InputBox( | |||
I18N.GetString("Please input PAC Url"), | |||
I18N.GetString("Edit Online PAC URL"), | |||
origPacUrl, -1, -1); | |||