2013-07-22 77 views
1

是否有一個託管的VB.net方式從HWND獲取進程ID,而不是使用此Windows API調用。如何使用託管VB.net代碼從HWND獲取進程ID?

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

Sub GetProcessID() 

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

    '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) 

End Sub 
+0

簡短的回答,編號 –

+0

這裏有一些事情引發紅旗。 1.爲什麼Office在提供PIA時使用CreateObject? 2.爲什麼你需要Excel的進程ID? –

+0

@ Dan-o你的紅旗超出了這個問題的範圍。已經提出並回答了許多其他問題,以解決這些問題。我不想重複這些。 –

回答

1

不,這不是由.NET包裝的。但是調用本地API函數絕對沒有錯。這就是框架在內部所做的,這就是爲什麼P/Invoke是被髮明出來的,爲了讓它儘可能地簡單,讓你自己去做。我不確定你爲什麼要避免它。

當然,我會建議使用新式的聲明,這是在做.NET的東西(而不是舊的VB 6路)的更地道的方式:

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

你的其他選擇,如果你絕對無法克服託管代碼的非理性強迫,那就是利用Process這個類。這可用於啓動外部進程,並具有可用於檢索進程ID的屬性(Id)。我不確定這是否適合你。您特別避免告訴我們您爲什麼首先使用CreateObject

+0

感謝您的回答。我毫不猶豫地在需要時使用Windows API,但是我發現它使用起來更麻煩。我很高興繼續爲此使用Windows API。 –

+0

我改變了DllImport到System.Runtime.InteropServices.DllImport然後它工作正常。 –

+0

啊,是的,它必須是代碼文件頂部的'Imports'語句,或者在每次使用時限定。按照許多樣式指南的建議,我將所有API函數聲明保存在一個包含名爲'NativeMethods'的模塊的單獨文件中。 –