Я пытаюсь выполнить команду оболочки из созданной мной службы С#. Однако эта команда, похоже, не выполняется. Как стандартное консольное приложение, оно отлично работает, поэтому я знаю, что нет проблемы с самой командой или как она выполняется в коде. Может ли кто-нибудь сказать мне, почему это не сработает? Пожалуйста, имейте в виду, что я довольно новичок в С#, так что это может быть просто вопросом моей неопытности. Ниже приведен код из самой службы:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management;
using System.Diagnostics;
using System.ServiceProcess;
using System.Threading;
namespace AdapterDisableTest
{
class Program : ServiceBase
{
//private static Timer workTimer;
static void Main(string[] args)
{
ServiceBase.Run(new Program());
}
public Program()
{
this.ServiceName = "AdapterDisableTest";
}
protected override void OnStart(string[] args)
{
base.OnStart(args);
Process myProcess = new Process();
myProcess.StartInfo.FileName = @"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe";
myProcess.StartInfo.Arguments = "controlvm test setlinkstate1 off";
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.CreateNoWindow = true;
myProcess.Start();
}
protected override void OnStop()
{
base.OnStop();
//TODO: clean up any variables and stop any threads
}
}
}
Если это приложение Windows, которое требует рабочего стола, вы в значительной степени SOL. Если это стандартное консольное приложение, вам необходимо перенаправить стандартный ввод, стандартный вывод и стандартную ошибку. Вам также необходимо установить для свойства ProcessStartInfo
UseShellExecute
значение false
: вы не можете запустить оболочку ОС (cmd.exe
), поскольку для этого требуется доступ к рабочему столу... и, кроме того, вы не можете перенаправить стандартный ввод с этим свойством, установленным на true
.
Стандартный вход обычно подключается к клавиатуре. У вашей службы нет доступа к клавиатуре. Стандартная и стандартная ошибка обычно подключаются к окну консоли cmd.exe
.
Как только у вас есть стандартный вывод и стандартная ошибка перенаправлена, вам нужно подключить обработчик к этим событиям Process
объекта:
Exited
. При завершении процесса.OutputDataReceived
. Поднят, когда данные записываются на стандартный вывод процесса (в действительности, происходит, когда любые буферы в выходном потоке очищаются, поэтому он может отставать от фактической операции записи).ErrorDataReceived
. Поднято, когда данные записываются в стандартную ошибку.Я стараюсь перенаправить стандартный вывод и стандартную ошибку в тот же поток и убедиться, что этот поток не загружен. Это эквивалент заклинания cmd.exe
some-command 2>&1
перенаправить stdout и stderr в один и тот же дескриптор файла.
UseShellExecute = false ;
, ваш исполняемый процесс будет запущен под экземпляром CMD.EXE. Для этого требуется рабочий стол, а ваша служба не имеет к нему доступа.
Process
в .Net.