有没有办法将消息从C#.NET程序集(ActiveX)发送到VB6应用程序?

此问答指的是并且可以用于foll。 用途:

  1. 通过ActiveX dll从IE浏览器发送消息到vb6应用程序
  2. 从ActiveX DLL发送消息到vb6应用程序
  3. 将消息从C#.net(dll)发送到vb6应用程序

我读过这篇文章,但似乎并不十分清楚我的目的……

我还提到了这篇文章来创建ActiveX对象并实现了一个ActiveX dll,我从浏览器调用它来在客户端启动应用程序.dll检查VB6 exe(进程)是否正在运行,否则运行exe。 如果exe已经运行,那么我想将参数/消息传递给exe应用程序。

但我无法获得解决方案或参考样本来实现从此C#.NET程序集(ActiveX)向VB6应用程序发送消息的方法…我可以访问.NET和VB6应用程序的源代码。 ..

我尝试过使用: –

Process[] processes = Process.GetProcessesByName("MyProgram"); foreach (Process p in processes) { IntPtr pFoundWindow = p.MainWindowHandle; // how do I pass a value to MyProgram.exe ? // } 

我也试过这个:使用以下链接的帮助,但这不是我正在寻找的解决方案!: – e [C#]在其他程序上读取/写入文本框此代码已在我的activeX DLL上实现,它启动了VB6 App ..我正在通过.NET(进程)检查exe是否正在运行,如果没有,则启动它。 如果exe正在运行,那么我使用上面的文章代码示例通过设置控件(mycase中的文本框)向vb6应用程序发送消息…非常有用的代码..以下代码复制自: – c#reading&writing textbox在其他计划上

 public class ExternalWriter { [DllImport("user32.dll", SetLastError = true)] private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll", SetLastError = true)] private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string className, string lpszWindow); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)] private static extern int SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, string lParam); private const int WM_SETTEXT = 12; public void DoExternalWrite(string text) { IntPtr parent = FindWindow("", "); IntPtr child = GetchildHandle(parent, ""); SendMessage(child, WM_SETTEXT, IntPtr.Zero, text); } private IntPtr GetChildHandle(IntPtr parent, string className) { /* Here you need to perform some sort of function to obtain the child window handle, perhaps recursively */ IntPtr child = FindWindowEx(parent, IntPtr.Zero, className, null); child = FindWnidowEx(parent, child, className, null); /* You can use a tool like Spy++ to discover the hierachy on the Remedy 7 form, to find how many levels you need to search * to get to the textbox you want */ return child; } } 

堆栈溢出还有一个例子,但它是将数据从另一个应用程序读入.NET(对我的要求没有用)。但是,我把它归结为这个答案,以便有人可能想要阅读一个应用程序以及写入应用程序将在这里找到解决方案..以下代码获得: – 堆栈溢出

 public class GetWindowTextExample { // Example usage. public static void Main() { var allText = GetAllTextFromWindowByTitle("Untitled - Notepad"); Console.WriteLine(allText); Console.ReadLine(); } // Delegate we use to call methods when enumerating child windows. private delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter); [DllImport("user32")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i); [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)] private static extern IntPtr FindWindowByCaption(IntPtr zeroOnly, string lpWindowName); [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern IntPtr SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, [Out] StringBuilder lParam); // Callback method used to collect a list of child windows we need to capture text from. private static bool EnumChildWindowsCallback(IntPtr handle, IntPtr pointer) { // Creates a managed GCHandle object from the pointer representing a handle to the list created in GetChildWindows. var gcHandle = GCHandle.FromIntPtr(pointer); // Casts the handle back back to a List var list = gcHandle.Target as List; if (list == null) { throw new InvalidCastException("GCHandle Target could not be cast as List"); } // Adds the handle to the list. list.Add(handle); return true; } // Returns an IEnumerable containing the handles of all child windows of the parent window. private static IEnumerable GetChildWindows(IntPtr parent) { // Create list to store child window handles. var result = new List(); // Allocate list handle to pass to EnumChildWindows. var listHandle = GCHandle.Alloc(result); try { // Enumerates though all the child windows of the parent represented by IntPtr parent, executing EnumChildWindowsCallback for each. EnumChildWindows(parent, EnumChildWindowsCallback, GCHandle.ToIntPtr(listHandle)); } finally { // Free the list handle. if (listHandle.IsAllocated) listHandle.Free(); } // Return the list of child window handles. return result; } // Gets text text from a control by it's handle. private static string GetText(IntPtr handle) { const uint WM_GETTEXTLENGTH = 0x000E; const uint WM_GETTEXT = 0x000D; // Gets the text length. var length = (int)SendMessage(handle, WM_GETTEXTLENGTH, IntPtr.Zero, null); // Init the string builder to hold the text. var sb = new StringBuilder(length + 1); // Writes the text from the handle into the StringBuilder SendMessage(handle, WM_GETTEXT, (IntPtr)sb.Capacity, sb); // Return the text as a string. return sb.ToString(); } // Wraps everything together. Will accept a window title and return all text in the window that matches that window title. private static string GetAllTextFromWindowByTitle(string windowTitle) { var sb = new StringBuilder(); try { // Find the main window's handle by the title. var windowHWnd = FindWindowByCaption(IntPtr.Zero, windowTitle); // Loop though the child windows, and execute the EnumChildWindowsCallback method var childWindows = GetChildWindows(windowHWnd); // For each child handle, run GetText foreach (var childWindowText in childWindows.Select(GetText)) { // Append the text to the string builder. sb.Append(childWindowText); } // Return the windows full text. return sb.ToString(); } catch (Exception e) { Console.Write(e.Message); } return string.Empty; } } 

可以使用WM_COPYDATA和SENDMESSAGE对实现此目的的示例代码进行编程。

在.NET应用程序中,您可以发送消息。 在VB6端,您将不得不创建一个消息钩子。 这个钩子将使用WNDPROC函数循环并捕获发送给它的消息。

请参阅下文。 2个示例代码链接: –

对于C#.NET: C#Windows应用程序使用WM_COPYDATA进行IPC(CSSendWM_COPYDATA)

对于VB6: 如何使用SendMessage在应用程序之间传递字符串数据

以上两者都可以以这样的方式组合,即您可以在C#.NET和VB6 applciaiton之间传递数据……

快速而肮脏的方式:

  1. 当exe运行时,它将文本框的hwnd存储在注册表中(或者使用来自dll的FindWindow)
  2. 让dll读取hwnd并使用SendMessage + WM_SETTEXT来设置其文本
  3. 这将引发VB6 exe中的文本框更改事件,然后可以简单地读取它的.text

WM_COPYDATA消息。 看看这个问题

基本思路是:

1 – 在您的activex dll中初始化一个缓冲区,其中包含要发送的所需数据

2 – 您的activex dll找到( FindWindow )目标应用程序窗口

3 – 您的activex dll使用指向缓冲区的指针向目标窗口发送WM_COPYDATA消息。

4 – 您的vb6应用程序接收消息并读取已发送的数据。

OS在两个进程之间的地址空间中处理必要的转换,但是您需要在应用程序中inheritance接收窗口以便能够接收消息。