[Distutils] VBScript puzzle
Bill Janssen
janssen at parc.com
Mon Apr 26 23:04:12 CEST 2010
Jess Austin <jess.austin at gmail.com> wrote:
> C:\>cscript bdist.js "Python26\python.exe"
>
>
> Here's the script:
>
>
> 4 // 3; '''
> ;
> if (WScript.Arguments.Count() < 1)
> WScript.Echo("usage: " + WScript.ScriptName + " <path to python>");
> else
> WScript.CreateObject("WScript.Shell").Run(WScript.Arguments.Item(0) + " " +
> WScript.ScriptFullName, 1, true); /*
> '''
> # start of python script
> from time import sleep
> print("hello from python")
> sleep(5)
> # end of python script */
The killer here is WScript.ScriptFullName. The MSI framework does not
want to give that to you. The only way to do this (I think) is to
include the full Python program as a literal in the JScript program. It
can then create a temporary file in InstallTemp, write the Python to it,
find Python in the registry, and invoke Python on the Python script.
To make it more general, you could use a property for the location of
Python, and use another custom action to find and/or set that property.
What seems to work is to base64-encode the Python script andadd it as a
literal to the JScript. Then the JScript saves it to a file, and
invokes Python on it with
"import base64; exec(base64.decodestring(open(TEMPFILE).read().strip()))":
Here's my JScript:
var pythonscript_base64 = 'cHJpbnQgJ2hlbGxvLCB3b3JsZCEn\n';
var WshShell = new ActiveXObject ("WScript.Shell");
var filesystem = new ActiveXObject("Scripting.FileSystemObject");
var logfile = filesystem.CreateTextFile("C:\\install-script.log");
var installtemp = Session.Property("TempFolder");
logfile.WriteLine("TempFolder is " + installtemp);
var scriptfile = filesystem.CreateTextFile(installtemp + "iscript.py");
scriptfile.Write(pythonscript_base64);
scriptfile.Close();
var pythonDir = WshShell.RegRead ("HKEY_LOCAL_MACHINE\\Software\\Python\\PythonCore\\2.6\\InstallPath\\");
var pythonExe = pythonDir + "pythonw.exe";
if (! filesystem.FileExists(pythonExe)) {
logfile.WriteLine("Python not found!");
exit(1); // can we really just use exit?
} else {
logfile.WriteLine("python is " + pythonExe);
};
var cmd = pythonExe + ' -c "import base64; exec(base64.decodestring(open(' + "r'" + installtemp + "iscript.py').read()))" + '"';
logfile.WriteLine("cmd is " + cmd);
var oExec = WshShell.Exec(cmd);
while (oExec.Status == 0) {
while (!oExec.StdOut.AtEndOfStream) {
logfile.WriteLine(oExec.StdOut.ReadLine());
}
while (!oExec.StdErr.AtEndOfStream) {
logfile.WriteLine(oExec.StdErr.ReadLine());
}
// WScript.Sleep(100);
} /*
'''
Bill
More information about the Distutils-SIG
mailing list