8000 bpo-43538: Add extra arguments to os.startfile (GH-25538) · python/cpython@019e9e8 · GitHub
[go: up one dir, main page]

Skip to content

Commit 019e9e8

Browse files
authored
bpo-43538: Add extra arguments to os.startfile (GH-25538)
1 parent 3513d55 commit 019e9e8

File tree

6 files changed

+126
-25
lines changed

6 files changed

+126
-25
lines changed

Doc/library/os.rst

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4155,7 +4155,7 @@ written in Python, such as a mail server's external command delivery program.
41554155
.. availability:: Windows.
41564156

41574157

4158-
.. function:: startfile(path[, operation])
4158+
.. function:: startfile(path, [operation], [arguments], [cwd], [show_cmd])
41594159

41604160
Start a file with its associated application.
41614161

@@ -4169,22 +4169,40 @@ written in Python, such as a mail server's external command delivery program.
41694169
``'print'`` and ``'edit'`` (to be used on files) as well as ``'explore'`` and
41704170
``'find'`` (to be used on directories).
41714171

4172+
When launching an application, specify *arguments* to be passed as a single
4173+
string. This argument may have no effect when using this function to launch a
4174+
document.
4175+
4176+
The default working directory is inherited, but may be overridden by the *cwd*
4177+
argument. This should be an absolute path. A relative *path* will be resolved
4178+
against this argument.
4179+
4180+
Use *show_cmd* to override the default window style. Whether this has any
4181+
effect will depend on the application being launched. Values are integers as
4182+
supported by the Win32 :c:func:`ShellExecute` function.
4183+
41724184
:func:`startfile` returns as soon as the associated application is launched.
41734185
There is no option to wait for the application to close, and no way to retrieve
41744186
the application's exit status. The *path* parameter is relative to the current
4175-
directory. If you want to use an absolute path, make sure the first character
4176-
is not a slash (``'/'``); the underlying Win32 :c:func:`ShellExecute` function
4177-
doesn't work if it is. Use the :func:`os.path.normpath` function to ensure that
4178-
the path is properly encoded for Win32.
4187+
directory or *cwd*. If you want to use an absolute path, make sure the first
4188+
character is not a slash (``'/'``) Use :mod:`pathlib` or the
4189+
:func:`os.path.normpath` function to ensure that paths are properly encoded for
4190+
Win32.
41794191

41804192
To reduce interpreter startup overhead, the Win32 :c:func:`ShellExecute`
41814193
function is not resolved until this function is first called. If the function
41824194
cannot be resolved, :exc:`NotImplementedError` will be raised.
41834195

41844196
.. audit-event:: os.startfile path,operation os.startfile
41854197

4198+
.. audit-event:: os.startfile/2 path,operation,arguments,cwd,show_cmd os.startfile
4199+
41864200
.. availability:: Windows.
41874201

4202+
.. versionchanged:: 3.10
4203+
Added the *arguments*, *cwd* and *show_cmd* arguments, and the
4204+
``os.startfile/2`` audit event.
4205+
41884206

41894207
.. function:: system(command)
41904208

Lib/test/test_startfile.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@
1818
startfile = support.get_attribute(os, 'startfile')
1919

2020

21+
@unittest.skipIf(platform.win32_is_iot(), "starting files is not supported on Windows IoT Core or nanoserver")
2122
class TestCase(unittest.TestCase):
2223
def test_nonexisting(self):
2324
self.assertRaises(OSError, startfile, "nonexisting.vbs")
2425

25-
@unittest.skipIf(platform.win32_is_iot(), "starting files is not supported on Windows IoT Core or nanoserver")
2626
def test_empty(self):
2727
# We need to make sure the child process starts in a directory
2828
# we're not about to delete. If we're running under -j, that
@@ -32,6 +32,14 @@ def test_empty(self):
3232
empty = path.join(path.dirname(__file__), "empty.vbs")
3333
startfile(empty)
3434
startfile(empty, "open")
35+
startfile(empty, cwd=path.dirname(sys.executable))
36+
37+
def test_python(self):
38+
# Passing "-V" ensures that it closes quickly, though still not
39+
# quickly enough that we can run in the test directory
40+
cwd, name = path.split(sys.executable)
41+
startfile(name, arguments="-V", cwd=cwd)
42+
startfile(name, arguments="-V", cwd=cwd, show_cmd=0)
3543

3644
if __name__ == "__main__":
3745
unittest.main()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Adds additional arguments to :func:`os.startfile` function.

Modules/clinic/posixmodule.c.h

Lines changed: 71 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/posixmodule.c

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12485,6 +12485,9 @@ check_ShellExecute()
1248512485
os.startfile
1248612486
filepath: path_t
1248712487
operation: Py_UNICODE = NULL
12488+
arguments: Py_UNICODE = NULL
12489+
cwd: path_t(nullable=True) = None
12490+
show_cmd: int = 1
1248812491
1248912492
Start a file with its associated application.
1249012493
@@ -12495,6 +12498,16 @@ application (if any) its extension is associated.
1249512498
When another "operation" is given, it specifies what should be done with
1249612499
the file. A typical operation is "print".
1249712500
12501+
"arguments" is passed to the application, but should be omitted if the
12502+
file is a document.
12503+
12504+
"cwd" is the working directory for the operation. If "filepath" is
12505+
relative, it will be resolved against this directory. This argument
12506+
should usually be an absolute path.
12507+
12508+
"show_cmd" can be used to override the recommended visibility option.
12509+
See the Windows ShellExecute documentation for values.
12510+
1249812511
startfile returns as soon as the associated application is launched.
1249912512
There is no option to wait for the application to close, and no way
1250012513
to retrieve the application's exit status.
@@ -12506,8 +12519,9 @@ the underlying Win32 ShellExecute function doesn't work if it is.
1250612519

1250712520
static PyObject *
1250812521
os_startfile_impl(PyObject *module, path_t *filepath,
12509-
const Py_UNICODE *operation)
12510-
/*[clinic end generated code: output=66dc311c94d50797 input=c940888a5390f039]*/
12522+
const Py_UNICODE *operation, const Py_UNICODE *arguments,
12523+
path_t *cwd, int show_cmd)
12524+
/*[clinic end generated code: output=3baa4f9795841880 input=8248997b80669622]*/
1251112525
{
1251212526
HINSTANCE rc;
1251312527

@@ -12521,10 +12535,15 @@ os_startfile_impl(PyObject *module, path_t *filepath,
1252112535
if (PySys_Audit("os.startfile", "Ou", filepath->object, operation) < 0) {
1252212536
return NULL;
1252312537
}
12538+
if (PySys_Audit("os.startfile/2", "OuuOi", filepath->object, operation,
12539+
arguments, cwd->object ? cwd->object : Py_None,
12540+
show_cmd) < 0) {
12541+
return NULL;
12542+
}
1252412543

1252512544
Py_BEGIN_ALLOW_THREADS
1252612545
rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
12527-
NULL, NULL, SW_SHOWNORMAL);
12546+
arguments, cwd->wide, show_cmd);
1252812547
Py_END_ALLOW_THREADS
1252912548

1253012549
if (rc <= (HINSTANCE)32) {

0 commit comments

Comments
 (0)
0