在代码

时间:2015-10-23 00:46:16

标签: vb.net ms-office office-interop

我刚开始将一些代码从VBA迁移到VB.Net。所以我是VB.Net的绝对初学者 - 但我想做正确的事情。也许我的一些问题很愚蠢,但我想这是因为我是初学者。

因此,作为第一个练习,我开发了我的第一段代码(见下文)。现在我想我必须再次释放所有COM对象。其中两个在编写代码时已经抛出错误。其他人在运行时抛出错误。

但有趣的是:天气我释放了其余的COM对象(通过制作Marshal的相关尚未注释的行。也发表评论 - 然后所有以Marshal开头的行。请注释行)代码的行为对我来说绝对是一样的。

有人能告诉我在哪里可以看到/发现差异吗?

互联网告诉我必须有区别吗? 但我想我只是不明白(直到现在)。

除此之外,我脑子里还有很多问题:

  1. 每个“Dim”语句都会创建一个COM对象 - 必须稍后发布吗?
  2. 如果不是,我如何检测是否已创建COM对象?哪个“Dim”语句创建COM对象而哪些不是?
  3. 在此示例中:Dim ActiveWindow As Object = Nothing Try ActiveWindow = Me.HostApplication.ActiveWindow() Catch End Try
  4. Marshal.ReleaseComObject(ActiveWindow) 相同 Marshal.ReleaseComObject(Me.HostApplication.ActiveWindow())

    1. 根据这个:
    2. http://www.codeproject.com/Tips/235230/Proper-Way-of-Releasing-COM-Objects-in-NET

      单独释放每个“级别”会不会更好:

      Marshal.ReleaseComObject(Me.HostApplication.ActiveWindow())
      Marshal.ReleaseComObject(Me.HostApplication)
      Marshal.ReleaseComObject(Me)
      
      1. 总体而言:我试图释放太多吗?或者它是正确/好的实践?

      2. “GC.Collect()”和“...... = Null”与这一切有什么关系?我根本没用过它。我应该更好地使用它吗?为什么? (“...... = Null”我在这里看到了:

      3. http://www.codeproject.com/Tips/162691/Proper-Way-of-Releasing-COM-Objects-in-NET

        1. 为什么我会“未声明ShapeCount ...” - 如果我尝试“Marshal.ReleaseComObject(ShapeCount)”会出错?与“ShRange”相同。我认为这些也是COM对象?!?

        2. 如何注意何时再次释放COM对象的最佳时间?当我使用F11逐步处理/调试我的代码时,我是否可以确定最佳(最快)的发布点?到目前为止,我没有“感觉”什么时候不再需要COM对象,我可以释放它。

        3. 非常欢迎任何帮助和解释。

          以下是我要说的代码:

          Imports System.Runtime.InteropServices
          Imports System.ComponentModel
          Imports System.Windows.Forms
          Imports AddinExpress.MSO
          Imports PowerPoint = Microsoft.Office.Interop.PowerPoint
          
          'Add-in Express Add-in Module
          <GuidAttribute("D75C609E-7632-400F-8A6F-6A6E6E744E75"),
          ProgIdAttribute("MyAddin8.AddinModule")> _
          Public Class AddinModule
          Inherits AddinExpress.MSO.ADXAddinModule
          
          #Region " Add-in Express automatic code "
          […] 
          #End Region
          
          Public Shared Shadows ReadOnly Property CurrentInstance() As AddinModule
              Get
                  Return CType(AddinExpress.MSO.ADXAddinModule.CurrentInstance, AddinModule)
              End Get
          End Property
          
          Public ReadOnly Property PowerPointApp() As PowerPoint._Application
              Get
                  Return CType(HostApplication, PowerPoint._Application)
              End Get
          End Property
          
          Private Sub AdxRibbonButton2_OnClick(sender As Object, control As IRibbonControl, pressed As Boolean) Handles AdxRibbonButton2.OnClick
              MsgBox(GetInfoString2())
          End Sub
          
          Friend Function GetInfoString2() As String
              Dim ActiveWindow As Object = Nothing
              Try
                  ActiveWindow = Me.HostApplication.ActiveWindow()
              Catch
              End Try
              Dim Result As String = "No document window found!"
              If Not ActiveWindow Is Nothing Then
                  Select Case Me.HostType
                      Case ADXOfficeHostApp.ohaPowerPoint
                          Dim Selection As PowerPoint.Selection =
                              CType(ActiveWindow, PowerPoint.DocumentWindow).Selection
                          Dim WindowViewType As PowerPoint.PpViewType = PowerPoint.PpViewType.ppViewNormal
                          Dim SlideRange As PowerPoint.SlideRange = Selection.SlideRange
                          Dim SlideCountString = SlideRange.Count.ToString()
                          If WindowViewType = 9 And SlideCountString < 2 Then
                              Dim ShRange As PowerPoint.ShapeRange = Nothing
                              Try
                                  ShRange = Selection.ShapeRange
                              Catch
                              End Try
                              If Not ShRange Is Nothing Then
                                  Dim ShapeCount = ShRange.Count.ToString()
                                  Result = "You have " + ShapeCount _
                                      + " shapes selected."
                              Else
                                  Result = "You have 0 shapes selected."
                              End If
                          End If
                          'Marshal.ReleaseComObject(ShapeCount)
                          'Marshal.ReleaseComObject(ShRange)
                          'Marshal.ReleaseComObject(WindowViewType)
                          'Marshal.ReleaseComObject(SlideCountString)
                          Marshal.ReleaseComObject(SlideRange)
                          Marshal.ReleaseComObject(Selection)
                      Case Else
                          Result = AddinName + " doesn't support " + HostName
                  End Select
                  'Marshal.ReleaseComObject(Me.HostType)
                  'Marshal.ReleaseComObject(Result)
                  Marshal.ReleaseComObject(Me.HostApplication.ActiveWindow())
                  Marshal.ReleaseComObject(Me.HostApplication)
                  'Marshal.ReleaseComObject(Me)
              End If
              Return Result
          End Function
          
          End Class
          

2 个答案:

答案 0 :(得分:1)

Marshal类的ReleaseComObject方法减少与指定COM对象关联的指定运行时可调用包装器(RCW)的引用计数,它不会释放对象。它来自COM性质。

通常,您需要释放从Office(在您的案例中为PowerPoint)对象模型中返回的每个对象。异常是作为参数传递给事件处理程序的对象。

您可以在When to release COM objects in Office add-ins developed in .NET文章中详细了解并查找多个问题的答案。

答案 1 :(得分:0)

FinalReleaseComObject调用ReleaseComObject直到它返回0,这意味着释放COM对象。以Excel对象(应用程序,工作簿,工作表)中的相反顺序调用它们是处理相关COM对象的正确方法。

  

例外条件

     

的ArgumentException
  o不是有效的COM对象。

     

ArgumentNullException
  o为空。