我正在使用Cisco AnyConnect VpnApi,我创建了一个COM' Manifest?'我在我的服务中引用的dll。我也试过这个只是添加对COM服务的引用并让VS嵌入interop程序集。该服务在后台旋转并执行一些操作,等待自定义命令并在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 {C15C0F4F-DDFB-4591-AD53-C9A71C9C15C0}的组件的COM类工厂失败:800701e7。
所以我尝试在控制台应用程序中放置此代码并引用COM对象,它可以很好地解决,没有例外。
我已经尝试了所有我可以想到的事情,包括假冒使用我所拥有的一些经过测试和工作的pinvoke代码。似乎没有什么工作,无论何时从Windows服务调用,我都会得到其中一个例外。
答案 0 :(得分:1)
这些错误有时会因为链接问题而发生,而这个论坛帖子似乎暗示这可能是这种情况:
答案 1 :(得分:0)
所以我终于在将轮子旋转3天之后弄明白了。
问题是COM对象实际上是在另一个类中被引用的' bootstrapper'应用程序(我继承)并通过汇编搜索模式通过Unity间接加载,这有点模糊了问题。
问题的根源于内存中加载的COM对象的行为。当通过代理(由tlbimp.exe生成)引用时,显然,COM对象本身被加载到内存中的固定位置,然后在实例化时将其存储在代理中。它在引导strapper中引用并通过unity加载的简单事实在主线程的内存中创建了实例。
当OnCustomCommand事件被触发时,当显然无法访问主线程加载COM对象的内存时,它又回到了另一个线程上。因此,受保护的内存"错误。
也就是说,引用它的类没有被使用,所以我只是评论它并且一切都开始工作了。但是,我认为对此的最终解决方案将是某种代理类,用于对VpnApi COM对象的所有访问,该对象具有指向单个线程或可能某种单例类的调度程序。
还不确定,我还没有多想过。一旦我弄明白,我就放下麦克风回家了!大声笑如果你们有任何建议,你肯定会得到我的投票。