Send String to another application(Un-managed) using C#
-
Hello Expert I am facing a a problem from couple of weeks but net getting solution for that The stuation is .. I am sending a string from one application(written in c#) to another application(written in C++) in same machine using WM_COPYDATA. It is going fine with windows xp but while i am trying to run on windows 7 machine its going blank string (c++ application received null value). can you please help me out to solved this issue, i am unable to understand what could be the reason I will appriciate your help Thanks & Regards Shafiq
-
Hello Expert I am facing a a problem from couple of weeks but net getting solution for that The stuation is .. I am sending a string from one application(written in c#) to another application(written in C++) in same machine using WM_COPYDATA. It is going fine with windows xp but while i am trying to run on windows 7 machine its going blank string (c++ application received null value). can you please help me out to solved this issue, i am unable to understand what could be the reason I will appriciate your help Thanks & Regards Shafiq
I think there might be many causes so, before trying an answer, I think I need some information: - Can you show us the line where you have imported SedMenssage function to your C# application? - Can you show us the code snippet where you call SendMessage function in your C# application? - Can you show us the code snippet where you handle the WM_COPYDATA message in your C++ application? Maybe this could help us to help you.
-
I think there might be many causes so, before trying an answer, I think I need some information: - Can you show us the line where you have imported SedMenssage function to your C# application? - Can you show us the code snippet where you call SendMessage function in your C# application? - Can you show us the code snippet where you handle the WM_COPYDATA message in your C++ application? Maybe this could help us to help you.
Hello Erik Here are my code C# code to send message... public const int WM_COPYDATA = 0x004a; [StructLayout(LayoutKind.Sequential)] public struct COPYDATASTRUCT { [MarshalAs(UnmanagedType.I4)] public int dwData; [MarshalAs(UnmanagedType.I4)] public int cbData; [MarshalAs(UnmanagedType.LPStr)] public string lpData; } string reqFiles ="Some value"; COPYDATASTRUCT data = new COPYDATASTRUCT(); data.dwData = 0; data.cbData = reqFiles.Length * 2; IntPtr lpStruct = Marshal.AllocHGlobal(Marshal.SizeOf(data)); Marshal.StructureToPtr(data, lpStruct, false); Process[] processes1 = Process.GetProcessesByName("ProcessID"); IntPtr hTarget = processes1[0].MainWindowHandle; SendMessage(hTarget, WM_COPYDATA, this.Handle, lpStruct); //-----------------This is to receive message in C++ ------------------------------------ LRESULT APIENTRY MAxSubclassProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg==WM_COPYDATA) { char str[256]; COPYDATASTRUCT *cds; cds=(COPYDATASTRUCT *)lParam; // receiving/handling message } } If anything needed pls let me know.. Please help me to run in windows 7 machine. Regards shafiq
-
Hello Erik Here are my code C# code to send message... public const int WM_COPYDATA = 0x004a; [StructLayout(LayoutKind.Sequential)] public struct COPYDATASTRUCT { [MarshalAs(UnmanagedType.I4)] public int dwData; [MarshalAs(UnmanagedType.I4)] public int cbData; [MarshalAs(UnmanagedType.LPStr)] public string lpData; } string reqFiles ="Some value"; COPYDATASTRUCT data = new COPYDATASTRUCT(); data.dwData = 0; data.cbData = reqFiles.Length * 2; IntPtr lpStruct = Marshal.AllocHGlobal(Marshal.SizeOf(data)); Marshal.StructureToPtr(data, lpStruct, false); Process[] processes1 = Process.GetProcessesByName("ProcessID"); IntPtr hTarget = processes1[0].MainWindowHandle; SendMessage(hTarget, WM_COPYDATA, this.Handle, lpStruct); //-----------------This is to receive message in C++ ------------------------------------ LRESULT APIENTRY MAxSubclassProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg==WM_COPYDATA) { char str[256]; COPYDATASTRUCT *cds; cds=(COPYDATASTRUCT *)lParam; // receiving/handling message } } If anything needed pls let me know.. Please help me to run in windows 7 machine. Regards shafiq
Ok. I think the problem is with your COPYDATASTRUCT. This is how it is declared in winuser.h:
typedef struct tagCOPYDATASTRUCT {
ULONG_PTR dwData;
DWORD cbData;
PVOID lpData;
} COPYDATASTRUCT, *PCOPYDATASTRUCT;And these are the lines which declare ULONG_PTR and DWORD data types:
typedef unsigned __int3264 ULONG_PTR;
typedef unsigned long DWORD, *PDWORD, *LPDWORD;So ULONG_PTR is like a 32 bit unsigned integer in a 32 bit platform and a 64 bit unsigned integer in a 64 bit platform, and DWORD is always a 32 bit unsigned integer. Nevertheless, you are using the int type and MarshalAs.UnmanagedType.I4 for both of them in your C# declaration, I mean, you treat both of them as 32 bit signed integer. It will usually work in a 32 bit platform (though it could fail), but it will usually fail in a 64 bit platform. In a 64 bit platform you should change the COPYDATASTRUCT declaration in your C# application like this:
StructLayout(LayoutKind.Sequential)]
public struct COPYDATASTRUCT
{
[MarshalAs(UnmanagedType.U8)]
public ulong dwData;
[MarshalAs(UnmanagedType.U4)]
public uint cbData;
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
}I am not sure if it would work in a 32 bit platform becouse I don't know if dwData value would be appropiately truncated. You can try and if it does not work on a 32 bit platform you will have to make two versions of the struct. In this case, the 32 bit version of the struct should be like this:
StructLayout(LayoutKind.Sequential)]
public struct COPYDATASTRUCT32
{
[MarshalAs(UnmanagedType.U4)]
public uint dwData;
[MarshalAs(UnmanagedType.U4)]
public uint cbData;
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
}You have the System.Environment class to know which platform you are using. If you are using 4.0 version of .NET you can use System.Environment.Is64BitOperatingSystem, and if you are using a previous version of .NET you will have to go a little deeper into System.Environment (OSVersion, Platform, etc.).
-
Ok. I think the problem is with your COPYDATASTRUCT. This is how it is declared in winuser.h:
typedef struct tagCOPYDATASTRUCT {
ULONG_PTR dwData;
DWORD cbData;
PVOID lpData;
} COPYDATASTRUCT, *PCOPYDATASTRUCT;And these are the lines which declare ULONG_PTR and DWORD data types:
typedef unsigned __int3264 ULONG_PTR;
typedef unsigned long DWORD, *PDWORD, *LPDWORD;So ULONG_PTR is like a 32 bit unsigned integer in a 32 bit platform and a 64 bit unsigned integer in a 64 bit platform, and DWORD is always a 32 bit unsigned integer. Nevertheless, you are using the int type and MarshalAs.UnmanagedType.I4 for both of them in your C# declaration, I mean, you treat both of them as 32 bit signed integer. It will usually work in a 32 bit platform (though it could fail), but it will usually fail in a 64 bit platform. In a 64 bit platform you should change the COPYDATASTRUCT declaration in your C# application like this:
StructLayout(LayoutKind.Sequential)]
public struct COPYDATASTRUCT
{
[MarshalAs(UnmanagedType.U8)]
public ulong dwData;
[MarshalAs(UnmanagedType.U4)]
public uint cbData;
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
}I am not sure if it would work in a 32 bit platform becouse I don't know if dwData value would be appropiately truncated. You can try and if it does not work on a 32 bit platform you will have to make two versions of the struct. In this case, the 32 bit version of the struct should be like this:
StructLayout(LayoutKind.Sequential)]
public struct COPYDATASTRUCT32
{
[MarshalAs(UnmanagedType.U4)]
public uint dwData;
[MarshalAs(UnmanagedType.U4)]
public uint cbData;
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
}You have the System.Environment class to know which platform you are using. If you are using 4.0 version of .NET you can use System.Environment.Is64BitOperatingSystem, and if you are using a previous version of .NET you will have to go a little deeper into System.Environment (OSVersion, Platform, etc.).
-
Hello Expert I am facing a a problem from couple of weeks but net getting solution for that The stuation is .. I am sending a string from one application(written in c#) to another application(written in C++) in same machine using WM_COPYDATA. It is going fine with windows xp but while i am trying to run on windows 7 machine its going blank string (c++ application received null value). can you please help me out to solved this issue, i am unable to understand what could be the reason I will appriciate your help Thanks & Regards Shafiq
I just finished writing my own library using WM_COPYDATA, and would happy to help you. I've learnt a few interesting things about WM_COPYDATA, like this: - It doesn't work across UAC, i.e. communicating processes must run in the same trust level for the messaging to work; - This messaging doesn't work for different bit platforms, i.e. communicating processes must be either 32-bit or 64-bit, no mix is supported. If you interested, my library allows easy communication with WM_COPYDATA for any .NET application ;)
Professional System Library on www.prosyslib.org