テストを行い、ネイティブの p/invoke 関数について学習しようとしていたので、pinvoke のみを使用して、プロセス情報を取得するのにかかる時間を .net simple と比較しようとしていました。
Process myProc = Process.GetProcessByName("WinRAR");
P/invoke を使用してほぼ 2 ページの長さのコードを実際に測定する必要があると感じていますが、同じ結果を得ることができますが、今回はネイティブ コードのみで、より高速である必要があり、少なくとも取得したいと思います両方をベンチマークするため、ここで助けてください。
だから、私のコードは 1) のようです ... OK、すべての問題を「列挙」して 20 まで数えることができると思いますが、主に:
- たとえば、winrarが表示されなかったという奇妙な理由で、すべてのプロセスを列挙しません
- 次に、pinvoke のメソッド群が必要とするほど短くはありません。
(私はWinformsアプリを使用していますがProcessName
、正しいプロセスを「検索」するために必要なものをハードコーディングできます)
ここにあるコメントのほとんどは、まあの作者によるものです。コードのほとんどの部分は、後で列挙するように少し変更しただけなので、ウィンドウのタイトルまたはプロセス名で検索するかを選択できます
これはコードです:
メインエントリ - クラスのインスタンスを作成:
pinvokers Pi = new pinvokers();
// Find all Internet Explorer instances(i used winrar, as my second task in this project is also test application performance... later on, and again, using only native calls)
Pi.FindWindows(0, pinvokers.SearchWin.ProcName, null, new Regex(TBX_SelectedWinName.Text), new pinvokers.FoundWindowCallback(pinvokers.foundWindowToPrint));
public class pinvokers
{
// Win32 constants.
const int WM_GETTEXT = 0x000D;
const int WM_GETTEXTLENGTH = 0x000E;
[DllImport("user32.Dll")]
private static extern Boolean EnumChildWindows(int hWndParent, PChildCallBack lpEnumFunc, int lParam);
[DllImport("user32.Dll")]
private static extern int GetWindowText(int hWnd, StringBuilder text, int count);
[DllImport("user32.Dll")]
private static extern int GetWindowThreadProcessId(int hWnd, out int lpdwProcessId);
[DllImport("user32.Dll")]
private static extern Int32 SendMessage(int hWnd, int Msg, int wParam, StringBuilder lParam);
[DllImport("user32.Dll")]
private static extern Int32 SendMessage(int hWnd, int Msg, int wParam, int lParam);
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern uint GetWindowModuleFileName(IntPtr hwnd,
StringBuilder lpszFileName, uint cchFileNameMax);
[DllImport("psapi.dll")]
private static extern uint GetModuleFileNameEx(IntPtr hWnd, IntPtr hModule, StringBuilder lpFileName, int nSize);
// The PChildCallBack delegate that we used with EnumWindows.
private delegate bool PChildCallBack(int hWnd, int lParam);
// This is an event that is run each time a window was found that matches the search criterias. The boolean
// return value of the delegate matches the functionality of the PChildCallBack delegate function.
static event FoundWindowCallback foundWindowCB;
public delegate bool FoundWindowCallback(int hWnd);
int parentHandle;
Regex process;
#region <<=========== not nedded - search by window title. i am looking to search via process name ===========>>
/* <- commented all unsuesd
Regex windowText;
public static bool foundWindowToPrint(int handle)
{
// Print the window info.
printWindowInfo(handle);
// Continue on with next window.
return true;
}
static void printWindowInfo(int handle)
{
// Get the text.
int txtLength = SendMessage(handle, WM_GETTEXTLENGTH, 0, 0);
StringBuilder sbText = new StringBuilder(txtLength + 1);
SendMessage(handle, WM_GETTEXT, sbText.Capacity, sbText);
// Now we can write out the information we have on the window.
MessageBox.Show("Handle: " + handle);
MessageBox.Show("Text : " + sbText);
}
=====>end of un needed search bywindowtitle1
*/
#endregion
// my plan was to use enum instead of if !empty or null value for ither title name or process name so that's how the original code ditermin wich one to execute.
public enum SearchWin
{
Title, ProcName
}
//first method (and that's all i could really tell.. as it is full of callbacks and private extern, and delegates ... so complex
public void FindWindows(int parentHandle, SearchWin By, Regex windowText, Regex process, FoundWindowCallback fwc)
{
this.parentHandle = parentHandle;
//this.windowText = windowText;
this.process = process;
// Add the FounWindowCallback to the foundWindow event.
foundWindowCB = fwc;
// Invoke the EnumChildWindows function.
EnumChildWindows(parentHandle, new PChildCallBack(enumChildWindowsCallback), 0);
}
// This function gets called each time a window is found by the EnumChildWindows function. The foun windows here
// are NOT the final found windows as the only filtering done by EnumChildWindows is on the parent window handle.
private bool enumChildWindowsCallback(int handle, int lParam)
{
#region <<=========== not nedded - search by window title. #2 ===========>>
/* <--here too window title portion of code commented
// If a window text was provided, check to see if it matches the window.
if (windowText != null)
{
int txtLength = SendMessage(handle, WM_GETTEXTLENGTH, 0, 0);
StringBuilder sbText = new StringBuilder(txtLength + 1);
SendMessage(handle, WM_GETTEXT, sbText.Capacity, sbText);
// If it does not match, return true so we can continue on with the next window.
if (!windowText.IsMatch(sbText.ToString()))
return true;
}
*/
#endregion //endr2
// If a process name was provided, check to see if it matches the window.
if (process != null)
{
int processID;
GetWindowThreadProcessId(handle, out processID);
// Now that we have the process ID, we can use the built in .NET function to obtain a process object.
var ProcessName = GetProcNameByID(processID);
// If it does not match, return true so we can continue on with the next window.
if (!process.IsMatch(ProcessName))
return true;
}
// If we get to this point, the window is a match. Now invoke the foundWindow event and based upon
// the return value, whether we should continue to search for windows.
return foundWindowCB(handle);
}
private string GetProcNameByID(int ProcID)
{
IntPtr hProcess = OpenProcess(0x0410, false, ProcID);
StringBuilder text = new StringBuilder(1000);
GetWindowModuleFileName(hProcess, text, (uint)text.Capacity);
//GetModuleFileNameEx(hProcess, IntPtr.Zero, text, text.Capacity);
//CloseHandle(hProcess); here i am trying to catch what enumeration of windows got in its net , all this code does work just copy and paste it .
var t = text.ToString();
if (t.ToLower().Contains("inra"))
MessageBox.Show(t);
return t;
}
}
したがって、これは少し短くなる可能性がありますが、主な質問は次のとおりです。
すべてのプロセスを列挙しないのはなぜですか?