Скрыть командное окно в приложении C#

Прежде чем вы скажете, что это дублирующий вопрос, позвольте мне объяснить (поскольку я прочитал все подобные темы).

В моем приложении есть обе эти настройки:

  procStartInfo.CreateNoWindow = true;
  procStartInfo.WindowStyle = ProcessWindowStyle.Hidden;

а также имеет WindowsApplication в качестве типа вывода.

Черное окно ЕЩЕ появляется, когда я вызываю команду командной строки. Есть ли что-нибудь еще, что я могу сделать, чтобы скрыть окно? Это происходит не со всеми командами, XCOPY - это ситуация, когда черное окно действительно вспыхивает. Это происходит только тогда, когда пункт назначения, который я XCOPYing, уже содержит файл, и он предлагает мне заменить его. Даже если я передам /Y, он все равно будет кратковременно мигать.

Я открыт для использования vbscript, если это поможет, но есть ли другие идеи?

Клиент вызовет мой исполняемый файл, а затем передаст команду командной строки, т.е.:

C:\MyProgram.exe start XCOPY c:\Test.txt c:\ProgramFiles\

Вот полный код приложения:

class Program
{
    static void Main(string[] args)
    {      
            string command = GetCommandLineArugments(args);

            // /c tells cmd that we want it to execute the command that follows and then exit.
            System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd.exe", "/c " + command);

            procStartInfo.RedirectStandardOutput = true;
            procStartInfo.UseShellExecute = false;

            // Do not create the black window.
            procStartInfo.CreateNoWindow = true;
            procStartInfo.WindowStyle = ProcessWindowStyle.Hidden;

            System.Diagnostics.Process process = new System.Diagnostics.Process();
            process.StartInfo = procStartInfo;
            process.Start();

        }

    private static string GetCommandLineArugments(string[] args)
    {
        string retVal = string.Empty;

        foreach (string arg in args)
            retVal += " " + arg;


        return retVal;
    }
}

person mint    schedule 09.08.2010    source источник
comment
Можете ли вы опубликовать остальную часть вашего кода Process/ProcessStartInfo?   -  person Tim Robinson    schedule 09.08.2010
comment
@fletcher: В вопросе указано, что тип вывода — приложение Windows, а не консоль. Я протестировал его с типом вывода, установленным для приложения Windows, и он отлично работает. @snow: я бы еще раз проверил вашу настройку OutputType.   -  person Matt B    schedule 09.08.2010
comment
@fletcher Вот в чем проблема! Я бы хотел, чтобы окно вообще не отображалось!   -  person mint    schedule 09.08.2010
comment
Я начинаю думать, что это ошибка, специфичная для XCOPY ... у кого-нибудь есть опыт с этим?   -  person mint    schedule 09.08.2010
comment
Ах, моя вина. Я пропустил часть WinForms   -  person fletcher    schedule 09.08.2010
comment
Есть несколько переключателей, которые вы можете попробовать для команды XCOPY. /Q - Не отображать имя файла при копировании. /Y — подавляет запрос на подтверждение перезаписи файла. Может быть, вы получаете приглашение, но оно перенаправляется на ваш STDOUT?   -  person fletcher    schedule 09.08.2010
comment
@fletcher Возможно, черное окно очень быстро мигает с каким-то сообщением, но я не могу его прочитать, потому что оно мигает так быстро. Есть ли способ подавить сообщение STDOUT?   -  person mint    schedule 09.08.2010
comment
Если вы хотите попытаться прочитать сообщение stdout/stderr, вы можете перенаправить его в строку, выполнив: procStartInfo.RedirectStandardOutput = true; procStartInfo.RedirectStandardError = истина; ... строка stdout = process.StandardOutput.ReadToEnd(); строка stderr = process.StandardError.ReadToEnd();   -  person James Sulak    schedule 09.08.2010
comment
@James Они оба кажутся пустыми строками.   -  person mint    schedule 09.08.2010


Ответы (4)


Проблема в том, что вы используете cmd.exe. Будет скрыто только его окно консоли, а не окно консоли процесса, который вы попросите его запустить. Нет смысла использовать cmd.exe, если только вы не пытаетесь выполнить некоторые команды, которые он реализует сам. Как КОПИРОВАТЬ.

Вы все равно можете скрыть окно, если вам нужен cmd.exe, вам придется использовать параметр /B для запуска. Введите начало /? в командной строке, чтобы увидеть параметры. Не то, чтобы это помогло, вы не можете использовать START COPY.

В xcopy.exe есть специфическая особенность, которая также может сбить вас с толку. Он не выполняется, если вы также не перенаправляете ввод. Просто без диагностики не заводится.

person Hans Passant    schedule 09.08.2010
comment
/B работал для команды xcopy, это может быть все, что нам нужно, если честно. - person mint; 09.08.2010

я вижу, что вы вызываете cmd, а затем передаете команду в качестве параметров. Вместо этого вызовите команду напрямую

e.g.

    System.Diagnostics.ProcessStartInfo procStartInfo = new System.DiagnosticsProcessStartInfo("xcopy", "<sourcedir> <destdir> <other parameters>");

procStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
person ajay_whiz    schedule 09.08.2010
comment
Я, вероятно, должен был указать это в вопросе, но клиент передаст любую команду командной строки, которую он захочет, в мою программу, поэтому я не могу жестко кодировать xcopy, тем не менее, вы все равно представили меня! - person mint; 09.08.2010
comment
@Сноу, ты все еще можешь делать то, что он говорит, ProcessStartInfo procStartInfo = new ProcessStartInfo(Arg[0], String.Join(" ", Arg.Skip(1).ToArray()); - person Scott Chamberlain; 09.08.2010
comment
@snow xcopy был просто для примера - person ajay_whiz; 09.08.2010

Вы можете попробовать добавить

process.StartInfo.UseShellExecute = false; 

к вашему процессу

person Andrei C    schedule 14.11.2012
comment
Просто для уточнения ответа. Вам нужны process.StartInfo.UseShellExecute = false; и process.StartInfo.CreateNoWindow = false;. Эти два вместе скроют окно процесса - person Rémi; 15.07.2014
comment
@Rémi: тебе нужно process.StartInfo.CreateNoWindow = true; - person Sjoerd222888; 04.05.2015
comment
Я получаю сообщение об ошибке Система не может найти указанный файл. Это несмотря на то, что я добавил пользовательскую команду в системную переменную PATH. - person Najeeb; 04.08.2016

У меня была аналогичная задача - Можно скрыть окно после создания через вызов API. (В вашем случае вам может понадобиться вспомогательный поток.)

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

Если вы знаете дескриптор нового окна, вы можете позвонить

ShowWindow(hWnd, 0);

0 скрывает окно, 1 показывает окно

Чтобы получить дескриптор окна, взгляните на:

pinvoke.net enumwindows(user32)

person Cadburry    schedule 04.05.2015