我正在编写一个使用COM库的应用程序。我有一个类库,它包含对COM库的调用并添加了一些更多的功能。最终,它将作为Windows服务运行。现在我使用Winforms测试工具进行测试。
当测试工具创建类库时,一切似乎都正常。当我尝试将其作为服务运行时,问题就开始了。创建好了,甚至第一次调用COM都可以。然后,COM对象引发一个我处理的事件,并响应事件中的结果,我调用COM库中的另一个函数。当我从测试工具运行它时,该函数被成功调用,但当作为服务运行时抛出异常:
发生System.InvalidCastException Message =“无法转换COM ''到接口类型''类型的对象。此操作失败,因为 用于接口的COM组件的QueryInterface调用 IID'{350ADD2A-18CB-4D9C-BE28-48D53F14E6FB}'由于 以下错误:应用程序调用了一个接口 为不同的线程编组。 (HRESULT的例外情况:0x8001010E (RPC_E_WRONG_THREAD))“。
我可以看到存在线程问题。在测试工具的情况下,所有这些调用都发生在主线程上,而在Windows服务的情况下,Service OnStart覆盖和COM事件处理程序都在不同的线程上。我一直在努力尝试不同的事情。有什么建议吗?
答案 0 :(得分:1)
某些COM组件只能由STA线程访问。如果是你的情况, 你可以像这样在STA线程中进行COM工作:
RunInSTAThread( () => com_object.DoSomething() );
private static void RunInSTAThread(ThreadStart thread_start)
{
Exception threadEx = null;
ThreadStart wrapped_ts = () =>
{
try
{
thread_start();
}
catch (Exception ex)
{
MethodInfo preserveStackTrace =
typeof(Exception).GetMethod("InternalPreserveStackTrace",
BindingFlags.Instance | BindingFlags.NonPublic);
preserveStackTrace.Invoke(ex, null);
threadEx = ex;
}
};
Thread thread = new Thread(wrapped_ts);
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
if (threadEx != null)
{
throw threadEx;
}
}
对于您的情况,这可能不是线程的最佳使用(每次调用的新线程),但它是一个起点。
答案 1 :(得分:0)
Win服务是否在与Winforms应用程序相同的用户帐户下运行?
答案 2 :(得分:0)
现在已经解决了。我不得不重新安排线程。现在COM对象和它的所有调用都在同一个线程上,没有线程间的问题。 在常见情况下如何处理它的问题仍然不清楚。
答案 3 :(得分:-1)
我刚刚关闭了项目并再次打开它并解决了错误