Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从Python访问我的WPF COM库_C#_Python_Wpf_Com_Python.net - Fatal编程技术网

C# 从Python访问我的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

我想从python脚本运行我的WPF应用程序,但是我有困难。 为了实现这一点,我将WPF应用程序转换为COM库,如下所示:

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