Use C # To call Windows API to communicate with other processes

Source: Internet
Author: User

 

Keywords:
C #, API, FindWindow, FindWindowEx, SendMessage, process, registry

Original Design:
To facilitate network management, the company uses IEEE 802.1X network access control, so that two logon passwords are required for each start-up, so I studied how to use C # To help me enter the second login password.

Design Philosophy:
Mainly by calling some methods in the Windows API, we use the FindWindow, findjavaswex, and SendMessage functions to traverse all the current Windows cyclically, find the target window and process, and enter the username and password and domain information stored in the specific location in the input box. Then, trigger the button event and exit the program.

Environment:
Developed in Windows 2000 Chinese version + sp4, VS.net 2003 Chinese Version
Passed the test in Windows 2000 Chinese Version

Program:

The code for designing this Form is omitted in detail.

 

 

To use the Win32 API, you must first introduce the following namespace:

Using System. Runtime. InteropServices;

In addition, process and registry are also required. Therefore, we need to introduce the following two namespaces:

Using System. Threading;
Using Microsoft. Win32;

The following code adds an API reference:

Dll Import # region Dll Import
 
[DllImport ("User32.dll", EntryPoint = "FindWindow")]
Private static extern IntPtr FindWindow (string lpClassName,
String lpWindowName );
 
[DllImport ("user32.dll", EntryPoint = "find1_wex")]
Private static extern IntPtr find1_wex (IntPtr hwndParent,
IntPtr hwndChildAfter, string lpszClass, string lpszWindow );
 
[DllImport ("User32.dll", EntryPoint = "SendMessage")]
Private static extern int SendMessage (IntPtr hWnd,
Int Msg, IntPtr wParam, string lParam );
 
# Endregion
 

These three methods are mainly used. I will not detail them here. Please refer to MSDN.

Required parameters:

Const int WM_GETTEXT = 0x000D;
Const int WM_SETTEXT = 0x000C;
Const int WM_CLICK = 0x00F5;
 

The specific meanings of these parameters should be known from the name, and these parameters can be found through the tool Spy ++ included in.

The following is the core part of the entire program. Find and operate the form:

SearchWindow # region SearchWindow
Private int SearchWindow ()
{
Int retval = 0; // Add a return value to determine whether the operation is successful
 
// The following parameters can be found using Spy ++.
String lpszParentClass = "#32770"; // Class Name of the entire window
String lpszParentWindow = "Local Connection"; // window title
String lpszClass = "Edit"; // Class Name of the subwindow to be searched, that is, the input box
String lpszClass_Submit = "Button"; // The Class Name of the Button to be searched
String lpszName_Submit = "OK"; // the title of the Button to be searched
String text = "";
 
IntPtr ParenthWnd = new IntPtr (0 );
IntPtr EdithWnd = new IntPtr (0 );
 
// Check the form to obtain the entire form
ParenthWnd = FindWindow (lpszParentClass, lpszParentWindow );
 
// Determine whether the form is valid
If (! ParenthWnd. Equals (IntPtr. Zero ))
{
// Obtain the subform "User Name" and set its content
EdithWnd = find1_wex (ParenthWnd, EdithWnd, lpszClass ,"");
If (! EdithWnd. Equals (IntPtr. Zero ))
{
Text = this. tbUserName. Text. Trim ();
// Call the SendMessage method to set its content
SendMessage (EdithWnd, WM_SETTEXT, (IntPtr) 0, text );
Retval ++;
}
 
// Obtain the Password subform and set its content
EdithWnd = find1_wex (ParenthWnd, EdithWnd, lpszClass ,"");
If (! EdithWnd. Equals (IntPtr. Zero ))
{
Text = this. tbPassword. Text. Trim ();
SendMessage (EdithWnd, WM_SETTEXT, (IntPtr) 0, text );
Retval ++;
}
 
// Obtain the subform of Domain and set its content
EdithWnd = find1_wex (ParenthWnd, EdithWnd, lpszClass ,"");
If (! EdithWnd. Equals (IntPtr. Zero ))
{
Text = this. tbDomain. Text. Trim ();
SendMessage (EdithWnd, WM_SETTEXT, (IntPtr) 0, text );
Retval ++;
}
 
// Obtain the Button subform and trigger its Click Event
EdithWnd = find1_wex (ParenthWnd,
EdithWnd, lpszClass_Submit, lpszName_Submit );
If (! EdithWnd. Equals (IntPtr. Zero ))
{
SendMessage (EdithWnd, WM_CLICK, (IntPtr) 0, "0 ");
Retval ++;
}
}
 
Return retval;
}
# Endregion
 

