Search code examples
c#labview

How to get the name of an External window in C# Application?


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.


Solution

  • 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...