[GRASS-dev] porting r.in.wms to python

Glynn Clements glynn at gclements.plus.com
Mon Oct 6 00:51:36 EDT 2008


Paul Kelly wrote:

> > Also, should we change windows_launch.bat to invoke Python on the
> > scripts, or just install the scripts with a .py extension and add .PY
> > to PATHEXT?
> 
> windows_launch.bat was only needed because there was no way to persuade 
> Tcl on Windows to execute any files that did not have a .exe, .com or .bat 
> extension. It didn't respect PATHEXT or anything similar. But 
> windows_launch.bat turned out to be a neat way of handling things. However if
> (1) Python respects PATHEXT and
> (2) PATHEXT as a method of executing scripts is reliable
> then I'm sure that would a good way of doing it and would be one less 
> thing to go wrong. As long as they could be installed without the .py 
> extension on Unix platforms I suppose.

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 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].

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.

> 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.

In order for PATHEXT to work, ".py" has to be added to PATHEXT
somehow. We can do that in init.bat.

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\.py')
	>>> (val, type) = _winreg.QueryValueEx(h, None)
	>>> print (val, type)
	(u'python.file', 1)
	>>> h = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\Classes\python.file\Shell\Open\Command')
	>>> (val, type) = _winreg.QueryValueEx(h, None)
	>>> print (val, type)
	(u'"C:\\Program Files\\Python25\\python.exe" "%1"', 2)

1 is REG_SZ (NUL-terminated string), while 2 is REG_EXPAND_SZ
(NUL-terminated string containing environment substitutions).

-- 
Glynn Clements <glynn at gclements.plus.com>


More information about the grass-dev mailing list