0

I've looked through several examples of trying to do this listed on stackoverflow, but i haven't found anything that lists how to do this for .NET coding. Also I need it to detect the popup, and once its found the popup then pull the title of the window, and the text inside the popup.

I tried using the post: how-can-i-change-text-on-a-win32-window

but i had no luck with trying to find how to "get text" only how to see if the popup exists. The window i'm trying to get text from is a standard Windows error window (#32770) a.k.a WIN32 Critical popup window (one with Red X). I know the title of the error window is always going to be "TLP2011"

I just need to be able to read the Title, Text, and then click "OK" on the error button.

Reason? There's a software I run IT for and to cut back on inbound call costs i want to write a program that detects the errors as they popup, then once its been detected close the error window and tell the user that the error will be automatically fixed. (my new program will have to be able to read the text from the error window in order to determine how to automatically fix the error so this error doesn't show up again)

----------Edited to show latest finds------------

Thanks to GX for posting the following link How can I get functionality similar to Spy++ in my C# app?

Now i have determined that i need something like the following:

Dim pProcess() As Process = Process.GetProcessesByName("TLP2011")

    For Each p As Process In pProcess
        For Each threadInfo As ProcessThread In p.Threads

            ' uncomment to dump thread handles
            'Console.WriteLine("\tthread {0:x}", threadInfo.Id);
            Dim windows As IntPtr() = GetWindowHandlesForThread(threadInfo.Id)
            If windows IsNot Nothing AndAlso windows.Length > 0 Then
                For Each hWnd As IntPtr In windows
                    Console.WriteLine(vbTab & "window {0:x} text:{1} caption:{2}", hWnd.ToInt32(), GetText(hWnd), GetEditText(hWnd))
                Next
            End If
        Next
    Next

Now this lists everything on the actual program itself. Every piece of text and everything. Anyone know a trick to just single out the popup box?

Here is an example of what displays

window 3d21aa text:Select Package caption:
window 551176 text: caption:
window e8147c text:Do Not Auto Show  caption:Do Not Auto Show 
window 8e21c6 text:&Select All caption:&Select All
window 2300e10 text:&Help caption:&Help
window 762164 text:Cancel caption:Cancel
window 330f0e text:OK caption:OK
window e8147c text:Do Not Auto Show  caption:Do Not Auto Show 
window 8e21c6 text:&Select All caption:&Select All
window 2300e10 text:&Help caption:&Help
window 762164 text:Cancel caption:Cancel
window 330f0e text:OK caption:OK
window 10f20a6 text: caption:
window 5f122ce text: caption:
window 1824e2 text: caption:
window 1824e2 text: caption:
window 5f122ce text: caption:
window 1824e2 text: caption:
window 1824e2 text: caption:
window 6e1be4 text: caption:
window 342162 text: caption:
window 1c1b92 text: caption:
window 65105a text: caption:Admin
window 291f72 text: caption:
window 375104e text: caption:
window 375104e text: caption:
window 1c1b92 text: caption:
window 65105a text: caption:Admin
window 291f72 text: caption:
window 375104e text: caption:
window 375104e text: caption:
window 242308 text:Form Filter caption:
window 9ee294e text: caption:
window 8ff0f54 text: caption:All Status
window 468273c text: caption:
window 1d110c text: caption:
window 1d110c text: caption:
window 8ff0f54 text: caption:All Status
window 468273c text: caption:
window 1d110c text: caption:
window 1d110c text: caption:
window b90bea text:cbEngine caption:
window 5b17b0 text: caption:
window ee24c6 text: caption:
window ee24c6 text: caption:
window fc1ae0 text: caption:
window 141cfc text:TLP2011 caption:
window d51928 text:OK caption:OK
window 2c1223c text: caption:
window 100f08 text:Access violation at address 6CABC667 in module 'tlpcore.dll'. Write of address F8FFFF86. caption:Access violation at address 6CABC667 in module 'tlpcore.dll'. Write of address F8FFFF86.
window b2a214e text: caption:

Anyone know a better way to try and find the error box? I don't think that doing a search for "TLP2011" then using the next 3 lines to try and determine the msgbox text to be a very "reliable" method. Anyone know how to single it out more?

