2017-02-01 60 views
11

Czy można uruchomić program uruchamiający, nie wymagając podniesienia poziomu.Przenośny serwer w języku Python za pomocą pywin32

Na przykład mogę uruchomić kod z Python.TestServer (poniżej), ale wymaga to podniesienia.

kod Python.TestServer jest pod adresem: Consuming Python COM Server from .NET

Czy możliwe jest uruchomienie serwera COM, który nie wymaga elewację tak, że mogę uruchomić com obiektu bez konieczności hasło administracyjne.

np

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') 

Próbowałem powyżej kodu, ale mówi pywintypes.com_error: (-2147221005, 'Invalid class string', None, None)

jak zrobić prawidłowy ciąg klasy dla lokalnego serwera?

Przykład VBA:

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

Serwer Com będą spożywane przez VBA. Jaki jest twój problem z vba? – Rahul

+0

Z ciekawości, co próbujesz zrobić? Wiem, że w vba istnieją inne alternatywy, aby połączyć Excela i Pythona – Kelvin

+0

czy próbowałeś xlwings? – denfromufa

Odpowiedz

7

Jest możliwe, aby zarejestrować się i korzystać z klasy bez przywilejów. Klasa musi być zarejestrowana w bieżącym użytkowniku zamiast wszystkich użytkowników. Ta opcja nie jest dostępna, więc musisz zarejestrować ją samodzielnie, pisząc klucze pod numerem HKCU\SOFTWARE\Classes.

Oto przykład praca:

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) 
+0

Wygląda na to, że działa. Przepraszam za spóźnienie, aby odpowiedzieć. Byłem na wakacjach – Rahul