I've been spending a few days (or more) trying to get this to work.
The application at hand is FTPRush
, and I know there is a cmd line application called rush_cmdline.exe
which uses SendMessage
to send requests to FTPRush
.
From debugging the rush_cmdline.exe
I can see lParam
, wParam
, Message
and hWnd
.
My code is as follows (using SendMessage, not 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);
And I've tried a another specification also:
[DllImport("User32.dll", EntryPoint = "SendMessage")]
public static extern int SendMessage(int hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);
The handle (hWnd
) is not the problem, as this works:
int ftprush = FindWindow("TfmRush", null);
ShowWindow(ftprush, 8);
Which (I didn't paste the dllimport as it's not important here. Let me know if you wish to see it) brings the window to front. Also, I checked by debugging rush_cmdline.exe
. So the handle is the same.
Two attempts which both fail (silently):
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);
I would expect at least the 2nd solution to work, as it matches up pretty well with this: perl example
Any enlightenment is GREATLY appreciated!
Thanks,
UPDATE:
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);
My Definitions have
[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);
Of course, make sure that str is null terminated "\0"
Alternatively a definition given by PInvoke.NET is
[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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With