我已经花了几天(或更长时间)来尝试使它生效。

当前的应用程序是FTPRush,我知道有一个名为rush_cmdline.exe的cmd行应用程序,它使用SendMessage将请求发送到FTPRush

通过调试rush_cmdline.exe,我可以看到lParamwParamMessagehWnd

我的代码如下(使用SendMessage,而不是SendMessageW):

[DllImport("User32.dll", EntryPoint = "FindWindow")]
public static extern Int32 FindWindow(String lpClassName, String lpWindowName);
[DllImport("USER32.DLL", EntryPoint= "SendMessage")]
public static extern IntPtr SendMessage(int hWnd, int Msg, int wParam, IntPtr lParam);

而且我还尝试了另一个规范:
[DllImport("User32.dll", EntryPoint = "SendMessage")]
public static extern int SendMessage(int hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);

句柄(hWnd)并不是问题,因为这可行:
int ftprush = FindWindow("TfmRush", null);
ShowWindow(ftprush, 8);

哪一个(我没有粘贴dllimport,因为它在这里并不重要。如果您希望看到它,请告诉我)将窗口移到最前面。另外,我通过调试rush_cmdline.exe进行了检查。因此手柄是相同的。

两次尝试均失败(无提示):
public const Int32 WM_COPYDATA = 0x4A;
string msg = "RushApp.FTP.Login('backup','',0); ";
// 1
byte[] array = Encoding.UTF8.GetBytes((string)msg);
int size = Marshal.SizeOf(array[0]) * array.Length + Marshal.SizeOf(array[0]);
IntPtr ptr = Marshal.AllocHGlobal(size);
Marshal.Copy(array, 0, ptr, array.Length);
Marshal.WriteByte(ptr, size - 1, 0);
SendMessage(ftprush, WM_COPYDATA, 0, ptr);

// 2
public struct COPYDATASTRUCT
{
   public IntPtr dwData;
   public int cbData;
   [MarshalAs(UnmanagedType.LPStr)]
   public string lpData;
}

COPYDATASTRUCT cds;
cds.dwData = (IntPtr)100;
cds.lpData = msg;
cds.cbData = sarr.Length + 1;
SendMessage(ftprush, WM_COPYDATA, 0, ref cds);

我希望至少第二个解决方案能起作用,因为它与此非常匹配:perl example

非常感谢任何启发!

谢谢,
  • 弗兰克

  • 更新:
    string msg = "RushApp.FTP.Login('backup','',0);\0";
    var cds = new COPYDATASTRUCT
    {
                dwData = new IntPtr(3),
                cbData = msg.Length + 1,
                lpData = msg
    };
    IntPtr ftprush = FindWindow("TfmRush", null);
    SendMessage(ftprush, WM_COPYDATA, IntPtr.Zero, ref cds);
    

    最佳答案

    我的定义有

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
    public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, ref COPYDATASTRUCT lParam);
    
    public struct COPYDATASTRUCT {
      public int cbData;
      public IntPtr dwData;
      [MarshalAs(UnmanagedType.LPStr)] public string lpData;
    }
    
    var cds = new Win32.COPYDATASTRUCT {
                                               dwData = new IntPtr(3),
                                               cbData = str.Length + 1,
                                               lpData = str
                                             };
    Win32.SendMessage(ftprush, Win32.WM_COPYDATA, IntPtr.Zero, ref cds);
    

    当然,请确保str为null终止的“\0”

    或者,由PInvoke.NET给出的定义是
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, StringBuilder lParam);
    //If you use '[Out] StringBuilder', initialize the string builder with proper length first.
    

    关于c# - C#使用SendMessage,WM_COPYDATA问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6779731/

    10-11 18:25