Есть ли способ запускать процессы в фоновом режиме?

Существует ли какая-либо командная строка или метод .NET, который запускает процесс в фоновом режиме, скрывая любое окно, которое он пытается открыть?

Уже пробовал:

 var process = new Process()
 {
      StartInfo = new ProcessStartInfo()
      {
          CreateNoWindow = true,
          WindowStyle = ProcessWindowStyle.Hidden,
          FileName = TheRealExecutableFileNameHere
      }
 }
 process.Start();

Пока безуспешно


person Jader Dias    schedule 12.07.2009    source источник
comment
Может помочь сообщить нам, какой процесс вы пытаетесь запустить.   -  person Noldorin    schedule 12.07.2009
comment
что, ничего не запускается или окно показывает? Если ничего не запускается, значит вы забыли process.Start()...   -  person Dave Markle    schedule 12.07.2009
comment
Да, у вас есть вызов process.Start(), который является частью этого? Я нигде не вижу, где вы также назначаете аргументы процесса и командной строки.   -  person jjxtra    schedule 12.07.2009
comment
@Dave отредактировал для уточнения. Появляется окно, я хочу, чтобы оно исчезло.   -  person Jader Dias    schedule 12.07.2009
comment
@Jeff отредактировал для уточнения. Я использую его правильно.   -  person Jader Dias    schedule 12.07.2009
comment
Хм. Является ли окно, о котором вы говорите, оболочкой cmd? Это будет вести себя иначе, чем фактическое оконное приложение.   -  person Sean    schedule 12.07.2009
comment
@Darth, оболочка cmd скрыта, приложение порождает новое окно, это то новое окно, о котором я говорю   -  person Jader Dias    schedule 12.07.2009
comment
Хм. Что ж, я только что попробовал этот точный код с notepad.exe в качестве исполняемого файла, и он работал нормально, поэтому, должно быть, это проблема с тем процессом, который вы пытаетесь запустить. Может быть, он заставляет свои окна как-то показывать?   -  person Sean    schedule 12.07.2009
comment
@ Дарт Эру, я думаю, что этот процесс представляет собой консольное приложение, которое порождает приложение Forms в другом потоке, и поэтому оно всегда показывает окно.   -  person Jader Dias    schedule 12.07.2009
comment
@Noldorin Процесс matlab.exe -nodisplay -nojvm   -  person Jader Dias    schedule 12.07.2009
comment
@Jader: Является ли matlab.exe консольным приложением, которое вы пытаетесь запустить из .NET, которое, в свою очередь, порождает оконный процесс?   -  person Abhijeet Patel    schedule 27.07.2009
comment
@Abhijeet Да, но я отказался от этого подхода к вопросу, так как нашел лучший способ общения с Matlab.   -  person Jader Dias    schedule 27.07.2009


Ответы (14)


Ознакомьтесь с Matlab Engine.

На CodeProject даже есть интересная статья, если такой подход вам подходит.

person Kenan E. K.    schedule 20.07.2009
comment
+1 Помимо того, что я не отвечаю на вопрос заголовка, это лучшее решение моей проблемы. Я должен перестать поступать неправильно. - person Jader Dias; 21.07.2009
comment
Помимо этого, я видел, как люди используют WinAPI FindWindow и SendMessage с CS_MINIMIZE или что-то в этом роде, если вы действительно хотите попробовать. - person Kenan E. K.; 21.07.2009
comment
Способ запустить процесс в фоновом режиме - это... использовать движок Matlab. ... Должно быть, я что-то упускаю. - person bohdan_trotsenko; 21.07.2009
comment
@modosansreves: проверьте всю ветку и комментарии, в данном случае все сводится к Matlab. - person Kenan E. K.; 21.07.2009
comment
@jader dias: если я что-то не упустил, разве вы не должны принять этот ответ, так как вы считаете его лучшим ответом на данный момент? - person Liao; 27.07.2009

Я просмотрел свой код, и он выглядит почти так же, как ваш:

ProcessStartInfo psi = new ProcessStartInfo(fileName, arguments)
{
   CreateNoWindow = true,
   WindowStyle = ProcessWindowStyle.Hidden,
   UseShellExecute = false,
   RedirectStandardOutput = true                                               
};

Process process = Process.Start(psi);

Единственное заметное отличие (помимо форматирования и выбранного нами конструктора PSI) заключается в использовании UseShellExecute и RedirectStandardOutput, поскольку мне нужно было прочитать результат запущенного процесса.

Я обнаружил, что приведенный выше код постоянно запускает скрытый процесс в XP и Vista. Однако я также обнаружил, и вы, возможно, испытываете то же самое, что скрытый процесс может запускать другой процесс, который по умолчанию не скрыт. Другими словами, если вы запускаете скрытый процесс A, а процесс A, в свою очередь, запускает процесс B, вы не можете контролировать, как будет отображаться процесс B. Могут отображаться окна, которыми вы не можете управлять.

