如何从创建的“Excel.Application”获取进程标识目的? [英] How do I get the Process ID from a created "Excel.Application" object?

查看:510
本文介绍了如何从创建的“Excel.Application”获取进程标识目的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何从正在运行的对象获取进程ID?

How do I get the Process ID from a running object?

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

我需要使用后期绑定,因为我无法保证我将使用哪个版本 Microsoft.Office.Interop.Excel 将无法正常工作。

I need to use late binding because I can't guarantee which version I will get so using Microsoft.Office.Interop.Excel won't work.

'do some work with xlApp

xlApp.Quit
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp)
xlApp = nothing

此时,Excel仍然在后台运行。我熟悉使用变量并发布它们的所有建议,然后使用: System.Runtime.InteropServices.Marshal.ReleaseComObject(o)。这不能可靠地工作。我正在做的工作非常复杂。我使用多个文件的每个循环等。不可能释放Excel中的所有资源。我需要一个更好的选择。

At this point Excel is still running in the background. I am familiar with all the recommendations to use variables and release them then use: System.Runtime.InteropServices.Marshal.ReleaseComObject(o). This does not work reliably. The work that I'm doing is very complicated. I use for each loops etc using multiple files. It is impossible to release all of the resources in Excel. I need a better option.

我想在Excel上使用 Process.Kill ,但我不知道如何获取进程从xlApp对象。我不想杀死所有的Excel进程,因为用户可能打开一个工作簿。

I'd like to use Process.Kill on Excel but I don't know how to get the process from the xlApp object. I don't want to kill all Excel processes because the user might have a workbook open.

我尝试使用 Dim xProc As Process = Process.Start(ExcelPath)然后使用 xProc.Kill()有效的工作,除了使用 XLApp = GetObject(Book1)获取正确的Excel对象有点棘手。应用程序 XLApp = GetObject(,Excel.Application)如果用户已经打开了Excel窗口。我需要一个更好的选择。

I tried using Dim xProc As Process = Process.Start(ExcelPath) then using xProc.Kill() That works sometimes except it's a little tricky to get the correct Excel object using XLApp = GetObject("Book1").Application or XLApp = GetObject("", "Excel.Application") if the user already has Excel windows open. I need a better option.

我不能使用 GetActiveObject BindToMoniker 来获取Excel对象,因为它们只能在使用早期绑定时工作。例如。 Microsoft.Office.Interop.Excel

如何从正在运行的对象获取进程标识?

How do I get the Process ID from a running object?

编辑:其实我并不真的很感兴趣,如何让Excel很好地退出。许多其他问题已经解决了。 此处这里我只想杀死它;干净,精确和直接。我想杀死我开始的确切过程,没有其他的。

Actually I'm not really interested in a rehash on how to get Excel to nicely exit. Many other questions have addressed that. here and here I just want to kill it; cleanly, precisely and directly. I want to kill the exact process that I started and no other.

推荐答案

其实不介意;我想到了。这是一个非常干净,精确的目标解决方案,可以杀死开始的确切过程。它不会干扰用户可能打开的任何其他进程或文件。在我的经验中,关闭文件并退出Excel后,这个过程是处理Excel的最快最简单的方法。 这是一个知识库文章,描述了问题和Microsoft推荐的解决方案。

Actually never mind; I figured it out. This is a very clean, precisely targeted solution that kills the exact process that was started. It doesn't interfere with any other process or file that the user might have open. In my experience killing the process after closing files and quitting Excel is the fastest and easiest way to deal with Excel. Here is a knowledge Base article describing the problem and Microsoft's recommended solution.

请注意,此解决方案不会杀死Excel应用程序。如果任何指针没有被正确处理,它只会杀死空的进程shell。当我们调用 xlApp.quit()时,Excel本身实际退出。这可以通过尝试附加正在运行的Excel应用程序来确认,这将因为Excel不运行而失败。

Please note that this solution does NOT kill the Excel application. It only kills the empty process shell if any pointers have not been properly disposed. Excel itself DOES actually quit when we call xlApp.quit(). This can be confirmed by trying to attach the running Excel application which will fail because Excel is not running at all.

许多人不建议将进程杀死;请参阅
如何正确清理Excel互操作对象
了解.net中的垃圾收集

Many people don't recommend killing the process; See How to properly clean up Excel interop objects and Understanding Garbage Collection in .net

另一方面,很多人不建议使用GC.Collect。请参阅使用GC.Collect()有什么问题?

On the other hand many people don't recommend using GC.Collect. See What's so wrong about using GC.Collect()?

确保关闭任何打开的工作簿,退出应用程序,释放xlApp对象。最后检查一下这个进程是否仍然存在,如果是这样,那么可以将其删除。

Be sure to Close any open workbooks, Quit the application, Release the xlApp object. Finally check to see if the process is still alive and if so then kill it.

Private Declare Auto Function GetWindowThreadProcessId Lib "user32.dll" (ByVal hwnd As IntPtr, _
              ByRef lpdwProcessId As Integer) As Integer

Sub testKill()

    'start the application
    Dim xlApp As Object = CreateObject("Excel.Application")

    'do some work with Excel

    'close any open files

    'get the window handle
    Dim xlHWND As Integer = xlApp.hwnd

    'this will have the process ID after call to GetWindowThreadProcessId
    Dim ProcIdXL As Integer = 0

    'get the process ID
    GetWindowThreadProcessId(xlHWND, ProcIdXL)

    'get the process
    Dim xproc As Process = Process.GetProcessById(ProcIdXL)

    'Quit Excel
    xlApp.quit()

    'Release
    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp)

    'set to nothing
    xlApp = Nothing

    'kill it with glee
    If Not xproc.HasExited Then
        xproc.Kill()
    End If

End Sub

一旦我意识到我可以从Excel获取窗口句柄,那么我只需要该函数从窗口句柄中获取进程ID。因此 GetWindowThreadProcessId 如果有人知道vb.net的方式让我感激不尽。

Once I realized that I could get the window handle from Excel, then I just needed the function to get the process ID from the window handle. Hence GetWindowThreadProcessId If anyone knows a vb.net way to get that I would be grateful.

这篇关于如何从创建的“Excel.Application”获取进程标识目的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