C # Call an API to send data to an external program

Source: Internet
Author: User

C # Call an API to send data to an external program

A project may be created recently. The project has such A function. After calling program B in program A and logging on to program, to automatically fill in the login name and password of program A to the Login Dialog Box of program B, so that program B does not need to enter the user name and password again, which simplifies the operations of the operator. Just recently I was idle, so I was wondering how to implement it. After two days of hard work, the above functions were basically completed. The following describes the implementation methods and processes.

I. Principles

To implement the above functions, you must call Win API. Win32 API is the Application Programming Interface on the Microsoft 32-bit platform ). All applications running on the Win32 platform can call these functions.

In the implementation process of this program, you need to use the following three API functions (function descriptions are all found online for your convenience) and a self-compiled FindWindowByIndex function.

1. static extern int SendMessage1 (IntPtr hwnd, uint wMsg, int wParam, int lParam );

As the name suggests, the SendMessage function is used to send a message to a specified object (such as an operating system, window, or control, to generate specific actions (such as scrolling and modifying the Object Appearance ).

The meanings and descriptions of the four independent variables are as follows:

HWnd: the handle of the object. If you want to send a message to an object, you can use the handle of the object as the real parameter.

WMsg: The sent message. Different messages are transmitted as real parameters based on specific requirements and different objects to produce the expected actions.

WParam and lParam: additional message information. These two are optional parameters used to provide more information about wMsg messages. Different wMsg may use 0, 1, or 2 of these two parameters. If no additional parameter is required, then, the real parameter is assigned NULL (0 in VB ).

2. public static extern IntPtr FindWindow (string className, string windowName );

The FindWindow function returns the window handle of the top-level window of the window class name or window name that matches the specified character creation. This function does not search for subwindows.

LpClassName: point to a string ending with null, used to specify the class name, or an atom that can determine the class name string. If this parameter is an atom, it must be a global atom that has been created through the GlobalAddAtom function before calling this function. This atom (a 16-bit value) must be placed in the low byte of the lpClassName, and the high byte of the lpClassName must be set to zero.

LpWindowName: a string that ends with null and is used to specify the window name (that is, the window title. If this parameter is NULL, all window names are matched.

Return Value: if the function is successfully executed, the return value is the handle of the window with the specified window class name or window name. If the function fails to be executed, the return value is NULL. You can call the GetLastError function to obtain more detailed error information.

3. static extern IntPtr find1_wex (IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow );

Find the first subwindow that matches the specified condition in the window list. The function obtains the handle of a window. The class name and window name of the window match the given string. This function searches for subwindows, starting from the next subwindow after the given subwindow. The search result is case insensitive.

HwndParent:SubwindowLocationParent window(If hwndParent is set, the Child Window is searched from the parent window pointed to by the hwndParent ). If hwndParent is 0, the function uses the desktop window as the parent window to find all child windows in the desktop window. Windows NT5.0 and later: If hwndParent is HWND_MESSAGE, the function only looks for all message Windows.

HwndChildAfter: the sub-window handle. The query starts from the next subwindow In the Z-order. The child window must be a direct Child Window of the hwndParent window, rather than a child window. If HwndChildAfter is NULL, search starts from the first subwindow of hwndParent. If both hwndParent and hwndChildAfter are NULL, the function searches for all top-level windows and message windows.

LpszClass: a pointer to an empty ending string that specifies the class name or a member that identifies the class name string. If this parameter is a member, it must be a global member generated by the previous call to the theGlobaIAddAtom function. This member is 16 bits, must be at the low 16 bits of the lpClassName, and the high bits must be 0.

PszWindow: point to an empty ending string that specifies the window name (window title. If this parameter is NULL, all windows are matched.

Return Value: Long, the handle of the window found. If no matching window is found, zero is returned. GetLastError is set. If the function is successful, the return value is a window handle with the specified class name and window name. If the function fails, the return value is NULL.

4. static IntPtr FindWindowByIndex (IntPtr hwndParent, int index)

This function uses an implicit index to find the corresponding control.

The source code of this function is as follows:

Static IntPtr FindWindowByIndex (IntPtr hwndParent, int index)

{

If (index = 0)

Return hwndParent;

Else

{

Int ct = 0;

IntPtr result = IntPtr. Zero;

Do

{

Result = find1_wex (hwndParent, result, null, null );

If (result! = IntPtr. Zero)

+ + Ct;

} While (ct <index & result! = IntPtr. Zero );

Return result;

}

}

Ii. API call method (Note: This text is excerpted from the Internet)

1. Use the corresponding namespace using System. Runtime. InteropServices;

2. Use the DllImportAttribute feature to introduce api functions. Note that empty methods are declared, that is, the method body is empty.

[DllImport ("user32.dll")]

Public static extern ReturnType FunctionName (type arg1, type arg2 ,...);

// There is no difference between calling and calling other methods

You can use fields to further describe features and separate them with commas, for example, [DllImport ("kernel32", EntryPoint = "GetVersionEx")]

The common fields of the DllImportAttribute feature are as follows:

1. CallingConvention indicates the CallingConvention value used to pass method parameters to an unmanaged implementation. CallingConvention. Cdecl: The caller clears the stack. It enables you to call functions with varargs. CallingConvention. StdCall: the called party clears the stack. It is the default convention for calling unmanaged functions from managed code.

2. CharSet controls the name version of the called function and indicates how to mail the String parameter to the method.

This field is set to one of the CharSet values. If the CharSet field is set to Unicode, all string parameters are converted to Unicode characters before being passed to an unmanaged implementation. This also causes the name of the DLL EntryPoint to be appended with the letter "W ". If this field is set to Ansi, the string is converted to an ANSI string and the name of the DLL EntryPoint is appended with the letter "". Most Win32 APIs use this APPEND "W" or "A" convention. If CharSet is set to Auto, the conversion is platform-related (Unicode on Windows NT and Ansi on Windows 98 ). The default value of CharSet is Ansi. The CharSet field is also used to determine which function version will be imported from the specified DLL. The name matching rules for CharSet. Ansi and CharSet. Unicode are very different. For Ansi, if EntryPoint is set to "MyMethod" and it exists, "MyMethod" is returned ". If the DLL does not contain "MyMethod", but "MyMethodA" exists, "MyMethodA" is returned ". The opposite is true for Unicode. If you set EntryPoint to "MyMethod" and it exists, "MyMethodW" is returned ". If "MyMethodW" does not exist in the DLL but "MyMethod" exists, "MyMethod" is returned ". If Auto is used, the matching rule is related to the platform (Unicode on Windows NT and Ansi on Windows 98 ). If ExactSpelling is set to true, "MyMethod" is returned only when "MyMethod" exists in the DLL ".

3. EntryPoint indicates the name or serial number of the DLL entry point to be called.

If you do not want the method name to be the same as the api function name, you must specify this parameter. For example:

[DllImport ("user32.dll", CharSet = "CharSet. Auto", EntryPoint = "MessageBox")]
Public static extern int MsgBox (IntPtrhWnd, string txt, string caption, int type );

4. ExactSpelling indicates whether to modify the name of the entry point in the unmanaged DLL to correspond to the CharSet value specified in the CharSet field. If this parameter is set to true, the parameter is set to DllImportAttribute. when the CharSet field is set to the Ansi value of CharSet, append the letter A to the method name, when DllImportAttribute. when the CharSet field is set to the Unicode value of CharSet, W is appended to the method name. The default value of this field is false.

5. PreserveSig indicates that the signature of the managed method should not be converted to an unmanaged signature that returns HRESULT and may have an additional [out, retval] parameter corresponding to the returned value.

6. SetLastError indicates that the called party will call the Win32 API SetLastError before returning the property method. True indicates that the caller calls SetLastError. The default value is false. GetLastError will be called by the mail collector during runtime and the returned value will be cached to prevent it from being overwritten by other API calls. You can call GetLastWin32Error to retrieve the error code.

3. program implementation process

Program A: Two text boxes and A start button. Two text boxes are used to enter the user name and password, and the start button is used to Start Program B.

Program B: Two text boxes used to accept the strings sent by program.

1. The code list of program A is as follows:

Using System. Runtime. InteropServices;

Using System. Threading;

 

Private staticSystem. Diagnostics. Process p;

[DllImport ("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet. Unicode)]

Static extern int SendMessage1 (IntPtrhwnd, uint wMsg, intwParam, int lParam );

[DllImport ("user32.dll", EntryPoint = "FindWindow", SetLastError = true, CallingConvention = CallingConvention. Winapi, CharSet = CharSet. Unicode)]

Public static extern IntPtrFindWindow (string className, string windowName );

[DllImport ("user32.dll", EntryPoint = "find?wex", CharSet = CharSet. Auto)]

Static extern IntPtr find1_wex (IntPtrhwndParent, IntPtr hwndChildAfter, string lpszClass, stringlpszWindow );

Static IntPtrFindWindowByIndex (IntPtr hwndParent, int index)

{

If (index = 0)

ReturnhwndParent;

Else

{

Intct = 0;

IntPtrresult = IntPtr. Zero;

Do

{

Result = find1_wex (hwndParent, result, null, null );

If (result! = IntPtr. Zero)

+ + Ct;

} While (ct <index & result! = IntPtr. Zero );

Returnresult;

}

}

2. startup button Event code

Privatevoid button4_Click (objectsender, EventArgs e)

{

If (p = null)

{

P = newSystem. Diagnostics. Process ();

P. StartInfo. FileName = "B Program Path ";

P. Start ();

// The thread must be suspended for a certain period of time; otherwise, the string cannot be sent automatically.

Thread. Sleep (500 );

 

IntPtrParenthWnd = new IntPtr (0 );

IntPtrpp = new IntPtr (0 );

IntPtrmwh = IntPtr. Zero;

// Obtain the window by the window title

ParenthWnd = FindWindow (null ,"******");

// Obtain the text edit box of program B through the index. Obtain the Control ID through the index, and then convert the ID to hexadecimal, compare with the view ID of Spy ++ to determine the control index.

IntPtrbutt = FindWindowByIndex (ParenthWnd, 5 );

UintWM_CHAR = 0x0102;

// SendMessage1 sends a string each time, so the complete user name is sent cyclically

Foreach (char c in this. textBox1.Text)

{

SendMessage1 (butt, WM_CHAR, c, 0 );

}

// Obtain the password input box

IntPtrbutt1 = FindWindowByIndex (ParenthWnd, 3 );

// Send the password

Foreach (char c in this. textBox2.Text)

{

SendMessage1 (butt1, WM_CHAR, c, 0 );

}

}

Else

{

If (p. HasExited) // whether it is running {

P. Start ();

}

}

3. program running result

 

After you click Start, in the second program (the previous one), you can directly obtain the user name and password sent by the first program.

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.