Надеюсь, это немного поможет. Удачи.

person Ben Griswold    schedule 12.07.2009
comment
Проклятие! Хорошая попытка, но Matlab очень настойчив... Не сработало - person Jader Dias; 13.07.2009
comment
Извиняюсь. Это лучшее, что у меня есть. Я с нетерпением жду разрешения. - person Ben Griswold; 13.07.2009
comment
Вышеупомянутый код работал для меня. Я использую 7zip.exe для архивирования файла и не хочу показывать окно командной строки 7z.exe. Спасибо. - person Mehdi Anis; 08.08.2012

Пробовали ли вы использовать команду Microsoft DOS start с переключателем /B?

Команда запуска Microsoft DOS

Например,

START /B cmd.exe
person Mark Good    schedule 24.07.2009
comment
В частности, замените Process.Start(exe, args) на Process.Start(cmd.exe, string.Format(/c start \notitle\ /B \{0}\ {1}, exe, args). не хотите, чтобы командное окно отображалось, используйте вместо этого ProcessStartInfo и установите UseShellExecute = false. - person yoyo; 21.11.2013

Нет Я не знаю чистого .Net способа добиться этого.

Затем я подумал о ядре Job Objects, но не нашел аналогичной опции в ограничениях пользовательского интерфейса.

Итак, следующая (пока непроверенная) идея состоит в том, чтобы создать, а затем приостановить процесс, затем создайте хук Windows, который будет отслеживать CallWndProc и отфильтровать сообщения WM_SHOW. (Затем обязательно возобновить процесс, дождаться в отдельном потоке его завершения, убрать хук)

person bohdan_trotsenko    schedule 21.07.2009

Вы можете попробовать класс BackgroundWorker в .Net Framework, если вы еще этого не сделали. Это для выполнения длительных процессов в отдельном потоке, чтобы они не мешали пользовательскому интерфейсу. Дайте ему посмотреть.

person CertifiedCrazy    schedule 24.07.2009

Я понимаю, что на этот вопрос был дан ответ, но вы можете скрыть окно с помощью неуправляемых вызовов FindWindow и ShowWindow.

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

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

psi = new ProcessStartInfo(); // etc..
some_process = Process.Start(psi);
System.Threading.Thread.Sleep(50); // need give the window a chance to be created
IntPtr hWnd = FindWindow(null, "name of the window");
if (hWnd != IntPtr.Zero) ShowWindow(hWnd, 0); // 0 = SW_HIDE

Скорее тупой.

person Mark    schedule 27.07.2009
comment
+1. Я думаю, что это действительно простое и эффективное решение, но мне не нужно Sleep(50), так как some_process.WaitToEnd() подойдет. - person Jader Dias; 27.07.2009

Это зависит от того, хотите ли вы запустить приложение в свернутом виде, но при необходимости разрешить ему взаимодействовать с пользователем, или же вы хотите запретить любой доступ к пользователю независимо от того, что происходит.

Если последнее, вы можете запустить процесс в контексте рабочего стола, отличном от текущего пользователя.

Различные контексты рабочего стола используются, например, в диалоговом окне входа в систему и в Vista UAC — все, что происходит в одном контексте рабочего стола, не зависит от других.

Возможно, это кувалдный подход к вашей проблеме.

person Bevan    schedule 12.07.2009
comment
Я хочу запретить любой доступ пользователю независимо от того, что происходит. - person Jader Dias; 12.07.2009
comment
Я не смог найти статью о контексте рабочего стола в .net, можете ли вы помочь мне найти ее? - person Jader Dias; 12.07.2009
comment
Мне не удалось найти именно ту страницу, которую я хотел, но я нашел страницу, на которой рассказывается о некоторых стандартных рабочих столах, которые обычно присутствуют. Начните здесь (msdn.microsoft.com/en-us/ library/aa375994(VS.85).aspx) и осмотритесь, вы должны найти то, что вам нужно. - person Bevan; 12.07.2009
comment
Я попытался запустить процесс от имени другого пользователя, но это не решило проблему. - person Jader Dias; 13.07.2009

Я заметил, что если CreateNoWindow = false абсолютно ничего не делает, когда имя файла указывает на исполняемый файл Windows, если у вас есть доступ к исходному коду приложения winform, вы можете предоставить аргумент командной строки, который управляет видимостью по умолчанию form и сделайте что-то подобное в коде запуска приложения Winform:

static void Main(string[] args)
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Form1 form1 = new Form1();

        form1.Load += new EventHandler((s,o) =>
            {
              //check if the form should be shown based on command line arg
                if (args.Contains("dontShowWindow"))
                {
                    //hide it
                    form1.ShowInTaskbar = false;
                    form1.Visible = form1.ShowInTaskbar = false;
                }
            }
        );
        Application.Run(form1);
    }

