您的位置:首页 > 编程语言 > C#

C#中用WinAPI调用外部程序

2012-02-17 21:56 274 查看
使用别人的程序时,我们常发现一些好的功能,想通过自己的程序来重复调用。可偏偏这个程序没有留可编程接口,无法通过API、DLL、COM等方式实现调用。早些年与同仁们讨论时,常对此深表遗憾。最近,通过研究Windows API的使用方法,终于从理论上解决了这一问题,即可通WinAPI中SendMessage、EnumChildWindows等,从模拟操作的角度来调用指定程序的指定功能。

我们知道,Windows是消息驱动的,即Windows窗口、控件的任何操作,都是通过消息事件来完成的。从理论上讲,在我们自己的程序中,只要能准确地找到相应功能所在的窗口或控件的句柄Handle,发出相应的消息,即可完成相应任务。从这个层面上,这种技术可以应用在所有windows程序上。只是这种技术的处理,需要非常细心。因为在实际应用中,从某一个程序中找到相应的控件(包括Parent/Child/Next等)还是比较麻琐的,一不小心,调用的功能就实法实现,还有可能导致程序甚至系统的崩溃。所以,这种技术的关键在于两个地方:一是找准句柄,二是找对消息。

推荐分析一个窗体(控件)的句柄或消息的工具:SPY++,这在Visual Studio Tools中有,操作起来很简单。



C#中实现外部程序调用,可以通过封装User32.dll中sendmessage等函数来实现。我已将常用的功能封装成一个类:

using System;

using System.Collections.Generic;

using System.Text;

using System.Runtime.InteropServices;

namespace MuliCall

