![](/img/trans.png)
[英]PInvoke.Net in C#, PostMessage method not accepting FindWindow (IntPtr hWnd) handle Pointer
[英]FindWindow in C#(via pinvoke) finds desired window handle, but not in the desired conditions. How do I fix it?
我正在嘗試獲取某些窗口句柄。 我一直在尋找解決方案好幾個小時,我知道我的問題聽起來與這個問題相似: FindWindow() 沒有找到我的窗口 [C++]但那個討論沒有幫助。
我試圖同時使用 FindWindow() 和 FindWindowEx() 像這兩個:
IntPtr SysPropWndHandler = FindWindow("#32770", "Параметри продуктивності");
IntPtr SysPropWndHandler = FindWindowEx(IntPtr.Zero, IntPtr.Zero, "#32770", "Параметри продуктивності");
奇怪的是,當我運行該程序時,它會從 system32 文件夾中為某些系統設置程序啟動新進程,並且在同一啟動時間內找不到它的句柄(如果這樣說是正確的)。 我試圖暫停它以給它時間來創建窗口和分配句柄,但這無濟於事。 但! 如果該系統程序首先啟動,然后我運行我的程序 - 它會立即找到它的句柄。 “外部發布”的兩種方式:
但我實際上試圖讓我的程序做的是:
由於我的代碼有效,至少在某些情況下,它看起來與編碼無關,編碼在那個類似的問題中有所體現。 否則根本就行不通。
我試圖將它隱藏起來,但沒有奏效。 我為記事本嘗試了相同的代碼來調試它 - 它有效。
string prog_path = @"C:\Windows\System32\SystemPropertiesPerformance.exe";
Process process = new Process();
process.StartInfo.FileName = prog_path;
process.StartInfo.CreateNoWindow = true; // no need for that, but I tried with it and without it just in case it works
process.StartInfo.UseShellExecute = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.Start();
根據 Microsoft 文檔,您需要將UseShellExecute
設置為true
才能使用StartInfo.WindowStyle = ProcessWindowStyle.Hidden
(我這樣做了),但程序仍然可以選擇忽略它。 看起來這正是那里發生的事情。 但是我試圖通過 Spy++ 獲取 exec 窗口句柄並嘗試隱藏它 - 它有效,所以我可以從那里操縱它並做我的事情。 唯一的問題是找到它的句柄......
在這種情況下我如何找到那個句柄?
聚苯乙烯
對我來說,這個工作正常(在 Windows 7 上):
using System;
using System.Diagnostics;
using System.Text;
using System.Runtime.InteropServices;
namespace findwindow
{
class Program
{
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
public static void Main(string[] args)
{
Process.Start(new ProcessStartInfo(){FileName=@"C:\Windows\System32\SystemPropertiesPerformance.exe"});
System.Threading.Thread.Sleep(100);
IntPtr hwnd = FindWindow("#32770", "Параметры быстродействия");
var sb = new StringBuilder(50);
GetWindowText(hwnd, sb, 49);
Console.WriteLine("hwnd:"+hwnd+", title:"+sb);
Console.ReadKey(true);
}
}
}
輸出:
hwnd:5636204, title:Параметры быстродействия
嘗試使用該代碼您的標題,然后說它是否有效。
還有一種不同的方法,如這個答案。
另一種方法是使用 Windows 內置的UI 自動化技術。 例如,這個示例控制台應用程序應該可以工作。 並且因為它是基於事件的,所以它不需要使用可以依賴於上下文的計時器:
public static void Main(string[] args)
{
Automation.AddAutomationEventHandler(WindowPattern.WindowOpenedEvent, AutomationElement.RootElement, TreeScope.Children, (sender, e) =>
{
var element = sender as AutomationElement;
if (element.Current.Name == "Параметры быстродействия")
{
Console.WriteLine("hwnd:" + element.Current.NativeWindowHandle);
}
});
Process.Start("SystemPropertiesPerformance.exe");
Console.ReadLine(); // wait ...
Automation.RemoveAllEventHandlers(); // cleanup
}
它在我的 Windows 10 x64 機器上運行良好。 如果這不起作用,請確保您的程序和 SystemPropertiesPerformance.exe 在相同的UAC 級別運行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.