Tag: com

访问COM组件时出错

我为Microsoft Office Word构build了一个加载项。 当Word以pipe理员身份运行时,使用外接程序时没有问题,但是如果没有以pipe理员身份运行Word,则存在两个访问function区元素的常见exception。 第一个例外: Unable to cast COM object of type 'System.__ComObject' to interface type 'Microsoft.Office.Core.IRibbonUI'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{000C03A7-0000-0000-C000-000000000046}' failed due to the following error: could not be found. (Exception from HRESULT: 0x80030002 (STG_E_FILENOTFOUND)). at Microsoft.Office.Core.IRibbonUI.InvalidateControl(String ControlID) 当控制被以下代码无效时,会发生此错误: ribbon.InvalidateControl("control-id"); 而第二个例外: […]

如何把WebBrowser控件到IE9标准?

我正在使用自动化(即COM自动化)在Internet Explorer(9)中显示一些HTML: ie = CoInternetExplorer.Create; ie.Navigate2("about:blank"); webDocument = ie.Document; webDocument.Write(szSourceHTML); webDocument.Close(); ie.Visible = True; 出现Internet Explorer,显示我的HTML,它的起点为: <!DOCTYPE html> <HTML> <HEAD> … 注意: html5标准模式select的doctype html 除非文件不在ie9标准模式下; 它在ie8标准模式下: 如果我把html保存到我的电脑里: 然后查看那个 html文件,IE是进入标准模式: 我的问题是如何更新我的SpawnIEWithSource(String html)函数将浏览器转换为标准模式? void SpawnIEWithSource(String html) { Variant ie = CoInternetExplorer.Create(); ie.Navigate2("about:blank"); webDocument = ie.Document; webDocument.Write(html); webDocument.Close(); ie.Visible = true; } 编辑:一个更详细,不易理解或可读的代码示例,这不能帮助进一步的问题可能是: IWebBrowser2 ie; CoCreateInstance(CLASS_InternetExplorer, null, CLSCTX_INPROC_SERVER […]

生成免注册COM的清单文件

我有一些应用程序(一些本地的,一些.NET),它们使用清单文件,以便它们可以完全隔离 ,而不需要任何全局COM注册。 例如,在与myapp.exe位于同一文件夹中的myapp.exe.manifest文件中声明了对dbgrid32.ocx com服务器的依赖关系,如下所示: <?xml version="1.0" encoding="utf-8" standalone="yes"?> <assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1"> <assemblyIdentity type="win32" name="myapp.exe" version="1.2.3.4" /> <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="dbgrid32.ocx" version="5.1.81.4" /> </dependentAssembly> </dependency> </assembly> dbgrid32.ocx和它自己的dbgrid32.ocx.manifest文件一起部署到同一个文件夹中: <?xml version="1.0" encoding="utf-8" standalone="yes"?> <assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1"> <assemblyIdentity type="win32" name="dbgrid32.ocx" version="5.1.81.4" /> <file name="dbgrid32.ocx"> <typelib tlbid="{00028C01-0000-0000-0000-000000000046}" version="1.0" helpdir=""/> <comClass progid="MSDBGrid.DBGrid" clsid="{00028C00-0000-0000-0000-000000000046}" description="DBGrid Control" /> </file> </assembly> 这一切工作正常,但手动维护这些清单文件是有点痛苦。 有没有办法自动生成这些文件? […]

StaTaskScheduler和STA线程消息抽取

TL; DR: 由StaTaskScheduler运行的任务内的死锁。 长版本: 我使用Parallel Team的ParallelExtensionsExtras中的StaTaskScheduler来托pipe由第三方提供的一些传统的STA COM对象。 StaTaskScheduler实现细节的描述如下: 好消息是TPL的实现能够在MTA或者STA线程上运行,并且考虑到WaitHandle.WaitAll(当方法提供了多个等待句柄时只支持MTA线程)等底层API的相关差异。 我认为这意味着TPL的阻塞部分将使用一个等待API的消息,如CoWaitForMultipleHandles ,以避免在STA线程上调用死锁情况。 在我的情况下,我相信以下情况正在发生:进程内的STA COM对象A调用了对象之外的对象B,然后期望从B通过作为传出呼叫的一部分的callback。 简化forms: var result = await Task.Factory.StartNew(() => { // in-proc object A var a = new A(); // out-of-proc object B var b = new B(); // A calls B and B calls back A during the Method call return a.Method(b); }, […]

如何处理AccessViolationException

我在.net应用程序中使用COM对象(MODI)。 我调用的方法抛出一个System.AccessViolationException,它被Visual Studio拦截。 奇怪的是,我已经把我的调用包装在一个try catch中,它有处理AccessViolationException,COMException和其他所有东西,但是当Visual Studio(2010)拦截AccessViolationException时,debugging器中断了方法调用(doc.OCR)如果我经过,它会继续到下一行,而不是进入catch块。 此外,如果我运行在Visual Studio以外,我的应用程序崩溃。 我怎样才能处理这个C​​OM对象中引发的exception? MODI.Document doc = new MODI.Document(); try { doc.Create(sFileName); try { doc.OCR(MODI.MiLANGUAGES.miLANG_ENGLISH, false, false); sText = doc.Images[0].Layout.Text; } catch (System.AccessViolationException ex) { //MODI seems to get access violations for some reason, but is still able to return the OCR text. sText = doc.Images[0].Layout.Text; } catch (System.Runtime.InteropServices.COMException ex) […]

你能解释STA和MTA吗?

你能用你自己的话来解释STA和MTA吗? 另外,什么是公寓线程,只涉及到COM? 如果是这样,为什么?

如何将消息发布到运行消息泵的STA线程?

所以,在这之后 ,我决定在一个专用STA线程上显式实例化一个COM对象。 实验表明,COM对象需要一个消息泵,我通过调用Application.Run()创build消息泵: private MyComObj _myComObj; // Called from Main(): Thread myStaThread = new Thread(() => { _myComObj = new MyComObj(); _myComObj.SomethingHappenedEvent += OnSomthingHappened; Application.Run(); }); myStaThread.SetApartmentState(ApartmentState.STA); myStaThread.Start(); 我如何从其他线程发布消息STA线程的消息泵? 注意:为了简洁起见,我大量地编辑了这个问题。 现在@Servy的答案的一些部分似乎是无关的,但他们是原来的问题。