我正在尝试使用IOfficeAntiVirus COM 接口调用使用 Microsoft 安全要点病毒扫描程序的扫描。
我正在做早期绑定,因为文档说 IOfficeAntiVirus 接口继承自 IUknown 并且不支持 IDispatch。
[Guid("56FFCC30-D398-11d0-B2AE-00A0C908FA49"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)
]
public interface IOfficeAntiVirus
{
void Scan(IntPtr info);
}
[ComImport, Guid("2781761E-28E1-4109-99FE-B9D127C57AFE")]
class SecurityEssentialsAntiVirus
{
}
scan 方法的参数是来自此示例的类型。该示例与我想要的相反,因为它使用 .NET 类而不是调用 scan 方法来实现 IOfficeAntiVirus 接口。据我所知,示例中的编组和类型似乎与文档相匹配。
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct MSOAVINFO
{
public int cbsize;
[MarshalAs(UnmanagedType.U4)]
public uint uFlags;
public IntPtr hwnd;
[MarshalAs(UnmanagedType.LPWStr)]
public string pwzFullPath;
[MarshalAs(UnmanagedType.LPWStr)]
public string pwzHostname;
[MarshalAs(UnmanagedType.LPWStr)]
public string pwzOrigURL;
}
这是我试图用来调用扫描方法的代码:
var antivirus = (IOfficeAntiVirus)new SecurityEssentialsAntiVirus();
var file = new MSOAVINFO();
file.pwzFullPath = @"test.txt";
IntPtr lParam = Marshal.AllocHGlobal(Marshal.SizeOf(file));
Marshal.StructureToPtr(file, lParam, false);
antivirus.Scan(lParam);
它在调用 scan 方法时失败。我得到一个例外,上面写着:
“试图读取或写入受保护的内存。这通常表明其他内存已损坏。”
我从 64 位系统上的 32 位命令行应用程序运行它。我已经尝试在 32 位和 64 位中运行命令行程序,但没有成功。
我确信 IOfficeAntiVirus guid 是正确的,因为我是从文档中获得的。当我尝试将对象强制转换到接口时,尝试使用不是 COM 接口的随机 GUID 也会导致错误。
我确信 SecurityEssentialsAntiVirus guid 实现了 IOfficeAntiVirus,因为当我尝试将不同类型的 COM 对象投射到该接口时出现错误。
我认为问题可能是没有正确声明接口上的 Scan 方法(在接口上声明随机方法会产生相同的错误)。我没有根据安全要素程序集的文档工作,因此它可能无法以我想象的方式(或根本没有)实现接口。有谁知道如何检查?
我可以在它的目录中看到一个 MpOAv.dll 文件,它与 IOfficeAntiVirus 文档中的头文件同名,我知道这没什么好做的。我无法在 ole-com 对象查看器中打开该 dll 以查看里面的内容。我收到一条消息说:
IMoniker::BindToObject 在从 ( "C:\Program Files\Microsoft Security Client\MpOAv.dll" ) 创建的文件名字对象上失败。文件扩展名错误
MK_E_INVALIDEXTENSION ($800401E6)
也可能是我没有将结构正确传递给 Scan 方法。我已经尝试了大约一百种变体,包括使用 AllocCoTaskMem() 和通过引用传递结构。
我真的没有太多的互操作经验(今天学习了一堆试图解决这个问题!)所以我真的很感激朝着正确的方向前进。:)