RE: [spambayes-dev] Problem with 1.0a9 Windows installer?
[Kenny]
OK, I've taken a look and it appears that registering the addin using the outlook_addin_register executable during install does two things differently than registering the addin DLL directly with regsvr32: * outlook_addin_register sets the DLL path in InprocServer32 to "pythoncom23.dll", while regsvr32 sets it to "<installation_path>\bin\outlook_addin.dll"
Did you ever figure out what was causing this? I have an Excel plug-in that uses the same registration trickery as the Outlook plug-in's addin.py (guess where the code came from <wink>), and I ran into this problem today; i.e. pythoncom23.dll was the DLL path, rather than my excel_addin.dll. Weirdly, it was working before this, and I can't think of what code I changed that could effect this. In any case (and to bring it back to spambayes <wink>), I put a "pythoncom.frozen = True" line in after the "sys.frozendllhandle = ..." line (at the end of addin.py), and that fixed it. I presume that would fix it for you, too. I'm not sure why pythoncom.frozen wasn't already True, though, since it was running in a binary (py2exe 0.5.0, win32 200). Maybe Mark knows :) =Tony Meyer
Tony Meyer wrote:
[Kenny]
OK, I've taken a look and it appears that registering the addin using the outlook_addin_register executable during install does two things differently than registering the addin DLL directly with regsvr32: * outlook_addin_register sets the DLL path in InprocServer32 to "pythoncom23.dll", while regsvr32 sets it to "<installation_path>\bin\outlook_addin.dll"
Did you ever figure out what was causing this? I have an Excel plug-in that uses the same registration trickery as the Outlook plug-in's addin.py (guess where the code came from <wink>), and I ran into this problem today;
No, I rebuilt my installer using the released version of py2exe but then I got tied up and didn't get around to testing it. I'll go give it a try right now, and if I still have the original problem then I'll try your fix and see if it makes a difference for me. -- Kenny Pitt
Tony Meyer wrote:
In any case (and to bring it back to spambayes <wink>), I put a "pythoncom.frozen = True" line in after the "sys.frozendllhandle = ..." line (at the end of addin.py), and that fixed it. I presume that would fix it for you, too. I'm not sure why pythoncom.frozen wasn't already True, though, since it was running in a binary (py2exe 0.5.0, win32 200). Maybe Mark knows :)
Yep, this was the fix that I needed to make it work for me. I also solved the mystery of why pythoncom.frozen isn't set, although I'm still clueless why it worked in some cases and not in others. Here's the reason why pythoncom.frozen isn't set: In the py2exe sources, there is only place that pythoncom.frozen is set and that is with the following lines in boot_com_servers.py: import pythoncom if not hasattr(sys, "frozen"): # standard exes have none. sys.frozen = pythoncom.frozen = 1 else: # com DLLs already have sys.frozen set to 'dll' pythoncom.frozen = sys.frozen But py2exe uses boot_com_servers.py only for COM DLL's and EXE's specified in the com_server= list. outlook_addin_register.exe is just a standard Windows executable, so py2exe uses boot_common.py instead which makes no reference to pythoncom at all. -- Kenny Pitt
"Tony Meyer" <tameyer@ihug.co.nz> writes:
[Kenny]
OK, I've taken a look and it appears that registering the addin using the outlook_addin_register executable during install does two things differently than registering the addin DLL directly with regsvr32: * outlook_addin_register sets the DLL path in InprocServer32 to "pythoncom23.dll", while regsvr32 sets it to "<installation_path>\bin\outlook_addin.dll"
Did you ever figure out what was causing this? I have an Excel plug-in that uses the same registration trickery as the Outlook plug-in's addin.py (guess where the code came from <wink>), and I ran into this problem today; i.e. pythoncom23.dll was the DLL path, rather than my excel_addin.dll. Weirdly, it was working before this, and I can't think of what code I changed that could effect this.
In any case (and to bring it back to spambayes <wink>), I put a "pythoncom.frozen = True" line in after the "sys.frozendllhandle = ..." line (at the end of addin.py), and that fixed it. I presume that would fix it for you, too. I'm not sure why pythoncom.frozen wasn't already True, though, since it was running in a binary (py2exe 0.5.0, win32 200). Maybe Mark knows :)
I wasn't aware of the hackery Mark does at the end of the script - use a frozen exe, pretend it is a frozen dll, to trick win32com.server.register into registering it as dll server.
From what I have found in the code, setting pythoncom.frozen = True seems to be safe. It would be interesting to know the values of sys.frozen and pythoncom.frozen (if any) before.
I wanted to make a bugfix release of py2exe - although this fixes different bugs (I assume). If there's a problem with COM registration I would like to wait until this is resolved. Thomas
Thomas Heller wrote:
I wasn't aware of the hackery Mark does at the end of the script - use a frozen exe, pretend it is a frozen dll, to trick win32com.server.register into registering it as dll server.
From what I have found in the code, setting pythoncom.frozen = True seems to be safe. It would be interesting to know the values of sys.frozen and pythoncom.frozen (if any) before.
I printed pythoncom.frozen before I made the change, and it was 0/False. I didn't print sys.frozen, though. I'll check that if I get a chance. The hackery is a result of an apparent problem with the Inno installer during uninstall. When Inno tried to unregister the COM DLL using the usual LoadLibrary/DllUnregisterServer method, it apparently didn't release the DLL properly and then failed to delete some of the files. The outlook_addin_register stuff was needed so that the DLL could be registered and unregistered without actually loading the DLL. -- Kenny Pitt
Nice analysis Kenny. Just to clarify:
The hackery is a result of an apparent problem with the Inno installer during uninstall. When Inno tried to unregister the COM DLL using the usual LoadLibrary/DllUnregisterServer method, it apparently didn't release the DLL properly and then failed to delete some of the files.
To be fair to Inno, it is more Python's fault. The problem is more that doing a LoadLibrary(), executing Python code, then doing a FreeLibrary() doesn't release every DLL. The inno guy mailed me back suggesting later versions may spawn a separate process for this unregistration to get around this and similar issues. Given that hackery, I think it fair to say the error is in the hackery, rather than in py2exe, and that py2exe is fine the way it is. Mark.
Mark Hammond wrote:
The hackery is a result of an apparent problem with the Inno installer during uninstall. When Inno tried to unregister the COM DLL using the usual LoadLibrary/DllUnregisterServer method, it apparently didn't release the DLL properly and then failed to delete some of the files.
To be fair to Inno, it is more Python's fault. The problem is more that doing a LoadLibrary(), executing Python code, then doing a FreeLibrary() doesn't release every DLL.
Yeah, I discovered that later when I tried this out using a simple NSIS install script (for those who don't know, it's another open-source alternative to Inno) and got the same result. -- Kenny Pitt
"Kenny Pitt" <kennypitt@hotmail.com> writes:
Mark Hammond wrote:
The hackery is a result of an apparent problem with the Inno installer during uninstall. When Inno tried to unregister the COM DLL using the usual LoadLibrary/DllUnregisterServer method, it apparently didn't release the DLL properly and then failed to delete some of the files.
To be fair to Inno, it is more Python's fault. The problem is more that doing a LoadLibrary(), executing Python code, then doing a FreeLibrary() doesn't release every DLL.
Yeah, I discovered that later when I tried this out using a simple NSIS install script (for those who don't know, it's another open-source alternative to Inno) and got the same result.
So, neither innosetup nor nsis can remove in-use files (after a reboot)? Isn't that a problem? Thomas
Thomas Heller wrote:
The hackery is a result of an apparent problem with the Inno installer during uninstall. When Inno tried to unregister the COM DLL using the usual LoadLibrary/DllUnregisterServer method, it apparently didn't release the DLL properly and then failed to delete some of the files.
To be fair to Inno, it is more Python's fault. The problem is more that doing a LoadLibrary(), executing Python code, then doing a FreeLibrary() doesn't release every DLL.
Yeah, I discovered that later when I tried this out using a simple NSIS install script (for those who don't know, it's another open-source alternative to Inno) and got the same result.
So, neither innosetup nor nsis can remove in-use files (after a reboot)? Isn't that a problem?
I don't think that's the issue. I'm not sure if Inno supports it or not, but in NSIS I can set my deletes up to require reboot for in-use files if I explicitly tell it that's what I want. The problem is that the DLL isn't actually "in use" because no other apps have it loaded, so there wouldn't normally be a reason to need this. A C++ COM DLL in the same circumstance would not require a reboot. We're the ones that caused the DLL to be in use by trying to unregister it, so forcing the user to do a reboot just for that seems a bit harsh. The "register-with-an-EXE" hack gets the job done with less hassle to the user, we just needed to tweak the hack to make it work right. Of course, I wouldn't be opposed if you have some neat idea up your sleeve to change py2exe so that everything just magically gets released after the FreeLibrary call <wink>. No-pressure-we-love-py2exe-anyway-ly yours, -- Kenny Pitt
participants (4)
-
Kenny Pitt -
Mark Hammond -
Thomas Heller -
Tony Meyer