mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-06-07 09:28:03 +08:00
Change Python C Wrapper
This commit is contained in:
parent
bdf77b2782
commit
5893564f46
@ -1,69 +1,116 @@
|
||||
#include <tchar.h>
|
||||
#include "Python.h"
|
||||
|
||||
#include <thread>
|
||||
#include <future>
|
||||
|
||||
extern "C" __declspec(dllexport) void InitPythonEnv()
|
||||
{
|
||||
Py_Initialize();
|
||||
PyEval_InitThreads();
|
||||
}
|
||||
|
||||
char* GetErrorMessage()
|
||||
{
|
||||
char *pStrErrorMessage = NULL;
|
||||
|
||||
if(PyErr_Occurred()){
|
||||
PyObject *ptype, *pvalue, *ptraceback;
|
||||
PyErr_Fetch(&ptype, &pvalue, &ptraceback);
|
||||
pStrErrorMessage = PyString_AsString(pvalue);
|
||||
}
|
||||
|
||||
return pStrErrorMessage;
|
||||
}
|
||||
|
||||
|
||||
char* Exec(char* directory, char* file, char* method, char* para)
|
||||
{
|
||||
PyObject *pName, *pModule, *pDict, *pFunc, *pValue, *pClass, *pInstance;
|
||||
char *error;
|
||||
|
||||
PyThreadState* global_state = PyThreadState_Get();
|
||||
PyThreadState* ts = Py_NewInterpreter();
|
||||
PyThreadState_Swap(ts);
|
||||
// Initialise the Python interpreter
|
||||
|
||||
// Create GIL/enable threads
|
||||
|
||||
//PyGILState_STATE gstate = PyGILState_Ensure();
|
||||
// // Get the default thread state
|
||||
// PyThreadState* state = PyThreadState_Get();
|
||||
// // Once in each thread
|
||||
//PyThreadState* stateForNewThread = PyThreadState_New(state->interp);
|
||||
//PyEval_RestoreThread(stateForNewThread);
|
||||
|
||||
// Build the name object
|
||||
PyObject *sys = PyImport_ImportModule("sys");
|
||||
PyObject *path = PyObject_GetAttrString(sys, "path");
|
||||
PyList_Append(path, PyString_FromString(directory));
|
||||
|
||||
pName = PyString_FromString(file);
|
||||
error = GetErrorMessage();
|
||||
if(error != NULL){
|
||||
char* err =new char[5000]();
|
||||
sprintf(error, "%s:%s","PYTHONERROR",error);
|
||||
return err;
|
||||
}
|
||||
|
||||
pModule = PyImport_Import(pName);
|
||||
error = GetErrorMessage();
|
||||
if(error != NULL){
|
||||
char* err =new char[5000]();
|
||||
sprintf(err, "%s:%s","PYTHONERROR",error);
|
||||
return err;
|
||||
}
|
||||
|
||||
pDict = PyModule_GetDict(pModule);
|
||||
error = GetErrorMessage();
|
||||
if(error != NULL){
|
||||
char* err =new char[5000]();
|
||||
sprintf(err, "%s:%s","PYTHONERROR",error);
|
||||
return err;
|
||||
}
|
||||
|
||||
pClass = PyDict_GetItemString(pDict,"PyWinAlfred");
|
||||
error = GetErrorMessage();
|
||||
if(error != NULL){
|
||||
char* err =new char[5000]();
|
||||
sprintf(err, "%s:%s","PYTHONERROR",error);
|
||||
return err;
|
||||
}
|
||||
|
||||
pInstance = PyObject_CallObject(pClass, NULL);
|
||||
error = GetErrorMessage();
|
||||
if(error != NULL){
|
||||
char* err =new char[5000]();
|
||||
sprintf(err, "%s:%s","PYTHONERROR",error);
|
||||
return err;
|
||||
}
|
||||
|
||||
// Call a method of the class with two parameters
|
||||
pValue = PyObject_CallMethod(pInstance,method, "(s)",para);
|
||||
error = GetErrorMessage();
|
||||
if(error != NULL){
|
||||
char* err =new char[5000]();
|
||||
sprintf(err, "%s:%s","PYTHONERROR",error);
|
||||
return err;
|
||||
}
|
||||
|
||||
char * str_ret = PyString_AsString(pValue);
|
||||
|
||||
//PyEval_SaveThread();
|
||||
|
||||
// Finish the Python Interpreter
|
||||
|
||||
PyErr_Clear();
|
||||
Py_EndInterpreter(ts);
|
||||
PyThreadState_Swap(global_state);
|
||||
|
||||
return str_ret;
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) char* ExecPython(char* directory, char* file, char* method, char* para)
|
||||
{
|
||||
try{
|
||||
PyObject *pName, *pModule, *pDict, *pFunc, *pValue, *pClass, *pInstance;
|
||||
|
||||
// Initialise the Python interpreter
|
||||
Py_Initialize();
|
||||
|
||||
// Create GIL/enable threads
|
||||
//PyEval_InitThreads();
|
||||
|
||||
//PyGILState_STATE gstate = PyGILState_Ensure();
|
||||
// // Get the default thread state
|
||||
// PyThreadState* state = PyThreadState_Get();
|
||||
// // Once in each thread
|
||||
//PyThreadState* stateForNewThread = PyThreadState_New(state->interp);
|
||||
//PyEval_RestoreThread(stateForNewThread);
|
||||
|
||||
// Build the name object
|
||||
PyObject *sys = PyImport_ImportModule("sys");
|
||||
PyObject *path = PyObject_GetAttrString(sys, "path");
|
||||
PyList_Append(path, PyString_FromString(directory));
|
||||
|
||||
pName = PyString_FromString(file);
|
||||
|
||||
// Load the module object
|
||||
pModule = PyImport_Import(pName);
|
||||
|
||||
// pDict is a borrowed reference
|
||||
pDict = PyModule_GetDict(pModule);
|
||||
|
||||
// pFunc is also a borrowed reference
|
||||
pClass = PyDict_GetItemString(pDict,"PyWinAlfred");
|
||||
|
||||
if (PyCallable_Check(pClass))
|
||||
{
|
||||
pInstance = PyObject_CallObject(pClass, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_Print();
|
||||
return "failed";
|
||||
}
|
||||
|
||||
// Call a method of the class with two parameters
|
||||
pValue = PyObject_CallMethod(pInstance,method, "(s)",para);
|
||||
char * str_ret = PyString_AsString(pValue);
|
||||
|
||||
//PyGILState_Release(gstate);
|
||||
//PyEval_SaveThread();
|
||||
|
||||
// Finish the Python Interpreter
|
||||
//Py_Finalize();
|
||||
|
||||
return str_ret;
|
||||
}
|
||||
catch(int& value){
|
||||
PyErr_Print();
|
||||
}
|
||||
auto future = std::async(Exec,directory,file,method,para);
|
||||
return future.get();
|
||||
}
|
@ -103,7 +103,7 @@
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;PYWINALFRED_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;PYWINALFRED_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
|
@ -68,8 +68,8 @@ namespace WinAlfred
|
||||
private void TextBoxBase_OnTextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
string query = tbQuery.Text;
|
||||
ThreadPool.QueueUserWorkItem(state =>
|
||||
{
|
||||
//ThreadPool.QueueUserWorkItem(state =>
|
||||
//{
|
||||
results.Clear();
|
||||
foreach (PluginPair pair in plugins)
|
||||
{
|
||||
@ -98,7 +98,7 @@ namespace WinAlfred
|
||||
resultCtrl.AddResults(results.OrderByDescending(o => o.Score).ToList());
|
||||
resultCtrl.SelectFirst();
|
||||
}));
|
||||
});
|
||||
//});
|
||||
}
|
||||
|
||||
private void HideWinAlfred()
|
||||
|
@ -25,12 +25,24 @@ namespace WinAlfred.PluginLoader
|
||||
try
|
||||
{
|
||||
string s = Marshal.PtrToStringAnsi(ExecPython(metadata.PluginDirecotry, metadata.ExecuteFileName.Replace(".py", ""), "query", query.RawQuery));
|
||||
if (string.IsNullOrEmpty(s))
|
||||
{
|
||||
return new List<Result>();
|
||||
}
|
||||
|
||||
if (s.StartsWith("PYTHONERROR"))
|
||||
{
|
||||
throw new ArgumentException(s);
|
||||
}
|
||||
List<PythonResult> o = JsonConvert.DeserializeObject<List<PythonResult>>(s);
|
||||
List<Result> r = new List<Result>();
|
||||
foreach (PythonResult pythonResult in o)
|
||||
{
|
||||
PythonResult ps = pythonResult;
|
||||
ps.Action = () => ExecPython(metadata.PluginDirecotry, metadata.ExecuteFileName.Replace(".py", ""), ps.ActionName, ps.ActionPara);
|
||||
if (!string.IsNullOrEmpty(ps.ActionName))
|
||||
{
|
||||
ps.Action = () => ExecPython(metadata.PluginDirecotry, metadata.ExecuteFileName.Replace(".py", ""), ps.ActionName, ps.ActionPara);
|
||||
}
|
||||
r.Add(ps);
|
||||
}
|
||||
return r;
|
||||
|
@ -152,7 +152,7 @@ namespace WinAlfred
|
||||
var resultItemControl = pnlContainer.Children[index] as ResultItem;
|
||||
if (resultItemControl != null)
|
||||
{
|
||||
resultItemControl.Result.Action();
|
||||
if (resultItemControl.Result.Action != null) resultItemControl.Result.Action();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user