problem with bdist_msi post-install script
When I try to include a post-install script in my MSI built with bdist_msi, it seem to be included and unpacked properly, but it doesn't run successfully. Here's what's in the script (after unpacking): #!c:\Python26\python.exe # do nothing much import sys, os, time print "Hello, World" time.sleep(10) sys.exit(0) And here's what I get in my install log (generated with "msiexec /i foo.msi /L*v foo.log"): Action 18:35:46: install_script. Action start 18:35:46: install_script. MSI (s) (40:E0) [18:35:46:882]: Note: 1: 1722 2: install_script 3: C:\Python26\\python.exe 4: C:\Python26\Scripts\foo-install-script.py MSI (s) (40:E0) [18:35:46:882]: Note: 1: 2262 2: Error 3: -2147287038 MSI (c) (FC:78) [18:35:46:902]: Note: 1: 2262 2: Error 3: -2147287038 DEBUG: Error 2835: The control ErrorIcon was not found on dialog ErrorDlg The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is 2835. The arguments are: ErrorIcon, ErrorDlg, Error 1722. There is a problem with this Windows Installer package. A program run as part of the setup did not finish as expected. Contact your support personnel or package vendor. Action install_script, location: C:\Python26\\python.exe, command: C:\Python26\Scripts\foo-install-script.py MSI (s) (40:E0) [18:35:50:978]: Note: 1: 2262 2: Error 3: -2147287038 Any ideas? What's a postinstall script supposed to return or exit with to indicate success or failure, anyway? What does "The control ErrorIcon was not found on dialog ErrorDlg" mean? Bill
On Sun, Mar 21, 2010 at 9:45 PM, Bill Janssen <janssen@parc.com> wrote:
When I try to include a post-install script in my MSI built with bdist_msi, it seem to be included and unpacked properly, but it doesn't run successfully. Here's what's in the script (after unpacking):
#!c:\Python26\python.exe
# do nothing much import sys, os, time print "Hello, World"
time.sleep(10) sys.exit(0)
And here's what I get in my install log (generated with "msiexec /i foo.msi /L*v foo.log"):
Action 18:35:46: install_script. Action start 18:35:46: install_script. MSI (s) (40:E0) [18:35:46:882]: Note: 1: 1722 2: install_script 3: C:\Python26\\python.exe 4: C:\Python26\Scripts\foo-install-script.py MSI (s) (40:E0) [18:35:46:882]: Note: 1: 2262 2: Error 3: -2147287038 MSI (c) (FC:78) [18:35:46:902]: Note: 1: 2262 2: Error 3: -2147287038 DEBUG: Error 2835: The control ErrorIcon was not found on dialog ErrorDlg The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is 2835. The arguments are: ErrorIcon, ErrorDlg, Error 1722. There is a problem with this Windows Installer package. A program run as part of the setup did not finish as expected. Contact your support personnel or package vendor. Action install_script, location: C:\Python26\\python.exe, command: C:\Python26\Scripts\foo-install-script.py MSI (s) (40:E0) [18:35:50:978]: Note: 1: 2262 2: Error 3: -2147287038
Any ideas? What's a postinstall script supposed to return or exit with to indicate success or failure, anyway?
What does "The control ErrorIcon was not found on dialog ErrorDlg" mean?
The only reference to ErrorIcon was commented out by Martin a while ago. It was the icon attached to the Error Dialog you. I am not sure why you get this error. MacZiade:command tarek$ svn blame bdist_msi.py |grep ErrorIcon 42847 martin.v.loewis #error.control("ErrorIcon", "Icon", 15, 9, 24, 24, 5242881, None, "py.ico", None, None) I am cc'ing him.
Bill _______________________________________________ Distutils-SIG maillist - Distutils-SIG@python.org http://mail.python.org/mailman/listinfo/distutils-sig
-- Tarek Ziadé | http://ziade.org
Thanks, Tarek. I think I see why he commented it out -- there's the issue of having your hands on the .ico bits when you need them. Though it does seem that the MSI installer requires it in spite of the docs. But the real problem turns out to be in the add_scripts() method. Right now, it starts out def add_scripts(self): if self.install_script: add_data(self.db, "CustomAction", [("install_script", 50, "PYTHON", self.install_script_key)]) add_data(self.db, "InstallExecuteSequence", [("install_script", "NOT Installed", 6800)]) But if the target dir has a space in the path, this command invocation will fail, because Python will only see the first part of the path name. If I add double-quotes around the install script name, it works: def add_scripts(self): if self.install_script: # need to quote install_script_key here to pass pathnames containing # spaces (like "Program Files") through add_data(self.db, "CustomAction", [("install_script", 50, "PYTHON", '"' + self.install_script_key + '"')]) add_data(self.db, "InstallExecuteSequence", [("install_script", "NOT Installed", 6800)]) And, my other question, was, how should the script exit? Seems that sys.exit(0) works just fine. Bill Tarek Ziadé <ziade.tarek@gmail.com> wrote:
On Sun, Mar 21, 2010 at 9:45 PM, Bill Janssen <janssen@parc.com> wrote:
When I try to include a post-install script in my MSI built with bdist_msi, it seem to be included and unpacked properly, but it doesn't run successfully. Here's what's in the script (after unpacking):
#!c:\Python26\python.exe
# do nothing much import sys, os, time print "Hello, World"
time.sleep(10) sys.exit(0)
And here's what I get in my install log (generated with "msiexec /i foo.msi /L*v foo.log"):
Action 18:35:46: install_script. Action start 18:35:46: install_script. MSI (s) (40:E0) [18:35:46:882]: Note: 1: 1722 2: install_script 3: C:\Python26\\python.exe 4: C:\Python26\Scripts\foo-install-script.py MSI (s) (40:E0) [18:35:46:882]: Note: 1: 2262 2: Error 3: -2147287038 MSI (c) (FC:78) [18:35:46:902]: Note: 1: 2262 2: Error 3: -2147287038 DEBUG: Error 2835: The control ErrorIcon was not found on dialog ErrorDlg The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is 2835. The arguments are: ErrorIcon, ErrorDlg, Error 1722. There is a problem with this Windows Installer package. A program run as part of the setup did not finish as expected. Contact your support personnel or package vendor. Action install_script, location: C:\Python26\\python.exe, command: C:\Python26\Scripts\foo-install-script.py MSI (s) (40:E0) [18:35:50:978]: Note: 1: 2262 2: Error 3: -2147287038
Any ideas? What's a postinstall script supposed to return or exit with to indicate success or failure, anyway?
What does "The control ErrorIcon was not found on dialog ErrorDlg" mean?
The only reference to ErrorIcon was commented out by Martin a while ago. It was the icon attached to the Error Dialog you. I am not sure why you get this error.
MacZiade:command tarek$ svn blame bdist_msi.py |grep ErrorIcon 42847 martin.v.loewis #error.control("ErrorIcon", "Icon", 15, 9, 24, 24, 5242881, None, "py.ico", None, None)
I am cc'ing him.
Bill _______________________________________________ Distutils-SIG maillist - Distutils-SIG@python.org http://mail.python.org/mailman/listinfo/distutils-sig
-- Tarek Ziadé | http://ziade.org
The only reference to ErrorIcon was commented out by Martin a while ago. It was the icon attached to the Error Dialog you.
I'm not quite sure why I commented this out. See whether adding it back fixes the problem. The only reason I can see now is that py.ico isn't really an appropriate error icon, instead, a stop sign or something like that should be used - I may not have known then (as I don't know now) how to get that into the MSI file. Regards, Martin
Martin v. Löwis <martin@v.loewis.de> wrote:
The only reference to ErrorIcon was commented out by Martin a while ago. It was the icon attached to the Error Dialog you.
I'm not quite sure why I commented this out. See whether adding it back fixes the problem.
Yes, it gets rid of the secondary error, the bit about ErrorIcon and ErrorDlg.
The only reason I can see now is that py.ico isn't really an appropriate error icon, instead, a stop sign or something like that should be used - I may not have known then (as I don't know now) how to get that into the MSI file.
Well, in http://svn.python.org/projects/sandbox/branches/MvL/msi/msi.py: # Bitmaps add_data(db, "Binary", [("PythonWin", msilib.Binary(srcdir+r"\PCbuild\installer.bmp")), ("Up",msilib.Binary("Up.bin")), ("New",msilib.Binary("New.bin")), ("InfoIcon",msilib.Binary("info.bin")), ("ExclamationIcon",msilib.Binary("exclamic.bin")), ]) Doesn't this work? Bill
Well, in http://svn.python.org/projects/sandbox/branches/MvL/msi/msi.py:
# Bitmaps add_data(db, "Binary", [("PythonWin", msilib.Binary(srcdir+r"\PCbuild\installer.bmp")), ("Up",msilib.Binary("Up.bin")), ("New",msilib.Binary("New.bin")), ("InfoIcon",msilib.Binary("info.bin")), ("ExclamationIcon",msilib.Binary("exclamic.bin")), ])
Doesn't this work?
See http://svn.python.org/projects/sandbox/branches/MvL/msi/README.txt I now remember the problem: the icons are "Microsoft Sample Source Code", and I was unsure whether I can legally include them with Python. It might be useful to look at a recent PSDK whether this license still holds, and also whether there are CC icons somewhere that can be freely used (or someone could draw icons and contribute them to Python). Regards, Martin
MSI (s) (40:E0) [18:35:46:882]: Note: 1: 1722 2: install_script 3: C:\Python26\\python.exe 4: C:\Python26\Scripts\foo-install-script.py
This means: There is a problem with this Windows Installer package. A program run as part of the setup did not finish as expected. Contact your support personnel or package vendor. Action [2], location: [3], command: [4]
MSI (s) (40:E0) [18:35:50:978]: Note: 1: 2262 2: Error 3: -2147287038
This means: Stream does not exist: [2]. System error: [3].
What does "The control ErrorIcon was not found on dialog ErrorDlg" mean?
It probably means it couldn't post the error message for the first error, because the icon to indicate "error" isn't included in the MSI file (which is a separate bug).
What's a postinstall script supposed to return or exit with to indicate success or failure, anyway?
It should return 0 as the exit code.
Any ideas?
I can think of two reasons: a) it may dislike the double-backslash in the Python path. Try removing one of them b) the command line may need to repeat the executable name as argv0. I would use orca (from the platform SDK) to edit the MSI file, and see whether this fixes anything. Regards, Martin
Martin v. Löwis <martin@v.loewis.de> wrote:
What does "The control ErrorIcon was not found on dialog ErrorDlg" mean?
It probably means it couldn't post the error message for the first error, because the icon to indicate "error" isn't included in the MSI file (which is a separate bug).
Yes, I started getting better errors when I added an icon back in.
What's a postinstall script supposed to return or exit with to indicate success or failure, anyway?
It should return 0 as the exit code.
Thanks. What if there's actually an error? Just throw an exception?
Any ideas?
I can think of two reasons: a) it may dislike the double-backslash in the Python path. Try removing one of them
I was wondering about that. There's this clause in add_find_python: add_data(self.db, "CustomAction", [("PythonFromMachine", 51+256, "PYTHONDIR", "[PYTHON.MACHINE]"), ("PythonFromUser", 51+256, "PYTHONDIR", "[PYTHON.USER]"), ("PythonExe", 51+256, "PYTHON", "[PYTHONDIR]\\python.exe"), ("InitialTargetDir", 51+256, "TARGETDIR", "[PYTHONDIR]")]) and the backslash there seems redundant. Changing it to "[PYTHONDIR]python.exe" removes the extra backslash in the value of PYTHON. Shall I file a patch?
b) the command line may need to repeat the executable name as argv0.
No, but that first arg, the name of the script file, should be quoted.
I would use orca (from the platform SDK) to edit the MSI file, and see whether this fixes anything.
OK, thanks. Bill
What's a postinstall script supposed to return or exit with to indicate success or failure, anyway? It should return 0 as the exit code.
Thanks. What if there's actually an error? Just throw an exception?
Installer will look for a non-zero exit. It will display it as "a action has failed". So how you arrive at the non-zero exit code is irrelevant.
I was wondering about that. There's this clause in add_find_python:
add_data(self.db, "CustomAction", [("PythonFromMachine", 51+256, "PYTHONDIR", "[PYTHON.MACHINE]"), ("PythonFromUser", 51+256, "PYTHONDIR", "[PYTHON.USER]"), ("PythonExe", 51+256, "PYTHON", "[PYTHONDIR]\\python.exe"), ("InitialTargetDir", 51+256, "TARGETDIR", "[PYTHONDIR]")])
and the backslash there seems redundant. Changing it to "[PYTHONDIR]python.exe" removes the extra backslash in the value of PYTHON. Shall I file a patch?
Sure. Please indicate whether this is just cosmetical (and if so, better file a patch for trunk, which has that code changed). Regards, Martin
Martin, here's another question. The ability to add pre-install scripts seems to be implemented: if self.pre_install_script: scriptfn = os.path.join(self.bdist_dir, "preinstall.bat") f = open(scriptfn, "w") # The batch file will be executed with [PYTHON], so that %1 # is the path to the Python interpreter; %0 will be the path # of the batch file. # rem =""" # %1 %0 # exit # """ # <actual script> f.write('rem ="""\n%1 %0\nexit\n"""\n') f.write(open(self.pre_install_script).read()) f.close() add_data(self.db, "Binary", [("PreInstall", msilib.Binary(scriptfn)) ]) add_data(self.db, "CustomAction", [("PreInstall", 2, "PreInstall", None) ]) add_data(self.db, "InstallExecuteSequence", [("PreInstall", "NOT Installed", 450)]) But this doesn't look quite complete. I don't see where the Python interpreter is actually invoked here. (Cute trick swapping the args, by the way). Which is presumably why, in finalize_options, we find: if self.pre_install_script: raise DistutilsOptionError, "the pre-install-script feature is not yet implemented" Shouldn't the custom action be this: add_data(self.db, "CustomAction", [("PreInstall", 2, "PreInstall", '"PYTHON"'), ]) Bill
But this doesn't look quite complete. I don't see where the Python interpreter is actually invoked here. (Cute trick swapping the args, by the way).
Which is presumably why, in finalize_options, we find:
if self.pre_install_script: raise DistutilsOptionError, "the pre-install-script feature is not yet implemented"
Shouldn't the custom action be this:
add_data(self.db, "CustomAction", [("PreInstall", 2, "PreInstall", '"PYTHON"'), ])
I don't remember the details, but one problem might have been that custom action 2 is defined as "EXE file stored in a Binary table stream." Not sure whether batch files are even allowed here. In any case, the value should probably be '"[PYTHON]"', then so that the property gets expanded. Regards, Martin
Martin v. Löwis <martin@v.loewis.de> wrote:
But this doesn't look quite complete. I don't see where the Python interpreter is actually invoked here. (Cute trick swapping the args, by the way).
Which is presumably why, in finalize_options, we find:
if self.pre_install_script: raise DistutilsOptionError, "the pre-install-script feature is not yet implemented"
Shouldn't the custom action be this:
add_data(self.db, "CustomAction", [("PreInstall", 2, "PreInstall", '"PYTHON"'), ])
I don't remember the details, but one problem might have been that custom action 2 is defined as "EXE file stored in a Binary table stream." Not sure whether batch files are even allowed here.
In any case, the value should probably be '"[PYTHON]"', then so that the property gets expanded.
Ah, thanks. Bill
So, in add_ui(), I tried changing error.control("ErrorIcon", "Icon", 15, 9, 24, 24, 5242881, None, "py.ico", None, None) to error.control("ErrorIcon", "Icon", 15, 9, 24, 24, 5242881, None, None, None, None) But I still get this (when I've enabled the pre-install script feature), so I think this is a bug in MSI. Now to figure out the pre-install problem, once I've put an icon back in the Dialog. Action 10:32:02: PreInstall. Action start 10:32:02: PreInstall. MSI (s) (2C:A8) [10:32:02:322]: Note: 1: 1721 2: PreInstall 3: C:\WINDOWS\Installer\MSIB4.tmp 4: MSI (s) (2C:A8) [10:32:02:322]: Note: 1: 2262 2: Error 3: -2147287038 MSI (c) (C8:68) [10:32:02:332]: Note: 1: 2262 2: Error 3: -2147287038 DEBUG: Error 2835: The control ErrorIcon was not found on dialog ErrorDlg The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is 2835. The arguments are: ErrorIcon, ErrorDlg, Error 1721. There is a problem with this Windows Installer package. A program required for this install to complete could not be run. Contact your support personnel or package vendor. Action: PreInstall, location: C:\WINDOWS\Installer\MSIB4.tmp, command: MSI (s) (2C:A8) [10:32:05:286]: Note: 1: 2262 2: Error 3: -2147287038 MSI (s) (2C:A8) [10:32:05:286]: Product: UpLib-1.7.9 -- Error 1721. There is a problem with this Windows Installer package. A program required for this install to complete could not be run. Contact your support personnel or package vendor. Action: PreInstall, location: C:\WINDOWS\Installer\MSIB4.tmp, command:
Martin v. Löwis <martin@v.loewis.de> wrote:
But this doesn't look quite complete. I don't see where the Python interpreter is actually invoked here. (Cute trick swapping the args, by the way).
Which is presumably why, in finalize_options, we find:
if self.pre_install_script: raise DistutilsOptionError, "the pre-install-script feature is not yet implemented"
Shouldn't the custom action be this:
add_data(self.db, "CustomAction", [("PreInstall", 2, "PreInstall", '"PYTHON"'), ])
I don't remember the details, but one problem might have been that custom action 2 is defined as "EXE file stored in a Binary table stream." Not sure whether batch files are even allowed here.
Apparently not. MSI (s) (2C:A0) [10:44:12:462]: Doing action: PreInstall Action 10:44:12: PreInstall. Action start 10:44:12: PreInstall. MSI (s) (2C:A0) [10:44:12:492]: Note: 1: 1721 2: PreInstall 3: C:\WINDOWS\Installer\MSIB7.tmp 4: "C:\Python26\\python.exe" MSI (s) (2C:A0) [10:44:12:492]: Note: 1: 2262 2: Error 3: -2147287038 MSI (c) (6C:C4) [10:44:12:502]: Note: 1: 2262 2: Error 3: -2147287038 DEBUG: Error 2888: Executing the Binary view failed The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is 2888. The arguments are: Binary, , Error 1721. There is a problem with this Windows Installer package. A program required for this install to complete could not be run. Contact your support personnel or package vendor. Action: PreInstall, location: C:\WINDOWS\Installer\MSIB7.tmp, command: "C:\Python26\\python.exe" MSI (s) (2C:A0) [10:44:14:545]: Note: 1: 2262 2: Error 3: -2147287038 MSI (s) (2C:A0) [10:44:14:545]: Product: UpLib-1.7.9 -- Error 1721. There is a problem with this Windows Installer package. A program required for this install to complete could not be run. Contact your support personnel or package vendor. Action: PreInstall, location: C:\WINDOWS\Installer\MSIB7.tmp, command: "C:\Python26\\python.exe" Action ended 10:44:14: PreInstall. Return value 3. Looks like we need JScript (what can that do, though?) or VBScript. By the way, the double backslashes don't seem to be a problem. Bill
Looks like we need JScript (what can that do, though?) or VBScript.
Not sure whether users could accept writing JScript or VBScript for bdist_msi, so (atleast for bdist_msi), I would like to either support Python pre-install scripts, or not support pre-install scripts at all. The question is whether we could trick a VBScript into also being a Python script. As this might be an interesting puzzle to solve, I'd like to pose it to the entire distutils-sig readership. So here is the problem again: As a batch file, my attempt at having a batch file that is also a Python script was to write it as rem=""" %1 %0 exit """ <python code here> This should have been run with argv[1] being the path to the Python interpreter. As a batch file, the first line is a comment, the second line runs Python, anbd the third line terminates the script (so it doesn't consider the following lines). As a Python script, the first block is a variable assignment, followed by the regular Python script. Now (as Installer won't run batch files) we need the same as VBScript (or, failing that, as JScript). The script would be computed at the time of MSI generation. TIA, Martin
participants (3)
-
"Martin v. Löwis"
-
Bill Janssen
-
Tarek Ziadé