C# 从Python访问我的WPF COM库
我想从python脚本运行我的WPF应用程序,但是我有困难。 为了实现这一点,我将WPF应用程序转换为COM库,如下所示:C# 从Python访问我的WPF COM库,c#,python,wpf,com,python.net,C#,Python,Wpf,Com,Python.net,我想从python脚本运行我的WPF应用程序,但是我有困难。 为了实现这一点,我将WPF应用程序转换为COM库,如下所示: namespace MyWpfApp { [Guid("F75D3377-D677-41BF-B3D5-C677C442228F")] public interface IMyWpfAppInterface { void ShowCOMDialog(); void ClickButton1(); void ClickButton2(); } [C
namespace MyWpfApp
{
[Guid("F75D3377-D677-41BF-B3D5-C677C442228F")]
public interface IMyWpfAppInterface
{
void ShowCOMDialog();
void ClickButton1();
void ClickButton2();
}
[ClassInterface(ClassInterfaceType.None)]
[Guid("D936A84B-8B1C-4D62-B090-C06E3EB5EEE9")]
public class MyWpfClass : IMyWpfAppInterface
{
private static Thread m_runDlgThread;
private static MainWindow m_mainWindow = null;
private static Application m_app = null;
public MyWpfClass() { }
public void ShowCOMDialog()
{
m_msgHelper = new MessageHelper();
m_runDlgThread = new Thread(runDlg);
m_runDlgThread.SetApartmentState(ApartmentState.STA);
m_runDlgThread.Start();
}
public void ClickButton1(){// to do}
public void ClickButton2(){// to do}
private void runDlg()
{
Application m_app = new Application();
m_mainWindow = new MainWindow();
m_app.Run(m_mainWindow);
}
}
}
我已将我的程序集安装到全局程序集缓存,并按如下方式注册了dll
gacutil.exe" /i MyWpfApp.dll
REGASM MyWpfApp.dll /tlb:com.MyWpfApp.tlb
我已经测试过,我可以成功地导入Typelib并从win32控制台应用程序运行我的WPF应用程序
#include "stdafx.h"
#import "..\MyWpfApp\bin\Debug\com.MyWpfApp.tlb" named_guids raw_interfaces_only
int _tmain(int argc, _TCHAR* argv[])
{
CoInitialize(NULL); //Initialize all COM Components
// <namespace>::<InterfaceName>
MyWpfApp::IMyWpfAppInterfacePtr pDotNetCOMPtr;
// CreateInstance parameters
// e.g. CreateInstance (<namespace::CLSID_<ClassName>)
HRESULT hRes =
pDotNetCOMPtr.CreateInstance(MyWpfApp::CLSID_MyWpfClass);
if (hRes == S_OK)
{
const DWORD cTimeout_ms = 500;
HANDLE hEvent = CreateEvent(0, TRUE, FALSE, 0);
BSTR str;
pDotNetCOMPtr->ShowCOMDialog ();
bool toggle = true;
while(true)
{
DWORD dwWait = WaitForSingleObject(hEvent,cTimeout_ms);
if(toggle)
{
pDotNetCOMPtr->ClickButton1();
toggle = false;
}
else
{
pDotNetCOMPtr->ClickButton2();
toggle = true;
}
}
//call .NET COM exported function ShowDialog ()
}
CoUninitialize (); //DeInitialize all COM Components
return 0;
}
这失败了,报告失败了
File "C:\Python27\lib\site-packages\win32com\client\dynamic.py", line 114, in _GetGoodDispatchAndUserName
return (_GetGoodDispatch(IDispatch, clsctx), userName)
File "C:\Python27\lib\site-packages\win32com\client\dynamic.py", line 91, in _GetGoodDispatch
IDispatch = pythoncom.CoCreateInstance(IDispatch, None, clsctx, pythoncom.IID_IDispatch)
com_error: (-2147221164, 'Class not registered', None, None)
我可以在注册表和OLE查看器中看到类“MyWpfApp.MyWpfClass”。
对于C++的应用程序,我已经做过很多次这种事情,没有任何问题。然而,这是一个ATL项目或MFC应用程序与自动化打开。在本例中,我已将WPF应用程序转换为dll,并手动转换为COM。
有人能告诉我从python运行应用程序还需要做些什么吗
提前谢谢
进一步编辑:
我可以在python中加载typelib,但仍然无法访问com类
我跑
这确认类已加载,但我无法访问它们,因为它们被报告为未注册
>>>
{B5E3A6C6-09A0-315C-BF3A-CB943389F610}
MessageHelper
{FBE23BB0-3EDC-3A65-90EB-DF84F7545D70}
COPYDATASTRUCT
{8BEE824F-F708-3052-BC21-A9EC4E1BB002}
MainWindow
{8C0044EF-91A9-3CB3-9945-1ACA076F3D7E}
NextPrimeDelegate
{F75D3377-D677-41BF-B3D5-C677C442228F}
IMyWpfAppInterface
{D936A84B-8B1C-4D62-B090-C06E3EB5EEE9}
MyWpfClass
Traceback (most recent call last):
File "D:\MyWorkSpace\testProgs\ATL_COM\WPF\MyWpfApp\MyWin32App\Python\MyPythonClient.py", line 15, in <module>
downloads_stat = win32com.client.Dispatch(type_iid)
File "C:\Python27\lib\site-packages\win32com\client\__init__.py", line 95, in Dispatch
dispatch, userName = dynamic._GetGoodDispatchAndUserName(dispatch,userName,clsctx)
File "C:\Python27\lib\site-packages\win32com\client\dynamic.py", line 114, in _GetGoodDispatchAndUserName
return (_GetGoodDispatch(IDispatch, clsctx), userName)
File "C:\Python27\lib\site-packages\win32com\client\dynamic.py", line 91, in _GetGoodDispatch
IDispatch = pythoncom.CoCreateInstance(IDispatch, None, clsctx, pythoncom.IID_IDispatch)
com_error: (-2147221164, 'Class not registered', None, None)
>>>
然而,这产生了以下错误
FileNotFoundException: Unable to find assembly 'MyWpfApp.dll'.
at Python.Runtime.CLRModule.AddReference(String name) in C:\Users\Barton\Documents\Visual Studio 2008\Projects\PySharp\trunk\pythonnet\src\runtime\moduleobject.cs:line 375
我对COM、程序集和TypeLib的了解非常有限,因此如果有人能帮助我理解从python访问DLL需要做什么,我将不胜感激
当我在OLE/COM对象查看器中查看条目时,它指向tlb文件,而不是dll,即
Win32=D:\MyWorkSpace\testProgs\ATL_COM\WPF\MyWpfApp\MyWpfApp\bin\Debug\com.MyWpfApp.tlb
因此,只有tlb文件被注册,而不是类。当我运行LoadTypeLib类时,我是从硬盘上的一个路径加载它的。我需要在尝试分派时注册dll。否则,如果我可以从一个固定的路径直接访问它,这也会很好,但我不知道如何做到这一点
再次感谢您的帮助。如果是C#-您可以使用clr(python.net)并直接加载程序集吗?可能更容易…恐怕这必须是常规的Python2.X。Python.net可以作为模块安装吗?是的,Python.net可以作为模块安装。谢谢我认为问题在于typelib是注册的,而不是类。因此,这个python.net对我没有帮助。如果您在python.net中将该类用作C#assembly,则不必注册该类。但它确实需要在本地驱动器上,否则会遇到奇怪的权限问题。但除此之外,您通常只需执行
导入clr;sys.path.append('assembly_path');clr.AddReference('AssemblyName');导入命名空间
,它通常只起作用。
import clr;
import sys
sys.path.append('D:\\MyWorkSpace\\testProgs\\ATL_COM\\WPF\\MyWpfApp\\MyWpfApp\\bin\\Debug')
clr.AddReference("MyWpfApp.dll")
FileNotFoundException: Unable to find assembly 'MyWpfApp.dll'.
at Python.Runtime.CLRModule.AddReference(String name) in C:\Users\Barton\Documents\Visual Studio 2008\Projects\PySharp\trunk\pythonnet\src\runtime\moduleobject.cs:line 375
Win32=D:\MyWorkSpace\testProgs\ATL_COM\WPF\MyWpfApp\MyWpfApp\bin\Debug\com.MyWpfApp.tlb