【问题标题】:StartInfo.WindowStyle = ProcessWindowStyle.Hidden is still not workingStartInfo.WindowStyle = ProcessWindowStyle.Hidden 仍然无法正常工作
【发布时间】:2013-06-15 14:36:33
【问题描述】:
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.WindowStyle = ProcessWindowStyle.Hidden;
proc.UseShellExecute = false;
proc.CreateNoWindow = true;
Process.Start(proc);
SendKeys.Send("{TAB}{TAB}{TAB}{TAB}{ENTER}");// Open Lan Setting window

我尝试了很多方法来隐藏/关闭“Internet 属性窗口”和 LAN 设置窗口,但此代码不起作用。 帮帮我!

【问题讨论】:

  • 你能给我们一些关于这段代码应该做什么以及它在什么方面不起作用的背景吗?
  • 天哪!我已经更改了代理,之后,打开 Internet 属性窗口和局域网设置窗口以查看更改,现在我想要的就是通过代码隐藏或关闭该窗口。
  • 恐怕你的问题还不够清楚(我还是不明白你的实际目标是什么)。我认为您应该从头到尾讲述整个故事,包括您要更改代理设置和其他细节。您可能想删除这个问题并重新发布它,因为它是反对票。
  • 你怎么知道进程在创建后不会改变它自己的窗口样式?毕竟,它拥有窗口......无论如何,你不应该像那样“隐藏”窗口。
  • 顺便说一句,如果您的目标是更改代理,您可以通过更好的方式来做到这一点。

标签: c# .net process processstartinfo


【解决方案1】:

我认为您应该找到另一种解决代理问题的方法,但是如果您仍想使用显示和关闭对话框的技巧,我在这里有一个解决方案可以帮助您(我已经测试过)并且您不必使用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++ 知道OK and LAN settings 的控件ID 是什么。 OK的控件ID为1LAN settings的控件ID为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 上认识你 :)

【讨论】:

  • Em đang học năm 4 Học viện Công Nghệ Bưu Chính Viễn Thông。 Em học ngành IT đó ^^ 也很高兴认识你!非常感谢你
  • hôm qua a ko vào được fb nên ko xem được, hôm nay mới vào đc thì xem hết rồi :)
  • anhơi, lệnh Sendmessage anh dùng reference nào ạ, em add hết những cái trên code của anh, tìm trên mạng nhưng vẫn k được
  • Có Reference đặc biệt gì đâu, em thêm using System.Runtime.InteropServices chưa? anh nói ngay ở đầu đấy。
  • em rồi mà sao nó vẫn báo 错误 1 ​​当前上下文中不存在名称“SendMessage” C:\Users\Vy\documents\visual studio 2010\Projects\Proxy\Proxy\Form1 .cs 43 13 代理
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-02
  • 1970-01-01
  • 2012-04-18
  • 2016-01-18
  • 2014-12-10
  • 2015-06-17
相关资源
最近更新 更多