C#中如何调用COM中的虚函数
How call virtual function in COM in C#
我是 COM 和 C# 的新手。我想做的是用 C# 重写以下源代码:
typedef interface IARPUninstallStringLauncher IARPUninstallStringLauncher;
typedef struct IARPUninstallStringLauncherVtbl {
BEGIN_INTERFACE
HRESULT(STDMETHODCALLTYPE *QueryInterface)(
__RPC__in IARPUninstallStringLauncher * This,
__RPC__in REFIID riid,
_COM_Outptr_ void **ppvObject);
ULONG(STDMETHODCALLTYPE *AddRef)(
__RPC__in IARPUninstallStringLauncher * This);
ULONG(STDMETHODCALLTYPE *Release)(
__RPC__in IARPUninstallStringLauncher * This);
HRESULT(STDMETHODCALLTYPE *LaunchUninstallStringAndWait)(
__RPC__in IARPUninstallStringLauncher * This,
_In_ HKEY hKey,
_In_ LPCOLESTR Item,
_In_ BOOL bModify,
_In_ HWND hWnd);
HRESULT(STDMETHODCALLTYPE *RemoveBrokenItemFromInstalledProgramsList)(
__RPC__in IARPUninstallStringLauncher * This,
_In_ HKEY hKey,
_In_ LPCOLESTR Item);
END_INTERFACE
} *PIARPUninstallStringLauncherVtbl;
interface IARPUninstallStringLauncher
{
CONST_VTBL struct IARPUninstallStringLauncherVtbl *lpVtbl;
};
据我了解,他反转了该接口中的函数并创建了一个结构,以便他可以访问该虚函数的地址。
此 COM 中的函数在 OLEVIEW 中不可见,而且我无法在 VisualStudio 中导入它。
我的问题是可以用C#写吗?
这将是 C# 等效项(您不需要定义 IUnknown 方法,并且 this
是隐式的):
[Guid("F885120E-3789-4FD9-865E-DC9B4A6412D2"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IARPUninstallStringLauncher
{
[PreserveSig]
int LaunchUninstallStringAndWait(
IntPtr hKey,
[MarshalAs(UnmanagedType.LPWStr)] string Item,
bool bModify,
IntPtr hWnd);
[PreserveSig]
int RemoveBrokenItemFromInstalledProgramsList(
IntPtr hKey,
[MarshalAs(UnmanagedType.LPWStr)] string Item);
}
你可以像这样声明组件类(是的,有一个空的主体)
[Guid("FCC74B77-EC3E-4DD8-A80B-008A702075A9"), ComImport]
public class UninstallStringLauncher
{
}
要创建和使用对象,您可以尝试这样的代码
var launcher = (IARPUninstallStringLauncher)new UninstallStringLauncher();
并确保您的 COM 对象的位数 (x86/x64) 与您的 C# 应用程序的位数匹配。
我是 COM 和 C# 的新手。我想做的是用 C# 重写以下源代码:
typedef interface IARPUninstallStringLauncher IARPUninstallStringLauncher;
typedef struct IARPUninstallStringLauncherVtbl {
BEGIN_INTERFACE
HRESULT(STDMETHODCALLTYPE *QueryInterface)(
__RPC__in IARPUninstallStringLauncher * This,
__RPC__in REFIID riid,
_COM_Outptr_ void **ppvObject);
ULONG(STDMETHODCALLTYPE *AddRef)(
__RPC__in IARPUninstallStringLauncher * This);
ULONG(STDMETHODCALLTYPE *Release)(
__RPC__in IARPUninstallStringLauncher * This);
HRESULT(STDMETHODCALLTYPE *LaunchUninstallStringAndWait)(
__RPC__in IARPUninstallStringLauncher * This,
_In_ HKEY hKey,
_In_ LPCOLESTR Item,
_In_ BOOL bModify,
_In_ HWND hWnd);
HRESULT(STDMETHODCALLTYPE *RemoveBrokenItemFromInstalledProgramsList)(
__RPC__in IARPUninstallStringLauncher * This,
_In_ HKEY hKey,
_In_ LPCOLESTR Item);
END_INTERFACE
} *PIARPUninstallStringLauncherVtbl;
interface IARPUninstallStringLauncher
{
CONST_VTBL struct IARPUninstallStringLauncherVtbl *lpVtbl;
};
据我了解,他反转了该接口中的函数并创建了一个结构,以便他可以访问该虚函数的地址。
此 COM 中的函数在 OLEVIEW 中不可见,而且我无法在 VisualStudio 中导入它。
我的问题是可以用C#写吗?
这将是 C# 等效项(您不需要定义 IUnknown 方法,并且 this
是隐式的):
[Guid("F885120E-3789-4FD9-865E-DC9B4A6412D2"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IARPUninstallStringLauncher
{
[PreserveSig]
int LaunchUninstallStringAndWait(
IntPtr hKey,
[MarshalAs(UnmanagedType.LPWStr)] string Item,
bool bModify,
IntPtr hWnd);
[PreserveSig]
int RemoveBrokenItemFromInstalledProgramsList(
IntPtr hKey,
[MarshalAs(UnmanagedType.LPWStr)] string Item);
}
你可以像这样声明组件类(是的,有一个空的主体)
[Guid("FCC74B77-EC3E-4DD8-A80B-008A702075A9"), ComImport]
public class UninstallStringLauncher
{
}
要创建和使用对象,您可以尝试这样的代码
var launcher = (IARPUninstallStringLauncher)new UninstallStringLauncher();
并确保您的 COM 对象的位数 (x86/x64) 与您的 C# 应用程序的位数匹配。