Wednesday, February 15, 2017

Portable Python com server using pywin32

Leave a Comment

Is it possible to run comserver without requiring elevation.

For example I am able to run code from Python.TestServer (below) but it requires elevation.

Python.TestServer code is at: Consuming Python COM Server from .NET

Is it possible to run com server which doesn't require elevation so that I can run com object without having Administrative password.

for example

import pythoncom from win32com.server import localserver  class demoObj(object):     _reg_clsctx_ = pythoncom.CLSCTX_LOCAL_SERVER     _reg_clsid_ = "{FA501660-8BB0-42F6-842B-A757FA3098DC}"     _reg_desc_ = "Demo COM server"     _reg_progid_ = "Python.Demo"     _public_methods_ = ['hello']  def hello(self, who):     return "Hellow " + who  localserver.serve('B83DD222-7750-413D-A9AD-01B37021B24B') 

I have tried above code but it says pywintypes.com_error: (-2147221005, 'Invalid class string', None, None)

how to make the valid class string for local server?

Example vba :

    Sub demodemo()         Set obj = CreateObject("Python.Demo")         Debug.Print obj.Hello("World")     End Sub 

1 Answers

Answers 1

It's possible to register and use a class without privileges. The class has to be registered in the current user instead of all users. The option is not provided, so you'll have to register it yourself by writing the keys in HKCU\SOFTWARE\Classes.

Here's a working example:

import os, sys, win32api, win32con, win32com.server.register  class HelloWorld(object):   _reg_progid_ = "Python.TestServer"   _reg_clsid_ = "{7CC9F362-486D-11D1-BB48-0000E838A65F}"   _reg_desc_ = "Python Test COM Server"   _public_methods_ = ['Hello']    def Hello(self):     return "Hello!"    def RegisterClass(cls):   file = sys.modules[cls.__module__].__file__   folder = os.path.dirname(file)   module = os.path.splitext(os.path.basename(file))[0]   python = win32com.server.register._find_localserver_exe(1)   python = win32api.GetShortPathName(python)   server = win32com.server.register._find_localserver_module()   command = '%s "%s" %s' % (python, server, cls._reg_clsid_)   typename = module + "." + cls.__name__    def write(path, value):     win32api.RegSetValue(win32con.HKEY_CURRENT_USER, path, win32con.REG_SZ, value)    write("SOFTWARE\\Classes\\" + cls._reg_progid_ + '\\CLSID', cls._reg_clsid_)   write("SOFTWARE\\Classes\\AppID\\" + cls._reg_clsid_, cls._reg_progid_)   write("SOFTWARE\\Classes\\CLSID\\" + cls._reg_clsid_, cls._reg_desc_)   write("SOFTWARE\\Classes\\CLSID\\" + cls._reg_clsid_ + '\\LocalServer32', command)   write("SOFTWARE\\Classes\\CLSID\\" + cls._reg_clsid_ + '\\ProgID', cls._reg_progid_)   write("SOFTWARE\\Classes\\CLSID\\" + cls._reg_clsid_ + '\\PythonCOMPath', folder)   write("SOFTWARE\\Classes\\CLSID\\" + cls._reg_clsid_ + '\\PythonCOM', typename)   write("SOFTWARE\\Classes\\CLSID\\" + cls._reg_clsid_ + '\\Debugging', "0")    print("Registered %s" % cls.__name__)  if __name__ == '__main__':   RegisterClass(HelloWorld) 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment