Conflicts: shadowsocks-csharp/Controller/Local.cs shadowsocks-csharp/Controller/PACServer.cs shadowsocks-csharp/Controller/PolipoRunner.cs shadowsocks-csharp/Controller/ShadowsocksController.cs shadowsocks-csharp/Program.cs shadowsocks-csharp/View/ConfigForm.Designer.cs shadowsocks-csharp/View/ConfigForm.cspull/44/head
@@ -1,6 +1,7 @@ | |||
Backup/ | |||
shadowsocks-csharp/bin/ | |||
shadowsocks-csharp/obj/ | |||
bin/ | |||
obj/ | |||
shadowsocks-csharp/shadowsocks-csharp.csproj.user | |||
TestResults | |||
*.suo | |||
@@ -1,12 +1,17 @@ | |||
2.0.4 | |||
2.0.5 2014-11-09 | |||
- Fix QRCode size | |||
- Share over LAN option | |||
- Log to temp path instead | |||
2.0.4 2014-11-09 | |||
- Try to fix data corruption | |||
- Remove all configuration except x86 | |||
2.0.3 | |||
2.0.3 2014-11-08 | |||
- Support QRCode generation | |||
- Fix compatibility issues with some Chrome version | |||
2.0.2 | |||
2.0.2 2014-11-08 | |||
- Add remarks | |||
- Fix error when polipo is killed | |||
@@ -20,6 +20,9 @@ For Windows 7 and older, please download Shadowsocks-win-x.x.x.zip. | |||
For Windows 8.1 and newer, please download Shadowsocks-win-dotnet4.0-x.x.x.zip. | |||
Notice there's a bug on .Net 4.0 version. If you encounter crashes, try using | |||
.Net 2.0 version. Please help us resolve this issue if you have any clue. | |||
### Usage | |||
1. Find Shadowsocks icon in notification tray | |||
@@ -3,6 +3,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00 | |||
# Visual Studio Express 2012 for Windows Desktop | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "shadowsocks-csharp", "shadowsocks-csharp\shadowsocks-csharp.csproj", "{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test", "test\test.csproj", "{45913187-0685-4903-B250-DCEF0479CD86}" | |||
ProjectSection(ProjectDependencies) = postProject | |||
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062} = {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062} | |||
EndProjectSection | |||
EndProject | |||
Global | |||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||
Debug|x86 = Debug|x86 | |||
@@ -14,6 +19,10 @@ Global | |||
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|x86.Deploy.0 = Debug|x86 | |||
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Release|x86.ActiveCfg = Release|x86 | |||
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Release|x86.Build.0 = Release|x86 | |||
{45913187-0685-4903-B250-DCEF0479CD86}.Debug|x86.ActiveCfg = Debug|x86 | |||
{45913187-0685-4903-B250-DCEF0479CD86}.Debug|x86.Build.0 = Debug|x86 | |||
{45913187-0685-4903-B250-DCEF0479CD86}.Release|x86.ActiveCfg = Release|x86 | |||
{45913187-0685-4903-B250-DCEF0479CD86}.Release|x86.Build.0 = Release|x86 | |||
EndGlobalSection | |||
GlobalSection(SolutionProperties) = preSolution | |||
HideSolutionNode = FALSE | |||
@@ -10,14 +10,15 @@ namespace Shadowsocks.Controller | |||
{ | |||
class Local | |||
{ | |||
private Server config; | |||
public bool openOnLan; | |||
{ | |||
private Server _server; | |||
private bool _shareOverLAN; | |||
//private Encryptor encryptor; | |||
Socket _listener; | |||
public Local(Server config) | |||
public Local(Configuration config) | |||
{ | |||
this.config = config; | |||
this._server = config.GetCurrentServer(); | |||
_shareOverLAN = config.shareOverLan; | |||
//this.encryptor = new Encryptor(config.method, config.password); | |||
} | |||
@@ -25,17 +26,17 @@ namespace Shadowsocks.Controller | |||
{ | |||
try | |||
{ | |||
// Create a TCP/IP socket. | |||
_listener = new Socket(AddressFamily.InterNetwork, | |||
SocketType.Stream, ProtocolType.Tcp); | |||
// Create a TCP/IP socket. | |||
_listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); | |||
_listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); | |||
IPEndPoint localEndPoint = null; | |||
if (openOnLan) | |||
if (_shareOverLAN) | |||
{ | |||
localEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), config.local_port); | |||
localEndPoint = new IPEndPoint(IPAddress.Any, _server.local_port); | |||
} | |||
else | |||
{ | |||
localEndPoint = new IPEndPoint(IPAddress.Loopback, config.local_port); | |||
localEndPoint = new IPEndPoint(IPAddress.Loopback, _server.local_port); | |||
} | |||
// Bind the socket to the local endpoint and listen for incoming connections. | |||
@@ -67,37 +68,19 @@ namespace Shadowsocks.Controller | |||
{ | |||
try | |||
{ | |||
// Get the socket that handles the client request. | |||
Socket listener = (Socket)ar.AsyncState; | |||
//if (!listener.Connected) | |||
//{ | |||
// return; | |||
//} | |||
Socket conn = listener.EndAccept(ar); | |||
listener.BeginAccept( | |||
new AsyncCallback(AcceptCallback), | |||
listener); | |||
// Create the state object. | |||
Handler handler = new Handler(); | |||
handler.connection = conn; | |||
//if (encryptor.method == "table") | |||
//{ | |||
// handler.encryptor = encryptor; | |||
//} | |||
//else | |||
//{ | |||
// handler.encryptor = new Encryptor(config.method, config.password); | |||
//} | |||
handler.encryptor = EncryptorFactory.GetEncryptor(config.method, config.password); | |||
handler.config = config; | |||
handler.encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password); | |||
handler.config = _server; | |||
handler.Start(); | |||
//handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, | |||
// new AsyncCallback(ReadCallback), state); | |||
} | |||
catch | |||
{ | |||
@@ -331,7 +314,7 @@ namespace Shadowsocks.Controller | |||
} | |||
else | |||
{ | |||
Console.WriteLine("bytesRead: " + bytesRead.ToString()); | |||
//Console.WriteLine("bytesRead: " + bytesRead.ToString()); | |||
this.Close(); | |||
} | |||
} | |||
@@ -0,0 +1,34 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.IO; | |||
using System.Text; | |||
namespace Shadowsocks.Controller | |||
{ | |||
public class Logging | |||
{ | |||
public static string LogFile; | |||
public static bool OpenLogFile() | |||
{ | |||
try | |||
{ | |||
string temppath = Path.GetTempPath(); | |||
LogFile = Path.Combine(temppath, "shadowsocks.log"); | |||
FileStream fs = new FileStream(LogFile, FileMode.Append); | |||
TextWriter tmp = Console.Out; | |||
StreamWriter sw = new StreamWriter(fs); | |||
sw.AutoFlush = true; | |||
Console.SetOut(sw); | |||
Console.SetError(sw); | |||
return true; | |||
} | |||
catch (IOException e) | |||
{ | |||
Console.WriteLine(e.ToString()); | |||
return false; | |||
} | |||
} | |||
} | |||
} |
@@ -1,4 +1,5 @@ | |||
using Shadowsocks.Properties; | |||
using Shadowsocks.Model; | |||
using Shadowsocks.Properties; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Diagnostics; | |||
@@ -12,51 +13,51 @@ namespace Shadowsocks.Controller | |||
{ | |||
class PACServer | |||
{ | |||
private static int PORT = 8090; | |||
private static string PAC_FILE = "pac.txt"; | |||
public bool openOnLan; | |||
Socket _listener; | |||
FileSystemWatcher watcher; | |||
public event EventHandler PACFileChanged; | |||
public void Start() | |||
public void Start(Configuration configuration) | |||
{ | |||
// Create a TCP/IP socket. | |||
_listener = new Socket(AddressFamily.InterNetwork, | |||
SocketType.Stream, ProtocolType.Tcp); | |||
_listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); | |||
IPEndPoint localEndPoint = null; | |||
if (openOnLan) | |||
try | |||
{ | |||
localEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 8090); | |||
// Create a TCP/IP socket. | |||
_listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); | |||
_listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); | |||
IPEndPoint localEndPoint = null; | |||
if (configuration.shareOverLan) | |||
{ | |||
localEndPoint = new IPEndPoint(IPAddress.Any, PORT); | |||
} | |||
else | |||
{ | |||
localEndPoint = new IPEndPoint(IPAddress.Loopback, PORT); | |||
} | |||
// Bind the socket to the local endpoint and listen for incoming connections. | |||
_listener.Bind(localEndPoint); | |||
_listener.Listen(100); | |||
_listener.BeginAccept( | |||
new AsyncCallback(AcceptCallback), | |||
_listener); | |||
WatchPacFile(); | |||
} | |||
else | |||
catch (SocketException) | |||
{ | |||
localEndPoint = new IPEndPoint(IPAddress.Loopback, 8090); | |||
_listener.Close(); | |||
throw; | |||
} | |||
// Bind the socket to the local endpoint and listen for incoming connections. | |||
_listener.Bind(localEndPoint); | |||
_listener.Listen(100); | |||
_listener.BeginAccept( | |||
new AsyncCallback(AcceptCallback), | |||
_listener); | |||
WatchPacFile(); | |||
} | |||
public void Stop() | |||
{ | |||
try | |||
{ | |||
_listener.Close(); | |||
} | |||
catch (Exception) | |||
{ | |||
throw; | |||
} | |||
_listener.Close(); | |||
_listener = null; | |||
} | |||
public string TouchPACFile() | |||
@@ -78,10 +79,10 @@ namespace Shadowsocks.Controller | |||
try | |||
{ | |||
Socket listener = (Socket)ar.AsyncState; | |||
Socket conn = listener.EndAccept(ar); | |||
listener.BeginAccept( | |||
new AsyncCallback(AcceptCallback), | |||
listener); | |||
Socket conn = listener.EndAccept(ar); | |||
conn.BeginReceive(new byte[1024], 0, 1024, 0, | |||
new AsyncCallback(ReceiveCallback), conn); | |||
@@ -115,7 +116,6 @@ namespace Shadowsocks.Controller | |||
return System.Text.Encoding.UTF8.GetString(buffer, 0, n); | |||
} | |||
} | |||
WatchPacFile(); | |||
} | |||
private void ReceiveCallback(IAsyncResult ar) | |||
@@ -127,7 +127,9 @@ namespace Shadowsocks.Controller | |||
string pac = GetPACContent(); | |||
string proxy = "PROXY 127.0.0.1:8123;"; | |||
IPEndPoint localEndPoint = (IPEndPoint)conn.LocalEndPoint; | |||
string proxy = "PROXY " + localEndPoint.Address + ":8123;"; | |||
pac = pac.Replace("__PROXY__", proxy); | |||
@@ -14,8 +14,9 @@ namespace Shadowsocks.Controller | |||
private Process _process; | |||
public bool openOnLan; | |||
public void Start(Server config) | |||
public void Start(Configuration configuration) | |||
{ | |||
Server server = configuration.GetCurrentServer(); | |||
if (_process == null) | |||
{ | |||
Process[] existingPolipo = Process.GetProcessesByName("ss_polipo"); | |||
@@ -31,17 +32,10 @@ namespace Shadowsocks.Controller | |||
Console.WriteLine(e.ToString()); | |||
} | |||
} | |||
string temppath = Path.GetTempPath(); | |||
string polipoConfig = Resources.polipo_config; | |||
polipoConfig = polipoConfig.Replace("__SOCKS_PORT__", config.local_port.ToString()); | |||
if (openOnLan) | |||
{ | |||
polipoConfig = polipoConfig.Replace("\"127.0.0.1\"", "\"0.0.0.0\""); | |||
} | |||
else | |||
{ | |||
polipoConfig = polipoConfig.Replace("\"0.0.0.0\"", "\"127.0.0.1\""); | |||
} | |||
string temppath = Path.GetTempPath(); | |||
string polipoConfig = Resources.polipo_config; | |||
polipoConfig = polipoConfig.Replace("__SOCKS_PORT__", server.local_port.ToString()); | |||
polipoConfig = polipoConfig.Replace("__POLIPO_BIND_IP__", configuration.shareOverLan ? "0.0.0.0" : "127.0.0.1"); | |||
FileManager.ByteArrayToFile(temppath + "/polipo.conf", System.Text.Encoding.UTF8.GetBytes(polipoConfig)); | |||
FileManager.UncompressFile(temppath + "/ss_polipo.exe", Resources.polipo_exe); | |||
@@ -50,11 +44,10 @@ namespace Shadowsocks.Controller | |||
_process.StartInfo.FileName = temppath + "/ss_polipo.exe"; | |||
_process.StartInfo.Arguments = "-c \"" + temppath + "/polipo.conf\""; | |||
_process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; | |||
_process.StartInfo.UseShellExecute = false; | |||
_process.StartInfo.UseShellExecute = true; | |||
_process.StartInfo.CreateNoWindow = true; | |||
_process.StartInfo.RedirectStandardOutput = true; | |||
_process.StartInfo.RedirectStandardError = true; | |||
//process.StandardOutput | |||
//_process.StartInfo.RedirectStandardOutput = true; | |||
//_process.StartInfo.RedirectStandardError = true; | |||
_process.Start(); | |||
} | |||
} | |||
@@ -3,6 +3,7 @@ using Shadowsocks.Model; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
using System.Threading; | |||
namespace Shadowsocks.Controller | |||
{ | |||
@@ -27,6 +28,7 @@ namespace Shadowsocks.Controller | |||
public event EventHandler ConfigChanged; | |||
public event EventHandler EnableStatusChanged; | |||
public event EventHandler ShareOverLANStatusChanged; | |||
// when user clicked Edit PAC, and PAC file has already created | |||
public event EventHandler<PathEventArgs> PACFileReadyToOpen; | |||
@@ -40,19 +42,15 @@ namespace Shadowsocks.Controller | |||
} | |||
openOnLan = _config.openOnLan; | |||
polipoRunner = new PolipoRunner(); | |||
polipoRunner.openOnLan = openOnLan; | |||
polipoRunner.Start(_config.GetCurrentServer()); | |||
local = new Local(_config.GetCurrentServer()); | |||
local.openOnLan = openOnLan; | |||
polipoRunner = new PolipoRunner(); | |||
polipoRunner.Start(_config); | |||
local = new Local(_config); | |||
try | |||
{ | |||
local.Start(); | |||
pacServer = new PACServer(); | |||
pacServer.PACFileChanged += pacServer_PACFileChanged; | |||
pacServer.openOnLan = openOnLan; | |||
pacServer.Start(); | |||
pacServer.PACFileChanged += pacServer_PACFileChanged; | |||
pacServer.Start(_config); | |||
} | |||
catch (Exception e) | |||
{ | |||
@@ -61,37 +59,7 @@ namespace Shadowsocks.Controller | |||
UpdateSystemProxy(); | |||
} | |||
public void SaveConfig(Configuration newConfig) | |||
{ | |||
Configuration.Save(newConfig); | |||
if (newConfig.noChange && newConfig.openOnLan == openOnLan) | |||
{ | |||
return; | |||
} | |||
// some logic in configuration updated the config when saving, we need to read it again | |||
_config = Configuration.Load(); | |||
openOnLan = _config.openOnLan; | |||
local.Stop(); | |||
polipoRunner.Stop(); | |||
polipoRunner.openOnLan = openOnLan; | |||
polipoRunner.Start(_config.GetCurrentServer()); | |||
local = new Local(_config.GetCurrentServer()); | |||
local.openOnLan = openOnLan; | |||
local.Start(); | |||
pacServer.Stop(); | |||
pacServer.openOnLan = openOnLan; | |||
pacServer.Start(); | |||
if (ConfigChanged != null) | |||
{ | |||
ConfigChanged(this, new EventArgs()); | |||
} | |||
} | |||
public Server GetCurrentServer() | |||
{ | |||
return _config.GetCurrentServer(); | |||
@@ -103,6 +71,11 @@ namespace Shadowsocks.Controller | |||
return Configuration.Load(); | |||
} | |||
public void SaveServers(List<Server> servers) | |||
{ | |||
_config.configs = servers; | |||
SaveConfig(_config); | |||
} | |||
public void ToggleEnable(bool enabled) | |||
{ | |||
@@ -115,6 +88,22 @@ namespace Shadowsocks.Controller | |||
} | |||
} | |||
public void ToggleShareOverLAN(bool enabled) | |||
{ | |||
_config.shareOverLan = enabled; | |||
SaveConfig(_config); | |||
if (ShareOverLANStatusChanged != null) | |||
{ | |||
ShareOverLANStatusChanged(this, new EventArgs()); | |||
} | |||
} | |||
public void SelectServerIndex(int index) | |||
{ | |||
_config.index = index; | |||
SaveConfig(_config); | |||
} | |||
public void Stop() | |||
{ | |||
if (stopped) | |||
@@ -147,6 +136,34 @@ namespace Shadowsocks.Controller | |||
return "ss://" + base64; | |||
} | |||
protected void SaveConfig(Configuration newConfig) | |||
{ | |||
Configuration.Save(newConfig); | |||
// some logic in configuration updated the config when saving, we need to read it again | |||
_config = Configuration.Load(); | |||
pacServer.Stop(); | |||
local.Stop(); | |||
// don't put polipoRunner.Start() before pacServer.Stop() | |||
// or bind will fail when switching bind address from 0.0.0.0 to 127.0.0.1 | |||
// though UseShellExecute is set to true now | |||
// http://stackoverflow.com/questions/10235093/socket-doesnt-close-after-application-exits-if-a-launched-process-is-open | |||
polipoRunner.Stop(); | |||
polipoRunner.Start(_config); | |||
local = new Local(_config); | |||
local.Start(); | |||
pacServer.Start(_config); | |||
if (ConfigChanged != null) | |||
{ | |||
ConfigChanged(this, new EventArgs()); | |||
} | |||
} | |||
private void UpdateSystemProxy() | |||
{ | |||
if (_config.enabled) | |||
@@ -0,0 +1,152 @@ | |||
using System; | |||
using System.Collections; | |||
using System.Collections.Generic; | |||
using System.Net; | |||
using System.Reflection; | |||
using System.Text; | |||
using System.Text.RegularExpressions; | |||
using System.Xml; | |||
namespace Shadowsocks.Controller | |||
{ | |||
public class UpdateChecker | |||
{ | |||
private const string UpdateURL = "https://sourceforge.net/api/file/index/project-id/1817190/path/dist/mtime/desc/limit/10/rss"; | |||
public string LatestVersionNumber; | |||
public string LatestVersionURL; | |||
public event EventHandler NewVersionFound; | |||
public void CheckUpdate() | |||
{ | |||
// TODO test failures | |||
WebClient http = new WebClient(); | |||
http.DownloadStringCompleted += http_DownloadStringCompleted; | |||
http.DownloadStringAsync(new Uri(UpdateURL)); | |||
} | |||
public static int CompareVersion(string l, string r) | |||
{ | |||
var ls = l.Split('.'); | |||
var rs = r.Split('.'); | |||
for (int i = 0; i < Math.Max(ls.Length, rs.Length); i++) | |||
{ | |||
int lp = (i < ls.Length) ? int.Parse(ls[i]) : 0; | |||
int rp = (i < rs.Length) ? int.Parse(rs[i]) : 0; | |||
if (lp != rp) | |||
{ | |||
return lp - rp; | |||
} | |||
} | |||
return 0; | |||
} | |||
public class VersionComparer : IComparer<string> | |||
{ | |||
// Calls CaseInsensitiveComparer.Compare with the parameters reversed. | |||
public int Compare(string x, string y) | |||
{ | |||
return CompareVersion(ParseVersionFromURL(x), ParseVersionFromURL(y)); | |||
} | |||
} | |||
private static string ParseVersionFromURL(string url) | |||
{ | |||
Match match = Regex.Match(url, @".*Shadowsocks-win.*?-([\d\.]+)\.\w+", RegexOptions.IgnoreCase); | |||
if (match.Success) | |||
{ | |||
if (match.Groups.Count == 2) | |||
{ | |||
return match.Groups[1].Value; | |||
} | |||
} | |||
return null; | |||
} | |||
private void SortVersions(List<string> versions) | |||
{ | |||
versions.Sort(new VersionComparer()); | |||
} | |||
private bool IsNewVersion(string url) | |||
{ | |||
// check dotnet 4.0 | |||
AssemblyName[] references = Assembly.GetExecutingAssembly().GetReferencedAssemblies(); | |||
Version dotNetVersion = Environment.Version; | |||
foreach (AssemblyName reference in references) | |||
{ | |||
if (reference.Name == "mscorlib") | |||
{ | |||
dotNetVersion = reference.Version; | |||
} | |||
} | |||
if (dotNetVersion.Major >= 4) | |||
{ | |||
if (url.IndexOf("dotnet4.0") < 0) | |||
{ | |||
return false; | |||
} | |||
} | |||
else | |||
{ | |||
if (url.IndexOf("dotnet4.0") >= 0) | |||
{ | |||
return false; | |||
} | |||
} | |||
string version = ParseVersionFromURL(url); | |||
if (version == null) | |||
{ | |||
return false; | |||
} | |||
string currentVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(); | |||
return CompareVersion(version, currentVersion) > 0; | |||
} | |||
private void http_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) | |||
{ | |||
try | |||
{ | |||
string response = e.Result; | |||
XmlDocument xmlDoc = new XmlDocument(); | |||
xmlDoc.LoadXml(response); | |||
XmlNodeList elements = xmlDoc.GetElementsByTagName("media:content"); | |||
List<string> versions = new List<string>(); | |||
foreach (XmlNode el in elements) | |||
{ | |||
foreach (XmlAttribute attr in el.Attributes) | |||
{ | |||
if (attr.Name == "url") | |||
{ | |||
Console.WriteLine(attr.Value); | |||
if (IsNewVersion(attr.Value)) | |||
{ | |||
versions.Add(attr.Value); | |||
} | |||
} | |||
} | |||
} | |||
if (versions.Count == 0) | |||
{ | |||
return; | |||
} | |||
// sort versions | |||
SortVersions(versions); | |||
LatestVersionURL = versions[versions.Count - 1]; | |||
LatestVersionNumber = ParseVersionFromURL(LatestVersionURL); | |||
if (NewVersionFound != null) | |||
{ | |||
NewVersionFound(this, new EventArgs()); | |||
} | |||
} | |||
catch (Exception ex) | |||
{ | |||
Console.Write(ex.ToString()); | |||
return; | |||
} | |||
} | |||
} | |||
} |
@@ -1,4 +1,4 @@ | |||
proxyAddress = "127.0.0.1" | |||
proxyAddress = "__POLIPO_BIND_IP__" | |||
socksParentProxy = "127.0.0.1:__SOCKS_PORT__" | |||
socksProxyType = socks5 | |||
@@ -15,6 +15,7 @@ namespace Shadowsocks.Model | |||
public List<Server> configs; | |||
public int index; | |||
public bool enabled; | |||
public bool shareOverLan; | |||
public bool isDefault; | |||
public bool openOnLan; | |||
public bool enableLog; | |||
@@ -46,7 +46,8 @@ namespace Shadowsocks | |||
Console.WriteLine(e.ToString()); | |||
} | |||
LoadLibrary(dllPath); | |||
Logging.OpenLogFile(); | |||
Application.EnableVisualStyles(); | |||
Application.SetCompatibleTextRenderingDefault(false); | |||
ShadowsocksController controller = new ShadowsocksController(); | |||
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices; | |||
// 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值, | |||
// 方法是按如下所示使用“*”: | |||
// [assembly: AssemblyVersion("1.0.*")] | |||
[assembly: AssemblyVersion("2.0.4")] | |||
[assembly: AssemblyVersion("2.0.5")] | |||
// [assembly: AssemblyFileVersion("2.0.0")] |
@@ -71,7 +71,7 @@ namespace Shadowsocks.Properties { | |||
} | |||
/// <summary> | |||
/// Looks up a localized string similar to proxyAddress = "127.0.0.1" | |||
/// Looks up a localized string similar to proxyAddress = "__POLIPO_BIND_IP__" | |||
/// | |||
///socksParentProxy = "127.0.0.1:__SOCKS_PORT__" | |||
///socksProxyType = socks5 | |||
@@ -50,12 +50,14 @@ | |||
this.panel1 = new System.Windows.Forms.Panel(); | |||
this.contextMenu1 = new System.Windows.Forms.ContextMenu(); | |||
this.enableItem = new System.Windows.Forms.MenuItem(); | |||
this.ShareOverLANItem = new System.Windows.Forms.MenuItem(); | |||
this.ServersItem = new System.Windows.Forms.MenuItem(); | |||
this.SeperatorItem = new System.Windows.Forms.MenuItem(); | |||
this.ConfigItem = new System.Windows.Forms.MenuItem(); | |||
this.menuItem4 = new System.Windows.Forms.MenuItem(); | |||
this.editPACFileItem = new System.Windows.Forms.MenuItem(); | |||
this.QRCodeItem = new System.Windows.Forms.MenuItem(); | |||
this.ShowLogItem = new System.Windows.Forms.MenuItem(); | |||
this.aboutItem = new System.Windows.Forms.MenuItem(); | |||
this.menuItem3 = new System.Windows.Forms.MenuItem(); | |||
this.quitItem = new System.Windows.Forms.MenuItem(); | |||
@@ -64,8 +66,6 @@ | |||
this.AddButton = new System.Windows.Forms.Button(); | |||
this.ServerGroupBox = new System.Windows.Forms.GroupBox(); | |||
this.ServersListBox = new System.Windows.Forms.ListBox(); | |||
this.openOnLanBox = new System.Windows.Forms.CheckBox(); | |||
this.enableLogBox = new System.Windows.Forms.CheckBox(); | |||
this.tableLayoutPanel1.SuspendLayout(); | |||
this.panel1.SuspendLayout(); | |||
this.panel3.SuspendLayout(); | |||
@@ -287,10 +287,12 @@ | |||
// | |||
this.contextMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { | |||
this.enableItem, | |||
this.ShareOverLANItem, | |||
this.ServersItem, | |||
this.menuItem4, | |||
this.editPACFileItem, | |||
this.QRCodeItem, | |||
this.ShowLogItem, | |||
this.aboutItem, | |||
this.menuItem3, | |||
this.quitItem}); | |||
@@ -301,9 +303,15 @@ | |||
this.enableItem.Text = "&Enable"; | |||
this.enableItem.Click += new System.EventHandler(this.EnableItem_Click); | |||
// | |||
// ShareOverLANItem | |||
// | |||
this.ShareOverLANItem.Index = 1; | |||
this.ShareOverLANItem.Text = "Share over LAN"; | |||
this.ShareOverLANItem.Click += new System.EventHandler(this.ShareOverLANItem_Click); | |||
// | |||
// ServersItem | |||
// | |||
this.ServersItem.Index = 1; | |||
this.ServersItem.Index = 2; | |||
this.ServersItem.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { | |||
this.SeperatorItem, | |||
this.ConfigItem}); | |||
@@ -322,35 +330,41 @@ | |||
// | |||
// menuItem4 | |||
// | |||
this.menuItem4.Index = 2; | |||
this.menuItem4.Index = 3; | |||
this.menuItem4.Text = "-"; | |||
// | |||
// editPACFileItem | |||
// | |||
this.editPACFileItem.Index = 3; | |||
this.editPACFileItem.Index = 4; | |||
this.editPACFileItem.Text = "Edit &PAC File..."; | |||
this.editPACFileItem.Click += new System.EventHandler(this.EditPACFileItem_Click); | |||
// | |||
// QRCodeItem | |||
// | |||
this.QRCodeItem.Index = 4; | |||
this.QRCodeItem.Index = 5; | |||
this.QRCodeItem.Text = "Show &QRCode..."; | |||
this.QRCodeItem.Click += new System.EventHandler(this.QRCodeItem_Click); | |||
// | |||
// ShowLogItem | |||
// | |||
this.ShowLogItem.Index = 6; | |||
this.ShowLogItem.Text = "Show Logs..."; | |||
this.ShowLogItem.Click += new System.EventHandler(this.ShowLogItem_Click); | |||
// | |||
// aboutItem | |||
// | |||
this.aboutItem.Index = 5; | |||
this.aboutItem.Index = 7; | |||
this.aboutItem.Text = "About..."; | |||
this.aboutItem.Click += new System.EventHandler(this.AboutItem_Click); | |||
// | |||
// menuItem3 | |||
// | |||
this.menuItem3.Index = 6; | |||
this.menuItem3.Index = 8; | |||
this.menuItem3.Text = "-"; | |||
// | |||
// quitItem | |||
// | |||
this.quitItem.Index = 7; | |||
this.quitItem.Index = 9; | |||
this.quitItem.Text = "&Quit"; | |||
this.quitItem.Click += new System.EventHandler(this.Quit_Click); | |||
// | |||
@@ -404,27 +418,6 @@ | |||
this.ServersListBox.TabIndex = 5; | |||
this.ServersListBox.SelectedIndexChanged += new System.EventHandler(this.ServersListBox_SelectedIndexChanged); | |||
// | |||
// openOnLanBox | |||
// | |||
this.openOnLanBox.AutoSize = true; | |||
this.openOnLanBox.Location = new System.Drawing.Point(16, 260); | |||
this.openOnLanBox.Name = "openOnLanBox"; | |||
this.openOnLanBox.Size = new System.Drawing.Size(90, 17); | |||
this.openOnLanBox.TabIndex = 7; | |||
this.openOnLanBox.Text = "Open On Lan"; | |||
this.openOnLanBox.UseVisualStyleBackColor = true; | |||
// | |||
// enableLogBox | |||
// | |||
this.enableLogBox.AutoSize = true; | |||
this.enableLogBox.Location = new System.Drawing.Point(112, 260); | |||
this.enableLogBox.Name = "enableLogBox"; | |||
this.enableLogBox.Size = new System.Drawing.Size(80, 17); | |||
this.enableLogBox.TabIndex = 7; | |||
this.enableLogBox.Text = "Enable Log"; | |||
this.enableLogBox.UseVisualStyleBackColor = true; | |||
this.enableLogBox.CheckedChanged += new System.EventHandler(this.enableLogBox_CheckedChanged); | |||
// | |||
// ConfigForm | |||
// | |||
this.AcceptButton = this.OKButton; | |||
@@ -433,8 +426,6 @@ | |||
this.AutoSize = true; | |||
this.CancelButton = this.MyCancelButton; | |||
this.ClientSize = new System.Drawing.Size(489, 286); | |||
this.Controls.Add(this.enableLogBox); | |||
this.Controls.Add(this.openOnLanBox); | |||
this.Controls.Add(this.ServersListBox); | |||
this.Controls.Add(this.ServerGroupBox); | |||
this.Controls.Add(this.panel1); | |||
@@ -446,7 +437,7 @@ | |||
this.MinimizeBox = false; | |||
this.Name = "ConfigForm"; | |||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; | |||
this.Text = "Shadowsocks"; | |||
this.Text = "Edit Servers"; | |||
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.ConfigForm_FormClosed); | |||
this.Load += new System.EventHandler(this.ConfigForm_Load); | |||
this.Shown += new System.EventHandler(this.ConfigForm_Shown); | |||
@@ -497,8 +488,8 @@ | |||
private System.Windows.Forms.TextBox RemarksTextBox; | |||
private System.Windows.Forms.Label label6; | |||
private System.Windows.Forms.MenuItem QRCodeItem; | |||
private System.Windows.Forms.CheckBox openOnLanBox; | |||
private System.Windows.Forms.CheckBox enableLogBox; | |||
private System.Windows.Forms.MenuItem ShowLogItem; | |||
private System.Windows.Forms.MenuItem ShareOverLANItem; | |||
} | |||
} | |||
@@ -13,6 +13,7 @@ namespace Shadowsocks.View | |||
public partial class ConfigForm : Form | |||
{ | |||
private ShadowsocksController controller; | |||
private UpdateChecker updateChecker; | |||
// this is a copy of configuration that we are working on | |||
private Configuration _modifiedConfiguration; | |||
@@ -29,6 +30,10 @@ namespace Shadowsocks.View | |||
controller.EnableStatusChanged += controller_EnableStatusChanged; | |||
controller.ConfigChanged += controller_ConfigChanged; | |||
controller.PACFileReadyToOpen += controller_PACFileReadyToOpen; | |||
controller.ShareOverLANStatusChanged += controller_ShareOverLANStatusChanged; | |||
this.updateChecker = new UpdateChecker(); | |||
updateChecker.NewVersionFound += updateChecker_NewVersionFound; | |||
LoadCurrentConfiguration(); | |||
} | |||
@@ -43,6 +48,11 @@ namespace Shadowsocks.View | |||
enableItem.Checked = controller.GetConfiguration().enabled; | |||
} | |||
void controller_ShareOverLANStatusChanged(object sender, EventArgs e) | |||
{ | |||
ShareOverLANItem.Checked = controller.GetConfiguration().shareOverLan; | |||
} | |||
void controller_PACFileReadyToOpen(object sender, ShadowsocksController.PathEventArgs e) | |||
{ | |||
string argument = @"/select, " + e.Path; | |||
@@ -50,6 +60,21 @@ namespace Shadowsocks.View | |||
System.Diagnostics.Process.Start("explorer.exe", argument); | |||
} | |||
void updateChecker_NewVersionFound(object sender, EventArgs e) | |||
{ | |||
notifyIcon1.BalloonTipTitle = "Shadowsocks " + updateChecker.LatestVersionNumber + " Update Found"; | |||
notifyIcon1.BalloonTipText = "You can click here to download"; | |||
notifyIcon1.BalloonTipIcon = ToolTipIcon.Info; | |||
notifyIcon1.BalloonTipClicked += notifyIcon1_BalloonTipClicked; | |||
notifyIcon1.ShowBalloonTip(5000); | |||
_isFirstRun = false; | |||
} | |||
void notifyIcon1_BalloonTipClicked(object sender, EventArgs e) | |||
{ | |||
Process.Start(updateChecker.LatestVersionURL); | |||
} | |||
private void ShowWindow() | |||
{ | |||
@@ -151,7 +176,7 @@ namespace Shadowsocks.View | |||
UpdateServersMenu(); | |||
enableItem.Checked = _modifiedConfiguration.enabled; | |||
openOnLanBox.Checked = _modifiedConfiguration.openOnLan; | |||
ShareOverLANItem.Checked = _modifiedConfiguration.shareOverLan; | |||
} | |||
private void UpdateServersMenu() | |||
@@ -192,6 +217,7 @@ namespace Shadowsocks.View | |||
{ | |||
_isFirstRun = true; | |||
} | |||
updateChecker.CheckUpdate(); | |||
} | |||
private void ServersListBox_SelectedIndexChanged(object sender, EventArgs e) | |||
@@ -258,6 +284,7 @@ namespace Shadowsocks.View | |||
{ | |||
notifyIcon1.BalloonTipTitle = "Shadowsocks is here"; | |||
notifyIcon1.BalloonTipText = "You can turn on/off Shadowsocks in the context menu"; | |||
notifyIcon1.BalloonTipIcon = ToolTipIcon.Info; | |||
notifyIcon1.ShowBalloonTip(0); | |||
_isFirstRun = false; | |||
} | |||
@@ -274,8 +301,7 @@ namespace Shadowsocks.View | |||
MessageBox.Show("Please add at least one server"); | |||
return; | |||
} | |||
_modifiedConfiguration.openOnLan = openOnLanBox.Checked; | |||
controller.SaveConfig(_modifiedConfiguration); | |||
controller.SaveServers(_modifiedConfiguration.configs); | |||
this.Hide(); | |||
ShowFirstTimeBalloon(); | |||
} | |||
@@ -309,6 +335,12 @@ namespace Shadowsocks.View | |||
controller.ToggleEnable(enableItem.Checked); | |||
} | |||
private void ShareOverLANItem_Click(object sender, EventArgs e) | |||
{ | |||
ShareOverLANItem.Checked = !ShareOverLANItem.Checked; | |||
controller.ToggleShareOverLAN(ShareOverLANItem.Checked); | |||
} | |||
private void EditPACFileItem_Click(object sender, EventArgs e) | |||
{ | |||
controller.TouchPACFile(); | |||
@@ -317,9 +349,14 @@ namespace Shadowsocks.View | |||
private void AServerItem_Click(object sender, EventArgs e) | |||
{ | |||
MenuItem item = (MenuItem)sender; | |||
Configuration configuration = controller.GetConfiguration(); | |||
configuration.index = (int)item.Tag; | |||
controller.SaveConfig(configuration); | |||
controller.SelectServerIndex((int)item.Tag); | |||
} | |||
private void ShowLogItem_Click(object sender, EventArgs e) | |||
{ | |||
string argument = Logging.LogFile; | |||
System.Diagnostics.Process.Start("notepad.exe", argument); | |||
} | |||
private void ConfigForm_Shown(object sender, EventArgs e) | |||
@@ -25,35 +25,50 @@ namespace Shadowsocks.View | |||
private void GenQR(string ssconfig) | |||
{ | |||
string qrText = ssconfig; | |||
QRCode4CS.QRCode qrCoded = new QRCode4CS.QRCode(6, QRErrorCorrectLevel.H); | |||
qrCoded.AddData(qrText); | |||
qrCoded.Make(); | |||
int blockSize = 5; | |||
Bitmap drawArea = new Bitmap((qrCoded.GetModuleCount() * blockSize), (qrCoded.GetModuleCount() * blockSize)); | |||
for (int row = 0; row < qrCoded.GetModuleCount(); row++) | |||
QRCode4CS.Options options = new QRCode4CS.Options(); | |||
options.Text = qrText; | |||
QRCode4CS.QRCode qrCoded = null; | |||
bool success = false; | |||
foreach (var level in new QRErrorCorrectLevel[]{QRErrorCorrectLevel.H, QRErrorCorrectLevel.Q, QRErrorCorrectLevel.M, QRErrorCorrectLevel.L}) | |||
{ | |||
for (int col = 0; col < qrCoded.GetModuleCount(); col++) | |||
for (int i = 3; i < 10; i++) | |||
{ | |||
bool isDark = qrCoded.IsDark(row, col); | |||
if (isDark) | |||
try | |||
{ | |||
for (int y = 0; y < blockSize; y++) | |||
{ | |||
int myCol = (blockSize * (col - 1)) + (y + blockSize); | |||
for (int x = 0; x < blockSize; x++) | |||
{ | |||
drawArea.SetPixel((blockSize * (row - 1)) + (x + blockSize), myCol, Color.Black); | |||
} | |||
} | |||
options.TypeNumber = i; | |||
options.CorrectLevel = level; | |||
qrCoded = new QRCode4CS.QRCode(options); | |||
qrCoded.Make(); | |||
success = true; | |||
break; | |||
} | |||
catch | |||
{ | |||
qrCoded = null; | |||
continue; | |||
} | |||
else | |||
} | |||
if (success) | |||
break; | |||
} | |||
if (qrCoded == null) | |||
{ | |||
return; | |||
} | |||
int blockSize = Math.Max(200 / qrCoded.GetModuleCount(), 1); | |||
Bitmap drawArea = new Bitmap((qrCoded.GetModuleCount() * blockSize), (qrCoded.GetModuleCount() * blockSize)); | |||
using (Graphics g = Graphics.FromImage(drawArea)) | |||
{ | |||
g.Clear(Color.White); | |||
using (Brush b = new SolidBrush(Color.Black)) | |||
{ | |||
for (int row = 0; row < qrCoded.GetModuleCount(); row++) | |||
{ | |||
for (int y = 0; y < blockSize; y++) | |||
for (int col = 0; col < qrCoded.GetModuleCount(); col++) | |||
{ | |||
int myCol = (blockSize * (col - 1)) + (y + blockSize); | |||
for (int x = 0; x < blockSize; x++) | |||
if (qrCoded.IsDark(row, col)) | |||
{ | |||
drawArea.SetPixel((blockSize * (row - 1)) + (x + blockSize), myCol, Color.White); | |||
g.FillRectangle(b, blockSize * row, blockSize * col, blockSize, blockSize); | |||
} | |||
} | |||
} | |||
@@ -63,11 +63,14 @@ | |||
<Reference Include="System.Data" /> | |||
<Reference Include="System.Drawing" /> | |||
<Reference Include="System.Windows.Forms" /> | |||
<Reference Include="System.XML" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Compile Include="3rd\QRCodeCS.cs" /> | |||
<Compile Include="3rd\SimpleJson.cs" /> | |||
<Compile Include="Controller\FileManager.cs" /> | |||
<Compile Include="Controller\Logging.cs" /> | |||
<Compile Include="Controller\UpdateChecker.cs" /> | |||
<Compile Include="Encrypt\EncryptorBase.cs" /> | |||
<Compile Include="Encrypt\EncryptorFactory.cs" /> | |||
<Compile Include="Encrypt\PolarSSL.cs" /> | |||
@@ -0,0 +1,36 @@ | |||
using System.Reflection; | |||
using System.Runtime.CompilerServices; | |||
using System.Runtime.InteropServices; | |||
// General Information about an assembly is controlled through the following | |||
// set of attributes. Change these attribute values to modify the information | |||
// associated with an assembly. | |||
[assembly: AssemblyTitle("test")] | |||
[assembly: AssemblyDescription("")] | |||
[assembly: AssemblyConfiguration("")] | |||
[assembly: AssemblyCompany("")] | |||
[assembly: AssemblyProduct("test")] | |||
[assembly: AssemblyCopyright("Copyright © 2014")] | |||
[assembly: AssemblyTrademark("")] | |||
[assembly: AssemblyCulture("")] | |||
// Setting ComVisible to false makes the types in this assembly not visible | |||
// to COM components. If you need to access a type in this assembly from | |||
// COM, set the ComVisible attribute to true on that type. | |||
[assembly: ComVisible(false)] | |||
// The following GUID is for the ID of the typelib if this project is exposed to COM | |||
[assembly: Guid("f74e87ac-7e3a-444b-a1d9-8b91a674c60f")] | |||
// Version information for an assembly consists of the following four values: | |||
// | |||
// Major Version | |||
// Minor Version | |||
// Build Number | |||
// Revision | |||
// | |||
// You can specify all the values or you can default the Build and Revision Numbers | |||
// by using the '*' as shown below: | |||
// [assembly: AssemblyVersion("1.0.*")] | |||
[assembly: AssemblyVersion("1.0.0.0")] | |||
[assembly: AssemblyFileVersion("1.0.0.0")] |
@@ -0,0 +1,22 @@ | |||
using System; | |||
using Microsoft.VisualStudio.TestTools.UnitTesting; | |||
using Shadowsocks.Controller; | |||
namespace test | |||
{ | |||
[TestClass] | |||
public class UnitTest | |||
{ | |||
[TestMethod] | |||
public void TestCompareVersion() | |||
{ | |||
Assert.IsTrue(UpdateChecker.CompareVersion("2.3.1.0", "2.3.1") == 0); | |||
Assert.IsTrue(UpdateChecker.CompareVersion("1.2", "1.3") < 0); | |||
Assert.IsTrue(UpdateChecker.CompareVersion("1.3", "1.2") > 0); | |||
Assert.IsTrue(UpdateChecker.CompareVersion("1.3", "1.3") == 0); | |||
Assert.IsTrue(UpdateChecker.CompareVersion("1.2.1", "1.2") > 0); | |||
Assert.IsTrue(UpdateChecker.CompareVersion("2.3.1", "2.4") < 0); | |||
Assert.IsTrue(UpdateChecker.CompareVersion("1.3.2", "1.3.1") > 0); | |||
} | |||
} | |||
} |
@@ -0,0 +1,81 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||
<PropertyGroup> | |||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | |||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | |||
<ProjectGuid>{45913187-0685-4903-B250-DCEF0479CD86}</ProjectGuid> | |||
<OutputType>Library</OutputType> | |||
<AppDesignerFolder>Properties</AppDesignerFolder> | |||
<RootNamespace>test</RootNamespace> | |||
<AssemblyName>test</AssemblyName> | |||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion> | |||
<FileAlignment>512</FileAlignment> | |||
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> | |||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion> | |||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> | |||
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath> | |||
<IsCodedUITest>False</IsCodedUITest> | |||
<TestProjectType>UnitTest</TestProjectType> | |||
<TargetFrameworkProfile /> | |||
</PropertyGroup> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'"> | |||
<OutputPath>bin\x86\Debug\</OutputPath> | |||
<PlatformTarget>x86</PlatformTarget> | |||
</PropertyGroup> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'"> | |||
<OutputPath>bin\x86\Release\</OutputPath> | |||
<PlatformTarget>x86</PlatformTarget> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<Reference Include="System" /> | |||
</ItemGroup> | |||
<Choose> | |||
<When Condition="('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'"> | |||
<ItemGroup> | |||
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" /> | |||
</ItemGroup> | |||
</When> | |||
<Otherwise> | |||
<ItemGroup> | |||
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework" /> | |||
</ItemGroup> | |||
</Otherwise> | |||
</Choose> | |||
<ItemGroup> | |||
<Compile Include="UnitTest.cs" /> | |||
<Compile Include="Properties\AssemblyInfo.cs" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\shadowsocks-csharp\shadowsocks-csharp.csproj"> | |||
<Project>{8c02d2f7-7cdb-4d55-9f25-cd03ef4aa062}</Project> | |||
<Name>shadowsocks-csharp</Name> | |||
</ProjectReference> | |||
</ItemGroup> | |||
<Choose> | |||
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'"> | |||
<ItemGroup> | |||
<Reference Include="Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<Private>False</Private> | |||
</Reference> | |||
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<Private>False</Private> | |||
</Reference> | |||
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Extension, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<Private>False</Private> | |||
</Reference> | |||
<Reference Include="Microsoft.VisualStudio.TestTools.UITesting, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<Private>False</Private> | |||
</Reference> | |||
</ItemGroup> | |||
</When> | |||
</Choose> | |||
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" /> | |||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.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"> | |||
</Target> | |||
<Target Name="AfterBuild"> | |||
</Target> | |||
--> | |||
</Project> |