0

目的是使用 winapi sendmessage 将消息从 vb.net 应用程序发送到另一个应用程序。我无法让它工作。非常感谢您的帮助

这是我所拥有的,但它似乎不起作用

Public Class WinAPI
    Private hwnd As Integer
    Private Declare Auto Function FindWindow Lib "user32" _
           (ByVal lpClassName As String, _
           ByVal lpWindowName As String) As IntPtr

    'FindWindowByClass
    Private Declare Auto Function FindWindow Lib "user32" _
             (ByVal lpClassName As String, _
             ByVal zero As IntPtr) As IntPtr

    'FindWindowByCaption
    Private Declare Auto Function FindWindow Lib "user32" _
             (ByVal zero As IntPtr, _
             ByVal lpWindowName As String) As IntPtr

    Private Declare Auto Function SendMessage Lib "user32" _
        (ByVal hWnd As IntPtr, _
         ByVal Msg As Integer, _
         ByVal wParam As IntPtr, _
         ByRef lParam As COPYDATASTRUCT) As Boolean

    Public Const WM_COPYDATA As Integer = &H4A

    <StructLayout(LayoutKind.Sequential)> _
    Structure COPYDATASTRUCT
        Dim dwData As Long
        Dim cbData As Long
        Dim lpData As IntPtr
    End Structure

    Public Sub SendToeSignal(ByVal strMessage As String)
        hwnd = FindWindow(vbNullString, "eSignalSink")
        ' hwnd = FindWindow("eSignalSink", "vbNullString")
        Dim DataStruct As New COPYDATASTRUCT
        ' strMessage = "1" & "," & strMessage & Chr(0) & vbCr 'Null terminated & carriage return
        strMessage = "1" & "," & strMessage & vbCr 'Null terminated & carriage return

        DataStruct.dwData = 1
        DataStruct.cbData = strMessage.Length * Marshal.SystemDefaultCharSize
        DataStruct.lpData = Marshal.StringToCoTaskMemAuto(strMessage)

        SendMessage(hwnd, WM_COPYDATA, 0, DataStruct)
        Marshal.FreeCoTaskMem(DataStruct.lpData)

    End Sub
End Class
4

2 回答 2

2

看起来你有一个 VB6 风格的定义,COPYDATASTRUCT 而不是你的 try this。

从上面的 PInvoke 链接:

<StructLayout(LayoutKind.Sequential)> _
Structure COPYDATASTRUCT 
   Public dwData As IntPtr
   Public cdData As Integer
   Public lpData As IntPtr
End Structure

首先,请帮自己一个忙,Option Strict特别是在使用 API 函数时启用。您正在您的应用程序之间发送一个结构,并且需要确保您可以在接收应用程序中检索它。我对您的示例代码进行了一些更改,它确实有效,在主窗体名为的测试程序中接收数据TestApp

您的修改示例

Option Strict On
Imports System.Runtime.InteropServices

Public Class Form1

    Public Sub New()

        ' This call is required by the designer.
        InitializeComponent()

        Dim myWinAPI As WinAPI = New WinAPI
        myWinAPI.SendToeSignal("Hello World")
        ' Add any initialization after the InitializeComponent() call.
    End Sub
End Class

Public Class WinAPI

    Private hwnd As IntPtr
    Private Declare Auto Function FindWindow Lib "user32" _
           (ByVal lpClassName As String, _
            ByVal lpWindowName As String) As IntPtr

    'FindWindowByClass
    Private Declare Auto Function FindWindow Lib "user32" _
           (ByVal lpClassName As String, _
            ByVal zero As IntPtr) As IntPtr

    'FindWindowByCaption
    Private Declare Auto Function FindWindow Lib "user32" _
           (ByVal zero As IntPtr, _
            ByVal lpWindowName As String) As IntPtr

    Private Declare Auto Function SendMessage Lib "user32" _
           (ByVal hWnd As IntPtr, _
            ByVal Msg As Integer, _
            ByVal wParam As IntPtr, _
            ByRef lParam As COPYDATASTRUCT) As Boolean

    Public Const WM_COPYDATA As Integer = &H4A

    <StructLayout(LayoutKind.Sequential)> _
    Structure COPYDATASTRUCT
        Dim dwData As IntPtr
        Dim cbData As Integer
        Dim lpData As IntPtr
    End Structure

    Public Sub SendToeSignal(ByVal strMessage As String)
        hwnd = FindWindow(IntPtr.Zero, "TestApp")
        Dim DataStruct As New COPYDATASTRUCT
        strMessage = "1" & "," & strMessage & vbCr 'Null terminated & carriage return

        DataStruct.dwData = CType(1, IntPtr)
        DataStruct.cbData = strMessage.Length * Marshal.SystemDefaultCharSize
        DataStruct.lpData = Marshal.StringToCoTaskMemAuto(strMessage)

        SendMessage(hwnd, WM_COPYDATA, IntPtr.Zero, DataStruct)
        Marshal.FreeCoTaskMem(DataStruct.lpData)

    End Sub

    Public Sub New()

    End Sub
End Class

接收申请

Imports System.Runtime.InteropServices
Imports System.Text

Public Class Form1
    <StructLayout(LayoutKind.Sequential)> _
    Structure COPYDATASTRUCT
        Dim dwData As IntPtr
        Dim cbData As Integer
        Dim lpData As IntPtr
    End Structure
    Public Const WM_COPYDATA As Integer = &H4A
    Dim split() As String = New String() {",", " "}
    Dim myData() As String

    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        MyBase.WndProc(m)
        If m.Msg = WM_COPYDATA Then
            Dim CD As COPYDATASTRUCT = DirectCast(m.GetLParam(GetType(COPYDATASTRUCT)), COPYDATASTRUCT)
            Dim B As Byte() = New Byte(CD.cbData - 1) {}
            Dim lpData As IntPtr = CD.lpData
            Marshal.Copy(lpData, B, 0, CD.cbData)
            Dim strData As String = Encoding.[Default].GetString(B)
            myData = strData.Split(split, StringSplitOptions.None)
        End If
    End Sub
End Class
于 2012-12-14T21:59:35.980 回答
0

感谢第一个几乎适用于我的应用程序的示例。接收器应用程序需要 ANSI ( WinAmp ) 中的字符串,所以我不得不更改该行:

DataStruct.lpData = Marshal.StringToCoTaskMemAuto(strMessage)

DataStruct.lpData = Marshal.StringToCoTaskMemAnsi(strMessage)

除此之外,它就像一个魅力,第一个示例正确地为 x64 - x32 获得了指针。只希望我在 24 小时任务中首先找到这个

赢 10. Visualstudio2017 vb.net

于 2018-01-15T21:45:22.060 回答