标签: rcw

关闭具有WebBrowser控件的表单时为什么会出现RaceOnRCWCleanup错误?

VS2008,.NET 2,VB.NET,XP ......

我有一个Windows窗体,有一个WebBrowser控件和一个关闭按钮,它只是一个Me.Close.表单的取消按钮设置为关闭按钮,以便我可以按ESC键关闭表单.

DocumentText在load事件中设置WebBrowser控件的属性,并显示HTML.

从Visual Studio运行应用程序,如果单击"关闭"按钮,表单将关闭,不会出现任何错误.

如果我按下ESC按钮,我会得到

检测到RaceOnRCWCleanup消息:已尝试释放正在使用的RCW.RCW正在活动线程或另一个线程上使用.尝试释放正在使用的RCW可能会导致损坏或数据丢失.

如果我在VS外面运行应用程序,我没有错误.

任何想法a)为什么错误,和b)如何预防或抑制它?

提前谢谢了.

.net webbrowser-control rcw winforms

24
推荐指数
1
解决办法
2万
查看次数

在C#中使用COM互操作时的RCW和引用计数

我有一个使用Office互操作程序集的应用程序.我知道运行时管理的"运行时可调用包装器(RCW)".但我不太确定引用计数如何增加.MSDN说,

RCW只保留对包装的COM对象的一个​​引用,而不管调用它的受管客户端的数量.

如果我理解正确,在以下示例中,

using Microsoft.Office.Interop.Word;

static void Foo(Application wrd)
{
    /* .... */
}

static void Main(string[] args)
{
    var wrd = new Application();
    Foo(wrd);
    /* .... */
}
Run Code Online (Sandbox Code Playgroud)

我将实例传递wrd给另一个方法.但这不会增加内部引用计数.所以我想知道引用计数增加的场景是什么?任何人都可以指出引用计数增加的情况吗?

另外我读了一些博客,说在使用COM对象编程时避免使用双点.像,wrd.ActiveDocument.ActiveWindow.作者声称编译器创建单独的变量来保存将增加引用计数器的值.恕我直言,这是错误的,第一个例子证明了这一点.那是对的吗?

任何帮助都会很棒!

c# com ms-office rcw office-pia

20
推荐指数
1
解决办法
1万
查看次数

使用WPF退出时出现COM异常

执行以下两个测试用例后,将向控制台打印COM执行.我究竟做错了什么?

如果我单独运行任一测试,或者如果我同时运行两个测试,则会将异常写入控制台一次.这让我怀疑是否存在某种我不会清理的每AppDomain资源.

我已尝试使用NUnit和MSTest进行测试,在两种环境中都具有相同的行为.(实际上,我不确定在MSTest中运行这两个测试是否会导致一个或两个异常打印输出.)

例外:

System.Runtime.InteropServices.InvalidComObjectException: COM object that has been separated from its underlying RCW cannot be used.
at System.Windows.Input.TextServicesContext.StopTransitoryExtension()
at System.Windows.Input.TextServicesContext.Uninitialize(Boolean appDomainShutdown)
at System.Windows.Input.TextServicesContext.TextServicesContextShutDownListener.OnShutDown(Object target)
at MS.Internal.ShutDownListener.HandleShutDown(Object sender, EventArgs e)
Run Code Online (Sandbox Code Playgroud)

测试代码:

using NUnit.Framework;

