Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Frozen environment and win32com.server.register.RegisterServer() #868

Open
ghost opened this issue May 12, 2014 · 3 comments
Open

Frozen environment and win32com.server.register.RegisterServer() #868

ghost opened this issue May 12, 2014 · 3 comments

Comments

@ghost
Copy link

ghost commented May 12, 2014

Hi,

I'm working on an Excel COM add-in with Python 3.3 / pywin32 v219. Everything works fine, except when I'm trying to cx_Freeze my app to distribute it.

The RegisterServer function doesn't create all requested keys in the windows registery.
You will find below a diff for my HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID{C5482ECA-F559-45A0-B078-B2036E6F011A} key.

Normal environment Frozen environment Status
\Debugging \Debugging OK
\Implemented Categories Not created missing key, but doesn't seem mandatory
\Implemented Categories\{B3EF80D0-68E2-11D0-A689-00C04FD658FF} Not created doesn't seem mandatory
\InprocServer32 Not created seems mandatory
\ProgID \ProgID OK
\PythonCOM \PythonCOM OK
\PythonCOMDispatcher \PythonCOMDispatcher OK (debug mode only)
\PythonCOMPath Not created seems mandatory
\PythonCOMPolicy \PythonCOMPolicy OK

When I create thoses registry keys by hand, my add-in registers in Excel.
Further researches in the register process shows me that the frozen case is implemented in win32com.server.register.RegisterServer(), but I don't know if cx_Freeze provides all requested env vars.

  • For the \InProcServer32 key, the involved RegisterServer() code says (register.py, line 209) :
if pythoncom.frozen:
 if hasattr(sys, "frozendllhandle"):
  dllName = win32api.GetModuleFileName(sys.frozendllhandle) 
 else:
  raise RuntimeError("We appear to have a frozen DLL, but I don't know the DLL to use")
  • For the \PythonCOMPath key, it's the RegisterClasses() function (register.py, line 426) which doesn't provide addnPath arg to RegisterServer() :
      # Frozen apps don't need their directory on sys.path
      if not pythoncom.frozen:
        scriptDir = os.path.split(sys.argv[0])[0]
        if not scriptDir: scriptDir = "."
        addnPath = win32api.GetFullPathName(scriptDir)

As I'm a new Python user, maybe I miss something with cx_freeze (need to provide more elements to make pywin32 works in frozen env ?), or maybe cx_freeze is not the best tool to freeze my pywin32 app ?

Hope to read you soon,

Best regards,

Jonathan

Reported by: jbesanceney

Original Ticket: pywin32/feature-requests/109

@ghost ghost assigned ghost and unassigned ghost Oct 24, 2017
@emaimone
Copy link

Hi
I read a while ago in Stack OverFlow that cx_freeze does not work when your app generates and registers a COM.

In Python 2.7, I used py2exe and it worked nicely.
I was able to package the generated distribution files using INNO and at the end of the INNO.ISS setup file, the following code registered the COM server in the end user´s machine

[Run]
Filename: "{app}\COM_files\COMBuilder.exe"; 

I am trying to bring that to 3.7 now, using https://github.com/albertosottile/py2exe and pywin225, but I am facing an issue similar to what you described above.

I opened an issue in the py2exe github https://github.com/albertosottile/py2exe/issues/24 and I am doing some investigation.

What I found out so far is that in the same win32com.server.register.RegisterServer() function that you mention, this will register the COM, when the exe is executed

if clsctx & pythoncom.CLSCTX_LOCAL_SERVER:
    if pythoncom.frozen:
      # If we are frozen, we write "{exe} /Automate", just
      # like "normal" .EXEs do
      exeName = win32api.GetShortPathName(sys.executable)
      command = '%s /Automate' % (exeName,)

and the generated COM has the following local path:

C:\Users\emaimone\......\COMBUILDER.EXE /Automate

The problem is that when the VBA client tries to create an object to use COM´s public methods:

Set PythonUtils = CreateObject("PythonZ.COMTest")

it actually tries to register the COM again

As I said it worked fine with pywin32 + py2exe in Python 2.7.

Did you find a way to deploy, freeze and distribute COMs in Python 3.7?
Thank you
Enzo

@Avasam
Copy link
Collaborator

Avasam commented Mar 16, 2024

I opened an issue in the py2exe github https://github.com/albertosottile/py2exe/issues/24 and I am doing some investigation.

Linked issue is now py2exe/py2exe#24 . Which was closed for being stale w/o resolution.
@emaimone I'd love to know if this is still an issue with on Python>=3.8 with he most recent pywin32 version.

@junkmd
Copy link

junkmd commented Dec 5, 2024

@Avasam

Hi,

py2exe/py2exe#217 might be related to this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants