سؤال

New to C#. But due to circumstances at work I have to "learn on the fly."

Been struggling the last 2 days with my code and I consumed as many questions here and articles on MSDN as I could but I think they confused me further.

I launch app A using my code. App A launches app B (I cannot launch app B, I'm beyond that).
What I want to do w/ my code is the moment app B's MainWindowTitle is available, hide the window.

So far, I can only accomplish this w/ a Thread.Sleep(xxx); before the code you see below. I want to avoid using timers.

What I'm trying to do is loop the code below until it is true.

When app A launches app B, it takes a few seconds for the MainWindowTitle to become available. But the code runs so fast that it's not available yet and the code is done.

IntPtr hWnd = IntPtr.Zero;
foreach (Process procList in Process.GetProcess())
{
    if (procList.MainWindowTitle.Contains("SAP Logon"))
    {
        hWnd = procList.MainWindowHandle;
    }
}
ShowWindow(hWnd, 0);

That code only works if I precede it with something like:

Thread.Sleep(10000);

before the entire block of code. And the only reason it works is b/c it allows enough time to pass for the Window to open and contain the title I'm looking for.

I have tried while loops.

  • Outside the 'foreach'
  • Outside the 'if'
  • Around the 'foreach' (that locked up the system really quickly...) hah!
  • Around the 'if'

I feel like one of the following should work, but it doesn't, or I'm completely screwing it up.

while (!procList.MainWindowTitle.Contains("SAP Logon")) { } // ! at the beginning OR
while (procList.MainWindowTitle.Contains("SAP Logon") == null) { } // equaling null OR
while (procList.MainWindowTitle.Contains("SAP Logon") < 0) { } // etc., etc.,
while (procList.MainWindowTitle.DOESNOTContain("SAP Logon")) { } // I know this is wrong but it almost seems like what I need...

Anyone have any suggestions? My brain is scrambled eggs and this is the last bit that I need to finish this app. If my only alternative IS Thread.Sleep(), so be it, but I would prefer to not use it. One last thing: I have to target .net 2.0.

Thank you kindly!

هل كانت مفيدة؟

المحلول

Your idea of using the while loop should work. You could try something like this:

IntPtr hWnd = IntPtr.Zero;
bool isFound = false;
while(!isFound)
{
  foreach (Process procList in Process.GetProcess())
  {
    if (procList.MainWindowTitle.Contains("SAP Logon"))
    {
        isFound = true;
        hWnd = procList.MainWindowHandle;
    }
  }
  Thread.Sleep(100); // You may or may not want this
}
ShowWindow(hWnd, 0);

نصائح أخرى

Instead of checking for the caption of the app in every single process, you can check using just the name of the EXE itself. I would also put in a timeout for good measure. For example, with Notepad you'd do:

        Process[] ps;
        DateTime timeout = DateTime.Now.AddSeconds(30);
        do
        {
            System.Threading.Thread.Sleep(100);
            ps = Process.GetProcessesByName("notepad"); // <--- no path, AND no extension (just the EXE name)
        } while (ps.Length == 0 && timeout > DateTime.Now);
        if (ps.Length > 0)
        {
            ShowWindow(ps[0].MainWindowHandle, 0);
        }
        else
        {
            MessageBox.Show("Process Not Found within Timeout Period", "Process Failed to Spawn");
        }

Have you tried or seen this:

.NET Events for Process executable start

This should do what you are looking for...

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top