0

リボン バーをエクセルするボタンを作成する pywin パッケージ デモを変更しました。ボタンが押されると、選択されたテキストがコマンドラインで実行され、選択されたテキストが出力に置き換えられます。

clsid とファイル名の組み合わせが異なるプログラムを登録すると問題が発生します。コードの clsid やファイル名を変更できません。このファイルのコピーを作成し、変更して登録すると、実行される COM オブジェクトは、新しく変更されたファイルではなく、元の excelAddin.py になります。COM 登録プロセスのステップが欠落しています。どの行をどこに追加すればよいですか?

from win32com import universal
from win32com.server.exception import COMException
from win32com.client import gencache, DispatchWithEvents
import winerror
import pythoncom
from win32com.client import constants, Dispatch
import sys
import win32traceutil

# Support for COM objects we use.
gencache.EnsureModule('{00020813-0000-0000-C000-000000000046}', 0, 1, 3, bForDemand=True) # Excel 9
gencache.EnsureModule('{2DF8D04C-5BFA-101B-BDE5-00AA0044DE52}', 0, 2, 1, bForDemand=True) # Office 9

# The TLB defiining the interfaces we implement
universal.RegisterInterfaces('{AC0714F2-3D04-11D1-AE7D-00A0C90F26F4}', 0, 1, 0, ["_IDTExtensibility2"])
class ButtonEvent:
    def OnClick(self, button, cancel):
        import win32ui # Possible, but not necessary, to use a Pythonwin GUI
        import win32con
        import subprocess
        app = Dispatch("Word.Application")
        cmd = app.Selection

        #subprocess.Popen(str(cmd))
        cmdP = subprocess.Popen(str(cmd), shell = True, stdout = subprocess.PIPE)
        txt = cmdP.stdout.readlines()
        output = ''
        for line in txt:
            output += line

        app.Selection.TypeText(output)
        #win32ui.MessageBox(txt, "Python Test",win32con.MB_OKCANCEL)
        return cancel

class ExcelAddin:
    _com_interfaces_ = ['_IDTExtensibility2']
    _public_methods_ = []
    _reg_clsctx_ = pythoncom.CLSCTX_INPROC_SERVER
    #_reg_clsid_ = ""
    _reg_clsid_ = "{C5482ECA-F559-45A0-B078-B2036E6F011A}"
    #_reg_clsid_ = "{E44EF798-7FDF-4015-AED6-00234CBBBA77}"
    #_reg_clsid_ = "{91A89B71-56C0-4a76-BF1F-CF52E3671740}"
    _reg_progid_ = 'Juha.test'#"Python.Test.ExcelAddin2"
    _reg_policy_spec_ = "win32com.server.policy.EventHandlerPolicy"

    def __init__(self):
        self.appHostApp = None    

    def OnConnection(self, application, connectMode, addin, custom):
        print "OnConnection", application, connectMode, addin, custom
        try:
            self.appHostApp = application
            cbcMyBar = self.appHostApp.CommandBars.Add(Name="PythonBar", 
                                                       Position=constants.msoBarTop, 
                                                       MenuBar=constants.msoBarTypeNormal, 
                                                       Temporary=True)
            btnMyButton = cbcMyBar.Controls.Add(Type=constants.msoControlButton, Parameter="Greetings")
            btnMyButton=self.toolbarButton = DispatchWithEvents(btnMyButton, ButtonEvent)
            btnMyButton.Style = constants.msoButtonCaption
            btnMyButton.BeginGroup = True
            btnMyButton.Caption = "&Run..."
            btnMyButton.TooltipText = "Runs the selected text in command line"
            btnMyButton.Width = "34"
            cbcMyBar.Visible = True
        except pythoncom.com_error, (hr, msg, exc, arg):
            print "The Excel call failed with code %d: %s" % (hr, msg)
            if exc is None:
                print "There is no extended error information"
            else:
                wcode, source, text, helpFile, helpId, scode = exc
                print "The source of the error is", source
                print "The error message is", text
                print "More info can be found in %s (id=%d)" % (helpFile, helpId)

    def OnDisconnection(self, mode, custom):
        print "OnDisconnection"
        self.appHostApp.CommandBars("PythonBar").Delete
        self.appHostApp=None

    def OnAddInsUpdate(self, custom):
        print "OnAddInsUpdate", custom
    def OnStartupComplete(self, custom):
        print "OnStartupComplete", custom
    def OnBeginShutdown(self, custom):
        print "OnBeginShutdown", custom

def RegisterAddin(klass):
    import _winreg
    key = _winreg.CreateKey(_winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Office\\Word\\Addins")
    #key = _winreg.CreateKey(_winreg.HKEY_LOCAL_MACHINE, "Software\\Classes\\CLSID")
    subkey = _winreg.CreateKey(key, klass._reg_progid_)
    _winreg.SetValueEx(subkey, "CommandLineSafe", 0, _winreg.REG_DWORD, 0)
    _winreg.SetValueEx(subkey, "LoadBehavior", 0, _winreg.REG_DWORD, 3)
    _winreg.SetValueEx(subkey, "Description", 0, _winreg.REG_SZ, "Runs selection in command line and pastes output")
    _winreg.SetValueEx(subkey, "FriendlyName", 0, _winreg.REG_SZ, "cmdlineRunner")

def UnregisterAddin(klass):
    import _winreg
    try:
        _winreg.DeleteKey(_winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Office\\Word\\Addins\\" + klass._reg_progid_)
    except WindowsError:
        pass

if __name__ == '__main__':
    import win32com.server.register
    win32com.server.register.UseCommandLine(ExcelAddin)
    if "--unregister" in sys.argv:
        UnregisterAddin(ExcelAddin)
    else:
        RegisterAddin(ExcelAddin)
4

0 に答える 0