问题
I have 2 programs (.exe) which I've created in .NET. We'll call them the Master and the Worker. The Master starts 1 or more Workers. The Worker will not be interacted with by the user, but it is a WinForms app that receives commands and runs WinForms components based on the commands it receives from the Master.
I want the Worker app to run completely hidden (except showing up in the Task Manager of course). I thought that I could accomplish this with the StartInfo.CreateNoWindow and StartInfo.WindowStyle properties, but I still see the Client.exe window and components in the form. However, it doesn't show up in the taskbar.
Process process = new Process
{
EnableRaisingEvents = true,
StartInfo =
{
CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden
FileName = "Client.exe",
UseShellExecute = false,
ErrorDialog = false,
}
};
What do I need to do to let Client.exe run, but not show up?
回答1:
Your usage of CreateNoWindow
/WindowStyle
works fine on my system with notepad.exe (e.g. it is hidden but running in the background), so it's probably something the WinForms app is doing. Some ideas:
Option 1: If you control the WinForms worker process, you can override Control.SetVisibleCore to always hide the form. If you don't want to always hide it, you can pass a command-line argument to it, e.g. /hide
that will cause it to be hidden. Example (assuming there's already code-behind for the form):
public partial class MyForm : Form
{
public MyForm()
{
InitializeComponent();
}
protected override void SetVisibleCore(bool value)
{
// You'd probably want to parse the command line.
if (Environment.CommandLine.Contains("/hide"))
base.SetVisibleCore(false);
else
base.SetVisibleCore(value);
}
}
With this, running MyForm.exe
results in a process with a visible form. Running MyForm.exe /hide
results in a process with a hidden form. You could pass the /hide
argument from your master process, so then normal users running the application will still see it.
Option 2: You can hide the application after it starts by doing a P/Invoke to ShowWindow. More info on this here. This has the drawback that you can sometimes see the worker window flicker into existence before being hidden. Example:
class Program
{
public static void Main(string[] args)
{
ProcessStartInfo psi = new ProcessStartInfo()
{
FileName = @"C:\windows\system32\notepad.exe",
};
Process process = Process.Start(psi);
// Wait until the process has a main window handle.
while (process.MainWindowHandle == IntPtr.Zero)
{
process.Refresh();
}
ShowWindow(process.MainWindowHandle, SW_HIDE);
}
const int SW_HIDE = 0;
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
}
回答2:
The problem is with UseShellExecute = false
, set this to true
and the process will be started as hidden. Using the shell to start the process understands how to make the application hidden, where as starting the process directly with UseShellExecute = false
starts the process directly, and as Chris Schmich mentioned, you'd have to handle hiding the window from inside the client application. This might be more desirable if you want the option of running the application manually for debugging or testing purposes.
回答3:
You have to add base.Visibility = Visibility.Hidden;
in Win Form application constructor.
来源:https://stackoverflow.com/questions/3011209/c-sharp-launch-invisible-process-createnowindow-windowstyle-not-working