我认为您应该找到另一种解决代理问题的方法,但是如果您仍然想使用显示和关闭对话框的技巧,我在这里有一个解决方案会有所帮助(我已经测试过)而您没有不得不用SendKeys
,感觉很不稳定。这是我的代码:
//You have to add these using first:
//using System.Runtime.InteropServices;
//using System.Threading;
//This is used to find a window
[DllImport("user32", CharSet=CharSet.Auto)]
private static extern IntPtr FindWindow(string className, string windowName);
//This is used to find Button in a window
[DllImport("user32")]
private static extern IntPtr FindWindowEx(IntPtr parent, IntPtr childAfter, string className, string windowName);
//This is to help you Click on a Button
[DllImport("user32")]
private static extern int SendMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam);
//---------------------------
//Here are our methods
//---------------------------
//This is used to Get handle of a Button of a Parent window by its Text
private IntPtr GetButton(IntPtr parent, string text)
{
return FindWindowEx(parent, IntPtr.Zero, "Button", text);
}
//This is used to Click on a Window (usually a Button) with its Handle passed in
private void ClickWindow(IntPtr hwnd)
{
SendMessage(hwnd, 0x201, IntPtr.Zero, IntPtr.Zero);
SendMessage(hwnd, 0x202, IntPtr.Zero, IntPtr.Zero);
}
//This is used to find the Local Area Network (LAN) Settings window
//This is called in a separate thread, because somehow the LAN settings window
//showing causes the main Form not-responding (we can't call anything in our main thread).
private void SearchForLanSettingsWindow()
{
int i = 0;
while (true)
{
Thread.Sleep(100);
IntPtr windowHandle = FindWindow(null,"Local Area Network (LAN) Settings");
if (windowHandle != IntPtr.Zero)
{
//Find the button OK, if you like, you can replace it with "Cancel",...
IntPtr button = GetButton(windowHandle, "OK");
//Click on that OK button to Close your Lan settings window
//You may want to research on the DestroyWindow or CloseWindow
//win32 api without having to click on a Button, but I think this should be better. It's up to you.
ClickWindow(button);
break;
}
i++;
if (i > 20)//timeout
{
break;
}
}
}
//And here is your code with my code appended
System.Diagnostics.ProcessStartInfo proc = new System.Diagnostics.ProcessStartInfo();
proc.FileName = @"C:\\Windows\\System32\\RunDll32.exe";
proc.Arguments = "shell32.dll,Control_RunDLL inetcpl.cpl,Internet,4";//open Internet Properties window
proc.UseShellExecute = false;
System.Diagnostics.Process.Start(proc);
Thread.Sleep(100);//Sleep to be sure the Window is really created
//Get the handle to the window "Internet Properties"
IntPtr mainHandle = FindWindow(null, "Internet Properties");
//Find the tab "Connections", this tab has class "#32770" and is a child window of the window "Internet Properties"
IntPtr child = FindWindowEx(mainHandle, IntPtr.Zero, "#32770", "Connections");
//Get the button "LAN settings"
IntPtr button = GetButton(child, "&LAN settings");
//Create new thread and start it to find the Lan settings window
//we have to do this now because for some reason, after the LAN settings window shows
//we can't call any code in our class.
new Thread(SearchForLanSettingsWindow).Start();
//Click on the LAN settings button to Show the LAN settings window
ClickWindow(button);
//Get the button OK on the window "Internet Properties"
button = GetButton(mainHandle, "OK");
//Click on that button to close the window "Internet Properties"
ClickWindow(button);
就这样。
我发现如果计算机安装了非英语语言,按钮OK, LAN settings
可能会有所不同。所以更好的解决方案是使用GetDlgItem()
从他们的 ID 中获取按钮。为此,您必须先导入该函数GetDlgItem()
:
[DllImport("user32")]
private static extern IntPtr GetDlgItem(IntPtr dlgHandle, int itemID);
我曾经Spy++
知道控制IDOK and LAN settings
是什么。is的控制ID和OK
is1
的控制 ID 。因此,要获取这些按钮的句柄,您可以使用以下代码:LAN settings
0x62C
IntPtr button = GetDlgItem(parent, 1);//OK button
button = GetDlgItem(parent, 0x62C);//LAN settings, remember that the dialog containing LAN settings button is Connections not the Internet Properties.
这是另一种使用 的解决方案Process.Kill()
,我不确定杀死它RunDll32.exe
是否可以,但如果可以,这将是另一种更清洁的解决方案:
//You have to add these using first:
//using System.Runtime.InteropServices;
//using System.Diagnostics;
//using System.Threading;
//This is used to find a window
[DllImport("user32", CharSet=CharSet.Auto)]
private static extern IntPtr FindWindow(string className, string windowName);
[DllImport("user32")]
private static extern IntPtr FindWindowEx(IntPtr parent, IntPtr childAfter, string className, string windowName);
//This is to help you Click on a Button
[DllImport("user32")]
private static extern int SendMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam);
//This is used to get a Button (as an item) on a dialog
[DllImport("user32")]
private static extern IntPtr GetDlgItem(IntPtr dlgHandle, int itemID);
//---------------------------
//Here are our methods
//---------------------------
//This is used to Click on a Window (usually a Button) with its Handle passed in
private void ClickWindow(IntPtr hwnd)
{
SendMessage(hwnd, 0x201, IntPtr.Zero, IntPtr.Zero);
SendMessage(hwnd, 0x202, IntPtr.Zero, IntPtr.Zero);
}
//This is used to find the Local Area Network (LAN) Settings window
//This is called in a separate thread, because somehow the LAN settings window
//showing causes the main Form not-responding (we can't call anything in our main thread).
private void SearchForLanSettingsWindow()
{
int i = 0;
while (i < 20)
{
Thread.Sleep(100);
IntPtr windowHandle = FindWindow(null,"Local Area Network (LAN) Settings");
if (windowHandle != IntPtr.Zero)
{
if(runDll32 != null) runDll32.Kill();
break;
}
i++;
}
}
//the Process RunDll32
Process runDll32;
//And here is your code with my code appended
ProcessStartInfo proc = new ProcessStartInfo();
proc.FileName = @"C:\\Windows\\System32\\RunDll32.exe";
proc.Arguments = "shell32.dll,Control_RunDLL inetcpl.cpl,Internet,4";//open Internet Properties window
proc.UseShellExecute = false;
runDll32 = Process.Start(proc);
Thread.Sleep(100);//Sleep to be sure the Window is really created
//Get the handle to the window "Internet Properties"
IntPtr mainHandle = FindWindow(null, "Internet Properties");
//Find the tab "Connections", this tab has class "#32770" and is a child window of the window "Internet Properties"
IntPtr child = FindWindowEx(mainHandle, IntPtr.Zero, "#32770", "Connections");
//Get the button "LAN settings"
IntPtr button = GetDlgItem(child, 0x62C);
//Create new thread and start it to find the Lan settings window
//we have to do this now because for some reason, after the LAN settings window shows
//we can't call any code in our class.
new Thread(SearchForLanSettingsWindow).Start();
//Click on the LAN settings button to Show the LAN settings window
ClickWindow(button);
同样,我认为,您应该找到另一种解决方案来做您最初想做的事情。这种解决方案只是一个技巧。您可能想使用MoveWindow
win32 功能将所有对话框移出屏幕。
PS: này, em làm (hay vẫn đang học?) trong ngành tin thật à? Ở đâu vậy? 几岁?很高兴在 stack over flow 上认识你 :)