0
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

I've tried many way to hide/ close "Internet Properties window" and Lan Setting Window after it's called, but this code doesn't work. Help me !

nawfal
  • 70,104
  • 56
  • 326
  • 368
vyclarks
  • 854
  • 2
  • 15
  • 39
  • 2
    Can you give us some background on what is this code supposed to do, and in what way it doesn't work? – argaz Jun 15 '13 at 14:41
  • Oh dear! I've changed proxy already, after that, open the Internet Properties window and Lan Setting window to see that change, And now all the things I want is hide or close that windows by code. – vyclarks Jun 15 '13 at 15:01
  • I'm afraid that your question still isn't clear enough (I still can't understand what your actual goal is). I think you should just tell the whole story from start to end, include that you want to change the proxy settings and the other details. You might want to delete this question and repost it because of the downvotes. – argaz Jun 15 '13 at 15:40
  • How do you know the process doesn't change it's own window style after it's created? After all, it owns the window... You're not supposed to "hide" windows like that anyway. – Peter Ritchie Jun 15 '13 at 15:44
  • By the way, if your goal is to change the proxy you can do this in a better way. – argaz Jun 15 '13 at 15:55
  • I think the problem in this line: proc.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; ---> Actually the window is not hidden – vyclarks Jun 15 '13 at 15:58
  • @PeterRitchie: because the internet Properties Window still show up although I've used: "System.Diagnostics.ProcessWindowStyle.Hidden" – vyclarks Jun 15 '13 at 16:00
  • @argaz: Thanks dear! I've changed proxy perfectly already. That code is just order to show The Internet Properties up – vyclarks Jun 15 '13 at 16:02
  • Why do you need to open Internet Propeties (as a hidden window)? – argaz Jun 15 '13 at 16:09
  • @argaz it's a long story, it involves the previous question (also the first one in SO) of hers. :) – King King Jun 15 '13 at 17:32
  • Này em ơi, xem cái solution của anh mà dùng tạm đi, thực ra cái Process ấy là "RunDll32.exe" mà cái này thì nó ẩn mặc định rồi, cái cửa sổ kia hình như chỉ là cửa sổ phụ của RunDll32.exe thôi, vì vậy khó mà ẩn theo như cách của em được. – King King Jun 15 '13 at 17:40
  • @vyclarks my point is the app can change its WindowSytle any time it feels like--you can only do it when you invoke this app. You've got an inherent problem you can't get around. – Peter Ritchie Jun 15 '13 at 17:47
  • You'll never get anything you start through rundll32.exe hidden, it is not how the program works. Intentionally hiding that dialog is not you doing the user a favor btw. – Hans Passant Jun 15 '13 at 18:03
  • @KingKing dạ :(, tại em muốn làm 1 chương trình tự động trên nhiều máy, nên em nghĩ cần thiết để nó tự mở và tự tắt, vì auto thì làm gì có ai đi nhấn nút close của window đó, em sẽ thử – vyclarks Jun 16 '13 at 06:28
  • @KingKing anh ơi, vậy liệu rằng em có thể open window đó, sau đó hẹn delay 1 khoảng thời gian và exit window đó không? Em nghĩ như vậy nhưng em thử hoài cũng viết k đúng – vyclarks Jun 16 '13 at 06:30
  • @vyclarks delay thì cứ dùng `System.Threading.Thread.Sleep(...)` đúng chỗ là được mà. – King King Jun 16 '13 at 06:49

1 Answers1

1

I think you should find another way to play with your proxy problem, but if you still want to use the trick which plays with showing and closing dialogs, I have a solution here which would help (I've tested) and you don't have to use SendKeys which I feel very unstable. Here is my code:

//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);

And that's all.

I've found that if the computer is installed with a non-English language, the Buttons OK, LAN settings may be different. So the better solution is to use GetDlgItem() to get the buttons from their IDs. To do so, you have to import the function GetDlgItem() first:

[DllImport("user32")]
private static extern IntPtr GetDlgItem(IntPtr dlgHandle, int itemID);

I used Spy++ to know what the control ids of OK and LAN settings are. The control ID of OK is 1 and the control ID of LAN settings is 0x62C. So to get the handles of those buttons you can use this code:

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.

Here is another solution using Process.Kill(), I'm not sure if killing the RunDll32.exe will be OK, but if it's OK this will be another solution which is even cleaner:

//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);

Again, I think, you should find another solution to do what you want originally. This kind of solution is just a trick. You may want to use MoveWindow win32 function to move all the dialogs out of the screen.

PS: này, em làm (hay vẫn đang học?) trong ngành tin thật à? Ở đâu vậy? How old? nice to meet you on stack over flow :)

King King
  • 61,710
  • 16
  • 105
  • 130
  • 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 đó ^^ Nice to meet you too! And Thank you so much – vyclarks Jun 16 '13 at 06:41
  • 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 :) – King King Jun 16 '13 at 06:52
  • 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 – vyclarks Jun 16 '13 at 07:09
  • Có Reference đặc biệt gì đâu, em thêm using `System.Runtime.InteropServices` chưa? anh nói ngay ở đầu đấy. – King King Jun 16 '13 at 07:10
  • em thêm rồi mà sao nó vẫn báo Error 1 The name 'SendMessage' does not exist in the current context C:\Users\Vy\documents\visual studio 2010\Projects\Proxy\Proxy\Form1.cs 43 13 Proxy – vyclarks Jun 16 '13 at 07:11
  • mấy cái dòng khai báo hàm win32 api thôi mà, cứ copy code của anh là được, hay là chưa khai báo gì đã dùng ngay à? cái khai báo `[DllImport("user32")]...` đấy – King King Jun 16 '13 at 07:14
  • Em copy hết khúc code của anh luôn rồi đó ạ, hic, lỗi gì ta, huhu – vyclarks Jun 16 '13 at 07:16
  • hay là gửi cái demo đấy của em anh xem thử, chứ thế này thì chịu, không thì snapshot cũng được – King King Jun 16 '13 at 07:19
  • á anh ơi, em tìm ra lỗi của em rồi. Hì, phiền anh quá. Em cảm ơn anh nhiều lắm. Để em chạy thử đã. Thank a nhiều nhen :p – vyclarks Jun 16 '13 at 07:21
  • nhanh thế? :> có gì liên quan đến code của anh thì cứ hỏi, thực ra anh cũng chỉ biết mấy cái lặt vặt này thôi, còn phải học nhiều ... – King King Jun 16 '13 at 07:24
  • Thank you so much, again :p! It worked! Anh cho em hỏi chút nữa nhé,0x201 và 0x202 có trong lệnh Sendmessage của anh nghĩa là gì vậy anh. Và em tìm hiểu thì biết Spy++ là 1 chương trình quản lí các windown, process ID... anh cho em hỏi nó là 1 tool được tích hợp ở trong soft nào, hay là 1 soft riêng biệt vậy? – vyclarks Jun 16 '13 at 07:53
  • @vyclarks 0x201 là `WM_LBUTTONDOWN` và 0x202 là `WM_LBUTTONUP`, 2 cái message phím chuột ấy mà, down + up -> click. Còn cái `Spy++` là một công cụ đi kèm với Visual Studio em nhé, vào `Start -> All Programs -> Microsfot Visual Studio 20xx -> Visual Studio Tools` – King King Jun 16 '13 at 08:11
  • @vyclarks & KingKing: I'd recommend you stick to English next time. I'm sure, future visitors would be grateful to know what you're talking about, and I'm just as sure, that most don't understand Vietnamese (I know I don't). Besides, it's one of StackOverflow's rules, whether it's questions, answers or comments, they have to be in English. – Nolonar Jul 10 '13 at 12:14
  • @Nolonar I didn't know that rule, the conversation was between I and her personally so I didn't think other would have any involvement here. Moreover there is something we can't express best in English and we need to talk in our native language if possible to help each other. – King King Jul 10 '13 at 13:00
  • @KingKing As I said, I don't understand the conversation, but to me it looked like your answer didn't work out-of-the-box for her and she needed your assistance in the matter. If any new visitor encountered the same problem, he (or she) might find the result of your comments helpful. Me, I don't really care, but it would be sad if your comments were deleted by a moderator, just because they were not written in English. – Nolonar Jul 10 '13 at 13:05