c# - 尝试调用 COM 库时服务引发异常

标签 c# .net windows-services error-handling

这个问题不太可能帮助任何 future 的访客;它只与一个小地理区域、一个特定时刻或一个非常狭窄的情况相关,而这些情况通常不适用于互联网的全局受众。如需帮助使这个问题更广泛地适用,visit the help center .




10年前关闭。




我正在编写一个使用 COM 库的应用程序。我有一个类库,它封装了对 COM 库的调用并添加了更多功能。最终这将作为 Windows 服务运行。现在我使用 Winforms 测试工具对其进行测试。

当测试工具创建类库时,一切似乎都工作正常。当我尝试将其作为服务运行时,问题就开始了。它创建正常,甚至对 COM 的第一次调用也正常。然后,COM 对象引发我处理的事件,并响应事件中的结果,我调用 COM 库中的另一个函数。在我从测试工具运行它但作为服务运行时抛出异常的情况下,该函数被成功调用:

System.InvalidCastException occurred Message="Unable to cast COM object of type '' to interface type ''. This operation failed because the QueryInterface call on the COM component for the interface with IID '{350ADD2A-18CB-4D9C-BE28-48D53F14E6FB}' failed due to the following error: The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))."



我可以看到存在线程问题。在测试工具案例中,所有这些调用都发生在主线程上,而在 Windows 服务的情况下,Service OnStart 覆盖和 COM 事件处理程序都在不同的线程上。我一直在尝试不同的事情但没有成功。有什么建议么?

最佳答案

某些 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;
            }
        }

对于您的情况,这可能不是线程(每次调用的新线程)的最佳用途,但它是一个起点。

关于c# - 尝试调用 COM 库时服务引发异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/778104/

相关文章:

.net - Windows 编程与 Unix 编程有何不同

c# - 通过 URL 请求将参数传递给 azure 持久函数

c# - RabbitMQ 消费者

c# - 某些 Excel 文件未从共享路径移动到 SQL Server

c# - 检查 ASP.NET CheckboxList 中的多个项目

c# - ASP.Net Core - 将 SAML 断言转换为 ClaimsPrincipal

c# - Quartz C# 每小时运行一次

c# - 如何使用 .Net 使用 MVC 和 Entity Framework 在表中动态添加数据库字段?

.NET - 将颜色名称字符串转换为 System.Drawing.Color

c - 用户尝试停止服务时出现警告窗口