diff --git a/shadowsocks-csharp/Controller/Logging.cs b/shadowsocks-csharp/Controller/Logging.cs
index 81f16dd8..c9f753d0 100755
--- a/shadowsocks-csharp/Controller/Logging.cs
+++ b/shadowsocks-csharp/Controller/Logging.cs
@@ -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
}
}
+ ///
+ /// Clear the log file
+ ///
+ ///
+ 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)
{
}
diff --git a/shadowsocks-csharp/Data/cn.txt b/shadowsocks-csharp/Data/cn.txt
index e092575c..1d5d6213 100644
--- a/shadowsocks-csharp/Data/cn.txt
+++ b/shadowsocks-csharp/Data/cn.txt
@@ -20,6 +20,7 @@ Edit User Rule for GFWList...=编辑 GFWList 的用户规则...
Show QRCode...=显示二维码...
Scan QRCode from Screen...=扫描屏幕上的二维码...
Show Logs...=显示日志...
+Clear Logs...=清除日志...
About...=关于...
Quit=退出
Edit Servers=编辑服务器
diff --git a/shadowsocks-csharp/Program.cs b/shadowsocks-csharp/Program.cs
index 8ca485d7..c5601893 100755
--- a/shadowsocks-csharp/Program.cs
+++ b/shadowsocks-csharp/Program.cs
@@ -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();
diff --git a/shadowsocks-csharp/Properties/Resources.Designer.cs b/shadowsocks-csharp/Properties/Resources.Designer.cs
index a5d9c107..0d6c77c4 100755
--- a/shadowsocks-csharp/Properties/Resources.Designer.cs
+++ b/shadowsocks-csharp/Properties/Resources.Designer.cs
@@ -1,10 +1,10 @@
//------------------------------------------------------------------------------
//
-// 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.
+// 对此文件的更改可能会导致不正确的行为,并且如果
+// 重新生成代码,这些更改将会丢失。
//
//------------------------------------------------------------------------------
@@ -13,12 +13,12 @@ namespace Shadowsocks.Properties {
///
- /// A strongly-typed resource class, for looking up localized strings, etc.
+ /// 一个强类型的资源类,用于查找本地化的字符串等。
///
- // 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 {
}
///
- /// Returns the cached ResourceManager instance used by this class.
+ /// 返回此类使用的缓存的 ResourceManager 实例。
///
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
@@ -47,8 +47,8 @@ namespace Shadowsocks.Properties {
}
///
- /// Overrides the current thread's CurrentUICulture property for all
- /// resource lookups using this strongly typed resource class.
+ /// 使用此强类型资源类,为所有资源查找
+ /// 重写当前线程的 CurrentUICulture 属性。
///
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
@@ -61,7 +61,7 @@ namespace Shadowsocks.Properties {
}
///
- /// Looks up a localized resource of type System.Byte[].
+ /// 查找 System.Byte[] 类型的本地化资源。
///
internal static byte[] abp_js {
get {
@@ -71,33 +71,30 @@ namespace Shadowsocks.Properties {
}
///
- /// 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...=清除日志...
+ /// [字符串的其余部分被截断]"; 的本地化字符串。
///
internal static string cn {
get {
@@ -106,7 +103,7 @@ namespace Shadowsocks.Properties {
}
///
- /// Looks up a localized resource of type System.Byte[].
+ /// 查找 System.Byte[] 类型的本地化资源。
///
internal static byte[] libsscrypto_dll {
get {
@@ -116,16 +113,27 @@ namespace Shadowsocks.Properties {
}
///
- /// 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. 的本地化字符串。
+ ///
+ internal static string MultiProcess {
+ get {
+ return ResourceManager.GetString("MultiProcess", resourceCulture);
+ }
+ }
+
+ ///
+ /// 查找类似 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 的本地化字符串。
///
internal static string polipo_config {
get {
@@ -134,7 +142,7 @@ namespace Shadowsocks.Properties {
}
///
- /// Looks up a localized resource of type System.Byte[].
+ /// 查找 System.Byte[] 类型的本地化资源。
///
internal static byte[] polipo_exe {
get {
@@ -144,7 +152,7 @@ namespace Shadowsocks.Properties {
}
///
- /// Looks up a localized resource of type System.Byte[].
+ /// 查找 System.Byte[] 类型的本地化资源。
///
internal static byte[] proxy_pac_txt {
get {
@@ -154,7 +162,7 @@ namespace Shadowsocks.Properties {
}
///
- /// Looks up a localized resource of type System.Drawing.Bitmap.
+ /// 查找 System.Drawing.Bitmap 类型的本地化资源。
///
internal static System.Drawing.Bitmap ss16 {
get {
@@ -164,7 +172,7 @@ namespace Shadowsocks.Properties {
}
///
- /// Looks up a localized resource of type System.Drawing.Bitmap.
+ /// 查找 System.Drawing.Bitmap 类型的本地化资源。
///
internal static System.Drawing.Bitmap ss20 {
get {
@@ -174,7 +182,7 @@ namespace Shadowsocks.Properties {
}
///
- /// Looks up a localized resource of type System.Drawing.Bitmap.
+ /// 查找 System.Drawing.Bitmap 类型的本地化资源。
///
internal static System.Drawing.Bitmap ss24 {
get {
@@ -184,7 +192,7 @@ namespace Shadowsocks.Properties {
}
///
- /// Looks up a localized resource of type System.Drawing.Bitmap.
+ /// 查找 System.Drawing.Bitmap 类型的本地化资源。
///
internal static System.Drawing.Bitmap ssw128 {
get {
@@ -194,9 +202,9 @@ namespace Shadowsocks.Properties {
}
///
- /// 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
- ///.
+ /// 的本地化字符串。
///
internal static string user_rule {
get {
diff --git a/shadowsocks-csharp/Properties/Resources.resx b/shadowsocks-csharp/Properties/Resources.resx
index aa851e6b..41ba3382 100755
--- a/shadowsocks-csharp/Properties/Resources.resx
+++ b/shadowsocks-csharp/Properties/Resources.resx
@@ -151,4 +151,9 @@
..\data\user-rule.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8
+
+ Shadowsocks is already running.
+
+Find Shadowsocks icon in your notify tray.
+
\ No newline at end of file
diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs
index ff5a018c..abbd5ebb 100755
--- a/shadowsocks-csharp/View/MenuViewController.cs
+++ b/shadowsocks-csharp/View/MenuViewController.cs
@@ -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);