{

class WinApi

{

#region 宏定义

public const int WM_KEYDOWN = 0x100;

public const int WM_KEYUP = 0x101;

public const int VK_CONTROL = 0x11;

public const int VK_F5 = 0x74;

public const int KEYEVENTF_KEYUP = 0x2;

public const int VK_MENU = 0x12;

public const int WM_SETTEXT = 0xC;

public const int WM_CLEAR = 0x303;

public const int BN_CLICKED = 0;

public const int WM_LBUTTONDOWN = 0x201;

public const int WM_LBUTTONUP = 0x202;

public const int WM_CLOSE = 0x10;

public const int WM_COMMAND = 0x111;

public const int WM_SYSKEYDOWN = 0x104;

#endregion

public delegate bool EnumChildWindowsProc(IntPtr hwnd, int lParam);

#region WinAPI定义

[DllImport("User32.dll", EntryPoint = "SendMessage")]

public static extern int SendMessage(

int hWnd, // handle to destination window

int Msg, // message

int wParam, // first message parameter

int lParam // second message parameter

);

[DllImport("User32.dll", EntryPoint = "SendMessage")]

public static extern int SendTxtMessage(

int hWnd, // handle to destination window

int Msg, // message

int wParam, // first message parameter

char[] lParam

// int lParam // second message parameter

);

[DllImport("user32.dll", EntryPoint = "PostMessage")]

public static extern int PostMessage(

int hwnd,

int wMsg,

int wParam,

int lParam

);

[DllImport("user32.dll", EntryPoint = "FindWindow")]

public static extern int FindWindow(

string lpClassName,

string lpWindowName

);

[DllImport("user32.dll", EntryPoint = "FindWindowEx")]

public static extern int FindWindowEx(

int hwndParent,

int hwndChildAfter,

string lpszClass,

string lpszWindow

);

[DllImport("user32.dll", EntryPoint = "EnumChildWindows")]

public static extern int EnumChildWindows(

int hWndParent,

int lpEnumFunc,

int lParam

);

[DllImport("user32.dll", EntryPoint = "EnumChildWindows")]

public static extern int EnumChildWindows(

int hWndParent,

EnumChildWindowsProc lpEnumFunc,

int lParam

);

[DllImport("user32.dll", EntryPoint = "SetFocus")]

public static extern int SetFocus(

int hWnd

);

[DllImport("user32.dll", EntryPoint = "SetWindowText")]

public static extern int SetWindowText(

int hwnd,

string lpString

);

[DllImport("user32.dll", EntryPoint = "keybd_event")]

public static extern void keybd_event(

byte bVk,

byte bScan,

int dwFlags,

int dwExtraInfo

);

[DllImport("user32.dll", EntryPoint = "SetForegroundWindow")]

public static extern int SetForegroundWindow(

int hwnd

);

[DllImport("user32.dll", EntryPoint = "GetClassName")]

public static extern int GetClassName(

IntPtr hwnd,

StringBuilder lpClassName,

int nMaxCount

);

[DllImport("user32.dll", EntryPoint = "GetWindowText")]

public static extern int GetWindowText(

IntPtr hwnd,

StringBuilder lpString,

int cch

);

#endregion

//综合处理全局HWD

private static int CurrnetFormHandle = 0;

//综合处理函数

public static void SetCurrnetFormHandle(string strWindow)

{

SetCurrnetFormHandle(null, strWindow, false);

}

public static void SetCurrnetFormHandle(string strClass, string strWindow, bool beForeground)

{

CurrnetFormHandle = FindWindow(strClass, strWindow);

if (beForeground)

SetForegroundWindow(CurrnetFormHandle);

}

public static void SetCurrnetFormHandle(int hwd, bool beForeground)

{

CurrnetFormHandle = hwd;

if (beForeground)

SetForegroundWindow(CurrnetFormHandle);

}

public static void SetCurrnetFormHandle(int hwd)

{

CurrnetFormHandle = hwd;

}

public static int GetCurrentFormHandle()

{

return CurrnetFormHandle;

}

//模拟单击按钮

public static void ClickButton(string strWindow)

{

ClickButton("Button", strWindow);

}

public static void ClickButton(string strClass, string strWindow)

{

ClickButton(CurrnetFormHandle, 0, strClass, strWindow);

}

public static void ClickButton(int hwdParent, int hwndChildAfter, string strClass, string strWindow)

{

int hwdButton = FindWindowEx(hwdParent, hwndChildAfter, strClass, strWindow);

SendMessage(hwdButton, WM_LBUTTONDOWN, 0, 0);

SendMessage(hwdButton, WM_LBUTTONUP, 0, 0);

}

//修改文本框内容

public static void SetWindowsText(string Parnet_strClass, string Parnet_strText, string strClass, string strText)

{

int hwdParent = FindWindowEx(CurrnetFormHandle, 0, Parnet_strClass, Parnet_strText);

//停止 ThunderRT6OptionButton

int bntHwd = FindWindowEx(hwdParent, 0, "ThunderRT6OptionButton", "停止");

int hwdText = FindWindowEx(hwdParent, bntHwd, strClass, null); //ThunderRT6TextBox

SendTxtMessage(hwdText, WM_SETTEXT, 0, strText.ToCharArray());

}

public static void SetWindowsText(string strClass, string strText)

{

SetWindowsText(strClass, null, strText);

}

public static void SetWindowsText(string strClass, string strWindow, string strText)

{

SetWindowsText(CurrnetFormHandle, 0, strClass, strWindow, strText);

}

public static void SetWindowsText(int hwdParent, int hwndChildAfter, string strClass, string strWindow, string strText)

{

int hwdText = FindWindowEx(hwdParent, hwndChildAfter, strClass, strText);

SendTxtMessage(hwdText, WM_SETTEXT, 0, strText.ToCharArray());

}

//搜索子窗体

public static void SearchChild(string strWindow)

{

EnumChildWindowsProc myEnumChild = new EnumChildWindowsProc(EumWinChiPro);

try

{

EnumChildWindows(CurrnetFormHandle, myEnumChild, 0);

}

catch (Exception ex)

{

; // MessageBox.Show(ex.Message + "\r\n" + ex.Source + "\r\n\r\n" + ex.StackTrace.ToString());

}

}

public static bool EumWinChiPro(IntPtr hWnd, int lParam)

{

StringBuilder s = new StringBuilder(1256);

GetClassName(hWnd, s, 1257);

string ss = s.ToString();

if (ss == null)

ss = "";

ss = ss.Trim();

// MessageBox.Show(ss);

// ThunderRT6TextBox

StringBuilder s2 = new StringBuilder(1256);

GetWindowText(hWnd, s2, 1257);

ss = s2.ToString();

return true;

}

}

}

