Hide another application while keeping it active

2019-06-13 19:25发布

问题:

I'm having an external application that generates some data and stores it, when it runs (it is a window application - not a console application). Now I'm in the process of creating my own application that analyzes this data. The problem is that the external software has to run at the same time.

When the user opens my application I want it to automatically start the external application and hide it. I've searched a lot on the topic and tried some of the suggestions I found. First I tried:

Process p = new Process();
p.StartInfo.FileName = @"c:\app.exe";
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.UseShellExecute = false;
p.StartInfo.WorkingDirectory = @"c:\";
p.StartInfo.CreateNoWindow = true;
p.Start();

This starts the external application, but doesn't hide it. I then read that the command promt could hide the application:

ProcessStartInfo psi = new ProcessStartInfo("cmd.exe", "/c \""c:\app.exe\"");
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
psi.WindowStyle = ProcessWindowStyle.Hidden;
Process.Start(psi);

Again, this starts the application non-hidden.

I then thought of starting the application and then hide it. I found the following:

[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

var Handle = FindWindow(null, "Application Caption");
ShowWindow(Handle, 0);

This will hide the window. The problem is that the application is inactive in this state and doesn't generate any data.

EDIT: I've come a step closer to an acceptable solution (minimizing instead of hiding). As the external application is a little slow starting up, I do the following:

Process p = new Process();
p.StartInfo.FileName = @"c:\app.exe";
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.UseShellExecute = false;
p.StartInfo.WorkingDirectory = @"c:\";
p.StartInfo.CreateNoWindow = true;
p.Start();

while (true)
{
    int style = GetWindowLong(psi.MainWindowHandle, -16); // -16 = GWL_STYLE

    if ((style & 0x10000000) != 0) // 0x10000000 = WS_VISIBLE
    {
        ShowWindow(psi.MainWindowHandle, 0x06);
        break;
    }

    Thread.Sleep(200);          
}

This doesn't work either, but I believe it's a step in the right direction.

Is there a way to start and hide an external application, while keeping it active?

Best regards

回答1:

I made it work by doing the following:

const int GWL_STYLE = -16;
const long WS_VISIBLE = 0x10000000;

while (true)
{
    var handle = FindWindow(null, "Application Caption");

    if (handle == IntPtr.Zero)
    {
        Thread.Sleep(200);
    }
    else
    {
        int style = GetWindowLong(handle, GWL_STYLE);

        if ((style & WS_VISIBLE) != 0)
        {
            ShowWindow(handle, 0x06);
            break;
        }
    }
}