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

发布于 2024-09-25 20:59:15 字数 574 浏览 1 评论 0原文

我在 LABVIEW 中开发了一个简单的应用程序 (.dll),并将该 dll 移植到 C# windows 应用程序(Winforms) 中。就像

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

这样,当我调用函数MyFunc时,将会弹出一个窗口(我的labview应用程序的Lab View窗口(前面板

Window

我需要在我的 C# 应用程序中获取窗口名称 (ExpectedFuncName)。我的 C# 应用程序打开的外部窗口的名称 我们可以使用 FileVersionInfo程序集加载器 来获取名称吗

? 提前致谢。

i've developed a simple application (.dll) in LABVIEW and i implorted that dll to a C# windows application(Winforms) . Like

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

so when i call the function MyFunc a window will be popped up( the Lab View window( Front panel of my labview application

Window

i need to get the window name (ExpectedFuncName) in my C# application. i.e i need to get the name of the external window which is opend by my C# application. Can we use FileVersionInfo or assembly loader to get the name?

Is there any idea to do this?
Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

安穩 2024-10-02 20:59:15

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

[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 返回的值,但这需要另一个问题...

If you have the window handle, this is relatively easy:

[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();
}

Here, 'WindowHandle' is the handle of the created window.

In the case you do not have a window handle (I see you don't), you have to enumerate every desktop top-level window, filter them by the creating process (I see the window is created by you application by calling MyFunc, so you know the process ID [*]), and then use some heuristic to determine the required information.

Here is the C# import of the functions you shall use in the case you do not have the handle:

[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);

Basically EnumWindows calls EnumWindowsProc for each window found in the current desktop. So you can get the window caption.

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);
    }
}

[*] In the case the window is not created by your application (i.e but from another background process), you shall filter the values returned by GetWindowThreadProcessId using another process ID, but this requires another question...

乞讨 2024-10-02 20:59:15

If you activate LabVIEW scripting (LabVIEW 2010), or install it (LV 8.6, 2009) there is a front-panel property called 'FP.nativewindow'. This returns a handle to the front panel window.
Use the following snippet to get the property:
FP.NativeWindow

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文