在出错时杀死Excel

时间:2014-01-13 16:41:52

标签: vb.net excel

我希望你能在这里帮助我,过去你们都很棒。我已尝试使用kill脚本的每个变体来杀死来自vb.net的excel,但无济于事。

首先,我不能在这里发布显式代码,因为它是我公司的专有软件,但我可以告诉你一些事情。此外还有超过28,000行代码。

  1. 我没有使用

    Imports Excel = Microsoft.Office.Interop.Excel
    

    由于我们必须适应客户端软件的不同变体。我正在创建新的excel作为对象

    Dim XLObj As Object = CreateObject("Excel.Application")
    

    我已经看到过这个在其他几个网站上使用但是他们使用的杀戮功能是当你保存并关闭它时,我没有这样做。

  2. 我收到的错误消息说“无法使用与其基础RCW分离的Com对象”。我不确定这个com对象在哪里,因为我已经发布了工作表,工作簿和应用程序。

  3. 哦,我不想使用excel.kill(),因为如果客户端已经打开了excel,我不想在不保存的情况下将其删除。我只想杀死没有打开窗口的新生成的excel进程。

  4. 我的问题如下

    1. 我需要能够在/如果打开失败时关闭Excel应用程序。所以说我单击一个链接,它会打开对话框以选择要加载的Excel模板,但是数据库中的数据已损坏或者sql语句已损坏。程序抛出并出错,然后Excel应该在任务管理器中关闭。不幸的是它并没有因此而关闭。

    2. 有没有办法只关闭新创建的进程ID?我试图使用路线here,但它也不起作用。当我这样做时它给了我一个不同的错误“值不能为空参数名称:o”。抛出错误的行已打开(来自链接)

      Marshal.FinalReleaseComObject(tempVar)
      

      我只是尝试过这个,因为我们在XLObj上使用With。 With是参考工作簿本身,所以当我关闭工作簿时不应该发布它?因为我现在故意导致它出错,所以无论如何都不应该达到With声明。

    3. 有没有办法告诉哪个com对象没有关闭?

    4. 我尝试过的事情:

      1. 我在互联网上找到的这个版本对象。 (不要问我在哪里经历了大约75页)

        Private Sub releaseObject(ByRef obj As Object)
        Try
            System.Runtime.InteropServices.Marshal.FinalReleaseComObject(obj)
            If obj Is Nothing Then
        
            Else
                obj = Nothing
            End If
        
        
        Catch ex As Exception
            If obj Is Nothing Then
        
            Else
                obj = Nothing
            End If
        
        Finally
            GC.Collect()
            GC.WaitForPendingFinalizers()
        End Try
        End Sub
        
      2. 这与此功能一起使用(从我所在的许多网站拼凑而成)

            Public Sub CloseExcel(ByRef WorkBook As Object, ByRef Application As Object)
            Dim xLSheet As Object = WorkBook.Sheets
        
            For Each xLSheet In WorkBook.Sheets
                If xLSheet IsNot Nothing Then
                    releaseObject(xLSheet)
                End If
                If xLSheet IsNot Nothing Then
                    Kill(xLSheet)
                End If
            Next
        
            If WorkBook IsNot Nothing Then
                WorkBook.Close(False)
            End If
        
            If WorkBook IsNot Nothing Then
                Kill(WorkBook)
            End If
            releaseObject(WorkBook)
        
            If Application IsNot Nothing Then
                Application.Quit()
            End If
            If Application IsNot Nothing Then
                Kill(Application)
            End If
        
        
            releaseObject(Application)
        
            GC.Collect()
            GC.WaitForPendingFinalizers()
        
            Application.Quit()
        End Sub
        

        因为它也引用了Kill函数

            Public Sub Kill(ByRef obj As Object)
            Try
                System.Runtime.InteropServices.Marshal.FinalReleaseComObject(obj)
            Catch ex As Exception
                MessageBox.Show("moduleExcel.Kill  " &  ex.Message)
            Finally
                obj = Nothing
        
        
            End Try
        End Sub
        

        任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

好的,对于那些有完全相同问题的人。我确实有一个解决方案。是的,上面的代码确实有效,但需要进行一些小的调整。

  1. 您需要取出CloseExcel子代码中的所有代码并将其完全放置在您想要关闭的位置。因此,如果您希望它在程序错误时关闭,请放在catch语句之后。你不能调用Sub并传入你的对象并期望它杀死这个过程。

  2. 您需要在新Excel流程开头之上的几位。它们如下。

    'declare process for excel
    Dim XLProc As Process
    
    'loads the financials excel bookmarks
    'this will be where you declare your new excel opbject
    Dim XLObj As Object = CreateObject("Excel.Application") 
    
    
    'get window handle
    Dim xlHWND As Integer = XLObj.hwnd
    
    Dim ProcIDXL As Integer = 0
    'get the process ID
    GetWindowThreadProcessId(xlHWND, ProcIDXL)
    XLProc = Process.GetProcessById(ProcIDXL)
    
  3. 当然你需要我从原始问题中包含的链接获得的GetWindowThreadProcessId。我在这里发帖,所以你不必搜索它。

        <System.Runtime.InteropServices.DllImport("user32.dll", SetLastError:=True)> _
    Private Function GetWindowThreadProcessId(ByVal hWnd As IntPtr, ByRef lpdwProcessId As Integer) As Integer
    End Function
    

    此代码仅关闭与其关联的单个进程,不会关闭其他打开的Excel文件。我们的客户有时会打开多个文件,我们不想在不告诉他们的情况下关闭它们。这会导致在系统出错时在运行时创建的Excel进程。