如何在C#应用程序中获取外部窗口的名称?

时间:2010-10-03 07:54:48

标签: c# labview

我在.dll中开发了一个简单的应用程序(LABVIEW),然后我将这个dll打包到C#windows应用程序(Winforms)。像

    [DllImport(@".\sample.dll")]
    public static extern void MyFunc(char[] a, StringBuilder b ,Int32 c); 

所以当我调用函数MyFunc时,会弹出一个窗口(Lab View窗口(我的labview应用程序的Front panel

Window

我需要在我的C#应用​​程序中获取窗口名称(ExpectedFuncName)。即我需要获取由我的C#应用​​程序打开的外部窗口的名称。我们可以使用FileVersionInfoassembly loader来获取名称吗?

有什么想法吗? 提前谢谢。

2 个答案:

答案 0 :(得分:6)

如果您有窗口句柄,这相对容易:

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);


[DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
static extern int GetWindowTextLength(IntPtr hWnd);

...

int len;

// Window caption
if ((len = GetWindowTextLength(WindowHandle)) > 0) {
    sb = new StringBuilder(len + 1);
    if (GetWindowText(WindowHandle, sb, sb.Capacity) == 0)
        throw new Exception(String.Format("unable to obtain window caption, error code {0}", Marshal.GetLastWin32Error()));
    Caption = sb.ToString();
}

这里,'WindowHandle'是创建窗口的句柄。

如果你没有窗口句柄(我看不到你),你必须枚举每个桌面顶层窗口,通过创建过程过滤它们(我看到窗口是由你的应用程序创建的调用 MyFunc ,以便知道进程ID [*]),然后使用一些启发式方法来确定所需的信息。

以下是在没有句柄的情况下应使用的函数的C#导入:

[DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
static extern int GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);

[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);

private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);

基本上 EnumWindows 为当前桌面中找到的每个窗口调用 EnumWindowsProc 。所以你可以得到窗口标题。

List<string> WindowLabels = new List<string>();

string GetWindowCaption(IntPtr hWnd) { ... }

bool MyEnumWindowsProc(IntPtr hWnd, IntPtr lParam) {
    int pid;

    GetWindowThreadProcessId(hWnd, out pid);

    if (pid == Process.GetCurrentProcess().Id) {
        // Window created by this process -- Starts heuristic
        string caption = GetWindowCaption(hWnd);

        if (caption != "MyKnownMainWindowCaption") {
           WindowLabels.Add(caption);
        }
    }

    return (true);
}

void DetectWindowCaptions() {
    EnumWindows(MyEnumWindowsProc, IntPtr.Zero);

    foreach (string s in WindowLabels) {
        Console.WriteLine(s);
    }
}

[*]如果窗口不是由您的应用程序创建的(即从其他后台进程创建),您应使用另一个进程ID过滤GetWindowThreadProcessId返回的值,但这需要另一个问题......

答案 1 :(得分:4)

如果您激活LabVIEW脚本(LabVIEW 2010)或安装它(LV 8.6, 2009),则会有一个名为“FP.nativewindow”的前面板属性。这将返回前面板窗口的句柄 使用以下代码段获取属性:
FP.NativeWindow