diff options
author | Steve Dower <steve.dower@microsoft.com> | 2015-01-24 16:18:24 (GMT) |
---|---|---|
committer | Steve Dower <steve.dower@microsoft.com> | 2015-01-24 16:18:24 (GMT) |
commit | 7d0e0c9f7b0b86a25f10739b3c01195c8154f495 (patch) | |
tree | f6bc4c600d5426acadd34d8d7f3a954908fcf7d3 /Modules | |
parent | b95b56150fc3e7834783b54acdddeaed4fe44e27 (diff) | |
download | cpython-7d0e0c9f7b0b86a25f10739b3c01195c8154f495.zip cpython-7d0e0c9f7b0b86a25f10739b3c01195c8154f495.tar.gz cpython-7d0e0c9f7b0b86a25f10739b3c01195c8154f495.tar.bz2 |
Closes #23253: Delay-load ShellExecute
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/posixmodule.c | 47 |
1 files changed, 43 insertions, 4 deletions
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 542e600..502e933 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -15128,6 +15128,37 @@ The filepath is relative to the current directory. If you want to use\n\ an absolute path, make sure the first character is not a slash (\"/\");\n\ the underlying Win32 ShellExecute function doesn't work if it is."); +/* Grab ShellExecute dynamically from shell32 */ +static int has_ShellExecute = -1; +static HINSTANCE (CALLBACK *Py_ShellExecuteA)(HWND, LPCSTR, LPCSTR, LPCSTR, + LPCSTR, INT); +static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR, + LPCWSTR, INT); +static int +check_ShellExecute() +{ + HINSTANCE hShell32; + + /* only recheck */ + if (-1 == has_ShellExecute) { + Py_BEGIN_ALLOW_THREADS + hShell32 = LoadLibraryW(L"SHELL32"); + Py_END_ALLOW_THREADS + if (hShell32) { + *(FARPROC*)&Py_ShellExecuteA = GetProcAddress(hShell32, + "ShellExecuteA"); + *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32, + "ShellExecuteW"); + has_ShellExecute = Py_ShellExecuteA && + Py_ShellExecuteW; + } else { + has_ShellExecute = 0; + } + } + return has_ShellExecute; +} + + static PyObject * win32_startfile(PyObject *self, PyObject *args) { @@ -15138,6 +15169,14 @@ win32_startfile(PyObject *self, PyObject *args) HINSTANCE rc; PyObject *unipath, *uoperation = NULL; + + if(!check_ShellExecute()) { + /* If the OS doesn't have ShellExecute, return a + NotImplementedError. */ + return PyErr_Format(PyExc_NotImplementedError, + "startfile not available on this platform"); + } + if (!PyArg_ParseTuple(args, "U|s:startfile", &unipath, &operation)) { PyErr_Clear(); @@ -15166,8 +15205,8 @@ win32_startfile(PyObject *self, PyObject *args) woperation = NULL; Py_BEGIN_ALLOW_THREADS - rc = ShellExecuteW((HWND)0, woperation, wpath, - NULL, NULL, SW_SHOWNORMAL); + rc = Py_ShellExecuteW((HWND)0, woperation, wpath, + NULL, NULL, SW_SHOWNORMAL); Py_END_ALLOW_THREADS Py_XDECREF(uoperation); @@ -15189,8 +15228,8 @@ normal: } filepath = PyBytes_AsString(ofilepath); Py_BEGIN_ALLOW_THREADS - rc = ShellExecute((HWND)0, operation, filepath, - NULL, NULL, SW_SHOWNORMAL); + rc = Py_ShellExecuteA((HWND)0, operation, filepath, + NULL, NULL, SW_SHOWNORMAL); Py_END_ALLOW_THREADS if (rc <= (HINSTANCE)32) { PyObject *errval = win32_error("startfile", filepath); |