----Added more thoughts----

Doing a check for this through all of the different threads every like 10 seconds seems like it would put a huge drain on the system. Is this really the most logical way to go about doing this?

Community
  • 1
  • 1
eqiz
  • 1,521
  • 5
  • 29
  • 51
  • 1
    This thread should help you and there is even a c# example there http://stackoverflow.com/questions/1967604/how-can-i-get-functionality-similar-to-spy-in-my-c-sharp-app – G-Man Jul 03 '12 at 01:08
  • That link is perfect, but I just need to know 1 more thing. How do I create a variable to target a specific process? So if i know the processname is going to be TLP2011, how would i just single this process out so i can then pull all the information from that? – eqiz Jul 03 '12 at 01:36
  • The example on the page lists all the running processes, just create a constant and assign it the value "TLP2011" then when enumerating thee processes compare the process name (in the example procesInfo.ProcessName) to your constant – G-Man Jul 03 '12 at 02:32

1 Answers1

0

Gaetano got it correct with his response

static void Main(string[] args)
{
    foreach (Process procesInfo in Process.GetProcesses())
    {
        Console.WriteLine("process {0} {1:x}", procesInfo.ProcessName, procesInfo.Id);
        foreach (ProcessThread threadInfo in procesInfo.Threads)
        {
            // uncomment to dump thread handles
            //Console.WriteLine("\tthread {0:x}", threadInfo.Id);
            IntPtr[] windows = GetWindowHandlesForThread(threadInfo.Id);
            if (windows != null && windows.Length > 0)
                foreach (IntPtr hWnd in windows)
                    Console.WriteLine("\twindow {0:x} text:{1} caption:{2}",
                        hWnd.ToInt32(), GetText(hWnd), GetEditText(hWnd));
        }
    }
    Console.ReadLine();
}

private static IntPtr[] GetWindowHandlesForThread(int threadHandle)
{
    _results.Clear();
    EnumWindows(WindowEnum, threadHandle);
    return _results.ToArray();
}

// enum windows

private delegate int EnumWindowsProc(IntPtr hwnd, int lParam);

[DllImport("user32.Dll")]
private static extern int EnumWindows(EnumWindowsProc x, int y);
[DllImport("user32")]
private static extern bool EnumChildWindows(IntPtr window, EnumWindowsProc callback, int lParam);
[DllImport("user32.dll")]
public static extern int GetWindowThreadProcessId(IntPtr handle, out int processId);

private static List<IntPtr> _results = new List<IntPtr>();

private static int WindowEnum(IntPtr hWnd, int lParam)
{
    int processID = 0;
    int threadID = GetWindowThreadProcessId(hWnd, out processID);
    if (threadID == lParam)
    {
        _results.Add(hWnd);
        EnumChildWindows(hWnd, WindowEnum, threadID);
    }
    return 1;
}

// get window text

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

private static string GetText(IntPtr hWnd)
{
    int length = GetWindowTextLength(hWnd);
    StringBuilder sb = new StringBuilder(length + 1);
    GetWindowText(hWnd, sb, sb.Capacity);
    return sb.ToString();
}

// get richedit text 

public const int GWL_ID = -12;
public const int WM_GETTEXT = 0x000D;

[DllImport("User32.dll")]
public static extern int GetWindowLong(IntPtr hWnd, int index);
[DllImport("User32.dll")]
public static extern IntPtr SendDlgItemMessage(IntPtr hWnd, int IDDlgItem, int uMsg, int nMaxCount, StringBuilder lpString);
[DllImport("User32.dll")]
public static extern IntPtr GetParent(IntPtr hWnd);

private static StringBuilder GetEditText(IntPtr hWnd)
{
    Int32 dwID = GetWindowLong(hWnd, GWL_ID);
    IntPtr hWndParent = GetParent(hWnd);
    StringBuilder title = new StringBuilder(128);
    SendDlgItemMessage(hWndParent, dwID, WM_GETTEXT, 128, title);
    return title;
}
eqiz
  • 1,521
  • 5
  • 29
  • 51