@@ -15128,6 +15128,37 @@ The filepath is relative to the current directory. If you want to use\n\
15128
15128
an absolute path, make sure the first character is not a slash (\"/\");\n\
15129
15129
the underlying Win32 ShellExecute function doesn't work if it is." );
15130
15130
15131
+ /* Grab ShellExecute dynamically from shell32 */
15132
+ static int has_ShellExecute = -1 ;
15133
+ static HINSTANCE (CALLBACK * Py_ShellExecuteA )(HWND , LPCSTR , LPCSTR , LPCSTR ,
15134
+ LPCSTR , INT );
15135
+ static HINSTANCE (CALLBACK * Py_ShellExecuteW )(HWND , LPCWSTR , LPCWSTR , LPCWSTR ,
15136
+ LPCWSTR , INT );
15137
+ static int
15138
+ check_ShellExecute ()
15139
+ {
15140
+ HINSTANCE hShell32 ;
15141
+
15142
+ /* only recheck */
15143
+ if (-1 == has_ShellExecute ) {
15144
+ Py_BEGIN_ALLOW_THREADS
15145
+ hShell32 = LoadLibraryW (L"SHELL32" );
15146
+ Py_END_ALLOW_THREADS
15147
+ if (hShell32 ) {
15148
+ * (FARPROC * )& Py_ShellExecuteA = GetProcAddress (hShell32 ,
15149
+ "ShellExecuteA" );
15150
+ * (FARPROC * )& Py_ShellExecuteW = GetProcAddress (hShell32 ,
15151
+ "ShellExecuteW" );
15152
+ has_ShellExecute = Py_ShellExecuteA &&
15153
+ Py_ShellExecuteW ;
15154
+ } else {
15155
+ has_ShellExecute = 0 ;
15156
+ }
15157
+ }
15158
+ return has_ShellExecute ;
15159
+ }
15160
+
15161
+
15131
15162
static PyObject *
15132
15163
win32_startfile (PyObject * self , PyObject * args )
15133
15164
{
@@ -15138,6 +15169,14 @@ win32_startfile(PyObject *self, PyObject *args)
15138
15169
HINSTANCE rc ;
15139
15170
15140
15171
PyObject * unipath , * uoperation = NULL ;
15172
+
15173
+ if (!check_ShellExecute ()) {
15174
+ /* If the OS doesn't have ShellExecute, return a
15175
+ NotImplementedError. */
15176
+ return PyErr_Format (PyExc_NotImplementedError ,
15177
+ "startfile not available on this platform" );
15178
+ }
15179
+
15141
15180
if (!PyArg_ParseTuple (args , "U|s:startfile" ,
15142
15181
& unipath , & operation )) {
15143
15182
PyErr_Clear ();
@@ -15166,8 +15205,8 @@ win32_startfile(PyObject *self, PyObject *args)
15166
15205
woperation = NULL ;
15167
15206
15168
15207
Py_BEGIN_ALLOW_THREADS
15169
- rc = ShellExecuteW ((HWND )0 , woperation , wpath ,
15170
- NULL , NULL , SW_SHOWNORMAL );
15208
+ rc = Py_ShellExecuteW ((HWND )0 , woperation , wpath ,
15209
+ NULL , NULL , SW_SHOWNORMAL );
15171
15210
Py_END_ALLOW_THREADS
15172
15211
15173
15212
Py_XDECREF (uoperation );
@@ -15189,8 +15228,8 @@ win32_startfile(PyObject *self, PyObject *args)
15189
15228
}
15190
15229
filepath = PyBytes_AsString (ofilepath );
15191
15230
Py_BEGIN_ALLOW_THREADS
15192
- rc = ShellExecute ((HWND )0 , operation , filepath ,
15193
- NULL , NULL , SW_SHOWNORMAL );
15231
+ rc = Py_ShellExecuteA ((HWND )0 , operation , filepath ,
15232
+ NULL , NULL , SW_SHOWNORMAL );
15194
15233
Py_END_ALLOW_THREADS
15195
15234
if (rc <= (HINSTANCE )32 ) {
15196
15235
PyObject * errval = win32_error ("startfile" , filepath );
0 commit comments