使用这个类,在自己的程序中,比较方便地实现外部程序的调用。

int hwnd = (int) MainHandlArray[i];

WinApi.SetCurrnetFormHandle(hwnd);

WinApi.SetWindowsText(textBox_Class_EditPanel.Text,

textBox_Title_EditPanel.ToString(), textBox_Class_Edit.Text, textBoxWorkID.Text);

使用这种方法,我写个程序多开器,主要实现启动多个实例,能给EDIT框付值,能定时调用其中按钮。

C#中实现外部程序调用,可以通过封装User32.dll中sendmessage等函数来实现。我已将常用的功能封装成一个类:

using System;

using System.Collections.Generic;

using System.Text;

using System.Runtime.InteropServices;

namespace MuliCall

{

class WinApi

{

#region 宏定义

public const int WM_KEYDOWN = 0x100;

public const int WM_KEYUP = 0x101;

public const int VK_CONTROL = 0x11;

public const int VK_F5 = 0x74;

public const int KEYEVENTF_KEYUP = 0x2;

public const int VK_MENU = 0x12;

public const int WM_SETTEXT = 0xC;

public const int WM_CLEAR = 0x303;

public const int BN_CLICKED = 0;

public const int WM_LBUTTONDOWN = 0x201;

public const int WM_LBUTTONUP = 0x202;

public const int WM_CLOSE = 0x10;

public const int WM_COMMAND = 0x111;

public const int WM_SYSKEYDOWN = 0x104;

#endregion

public delegate bool EnumChildWindowsProc(IntPtr hwnd, int lParam);

#region WinAPI定义

[DllImport("User32.dll", EntryPoint = "SendMessage")]

public static extern int SendMessage(

int hWnd, // handle to destination window

int Msg, // message

int wParam, // first message parameter

int lParam // second message parameter

);

[DllImport("User32.dll", EntryPoint = "SendMessage")]

public static extern int SendTxtMessage(

int hWnd, // handle to destination window

int Msg, // message

int wParam, // first message parameter

char[] lParam

// int lParam // second message parameter

);

[DllImport("user32.dll", EntryPoint = "PostMessage")]

public static extern int PostMessage(

int hwnd,

int wMsg,

int wParam,

int lParam

);

[DllImport("user32.dll", EntryPoint = "FindWindow")]

public static extern int FindWindow(

string lpClassName,

string lpWindowName

);

[DllImport("user32.dll", EntryPoint = "FindWindowEx")]

public static extern int FindWindowEx(

int hwndParent,

int hwndChildAfter,

string lpszClass,

string lpszWindow

);

[DllImport("user32.dll", EntryPoint = "EnumChildWindows")]

public static extern int EnumChildWindows(

int hWndParent,

int lpEnumFunc,

int lParam

);

[DllImport("user32.dll", EntryPoint = "EnumChildWindows")]

public static extern int EnumChildWindows(

int hWndParent,

EnumChildWindowsProc lpEnumFunc,

int lParam

);

[DllImport("user32.dll", EntryPoint = "SetFocus")]

public static extern int SetFocus(

int hWnd

);

[DllImport("user32.dll", EntryPoint = "SetWindowText")]

public static extern int SetWindowText(

int hwnd,

string lpString

);

[DllImport("user32.dll", EntryPoint = "keybd_event")]

public static extern void keybd_event(

byte bVk,

byte bScan,

int dwFlags,

int dwExtraInfo

);

[DllImport("user32.dll", EntryPoint = "SetForegroundWindow")]

public static extern int SetForegroundWindow(

int hwnd

);

[DllImport("user32.dll", EntryPoint = "GetClassName")]

public static extern int GetClassName(

IntPtr hwnd,

StringBuilder lpClassName,

int nMaxCount

);

[DllImport("user32.dll", EntryPoint = "GetWindowText")]

public static extern int GetWindowText(

IntPtr hwnd,

StringBuilder lpString,

int cch

);

#endregion

//综合处理全局HWD

private static int CurrnetFormHandle = 0;

//综合处理函数

public static void SetCurrnetFormHandle(string strWindow)

{

SetCurrnetFormHandle(null, strWindow, false);

}

public static void SetCurrnetFormHandle(string strClass, string strWindow, bool beForeground)

{

CurrnetFormHandle = FindWindow(strClass, strWindow);

if (beForeground)

SetForegroundWindow(CurrnetFormHandle);

}

public static void SetCurrnetFormHandle(int hwd, bool beForeground)

{

CurrnetFormHandle = hwd;

if (beForeground)

SetForegroundWindow(CurrnetFormHandle);

}

public static void SetCurrnetFormHandle(int hwd)

{

CurrnetFormHandle = hwd;

}

public static int GetCurrentFormHandle()

{

return CurrnetFormHandle;

}

//模拟单击按钮

public static void ClickButton(string strWindow)

{

ClickButton("Button", strWindow);

}

public static void ClickButton(string strClass, string strWindow)

{

ClickButton(CurrnetFormHandle, 0, strClass, strWindow);

}

public static void ClickButton(int hwdParent, int hwndChildAfter, string strClass, string strWindow)

{

int hwdButton = FindWindowEx(hwdParent, hwndChildAfter, strClass, strWindow);

SendMessage(hwdButton, WM_LBUTTONDOWN, 0, 0);

SendMessage(hwdButton, WM_LBUTTONUP, 0, 0);

}

//修改文本框内容

public static void SetWindowsText(string Parnet_strClass, string Parnet_strText, string strClass, string strText)

{

int hwdParent = FindWindowEx(CurrnetFormHandle, 0, Parnet_strClass, Parnet_strText);

//停止 ThunderRT6OptionButton

int bntHwd = FindWindowEx(hwdParent, 0, "ThunderRT6OptionButton", "停止");

int hwdText = FindWindowEx(hwdParent, bntHwd, strClass, null); //ThunderRT6TextBox

SendTxtMessage(hwdText, WM_SETTEXT, 0, strText.ToCharArray());

}

public static void SetWindowsText(string strClass, string strText)

{

SetWindowsText(strClass, null, strText);

}

public static void SetWindowsText(string strClass, string strWindow, string strText)

{

SetWindowsText(CurrnetFormHandle, 0, strClass, strWindow, strText);

}

public static void SetWindowsText(int hwdParent, int hwndChildAfter, string strClass, string strWindow, string strText)

{

int hwdText = FindWindowEx(hwdParent, hwndChildAfter, strClass, strText);

SendTxtMessage(hwdText, WM_SETTEXT, 0, strText.ToCharArray());

}

//搜索子窗体

public static void SearchChild(string strWindow)

{

EnumChildWindowsProc myEnumChild = new EnumChildWindowsProc(EumWinChiPro);

try

{

EnumChildWindows(CurrnetFormHandle, myEnumChild, 0);

}

catch (Exception ex)

{

; // MessageBox.Show(ex.Message + "\r\n" + ex.Source + "\r\n\r\n" + ex.StackTrace.ToString());

}

}

public static bool EumWinChiPro(IntPtr hWnd, int lParam)

{

StringBuilder s = new StringBuilder(1256);

GetClassName(hWnd, s, 1257);

string ss = s.ToString();

if (ss == null)

ss = "";

ss = ss.Trim();

// MessageBox.Show(ss);

// ThunderRT6TextBox

StringBuilder s2 = new StringBuilder(1256);

GetWindowText(hWnd, s2, 1257);

ss = s2.ToString();

return true;

}

}

}