It should be noted that when there are several subforms with the same class names under a form, that is to say, if there are three input boxes, the class names in these three input boxes are all Edit, the search results are listed from top to bottom. At first, I didn't know what to do to separate different input boxes. Later, I had to try them one by one. I didn't expect it to be correct. (Is there any other way ?)

The above code is only applicable to the Chinese version of the operating system, because the names of the same form are different in different operating systems, and I do not have an English version of the system here, so there is no way to perform the test.

To avoid manual input, I need to save the information to a specific file. When the user runs the program for the first time, you only need to enter the information once, click Save, Save the information to a file, and then load the program itself into the system startup Item, in this way, the program can be started at the next boot, and then read information from the file to complete the following operations.

Select the path for storing the file:

 

 

Private string UserPro =
System. Environment. GetEnvironmentVariable ("USERPROFILE ");
Private string PATH = System. Environment. GetEnvironmentVariable ("USERPROFILE") + @ "Local SettingsAutoLog. ini ";
 

The event triggered when the user clicks the Save button:

Button Submit Click # region Button Submit Click
Private void btSubmit_Click (object sender, System. EventArgs e)
{
SaveData ();
}
 
Private void SaveData ()
{
Try
{
// Save Data
FileInfo obj = new FileInfo (PATH );
If (obj. Exists)
Obj. Delete ();
 
FileStream ofile = new FileStream (PATH, FileMode. Create );
// Hidden the file
File. SetAttributes (PATH, FileAttributes. Hidden );
StreamWriter sw = new StreamWriter (ofile );
// Write the username, password, and domain information into the file.
Sw. WriteLine (this. tbUserName. Text );
Sw. WriteLine (this. tbPassword. Text );
Sw. WriteLine (this. tbDomain. Text );
Sw. Flush ();
 
Sw. Close ();
Ofile. Close ();
 
// Copy the current file to the specified location and add it to the startup entry of the Registry.
String opath = Application. StartupPath + @ "Login.exe ";
String tpath = UserPro + @ "Local SettingsLogin.exe ";
If (File. Exists (tpath ))
File. Delete (tpath );
File. Copy (opath, tpath );
 
RegistryKey hklm = Registry. CurrentUser;
RegistryKey run =
Hklm. CreateSubKey (@ "SOFTWAREMicrosoftWindowsCurrentVersionRun ");
Run. SetValue ("AutoLogin", tpath );
 
// Exit the program
MessageBox. Show ("OK", "Information ",
MessageBoxButtons. OK, MessageBoxIcon. Information );
Application. Exit ();
}
Catch (Exception ex)
{
MessageBox. Show (ex. ToString (), "Error ",
MessageBoxButtons. OK, MessageBoxIcon. Error );
}
}
# Endregion
 

In this way, the program can read the stored information from the file for verification. The last thing to do is to open a separate process to execute the above SearchWindow method cyclically until the qualified window is found and verified successfully, and the process needs to start with the startup of the program.

We can add a method named LoadData In the constructor, and then perform the specific Read File Information and start process operations in this method.

Of course, first define this process:

Private Thread thread;

Then the LoadData method is used:

Load # region Load
 
Private void LoadData ()
{
// Load Data
FileStream ofile = new FileStream (PATH, FileMode. OpenOrCreate );
StreamReader sr = new StreamReader (ofile );
This. tbUserName. Text = sr. ReadLine ();
This. tbPassword. Text = sr. ReadLine ();

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.