On Mon, 6 Oct 2008, Glynn Clements wrote:

Oops. It turns out that Python doesn't understand %PATHEXT% (but it
least it's consistent; it doesn't work with .bat or .cmd files
either).

It looks to me like it doesn't work with .exe either, i.e. it doesn't assume the extension - e.g. trying to run a script on Windows I had to change line 139 of grass.py from
    os.execvp("g.parser", [name] + argv)
to
    os.execvp("g.parser.exe", [name] + argv)
to get it to do anything at all.


It appears that %PATHEXT%, assoc and ftype are features of cmd.exe.
CreateProcess() itself doesn't understand them:

        To run a batch file, you must start the command interpreter;
        set lpApplicationName to cmd.exe and set lpCommandLine to the
        following arguments: /c plus the name of the batch file.

[ http://msdn.microsoft.com/en-us/library/ms682425.aspx ]

It works if you use os.system(), or subprocess.Popen() with
shell=True, which isn't surprising. But none of the os.spawn* or
os.exec* functions work, nor subprocess.Popen() with shell=False.

Having said that, it should be simple enough to create a wrapper
around the Windows version of subprocess.Popen._execute_child() which
searches for the "executable" using PATH and PATHEXT, then
automatically prepends the interpreter where necessary. Or which uses
subprocess.list2cmdline() to convert the command to a string, then use
['cmd', '/c', cmdstring].

Looks like something like that will be necessary.

In any case, it appears that windows_launch.bat isn't an option, as we
would need to jump through the same hoops to be able to run .bat files
directly.

It's neat though in the sense that no registry editing is necessary to launch scripts that way, and it will work from the command-line.

On the other hand, for the PATHEXT method to work does Python have to be
officially "installed" on Windows in some manner? If it does that might
preclude just including the Python interpreter as part of a GRASS binary
distribution, which someone might want to do.

Also, in order to be able to execute a file without explicitly
specifying the interpreter, the extension and type have to be known to
"assoc" and "ftype". AFAICT, the "assoc" information is stored in:

      HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.py

while the "ftype" information is stored in:

      HKEY_LOCAL_MACHINE\SOFTWARE\Classes\python.file\Shell\Open\Command

At least, deleting those keys causes assoc and ftype to immediately
"forget" the association.

However, these keys weren't set by the Python installer, although it
did set the keys under both HKEY_CURRENT_USER\Software\Classes and
HKEY_CLASSES_ROOT. AFAIK, those are the ones which Explorer uses.

If we want to handle this ourselves from within GRASS' Python scripts,
we can use the _winreg module (note: leading underscore), e.g.:

      >>> import _winreg
>>> h = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,
r'SOFTWARE\Classes\$
      >>> (val, type) = _winreg.QueryValueEx(h, None)
      >>> print (val, type)
      (u'python.file', 1)
>>> h = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,
r'SOFTWARE\Classes\$
      >>> (val, type) = _winreg.QueryValueEx(h, None)
      >>> print (val, type)
      (u'"C:\\Program Files\\Python25\\python.exe" "%1"', 2)

This seems more complicated than a solution analogous to windows_launch.bat with a GRASS_PYTHON environment variable. I'm not sure what's best.

Paul

_______________________________________________
grass-dev mailing list
grass-dev@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/grass-dev

Reply via email to