首页 > 代码库 > 利用COPYDATASTRUCT传递命令行参数给驻留内存的进程(SendMessage应用)
利用COPYDATASTRUCT传递命令行参数给驻留内存的进程(SendMessage应用)
我们知道Window进程之间通过API的SendMessage方法传递消息。但是方法参数lParam是Long型,那么如果传递一个字符串(譬如命令行参数)应该怎么办呢,甚至一个对象、结构呢。VB的发送接收需要通过传递指针实现(换言之是字符串的内存地址),下面总结VB方式、C#方式各自如何实现消息的发送与接收;各自是可以互换的,譬如C#发送的消息,VB窗口可以收到;相反亦可以。当然同种语言之间更加没问题了。
VB发送端 Form1.frm:
1 Option Explicit 2 3 Private Type COPYDATASTRUCT 4 dwData As Long 5 cbData As Long 6 lpData As Long 7 End Type 8 9 Private Const WM_COPYDATA = http://www.mamicode.com/&H4A10 11 Private Declare Function FindWindow Lib "user32" Alias _12 "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName _13 As String) As Long14 15 Private Declare Function SendMessage Lib "user32" Alias _16 "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal _17 wParam As Long, lParam As Any) As Long18 19 ‘Copies a block of memory from one location to another.20 Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _21 (hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long)22 23 Private Sub Command1_Click()24 Dim cds As COPYDATASTRUCT25 Dim ThWnd As Long26 Dim buf(1 To 255) As Byte27 Dim a As String, i As Long28 29 ‘ Get the hWnd of the target application30 ThWnd = FindWindow(vbNullString, "Target")31 a$ = "It Works on " & Format(Now, "yyyy-MM-dd HH:mm:ss") & " !"32 ‘ Copy the string into a byte array, converting it to ASCII33 Call CopyMemory(buf(1), ByVal a$, Len(a$))34 cds.dwData = http://www.mamicode.com/335 cds.cbData = http://www.mamicode.com/Len(a$) + 136 cds.lpData = http://www.mamicode.com/VarPtr(buf(1))37 i = SendMessage(ThWnd, WM_COPYDATA, Me.hwnd, cds)38 End Sub39 40 Private Sub Form_Load()41 ‘ This gives you visibility that the target app is running42 ‘ and you are pointing to the correct hWnd43 Me.Caption = Hex$(FindWindow(vbNullString, "Target"))44 End Sub
VB接收端
1。MsgHook.bas:
1 Option Explicit 2 3 Type COPYDATASTRUCT 4 dwData As Long 5 cbData As Long 6 lpData As Long 7 End Type 8 9 Public Const GWL_WNDPROC = (-4)10 Public Const WM_COPYDATA = http://www.mamicode.com/&H4A11 Global lpPrevWndProc As Long12 Global gHW As Long13 14 ‘Copies a block of memory from one location to another.15 Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _16 (hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long)17 18 Declare Function CallWindowProc Lib "user32" Alias _19 "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As _20 Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As _21 Long) As Long22 23 Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _24 (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As _25 Long) As Long26 27 Public Sub Hook()28 lpPrevWndProc = SetWindowLong(gHW, GWL_WNDPROC, _29 AddressOf WindowProc)30 Debug.Print lpPrevWndProc31 End Sub32 33 Public Sub Unhook()34 Dim temp As Long35 temp = SetWindowLong(gHW, GWL_WNDPROC, lpPrevWndProc)36 End Sub37 38 Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, _39 ByVal wParam As Long, ByVal lParam As Long) As Long40 If uMsg = WM_COPYDATA Then41 Call mySub(lParam)42 End If43 WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, lParam)44 End Function45 46 Sub mySub(lParam As Long)47 Dim cds As COPYDATASTRUCT48 Dim buf(1 To 255) As Byte49 Dim a As String50 51 Call CopyMemory(cds, ByVal lParam, Len(cds))52 53 Select Case cds.dwData54 Case 155 Debug.Print "got a 1"56 Case 257 Debug.Print "got a 2"58 Case 359 Call CopyMemory(buf(1), ByVal cds.lpData, cds.cbData)60 a$ = StrConv(buf, vbUnicode)61 a$ = Left$(a$, InStr(1, a$, Chr$(0)) - 1)62 Form1.Label1.Caption = a$63 End Select64 End Sub
2。Target.frm:
1 Option Explicit 2 3 Private Sub Form_Load() 4 gHW = Me.hwnd 5 Hook 6 Me.Caption = "Target" 7 Me.Show 8 Label1.Caption = Hex$(gHW) 9 End Sub10 11 Private Sub Form_Unload(Cancel As Integer)12 Unhook13 End Sub
C#的发送端:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Windows; 6 using System.Windows.Controls; 7 using System.Windows.Data; 8 using System.Windows.Documents; 9 using System.Windows.Input;10 using System.Windows.Media;11 using System.Windows.Media.Imaging;12 using System.Windows.Navigation;13 using System.Windows.Shapes;14 using System.Runtime.InteropServices;15 16 namespace CSMsgSender17 {18 /// <summary>19 /// MainWindow.xaml 的交互逻辑20 /// </summary>21 public partial class MainWindow : Window22 {23 public MainWindow()24 {25 InitializeComponent();26 }27 28 private void button1_Click(object sender, RoutedEventArgs e)29 {30 int hwnd = FindWindow(null, "Target");31 if (hwnd != 0)32 {33 string str = "It Works on " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " !";34 byte[] arr = System.Text.Encoding.Default.GetBytes(str);35 int len = arr.Length;36 COPYDATASTRUCT cdata;37 cdata.dwData = http://www.mamicode.com/3;38 cdata.lpData =http://www.mamicode.com/ str;39 cdata.cbData = http://www.mamicode.com/len + 1;40 SendMessage(hwnd, WM_COPYDATA, 10, ref cdata);41 }42 }43 44 [DllImport("User32.dll")]45 public static extern int SendMessage(int hwnd, int msg, int wParam, ref COPYDATASTRUCT lParam);46 [DllImport("User32.dll")]47 public static extern int FindWindow(string lpClassName, string lpWindowName);48 49 private const int WM_COPYDATA = http://www.mamicode.com/0x004A;50 public struct COPYDATASTRUCT51 {52 public int dwData;53 public int cbData;54 [MarshalAs(UnmanagedType.LPStr)]55 public string lpData;56 }57 }58 }
C#接收端:
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Windows.Forms; 9 using System.Runtime.InteropServices;10 11 namespace CSMsgReceiver12 {13 public partial class Form1 : Form14 {15 public Form1()16 {17 InitializeComponent();18 this.Text = "Target";19 }20 21 protected override void DefWndProc(ref Message m)22 {23 switch (m.Msg)24 {25 case WM_COPYDATA:26 COPYDATASTRUCT cdata = http://www.mamicode.com/new COPYDATASTRUCT();27 Type mytype = cdata.GetType();28 cdata =http://www.mamicode.com/ (COPYDATASTRUCT)m.GetLParam(mytype);29 this.textBox1.Text = cdata.lpData;30 break;31 default:32 base.DefWndProc(ref m);33 break;34 }35 }36 37 //WM_COPYDATA消息的主要目的是允许在进程间传递只读数据。38 private const int WM_COPYDATA = http://www.mamicode.com/0x004A;39 40 //Windows在通过WM_COPYDATA消息传递期间,不提供继承同步方式。41 //其中,WM_COPYDATA对应的十六进制数为0x004A42 public struct COPYDATASTRUCT43 {44 public int dwData;45 public int cbData;46 [MarshalAs(UnmanagedType.LPStr)]47 public string lpData;48 }49 }50 }
利用COPYDATASTRUCT传递命令行参数给驻留内存的进程(SendMessage应用)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。