C# en utilisant la fonction SendMessage, problème avec WM_COPYDATA
J'ai passé quelques jours (ou plus) en essayant d'obtenir que cela fonctionne.
L'application à la main est FTPRush
, et je sais qu'il existe une ligne de cmd application appelée rush_cmdline.exe
qui utilise SendMessage
pour envoyer des demandes de FTPRush
.
De débogage de l' rush_cmdline.exe
je peux voir lParam
, wParam
, Message
et hWnd
.
Mon code est comme suit (en utilisant la fonction SendMessage, pas 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);
Et j'en ai essayé un autre spécification également:
[DllImport("User32.dll", EntryPoint = "SendMessage")]
public static extern int SendMessage(int hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);
La poignée (hWnd
) n'est pas le problème, tant que cela fonctionne:
int ftprush = FindWindow("TfmRush", null);
ShowWindow(ftprush, 8);
Qui (je n'ai pas de pâte de la dllimport que ce n'est pas important ici. Laissez-moi savoir si vous souhaitez voir) apporte la fenêtre à l'avant. Aussi, j'ai vérifié par le débogage rush_cmdline.exe
. Si la poignée est la même.
Deux tentatives qui ne (silencieusement):
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);
Je m'attends au moins la 2ème solution, car elle correspond assez bien à ce: perl exemple
Toute l'illumination est GRANDEMENT apprécié!
Merci,
- Frank
Mise à JOUR:
string msg = "RushApp.FTP.Login('backup','',0);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);
";
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);
il prend en charge WM_COPYDATA. C'est celui utilisé dans le perl exemple, et c'est celui utilisé par
rush_cmdline.exe
.
OriginalL'auteur Frank | 2011-07-21
Vous devez vous connecter pour publier un commentaire.
Mon Définitions ont
Bien sûr, assurez-vous que str est terminée par nul "\0"
Sinon une définition donnée par PInvoke.NET est
Win32.SendMessage(ftprush, Win32.WM_COPYDATA, IntPtr.Zero, ref cds);
(ref)? J'ai mis à jour ma question. J'ai dû ajouter de ref pour la compiler. Ou ai-je raté quelque chose ici?Oui, je ne veux dire ref, j'ai fait une faute de frappe!
Je ne peux pas le faire fonctionner avec FTPRush, mais votre approche concorde avec ce que je m'attends, donc je suppose que c'est une erreur stupide de ma part. Réponse acceptée. Avez-vous, par hasard, un exemple de SendMessage je peux essayer? (ce qui demande, qui lParam)
Je l'utilise pour communiquer entre deux de mes propres programmes, l'une des différences est que j'ai mis le 3e paramètre pour le hwnd de la fenêtre de l'application source. Je le prends à l'aide de la solution stringbuilder n'aide pas
Je vais jeter un oeil au ftp rush ce soir et voir si je peux faire un exemple
OriginalL'auteur Bob Vale
L'ordre des arguments dans la COPYDATASTRUCT sont d'une importance cruciale, et Bob Vale la réponse est dans le bon ordre. http://msdn.microsoft.com/en-us/library/windows/desktop/ms649010(v=vs. 85).aspx Il doit être dans cet ordre:
Je n'ai pas eu le
MarshalAs(UnmanagedType.LPStr)] public string lpData
au travail. J'ai seulement eu à le faire fonctionner en faisant la gare de moi-même:OriginalL'auteur Bryce Wagner
Entre les 2 réponses ci-dessus j'ai bricolé un exemple de travail. Bryce Wagner classe fonctionne, j'ai donc ajouté une méthode à utiliser SendMessageTimeout pour envoyer les données. c'est une méthode statique, il vous suffit de l'appeler pour envoyer des données. Ce n'est pas vraiment mon travail, un peu de collage et de partage de retour.
Pour l'utiliser:
Qui utilise la valeur par défaut de 1 seconde de délai d'expiration.
OriginalL'auteur Wade Hatler