namespace TaskdockSidebarTests.Client
{
    [TestFixture, RequiresSTA]
    public class ElementHostRCWError
    {
        [Test]
        public void WinForms()
        {
            var form = new System.Windows.Forms.Form();
            var elementHost = new System.Windows.Forms.Integration.ElementHost();
            form.Controls.Add(elementHost);

            // If the form is not shown, the exception is not printed.
            form.Show();

            // These lines are optional. The exception is …
Run Code Online (Sandbox Code Playgroud)

c# com wpf rcw

13
推荐指数
1
解决办法
2962
查看次数

通过 Powershell 关闭时无法停止所有 Excel 进程

使用此代码,我打开 excel(使用visible = false,以便用户看不到它),写入工作簿,然后在脚本结束后打开 excel(使其可见)或完全关闭它而不保存。当我保存 Excel、使其保持打开状态、结束脚本,然后稍后手动关闭 Excel 时,任务管理器中没有后台进程。但是,当我使用脚本关闭 Excel 时,它仍保留在任务管理器中。

以下是我开始使用 Excel 的方法:

    $script:excel = new-object -ComObject excel.application # create excel object
    $excel.visible = $false # hide excel window
    $script:workbook = $excel.Workbooks.Add() # add excel file
    $script:ws1 = $workbook.Worksheets.Item(1) # create new sheet
Run Code Online (Sandbox Code Playgroud)

这是我关闭它的方法:

        [gc]::Collect()
        [gc]::WaitForPendingFinalizers()
        if ($script:closeOnX) {
            #only do this if not keeping excel open
            Write-Host "Closing Excel"
            $excel.Quit()
        }
        [System.Runtime.InteropServices.Marshal]::ReleaseComObject($excel)
Run Code Online (Sandbox Code Playgroud)

closeOnX 只是一个标志,因此它仅在某些情况下实际关闭 Excel 应用程序。其余部分在每次脚本结束时执行。

当我结束脚本并同时关闭 Excel 时,我只想关闭当前的 Excel 进程(这就是我不想停止进程的原因),而不关闭用户可能正在处理的其他工作簿。

当我结束脚本、保存并打开 Excel 时,我希望当用户手动关闭 Excel 时所有进程都消失。(这是工作)

com excel powershell user-interface rcw

9
推荐指数
1
解决办法
4252
查看次数

VS2008 UnitTesting - 带有Office应用程序对象的分离RCW(PowerPoint等)

背景

  • 我通过C#自动化PowerPoint 2007
  • 我正在使用Visual Studio的内置单元测试(Microsoft.VisualStudio.TestTools.UnitTesting)为我的代码编写单元测试
  • 我在自动化Office 2007应用程序方面经验丰富

我的问题

  • 当我运行我的单元测试时,第一个单元测试方法运行正常,之后都有关于分离的RCW的错误
  • 我正在为要共享的测试方法创建一个PowerPoint的静态实例,但似乎应用程序RCW在第一个测试方法运行后被分离

来源代码

    using System;
    using System.Text;
    using System.Collections.Generic;
    using System.Linq;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    namespace TestDemo
    {



        [TestClass]
        public class UnitTest1
        {
            private static Microsoft.Office.Interop.PowerPoint.ApplicationClass 
              g_app = new Microsoft.Office.Interop.PowerPoint.ApplicationClass();

            private TestContext testContextInstance;

            public TestContext TestContext
            {
                get
                {
                    return testContextInstance;
                }
                set
                {
                    testContextInstance = value;
                }
            }



            [TestMethod]
            public void Test01()
            {
                g_app.Visible = Microsoft.Office.Core.MsoTriState.msoCTrue;
            }

            [TestMethod]
            public void Test02()
            {
                g_app.Visible = Microsoft.Office.Core.MsoTriState.msoCTrue;
            }
        }

    }
Run Code Online (Sandbox Code Playgroud)

错误信息

Test method TestDemo.UnitTest1.Test02 threw …
Run Code Online (Sandbox Code Playgroud)

unit-testing mstest ms-office rcw visual-studio

7
推荐指数
1
解决办法
1505
查看次数

如何在不依赖异常的情况下判断COM对象是否已与其基础RCW分离?

判断COM对象的引用计数是否达到0的一种方法是尝试访问其中一个成员并捕获生成的InvalidComObjectException,这不是很优雅,并且似乎不能很好地适应.另一种方法是调用Marshal.ReleaseComObject并检查结果,但这需要将Com对象的引用计数减少1.

有简单明了的方法吗?

.net com com-interop rcw

7
推荐指数
1
解决办法
357
查看次数

RCW终结器访问冲突

我正在使用COM interop在使用VS2012/.NET 4.5/Win8.1的非托管应用程序中创建托管插件.所有的互操作似乎都没问题,但是当我关闭应用程序时,我得到了一个MDA异常,告诉我在发布完成期间RCW持有的COM对象时发生了AV.

这是调用堆栈:

clr.dll!MdaReportAvOnComRelease::ReportHandledException()  + 0x91 bytes 
clr.dll!**SafeRelease_OnException**()  + 0x55 bytes 
clr.dll!SafeReleasePreemp()  + 0x312d5f bytes   
clr.dll!RCW::ReleaseAllInterfaces()  + 0xf3 bytes   
clr.dll!RCW::ReleaseAllInterfacesCallBack()  + 0x4f bytes   
clr.dll!RCW::Cleanup()  + 0x24 bytes    
clr.dll!RCWCleanupList::ReleaseRCWListRaw()  + 0x16 bytes   
clr.dll!RCWCleanupList::ReleaseRCWListInCorrectCtx()  + 0x9c bytes  
clr.dll!RCWCleanupList::CleanupAllWrappers()  + 0x2cd1b6 bytes  
clr.dll!RCWCache::ReleaseWrappersWorker()  + 0x277 bytes    
clr.dll!AppDomain::ReleaseRCWs()  + 0x120cb2 bytes  
clr.dll!ReleaseRCWsInCaches()  + 0x3f bytes 
clr.dll!InnerCoEEShutDownCOM()  + 0x46 bytes    
clr.dll!WKS::GCHeap::**FinalizerThreadStart**()  + 0x229 bytes  
clr.dll!Thread::intermediateThreadProc()  + 0x76 bytes  
kernel32.dll!BaseThreadInitThunk()  + 0xd bytes 
ntdll.dll!RtlUserThreadStart()  + 0x1d bytes    
Run Code Online (Sandbox Code Playgroud)

我的猜测是应用程序已经销毁了它的COM对象,其中一些引用被传递给托管插件 - 而对RCW的IUnknown :: Release的调用让它变得繁荣.

我可以在输出窗口(VS)中清楚地看到应用程序已经开始卸载其中的一些dll.

'TestHost.exe': Unloaded …
Run Code Online (Sandbox Code Playgroud)

c# com-interop rcw access-violation visual-studio-2012

7
推荐指数
1
解决办法
1461
查看次数

从.NET安全地释放COM对象引用

我已经在网上阅读了很多关于安全发布RCW的文章,在我看来,没有人能够确切地知道需要按什么顺序做什么,所以我要问你们各位的意见.例如,人们可以这样做:

object target = null;
try {
    // Instantiate and use the target object.
    // Assume we know what we are doing: the contents of this try block
    // do in fact represent the entire desired lifetime of the COM object,
    // and we are releasing all RCWs in reverse order of acquisition.
} finally {
    if(target != null) {
        Marshal.FinalReleaseComObject(target);
        target = null;
        GC.Collect();
        GC.WaitForPendingFinalizers();
    }
}
Run Code Online (Sandbox Code Playgroud)

然而,有些人主张在之前进行垃圾收集Marshal.FinalReleaseComObject,有些人在之后,有些则根本没有.是否真的有必要手动GC每个RCW,特别是在它已经从COM对象中分离出来之后?

在我看来,将RCW从COM对象中分离并让RCW自然过期会更简单,更容易:

object target = null;
try {
    // Same …
Run Code Online (Sandbox Code Playgroud)

.net com-interop rcw

6
推荐指数
1
解决办法
3223
查看次数

.NET运行时何时为COM对象保持引用计数> 1?

直到最近,我相信.NET运行时只在创建运行时可调用包装器时将COM对象的引用计数增加1 ,并且只为任何给定的COM对象创建一个这样的运行时可调用包装器.

如果我没有弄错的话,上面暗示Marshal.FinalReleaseComObjectMarshal.ReleaseComObject在实践中做同样的事情.

但是,今天我正在编写一些测试来验证我的代码是否正确释放了COM对象.我这样做是通过调用所谓的释放对象并检查预期的InvalidComObjectException.事实证明,有些情况下会抛出异常FinalReleaseComObject,但不会抛出异常ReleaseComObject.

这是否意味着.NET 2.0运行时可以包含多个COM对象的引用?如果是这样,它什么时候这样做?

.net com com-interop rcw

6
推荐指数
1
解决办法
332
查看次数

VS2010不会显示项目属性("底层RCW")?

只有时候(我还没有注意到一个模式),当我右键单击一个项目(各种类型的项目)并选择"时,VS2010显示以下错误(我希望属性页的主体是)"属性":

尝试加载页面时发生错误. 无法使用已与其基础RCW分离的COM对象.

我通常可以在重启VS2010后查看项目页面.我正在使用RTM版本.

什么可能导致此错误?

visual-studio-2010 comobject rcw project-properties

5
推荐指数
1
解决办法
2429
查看次数