Вопрос по .net, nohup, c# – Есть ли способ запустить процессы в фоновом режиме?

3

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

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

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

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

@Jader: Является ли matlab.exe консольным приложением, которое вы пытаетесь запустить из .NET, которое, в свою очередь, порождает оконный процесс? Abhijeet Patel
Может помочь нам рассказать, какой процесс вы пытаетесь запустить. Noldorin
Да, у вас есть вызов process.Start (), который является частью этого? Я не вижу нигде, где вы назначаете аргументы процесса и командной строки. jjxtra
что, ничего не запускается или окно показывает? Если ничего не начинается, это потому, что вы забыли process.Start () ... Dave Markle
Хм. Ну, я только что попробовал этот точный код с notepad.exe в качестве исполняемого файла, и он работал нормально, так что это должно быть проблемой для любого процесса, который вы пытаетесь запустить. Может, это заставляет свои окна показывать как-то? Sean

Ваш Ответ

14   ответов
0

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

1

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

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

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

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

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

Я заметил, что если 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);
    }

В коде вызова вы можете указать & quot; dontShowWindow & quot; как процесс Аргумент:

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

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

ответил на ваш комментарий в комментариях к вопросу Jader Dias
2

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

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

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

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

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

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

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

15

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

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

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

Черт! Хорошая попытка, но Matlab очень настойчивый ... Это не сработало Jader Dias
Сожалею. Это лучшее, что у меня есть. Я с нетерпением жду разрешения.
Выше код работал для меня. Я использую 7zip.exe для архивации файла и не хочу показывать окно командной строки 7z.exe. Благодарю.
3

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

Тогда я подумал о ядреОбъекты работы, но не нашел подобного варианта вОграничения интерфейса.

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

0

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

http://msdn.microsoft.com/en-us/library/ms681928(VS.85).aspx

7

ПроверьтеMatlab Engine.

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

@modosansreves: проверьте всю ветку и комментарии, в этом случае все сводится к matlab.
+1 Кроме того, не отвечая на заглавный вопрос, это лучшее решение для моей проблемы. Я должен отказаться от неправильного пути. Jader Dias
Кроме этого, я видел, как люди использовали WinAPI FindWindow и SendMessage с CS_MINIMIZE или что-то в этом роде, если вы действительно хотите попробовать это.
@jader dias: если я что-то упустил, вы не должны "принимать" этот ответ, так как вы считаете его лучшим ответом на данный момент?
Способ запустить процесс в фоновом режиме это ... использовать движок Matlab. ... Я должен что-то упустить.
0

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

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

Create a simple console app that keeps running (and launch it to test). Right click on Project --> Properties --> Application tab --> Output type --> Change it from "Console Application" to Windows Application. Launch the same app one more time (to see whether this is what you want). Close the app via Windows Task Manager :)

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

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

Спасибо, но это не будет работать для меня, так как приложение не является консольным приложением. Матлаб не злой. Jader Dias
2

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

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

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

Это скрываетits own окна, но не те изany arbitrary процесс.
5

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

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

Например,

START /B cmd.exe
Более конкретно, замените Process.Start (exe, args) на Process.Start ("cmd.exe", string.Format (/ c start \ "notitle \" / B \ & quot; {0} \). & quot; {1} & quot ;, exe, args). Если вы не хотите, чтобы окно командной строки отображалось в виде окна, вместо этого используйте ProcessStartInfo и установите UseShellExecute = false.

Похожие вопросы