У меня есть 2 программы (.exe), который я создал в.NET. Мы назовем их Ведущим устройством и Рабочим. Ведущее устройство запускает 1 или более Рабочих. Рабочий не будет взаимодействоваться с пользователем, но это - приложение WinForms, которое получает команды и выполняет компоненты WinForms на основе команд, которые это получает от Ведущего устройства.
Я хочу, чтобы приложение Рабочего работало абсолютно скрытый (кроме разоблачения в Диспетчере задач, конечно). Я думал, что мог выполнить это с StartInfo. CreateNoWindow и StartInfo. Свойства WindowStyle, но я все еще вижу окно Client.exe и компоненты в форме. Однако это не обнаруживается в панели задач.
Process process = new Process
{
EnableRaisingEvents = true,
StartInfo =
{
CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden
FileName = "Client.exe",
UseShellExecute = false,
ErrorDialog = false,
}
};
Что я должен сделать, чтобы позволить выполненному Client.exe, но не обнаружиться?
Ваше использование CreateNoWindow
/WindowStyle
прекрасно работает на моей системе с notepad.exe (например, он скрыт, но работает в фоне), так что это, вероятно, что-то, что делает приложение WinForms. Некоторые идеи:
Вариант 1: Если вы контролируете рабочий процесс WinForms, вы можете переопределить Control.SetVisibleCore
чтобы всегда скрывать форму. Если вы не хотите всегда скрывать ее, вы можете передать ей аргумент командной строки, например /hide
, который заставит ее быть скрытой. Пример (предполагается, что для формы уже есть code-behind):
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);
}
}
При этом, запуск MyForm.exe
приводит к процессу с видимой формой. Запуск MyForm.exe /hide
приводит к процессу со скрытой формой. Вы можете передать аргумент /hide
от главного процесса, тогда обычные пользователи, запускающие приложение, все равно увидят его.
Вариант 2: Вы можете скрыть приложение после его запуска, выполнив P/Invoke на ShowWindow
. Больше информации об этом здесь. Это имеет тот недостаток, что вы можете иногда видеть, как рабочее окно мелькает перед скрытием. Пример:
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);
}
Проблема в UseShellExecute = false
, установите true
и процесс будет запущен как скрытый. Использование оболочки для запуска процесса понимает, как сделать приложение скрытым, в то время как запуск процесса напрямую с UseShellExecute = false
запускает процесс напрямую, и, как отметил Крис Шмич, вам придется обрабатывать скрытие окна изнутри клиентского приложения. Это может быть более желательным, если вы хотите иметь возможность запускать приложение вручную для отладки или тестирования.