我正在使用思科AnyConnect VpnApi,我已经创建了一个COM 'Manifest?‘我在服务中引用的dll。我也尝试过这样做,只需添加对COM服务的引用,并让VS嵌入互操作程序集。该服务在后台旋转并执行一些工作,等待自定义的推荐,并在ServiceBase.OnCustomCommand函数中启动该进程。服务在系统帐户下运行。
使用:
using VpnApiLib;代码非常简单:
IVpnApi vpn = null;
try
{
vpn = new VpnApi();
return true;
}
catch (Exception ex)
{
EventManager.PublishExceptionLogMessage(ex);
}
finally {
if (vpn!= null)
Marshal.ReleaseComObject(vpn);
}
return false;但是,当从服务调用它时,我会得到一个AccessViolationException:
“试图读取或写入受保护的内存。这通常表明其他内存已损坏。”
我的书库痕迹:
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
at System.Activator.CreateInstance(Type type, Boolean nonPublic)
at System.Activator.CreateInstance(Type type)
at ...ConnectivityAction.IsVpnInstalled() in D:\...\ConnectivityAction.cs:line 208有一次,我得到了另一个例外:“使用CLSID检索组件的COM类工厂(C15C0F4F-DDFB-4591-AD53-C91C9C15C0}由于以下错误而失败: 800701e7。
因此,我尝试将这段代码和COM对象引用到控制台应用程序中,没有任何例外,它解决得很好。
我已经尝试了我能想到的每一件可能的事情,包括使用一些经过测试和编写的pinvoke代码来模拟。任何事情似乎都不起作用,每当从windows服务调用它时,我就会得到其中一个例外。
发布于 2016-01-14 15:23:04
所以我在这上面旋转了3天后,终于想出了办法。
问题是,COM对象实际上是在另一个类中引用的--应用程序的“引导程序”(我继承了它),并通过程序集搜索模式间接地加载了该对象,该模式在某种程度上掩盖了问题。
问题的根源在于加载在内存中的COM对象的行为。显然,当通过代理项(由生成)引用时,COM对象本身被加载到内存中的一个固定位置,然后当它被实例化时存储在代理项中。在引导引导程序中引用并通过统一加载它这一简单事实在主线程的内存中创建了实例。
当触发OnCustomCommand事件时,它返回到另一个线程上,而显然无法访问主线程加载COM对象的内存。因此出现了“保护内存”错误。
尽管如此,引用它的类并没有被使用,所以我只是把它注释掉了,一切都开始工作了。但是,我认为这一问题的最终解决方案将是对VpnApi COM对象的所有访问的某种代理类,该对象要么具有指向单个线程的调度程序,要么具有某种类型的单例类。
还不确定,我还没想太多。一旦我弄明白了,我就放下麦克风回家了!如果你们中有人有任何建议,你们一定会得到我的支持。
https://stackoverflow.com/questions/34777093
复制相似问题