This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author eryksun
Recipients busfault, eryksun, paul.moore, steve.dower, tim.golden, zach.ware
Date 2016-04-27.09:55:49
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1461750950.6.0.314131338872.issue26866@psf.upfronthosting.co.za>
In-reply-to
Content
Generally the directory that an application needs for its configuration files and data is either the script directory or an %AppData% or %LocalAppData% subdirectory. If the initial working directory matters for some reason (e.g. for writing output files), the parent process either changes to the desired directory beforehand or passes the working directory as a parameter to the CreateProcess or ShellExecuteEx API. It wouldn't make sense for Python to set the working directory to the script directory, because a standard user probably can't even modify that directory. 

> From Explorer:

When running a file, Explorer usually creates the child process with the initial working directory set to that of the target file. However, for "open with" it uses its own working directory, "%SystemRoot%\System32". Actually, the "open with" dialog (not the menu) that lets you select and run an application isn't even Explorer. It's openwith.exe. At least it is in Windows 10 and, IIRC, back to Windows 7.

A workaround is to create a "Run" command in "HKCU\SOFTWARE\Classes\SystemFileAssociations\.py". See the following page for more information about application registration:

https://msdn.microsoft.com/en-us/library/ee872121

For example, the follow .reg file defines a command to run a script using the py.exe launcher. It also adds an "Edit" command that uses DDE to open a script in Visual Studio 2015. 

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\SOFTWARE\Classes\SystemFileAssociations\.py]

[HKEY_CURRENT_USER\SOFTWARE\Classes\SystemFileAssociations\.py\shell]
@="Run"

[HKEY_CURRENT_USER\SOFTWARE\Classes\SystemFileAssociations\.py\shell\Edit]

[HKEY_CURRENT_USER\SOFTWARE\Classes\SystemFileAssociations\.py\shell\Edit\command]
@="\"C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\IDE\\devenv.exe\" /dde"

[HKEY_CURRENT_USER\SOFTWARE\Classes\SystemFileAssociations\.py\shell\Edit\ddeexec]
@="Open(\"%1\")"

[HKEY_CURRENT_USER\SOFTWARE\Classes\SystemFileAssociations\.py\shell\Edit\ddeexec\application]
@="VisualStudio.14.0"

[HKEY_CURRENT_USER\SOFTWARE\Classes\SystemFileAssociations\.py\shell\Edit\ddeexec\topic]
@="system"

[HKEY_CURRENT_USER\SOFTWARE\Classes\SystemFileAssociations\.py\shell\Run]

[HKEY_CURRENT_USER\SOFTWARE\Classes\SystemFileAssociations\.py\shell\Run\command]
@="\"C:\\Windows\\py.exe\" \"%1\" %*"

These commands are associated directly with the .py file extension, so they'll always be available, even if no ProgID (e.g. Python.File) is associated with .py scripts. However, the shell will prefer a selected ProgID's "Run" or "Edit" commands, if they exist.

FYI, Explorer's "FileExts\.py" key caches the OpenWithProgids, OpenWithList, and the selected UserChoice for .py files. It shouldn't be modified programmatically, and there's actually a deny ACE on the UserChoice subkey to prevent setting values. One thing you can do, if necessary, is delete the entire key to recompute the file association from the HKCR settings.

If you're manually testing changes by directly modifying the registry (such as deleting the above key), you can call the shell's SHChangeNotify function to refresh file associations, which avoids having to log off and back on. For example:

    import ctypes
    shell32 = ctypes.WinDLL('shell32')

    SHCNE_ASSOCCHANGED = 0x08000000
    shell32.SHChangeNotify.restype = None
    
    shell32.SHChangeNotify(SHCNE_ASSOCCHANGED, 0, 0, 0)

> from the command prompt:

cmd spawns a process using its current working directory (displayed in the prompt, or returned by "cd" without an argument). This is not necessarily the directory of the target file. You can use the /d option of the start command to override this with a specific working directory. For example:

    start "title" /d "C:\Temp" "C:\Temp\somescript.py"
History
Date User Action Args
2016-04-27 09:55:50eryksunsetrecipients: + eryksun, paul.moore, tim.golden, busfault, zach.ware, steve.dower
2016-04-27 09:55:50eryksunsetmessageid: <1461750950.6.0.314131338872.issue26866@psf.upfronthosting.co.za>
2016-04-27 09:55:50eryksunlinkissue26866 messages
2016-04-27 09:55:49eryksuncreate