本问答参考并可用于以下用途。目的:
- 通过ActiveX dll从IE浏览器发送消息到vb6应用程序
- 从 ActiveX dll 向 vb6 应用程序发送消息
- 从 C#.net (dll) 发送消息到 vb6 应用程序
我读过了本文 http://www.codeproject.com/Articles/6945/VB-NET-VB6-and-C-Interprocess-communication-via-Wi但对于我的目的来说似乎不太清楚......
我也提到过本文创建ActiveX对象 http://www.dreamincode.net/forums/topic/38890-activex-with-c#/并实现了一个 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#] 在其他程序上读/写文本框 http://www.neowin.net/forum/topic/607715-c#-readingwriting-textbox-on-other-program/这段代码已在我的 activeX DLL 上实现,它启动了 VB6 应用程序。我通过 .NET(进程)检查 exe 是否正在运行,如果没有,则启动它。如果 exe 正在运行,那么我将使用上面的文章代码示例通过设置控件(mycase 中的文本框)向 vb6 应用程序发送消息...非常有用的代码..以下代码复制自:- c# 读取和写入文本框在其他节目上
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("<window class name>", "<window title">);
IntPtr child = GetchildHandle(parent, "<class name>");
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<IntPtr>
var list = gcHandle.Target as List<IntPtr>;
if (list == null)
{
throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>");
}
// Adds the handle to the list.
list.Add(handle);
return true;
}
// Returns an IEnumerable<IntPtr> containing the handles of all child windows of the parent window.
private static IEnumerable<IntPtr> GetChildWindows(IntPtr parent)
{
// Create list to store child window handles.
var result = new List<IntPtr>();
// 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;
}
}