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

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

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

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

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

14 ответов

Решение

Проверьте двигатель Matlab.

Есть даже интересная статья о CodeProject, если этот подход соответствует вашим потребностям.

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

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. Могут отображаться окна, которые вы не можете контролировать.

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

Вы пытались использовать команду запуска Microsoft DOS с ключом /B?

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

Например,

START /B cmd.exe

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

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

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

Я понимаю, что на это ответили, но вы могли бы заставить окно скрыться с неуправляемыми вызовами 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

Скорее клудги.

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

Один из очень простых способов добиться этого - создать служебную учетную запись и запустить исполняемый файл в контексте пользователя служебной учетной записи с помощью планировщика задач 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

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

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

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

Я заметил, что если CreateNoWindow = false абсолютно ничего не делает, когда имя файла указывает на исполняемый файл Windows, если у вас есть доступ к исходному коду приложения winform, то вы можете предоставить аргумент командной строки, который контролирует видимость по умолчанию для и сделайте что-то вроде этого в коде запуска приложения 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);

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

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

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

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

Может быть, кувалдой подход к вашей проблеме, хотя.

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

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

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

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

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

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

                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();
                }

Я думаю, что вы можете попробовать создать новую станцию ​​Windows. Проверьте эту статью, которая объясняет немного о них на MSDN.

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

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

Другие вопросы по тегам