В вызывающем коде теперь вы можете указать «dontShowWindow» в качестве аргумента процесса:

 ProcessStartInfo info = new ProcessStartInfo
        {
            CreateNoWindow = false, 
            WindowStyle = ProcessWindowStyle.Hidden,
            UseShellExecute = false, 
            FileName = @"C:\temp\testWinForm.exe",
            Arguments = "dontShowWindow"
        };
        Process.Start(info);

Надеюсь это поможет

person Abhijeet Patel    schedule 27.07.2009
comment
ответил на ваш комментарий в комментариях к вопросу - person Jader Dias; 27.07.2009

Один очень простой способ добиться этого — создать учетную запись службы и запустить исполняемый файл в контексте пользователя учетной записи службы через планировщик заданий Windows.

Вы можете использовать этот CodeProject для настройки запланированной задачи:

http://www.codeproject.com/KB/cs/tsnewlib.aspx

Вы можете очень легко создать учетную запись службы программно в домене или на локальном компьютере с помощью C #.

http://www.codeproject.com/KB/system/OSUserMangement.aspx http://support.microsoft.com/kb/306273

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

person Keith Adler    schedule 27.07.2009

public Form1()
    {
        InitializeComponent();
        Form1 fm = new Form1();
        fm.ShowInTaskbar = false;
        fm.Visible = fm.ShowInTaskbar = false;
    }

Работает отлично !

person Rage    schedule 13.06.2015
comment
Это скрывает собственные окна, но не окна любого произвольного процесса. - person Nathan Tuggy; 13.06.2015

Я предполагаю, что вам нужен процесс, который не виден пользователям во время работы.

Вы можете попробовать следующее, чтобы увидеть, хотите ли вы этого.

  1. Создайте простое консольное приложение, которое продолжает работать (и запустите его для тестирования).
  2. Щелкните правой кнопкой мыши «Проект» -> «Свойства» -> вкладка «Приложение» -> «Тип вывода» -> «Измените его с «Консольное приложение» на «Приложение Windows».
  3. Запустите то же приложение еще раз (чтобы убедиться, что это то, что вам нужно).
  4. Закройте приложение через диспетчер задач Windows :)

Кажется, что процесс появляется в диспетчере задач, но не виден на панели задач. Alt+TAB не может запустить этот процесс.

Я просто надеюсь, что вы не делаете никаких вредоносных приложений :)

person Chansik Im    schedule 12.07.2009
comment
Спасибо, но у меня не получится, так как приложение не консольное. Matlab не является вредоносным. - person Jader Dias; 12.07.2009

Я думаю, вы могли бы попробовать создать новую Windows Station. Ознакомьтесь с этой статьей, которая немного объясняет их на msdn.

http://msdn.microsoft.com/en-us/library/ms681928%28VS.85%29.aspx

person Matt    schedule 24.07.2009

Вы можете сделать службу Windows. Любое окно, которое служба пытается открыть, просто запускается в сеансе 0, что означает, что ни один пользователь не может его увидеть. Это касается всех окон, так что, возможно, это не то, что вы ищете.

person NathanTempelman    schedule 14.07.2014

Ниже код работал для меня: ранее процесс (блокнот) использовался для запуска блокнота на экране рабочего стола для печати, но это отвлекало пользователя, поэтому ниже код скрывает процесс блокнота в фоновом режиме.

                System.Windows.Forms.PrintDialog printDialog = new PrintDialog();
                System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo(Application.StartupPath + "/PrintingDocketFile/PrintCustomerOrder.txt");
                psi.Verb = "PRINT";

                //Process.Start(psi);
                //psi.CreateNoWindow = true;
                psi.UseShellExecute = false;
                //---------------------------------------------------

                psi.CreateNoWindow = false;
                psi.UseShellExecute = true;
                psi.FileName = Application.StartupPath + "/PrintingDocketFile/PrintCustomerOrder.txt";
                psi.WindowStyle = ProcessWindowStyle.Hidden;
                psi.Arguments =  @"%windir%\system32\notepad.exe"; 
                //Process.Start(psi);
                //------------------------------------------------------

                /////////////////////----------------------------------

                printProcess.StartInfo = psi;
                /////psi.CreateNoWindow = true;

                //psi.FileName = "Application.StartupPath" + "/PrintingDocketFile/PrintCustomerOrder.txt";
                //p.StartInfo.FileName = "Notepad.EXE";
                //p.StartInfo.Arguments = "/i /q \"" + installationPackages[i] + "\"";

                printProcess.Start();

                /////////////////////////-------------------------------
                while (!printProcess.HasExited) ;


                if (!printProcess.HasExited)
                {
                    printProcess.Close();
                }
person Kishor H Oswal    schedule 14.09.2016