Pack python env to zip

This commit is contained in:
qianlifeng
2014-07-18 20:00:55 +08:00
parent 7be02731ee
commit 7b4d6ba57e
1022 changed files with 2670 additions and 246394 deletions

View File

@@ -23,4 +23,8 @@
<supportedRuntime version="v2.0.50727"/>
<supportedRuntime version="v4.0"/>
</startup>
<runtime>
<!--http://stackoverflow.com/questions/186854/how-to-prevent-an-exception-in-a-background-thread-from-terminating-an-applicati-->
<legacyUnhandledExceptionPolicy enabled="1" />
</runtime>
</configuration>

View File

@@ -16,20 +16,15 @@ namespace Wox.Helper.ErrorReporting
public static void UnhandledExceptionHandle(object sender, System.UnhandledExceptionEventArgs e)
{
if (System.Diagnostics.Debugger.IsAttached) return;
string error = CreateExceptionReport("System.AppDomain.UnhandledException", e.ExceptionObject);
if (e.IsTerminating)
{
Log.Fatal(error);
TryShowErrorMessageBox(error, e.ExceptionObject, true);
Environment.Exit(0);
}
else
{
Log.Error(error);
}
//e.IsTerminating is always true in most times, so try to avoid use this property
//http://stackoverflow.com/questions/10982443/what-causes-the-unhandledexceptioneventargs-isterminating-flag-to-be-true-or-fal
Log.Error(error);
TryShowErrorMessageBox(error, e.ExceptionObject);
}
public static void DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
if (System.Diagnostics.Debugger.IsAttached) return;
@@ -38,7 +33,7 @@ namespace Wox.Helper.ErrorReporting
string error = CreateExceptionReport("System.Windows.Application.DispatcherUnhandledException", e.Exception);
Log.Error(error);
if (TryShowErrorMessageBox(error, e.Exception, false))
if (TryShowErrorMessageBox(error, e.Exception))
{
Environment.Exit(0);
}
@@ -50,7 +45,7 @@ namespace Wox.Helper.ErrorReporting
string error = CreateExceptionReport("System.Windows.Forms.Application.ThreadException", e.Exception);
Log.Fatal(error);
TryShowErrorMessageBox(error, e.Exception, true);
TryShowErrorMessageBox(error, e.Exception);
Environment.Exit(0);
}
@@ -72,7 +67,7 @@ namespace Wox.Helper.ErrorReporting
exsb.Append(ex.GetType().FullName);
exsb.Append(": ");
exsb.AppendLine(ex.Message);
if (ex.Source != null)
if (ex.Source != null)
{
exsb.Append(" Source: ");
exsb.AppendLine(ex.Source);
@@ -80,7 +75,7 @@ namespace Wox.Helper.ErrorReporting
if (ex.TargetSite != null)
{
exsb.Append(" TargetAssembly: ");
exsb.AppendLine(ex.TargetSite.Module.Assembly.ToString());
exsb.AppendLine(ex.TargetSite.Module.Assembly.ToString());
exsb.Append(" TargetModule: ");
exsb.AppendLine(ex.TargetSite.Module.ToString());
exsb.Append(" TargetSite: ");
@@ -169,7 +164,7 @@ namespace Wox.Helper.ErrorReporting
foreach (ProcessThread th in process.Threads)
{
sb.Append("* ");
sb.AppendLine(string.Format("{0}, {1} {2}, Started: {3}, StartAddress: 0x{4:X16}", th.Id, th.ThreadState,th.PriorityLevel, th.StartTime, th.StartAddress.ToInt64()));
sb.AppendLine(string.Format("{0}, {1} {2}, Started: {3}, StartAddress: 0x{4:X16}", th.Id, th.ThreadState, th.PriorityLevel, th.StartTime, th.StartAddress.ToInt64()));
}
return sb.ToString();
@@ -244,7 +239,7 @@ namespace Wox.Helper.ErrorReporting
}
private static bool TryShowErrorMessageBox(string error, object exceptionObject, bool isTerminating = true)
public static bool TryShowErrorMessageBox(string error, object exceptionObject)
{
var title = "Wox - Unhandled Exception";
@@ -255,8 +250,7 @@ namespace Wox.Helper.ErrorReporting
}
catch { }
error = "Wox has occured an error that can't be handled. " + Environment.NewLine + Environment.NewLine +
error;
error = "Wox has occured an error that can't be handled. " + Environment.NewLine + Environment.NewLine + error;
try
{

44
Wox/Helper/HttpProxy.cs Normal file
View File

@@ -0,0 +1,44 @@
using Wox.Infrastructure.Storage.UserSettings;
using Wox.Plugin;
namespace Wox.Helper
{
public class HttpProxy : IHttpProxy
{
private static readonly HttpProxy instance = new HttpProxy();
private HttpProxy()
{
}
public static HttpProxy Instance
{
get { return instance; }
}
public bool Enabled
{
get { return UserSettingStorage.Instance.ProxyEnabled; }
}
public string Server
{
get { return UserSettingStorage.Instance.ProxyServer; }
}
public int Port
{
get { return UserSettingStorage.Instance.ProxyPort; }
}
public string UserName
{
get { return UserSettingStorage.Instance.ProxyUserName; }
}
public string Password
{
get { return UserSettingStorage.Instance.ProxyPassword; }
}
}
}

View File

@@ -5,9 +5,10 @@ using System.Text;
namespace Wox.Helper
{
public class WoxPythonException : WoxException
public class WoxJsonPRCException : WoxException
{
public WoxPythonException(string msg) : base(msg)
public WoxJsonPRCException(string msg)
: base(msg)
{
}
}

View File

@@ -1,4 +1,19 @@
using System.Collections.Generic;

/* We basically follow the Json-RPC 2.0 spec (http://www.jsonrpc.org/specification) to invoke methods between Wox and other plugins,
* like python or other self-execute program. But, we added addtional infos (proxy and so on) into rpc request. Also, we didn't use the
* "id" and "jsonrpc" in the request, since it's not so useful in our request model.
*
* When execute a query:
* Wox -------JsonRPCServerRequestModel--------> client
* Wox <------JsonRPCQueryResponseModel--------- client
*
* When execute a action (which mean user select an item in reulst item):
* Wox -------JsonRPCServerRequestModel--------> client
* Wox <------JsonRPCResponseModel-------------- client
*
*/
using System.Collections.Generic;
using System.Linq;
using Wox.Plugin;
@@ -16,8 +31,6 @@ namespace Wox.JsonRPC
public class JsonRPCModelBase
{
public int Id { get; set; }
public string JsonRPC { get; set; }
}
public class JsonRPCResponseModel : JsonRPCModelBase
@@ -32,28 +45,33 @@ namespace Wox.JsonRPC
public new List<JsonRPCResult> Result { get; set; }
}
public class JsonRPCRequestModel : JsonRPCModelBase
public abstract class JsonRPCRequestModel : JsonRPCModelBase
{
public string Method { get; set; }
public object[] Parameters { get; set; }
public bool DontHideAfterAction { get; set; }
public override string ToString()
{
string rpc = string.Empty;
if (Parameters != null && Parameters.Length > 0)
{
string parameters = Parameters.Aggregate("[", (current, o) => current + (GetParamterByType(o) + ","));
parameters = parameters.Substring(0, parameters.Length - 1) + "]";
return string.Format(@"{{\""method\"":\""{0}\"",\""parameters\"":{1}}}", Method, parameters);
rpc = string.Format(@"{{\""method\"":\""{0}\"",\""parameters\"":{1}", Method, parameters);
}
else
{
rpc = string.Format(@"{{\""method\"":\""{0}\"",\""parameters\"":[]", Method);
}
return string.Format(@"{{\""method\"":\""{0}\"",\""parameters\"":[]}}",Method);
return rpc;
}
private string GetParamterByType(object paramter)
{
if (paramter is string)
{
return string.Format(@"\""{0}\""", paramter);
@@ -70,8 +88,40 @@ namespace Wox.JsonRPC
}
}
/// <summary>
/// Json RPC Request that Wox sent to client
/// </summary>
public class JsonRPCServerRequestModel : JsonRPCRequestModel
{
public IHttpProxy HttpProxy { get; set; }
public override string ToString()
{
string rpc = base.ToString();
if (HttpProxy != null)
{
rpc += string.Format(@",\""proxy\"":{{\""enabled\"":{0},\""server\"":\""{1}\"",\""port\"":{2},\""username\"":\""{3}\"",\""password\"":\""{4}\""}}",
HttpProxy.Enabled.ToString().ToLower(), HttpProxy.Server, HttpProxy.Port, HttpProxy.UserName, HttpProxy.Password);
}
return rpc + "}";
}
}
/// <summary>
/// Json RPC Request that client sent to Wox
/// </summary>
public class JsonRPCClientRequestModel : JsonRPCRequestModel
{
public bool DontHideAfterAction { get; set; }
}
/// <summary>
/// Represent the json-rpc result item that client send to Wox
/// Typically, we will send back this request model to client after user select the result item
/// But if the request method starts with "Wox.", we will invoke the public APIs we expose.
/// </summary>
public class JsonRPCResult : Result
{
public JsonRPCRequestModel JsonRPCAction { get; set; }
public JsonRPCClientRequestModel JsonRPCAction { get; set; }
}
}

View File

@@ -6,9 +6,13 @@ using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Newtonsoft.Json;
using Wox.Helper;
using Wox.Helper.ErrorReporting;
using Wox.JsonRPC;
using Wox.Plugin;
using MessageBox = System.Windows.MessageBox;
namespace Wox.PluginLoader
{
@@ -48,8 +52,8 @@ namespace Wox.PluginLoader
{
string actionReponse = ExecuteAction(result1.JsonRPCAction);
JsonRPCRequestModel jsonRpcRequestModel = JsonConvert.DeserializeObject<JsonRPCRequestModel>(actionReponse);
if (jsonRpcRequestModel != null
&& string.IsNullOrEmpty(jsonRpcRequestModel.Method)
if (jsonRpcRequestModel != null
&& string.IsNullOrEmpty(jsonRpcRequestModel.Method)
&& jsonRpcRequestModel.Method.StartsWith("Wox."))
{
ExecuteWoxAPI(jsonRpcRequestModel.Method.Substring(4), jsonRpcRequestModel.Parameters);
@@ -63,8 +67,10 @@ namespace Wox.PluginLoader
}
return results;
}
catch
catch (Exception e)
{
ErrorReporting.TryShowErrorMessageBox(e.Message, e);
Wox.Helper.Log.Error(e.Message);
}
}
return null;
@@ -97,22 +103,45 @@ namespace Wox.PluginLoader
/// <param name="arguments"></param>
/// <returns></returns>
protected string Execute(string fileName, string arguments)
{
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = fileName;
start.Arguments = arguments;
start.UseShellExecute = false;
start.CreateNoWindow = true;
start.RedirectStandardOutput = true;
start.RedirectStandardError = true;
return Execute(start);
}
protected string Execute(ProcessStartInfo startInfo)
{
try
{
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = fileName;
start.Arguments = arguments;
start.UseShellExecute = false;
start.CreateNoWindow = true;
start.RedirectStandardOutput = true;
using (Process process = Process.Start(start))
using (Process process = Process.Start(startInfo))
{
if (process != null)
{
using (StreamReader reader = process.StandardOutput)
{
return reader.ReadToEnd();
string result = reader.ReadToEnd();
if (result.StartsWith("DEBUG:"))
{
System.Windows.Forms.MessageBox.Show(new Form { TopMost = true }, result.Substring(6));
return "";
}
if (string.IsNullOrEmpty(result))
{
using (StreamReader errorReader = process.StandardError)
{
string error = errorReader.ReadToEnd();
if (!string.IsNullOrEmpty(error))
{
ErrorReporting.TryShowErrorMessageBox(error, new WoxJsonPRCException(error));
}
}
}
return result;
}
}
}

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using Wox.Helper;
using Wox.Infrastructure.Storage.UserSettings;
using Wox.Plugin;
namespace Wox.PluginLoader
@@ -26,6 +27,7 @@ namespace Wox.PluginLoader
forker.Fork(() => pair.Plugin.Init(new PluginInitContext()
{
CurrentPluginMetadata = pair.Metadata,
Proxy = HttpProxy.Instance,
API = App.Window
}));
}

View File

@@ -1,5 +1,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using Wox.Helper;
using Wox.JsonRPC;
using Wox.Plugin;
@@ -8,26 +10,56 @@ namespace Wox.PluginLoader
public class PythonPlugin : BasePlugin
{
private static string woxDirectory = Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath);
private ProcessStartInfo startInfo;
public override string SupportedLanguage
{
get { return AllowedLanguage.Python; }
}
public PythonPlugin()
{
startInfo = new ProcessStartInfo
{
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardError = true
};
string additionalPythonPath = string.Format("{0};{1}",
Path.Combine(woxDirectory, "PythonHome\\DLLs"),
Path.Combine(woxDirectory, "PythonHome\\thirdparty"));
if (!startInfo.EnvironmentVariables.ContainsKey("PYTHONPATH"))
{
startInfo.EnvironmentVariables.Add("PYTHONPATH", additionalPythonPath);
}
else
{
startInfo.EnvironmentVariables["PYTHONPATH"] = additionalPythonPath;
}
}
protected override string ExecuteQuery(Query query)
{
string fileName = Path.Combine(woxDirectory, "PythonHome\\pythonw.exe");
string parameters = string.Format("{0} \"{1}\"", context.CurrentPluginMetadata.ExecuteFilePath,
string.Format(@"{{\""method\"": \""query\"", \""parameters\"": [\""{0}\""]}}",query.GetAllRemainingParameter()));
return Execute(fileName, parameters);
JsonRPCServerRequestModel request = new JsonRPCServerRequestModel()
{
Method = "query",
Parameters = new object[] { query.GetAllRemainingParameter() },
HttpProxy = HttpProxy.Instance
};
//Add -B flag to tell python don't write .py[co] files. Because .pyc contains location infos which will prevent python portable
startInfo.FileName = Path.Combine(woxDirectory, "PythonHome\\pythonw.exe");
startInfo.Arguments = string.Format("-B {0} \"{1}\"", context.CurrentPluginMetadata.ExecuteFilePath, request);
return Execute(startInfo);
}
protected override string ExecuteAction(JsonRPCRequestModel rpcRequest)
{
string fileName = Path.Combine(woxDirectory, "PythonHome\\pythonw.exe");
string parameters = string.Format("{0} \"{1}\"", context.CurrentPluginMetadata.ExecuteFilePath,rpcRequest);
return Execute(fileName, parameters);
startInfo.FileName = Path.Combine(woxDirectory, "PythonHome\\pythonw.exe");
startInfo.Arguments = string.Format("-B {0} \"{1}\"", context.CurrentPluginMetadata.ExecuteFilePath, rpcRequest);
return Execute(startInfo);
}
}
}

View File

@@ -279,28 +279,31 @@
<TextBlock >Server</TextBlock>
</Border>
<Border Grid.Row="0" Grid.Column="1" Padding="5">
<TextBox Width="200" HorizontalAlignment="Left"></TextBox>
<TextBox Width="200" HorizontalAlignment="Left" x:Name="tbProxyServer"></TextBox>
</Border>
<Border Grid.Row="0" Grid.Column="2" Padding="5">
<TextBlock>Port</TextBlock>
</Border>
<Border Grid.Row="0" Grid.Column="3" Padding="5">
<TextBox Width="50" HorizontalAlignment="Left"></TextBox>
<TextBox Width="50" HorizontalAlignment="Left" x:Name="tbProxyPort"></TextBox>
</Border>
<Border Grid.Row="1" Grid.Column="0" Padding="5">
<TextBlock >UserName</TextBlock>
</Border>
<Border Grid.Row="1" Grid.Column="1" Padding="5">
<TextBox Width="200" HorizontalAlignment="Left"></TextBox>
<TextBox Width="200" HorizontalAlignment="Left" x:Name="tbProxyUserName"></TextBox>
</Border>
<Border Grid.Row="1" Grid.Column="2" Padding="5">
<TextBlock>Password</TextBlock>
</Border>
<Border Grid.Row="1" Grid.Column="3" Padding="5">
<TextBox Width="200" HorizontalAlignment="Left"></TextBox>
<PasswordBox Width="200" HorizontalAlignment="Left" x:Name="tbProxyPassword" />
</Border>
</Grid>
<Button x:Name="btnTestProxy" Width="80" HorizontalAlignment="Left" Margin="10">Test Proxy</Button>
<StackPanel Orientation="Horizontal">
<Button x:Name="btnTestProxy" Width="80" HorizontalAlignment="Left" Margin="10" Click="btnTestProxy_Click">Test Proxy</Button>
<Button x:Name="btnSaveProxy" Width="80" HorizontalAlignment="Left" Margin="10" Click="btnSaveProxy_Click">Save</Button>
</StackPanel>
</StackPanel>
</TabItem>
</TabControl>

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
@@ -184,11 +185,47 @@ namespace Wox
#endregion
#region Proxy
cbEnableProxy.Checked += (o, e) => EnableProxy();
cbEnableProxy.Unchecked += (o, e) => DisableProxy();
cbEnableProxy.IsChecked = UserSettingStorage.Instance.ProxyEnabled;
tbProxyServer.Text = UserSettingStorage.Instance.ProxyServer;
tbProxyPort.Text = UserSettingStorage.Instance.ProxyPort.ToString();
tbProxyUserName.Text = UserSettingStorage.Instance.ProxyUserName;
tbProxyPassword.Password = UserSettingStorage.Instance.ProxyPassword;
if (UserSettingStorage.Instance.ProxyEnabled)
{
EnableProxy();
}
else
{
DisableProxy();
}
#endregion
//PreviewPanel
settingsLoaded = true;
App.Window.SetTheme(UserSettingStorage.Instance.Theme);
}
private void EnableProxy()
{
tbProxyPassword.IsEnabled = true;
tbProxyServer.IsEnabled = true;
tbProxyUserName.IsEnabled = true;
tbProxyPort.IsEnabled = true;
}
private void DisableProxy()
{
tbProxyPassword.IsEnabled = false;
tbProxyServer.IsEnabled = false;
tbProxyUserName.IsEnabled = false;
tbProxyPort.IsEnabled = false;
}
private List<string> LoadAvailableThemes()
{
string themePath = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "Themes");
@@ -565,5 +602,87 @@ namespace Wox
{
Process.Start("http://www.getwox.com/theme");
}
private void btnSaveProxy_Click(object sender, RoutedEventArgs e)
{
UserSettingStorage.Instance.ProxyEnabled = cbEnableProxy.IsChecked ?? false;
int port = 80;
if (UserSettingStorage.Instance.ProxyEnabled)
{
if (string.IsNullOrEmpty(tbProxyServer.Text))
{
MessageBox.Show("Server can't be empty");
return;
}
if (string.IsNullOrEmpty(tbProxyPort.Text))
{
MessageBox.Show("Server port can't be empty");
return;
}
if (!int.TryParse(tbProxyPort.Text, out port))
{
MessageBox.Show("Invalid port format");
return;
}
}
UserSettingStorage.Instance.ProxyServer = tbProxyServer.Text;
UserSettingStorage.Instance.ProxyPort = port;
UserSettingStorage.Instance.ProxyUserName = tbProxyUserName.Text;
UserSettingStorage.Instance.ProxyPassword = tbProxyPassword.Password;
UserSettingStorage.Instance.Save();
MessageBox.Show("Save Proxy Successfully");
}
private void btnTestProxy_Click(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(tbProxyServer.Text))
{
MessageBox.Show("Server can't be empty");
return;
}
if (string.IsNullOrEmpty(tbProxyPort.Text))
{
MessageBox.Show("Server port can't be empty");
return;
}
int port;
if (!int.TryParse(tbProxyPort.Text, out port))
{
MessageBox.Show("Invalid port format");
return;
}
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.baidu.com");
request.Timeout = 1000 * 5;
request.ReadWriteTimeout = 1000 * 5;
if (string.IsNullOrEmpty(tbProxyUserName.Text))
{
request.Proxy = new WebProxy(tbProxyServer.Text, port);
}
else
{
request.Proxy = new WebProxy(tbProxyServer.Text, port);
request.Proxy.Credentials = new NetworkCredential(tbProxyUserName.Text, tbProxyPassword.Password);
}
try
{
HttpWebResponse response = (HttpWebResponse) request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
MessageBox.Show("Proxy is ok");
}
else
{
MessageBox.Show("Proxy connect failed.");
}
}
catch
{
MessageBox.Show("Proxy connect failed.");
}
}
}
}

View File

@@ -121,6 +121,7 @@
</Compile>
<Compile Include="Helper\FontHelper.cs" />
<Compile Include="Helper\Forker.cs" />
<Compile Include="Helper\HttpProxy.cs" />
<Compile Include="Helper\ImageLoader.cs" />
<Compile Include="Helper\SyntaxSugars.cs" />
<Compile Include="Helper\WallpaperPathRetrieval.cs" />
@@ -130,7 +131,7 @@
<Compile Include="CustomPluginHotkeySetting.xaml.cs">
<DependentUpon>CustomPluginHotkeySetting.xaml</DependentUpon>
</Compile>
<Compile Include="DispatcherExtensions.cs" />
<Compile Include="Helper\DispatcherExtensions.cs" />
<Compile Include="Helper\DWMDropShadow.cs" />
<Compile Include="Helper\Log.cs" />
<Compile Include="Helper\PluginInstaller.cs" />