使用这个类,在自己的程序中,比较方便地实现外部程序的调用。

int hwnd = (int) MainHandlArray[i];

WinApi.SetCurrnetFormHandle(hwnd);

WinApi.SetWindowsText(textBox_Class_EditPanel.Text,

textBox_Title_EditPanel.ToString(), textBox_Class_Edit.Text, textBoxWorkID.Text);

使用这种方法,我写个程序多开器,主要实现启动多个实例,能给EDIT框付值,能定时调用其中按钮。

C#中实现外部程序调用,可以通过封装User32.dll中sendmessage等函数来实现。我已将常用的功能封装成一个类:

using System;

using System.Collections.Generic;

using System.Text;

using System.Runtime.InteropServices;

namespace MuliCall

{

class WinApi

{

#region 宏定义

public const int WM_KEYDOWN = 0x100;

public const int WM_KEYUP = 0x101;

public const int VK_CONTROL = 0x11;

public const int VK_F5 = 0x74;

public const int KEYEVENTF_KEYUP = 0x2;

public const int VK_MENU = 0x12;

public const int WM_SETTEXT = 0xC;

public const int WM_CLEAR = 0x303;

public const int BN_CLICKED = 0;

public const int WM_LBUTTONDOWN = 0x201;

public const int WM_LBUTTONUP = 0x202;

public const int WM_CLOSE = 0x10;

public const int WM_COMMAND = 0x111;

public const int WM_SYSKEYDOWN = 0x104;

#endregion

public delegate bool EnumChildWindowsProc(IntPtr hwnd, int lParam);

#region WinAPI定义

[DllImport("User32.dll", EntryPoint = "SendMessage")]

public static extern int SendMessage(

int hWnd, // handle to destination window

int Msg, // message

int wParam, // first message parameter

int lParam // second message parameter

);

[DllImport("User32.dll", EntryPoint = "SendMessage")]

public static extern int SendTxtMessage(

int hWnd, // handle to destination window

int Msg, // message

int wParam, // first message parameter

char[] lParam

// int lParam // second message parameter

);

[DllImport("user32.dll", EntryPoint = "PostMessage")]

public static extern int PostMessage(

int hwnd,

int wMsg,

int wParam,

int lParam

);

[DllImport("user32.dll", EntryPoint = "FindWindow")]

public static extern int FindWindow(

string lpClassName,

string lpWindowName

);

[DllImport("user32.dll", EntryPoint = "FindWindowEx")]

public static extern int FindWindowEx(

int hwndParent,

int hwndChildAfter,

string lpszClass,

string lpszWindow

);

[DllImport("user32.dll", EntryPoint = "EnumChildWindows")]

public static extern int EnumChildWindows(

int hWndParent,

int lpEnumFunc,

int lParam

);

[DllImport("user32.dll", EntryPoint = "EnumChildWindows")]

public static extern int EnumChildWindows(

int hWndParent,

EnumChildWindowsProc lpEnumFunc,

int lParam

);

[DllImport("user32.dll", EntryPoint = "SetFocus")]

public static extern int SetFocus(

int hWnd

);

[DllImport("user32.dll", EntryPoint = "SetWindowText")]

public static extern int SetWindowText(

int hwnd,

string lpString

);

[DllImport("user32.dll", EntryPoint = "keybd_event")]

public static extern void keybd_event(

byte bVk,

byte bScan,

int dwFlags,

int dwExtraInfo

);

[DllImport("user32.dll", EntryPoint = "SetForegroundWindow")]

public static extern int SetForegroundWindow(

int hwnd

);

[DllImport("user32.dll", EntryPoint = "GetClassName")]

public static extern int GetClassName(

IntPtr hwnd,

StringBuilder lpClassName,

int nMaxCount

);

[DllImport("user32.dll", EntryPoint = "GetWindowText")]

public static extern int GetWindowText(

IntPtr hwnd,

StringBuilder lpString,

int cch

);

#endregion

//综合处理全局HWD

private static int CurrnetFormHandle = 0;

//综合处理函数

public static void SetCurrnetFormHandle(string strWindow)

{

SetCurrnetFormHandle(null, strWindow, false);

}

public static void SetCurrnetFormHandle(string strClass, string strWindow, bool beForeground)

{

CurrnetFormHandle = FindWindow(strClass, strWindow);

if (beForeground)

SetForegroundWindow(CurrnetFormHandle);

}

public static void SetCurrnetFormHandle(int hwd, bool beForeground)

{

CurrnetFormHandle = hwd;

if (beForeground)

SetForegroundWindow(CurrnetFormHandle);

}

public static void SetCurrnetFormHandle(int hwd)

{

CurrnetFormHandle = hwd;

}

public static int GetCurrentFormHandle()

{

return CurrnetFormHandle;

}

//模拟单击按钮

public static void ClickButton(string strWindow)

{

ClickButton("Button", strWindow);

}

public static void ClickButton(string strClass, string strWindow)

{

ClickButton(CurrnetFormHandle, 0, strClass, strWindow);

}

public static void ClickButton(int hwdParent, int hwndChildAfter, string strClass, string strWindow)

{

int hwdButton = FindWindowEx(hwdParent, hwndChildAfter, strClass, strWindow);

SendMessage(hwdButton, WM_LBUTTONDOWN, 0, 0);

SendMessage(hwdButton, WM_LBUTTONUP, 0, 0);

}

//修改文本框内容

public static void SetWindowsText(string Parnet_strClass, string Parnet_strText, string strClass, string strText)

{

int hwdParent = FindWindowEx(CurrnetFormHandle, 0, Parnet_strClass, Parnet_strText);

//停止 ThunderRT6OptionButton

int bntHwd = FindWindowEx(hwdParent, 0, "ThunderRT6OptionButton", "停止");

int hwdText = FindWindowEx(hwdParent, bntHwd, strClass, null); //ThunderRT6TextBox

SendTxtMessage(hwdText, WM_SETTEXT, 0, strText.ToCharArray());

}

public static void SetWindowsText(string strClass, string strText)

{

SetWindowsText(strClass, null, strText);

}

public static void SetWindowsText(string strClass, string strWindow, string strText)

{

SetWindowsText(CurrnetFormHandle, 0, strClass, strWindow, strText);

}

public static void SetWindowsText(int hwdParent, int hwndChildAfter, string strClass, string strWindow, string strText)

{

int hwdText = FindWindowEx(hwdParent, hwndChildAfter, strClass, strText);

SendTxtMessage(hwdText, WM_SETTEXT, 0, strText.ToCharArray());

}

//搜索子窗体

public static void SearchChild(string strWindow)

{

EnumChildWindowsProc myEnumChild = new EnumChildWindowsProc(EumWinChiPro);

try

{

EnumChildWindows(CurrnetFormHandle, myEnumChild, 0);

}

catch (Exception ex)

{

; // MessageBox.Show(ex.Message + "\r\n" + ex.Source + "\r\n\r\n" + ex.StackTrace.ToString());

}

}

public static bool EumWinChiPro(IntPtr hWnd, int lParam)

{

StringBuilder s = new StringBuilder(1256);

GetClassName(hWnd, s, 1257);

string ss = s.ToString();

if (ss == null)

ss = "";

ss = ss.Trim();

// MessageBox.Show(ss);

// ThunderRT6TextBox

StringBuilder s2 = new StringBuilder(1256);

GetWindowText(hWnd, s2, 1257);

ss = s2.ToString();

return true;

}

}

}

使用这个类,在自己的程序中,比较方便地实现外部程序的调用。

int hwnd = (int) MainHandlArray[i];

WinApi.SetCurrnetFormHandle(hwnd);

WinApi.SetWindowsText(textBox_Class_EditPanel.Text,

textBox_Title_EditPanel.ToString(), textBox_Class_Edit.Text, textBoxWorkID.Text);

使用这种方法,我写个程序多开器,主要实现启动多个实例,能给EDIT框付值,能定时调用其中按钮。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: