Мне нужно удаленно останавливать и запускать службы с внутреннего веб-сайта, однако запуск / остановка службы должна выдавать себя за пользователя, который имеет на это разрешение.
Я использую System.Diagnostics.Process
для запуска процессакак другой пользователь, затем вызывая sc.exe
с аргументами для этого и прослушивая стандартный вывод.
Когда я запускаю sc query
, он работает нормально и возвращает мне ту же информацию, как если бы я запускал ее накомандная строка.Однако, когда я запускаю команду sc stop или start, выдается сообщение об ошибке
[SC] OpenService FAILED 1060: указанная служба не существует в качестве установленной службы.
Что странно, поскольку я позвонил sc query
с точно таким же именем службы, и он находит службу в порядке и возвращает ее состояние полностью.
Если я запускаю команду sc start
, запускаемую процессом, и выполняю ее из локальной командной строки, она работает нормально.Он просто выдает ошибку 1060 при запуске с использованием Process, как указано выше
Code (метод Exists работает, метод Stop - нет)
public ManualWindowsServiceController(string serviceName, string machineName, string serviceAccountName, string serviceAccountPassword)
{
_serviceName = serviceName;
_machineName = machineName;
_serviceAccountName = serviceAccountName;
_securePassword = new SecureString();
foreach (var c in serviceAccountPassword)
_securePassword.AppendChar(c);
}
public void StopService()
{
var process = RunCommand("stop");
if (process == null) throw new InvalidOperationException($"Could not get service status for {_serviceName}");
while (!process.StandardOutput.EndOfStream)
{
var line = process.StandardOutput.ReadLine();
}
}
public bool Exists()
{
var process = RunCommand("query");
if (process == null) return false;
while (!process.StandardOutput.EndOfStream)
{
var line = process.StandardOutput.ReadLine();
if (line != null && line.ToLower().Contains("does not exist")) return false;
}
return true;
}
private Process RunCommand(string command)
{
var arguments = $"\\\\{_machineName} {command} {_serviceName}";
var psi = new ProcessStartInfo
{
FileName = "sc.exe",
WorkingDirectory = @"c:\",
Arguments = arguments,
UserName = _serviceAccountName,
Password = _securePassword,
Domain = "MyDomain",
CreateNoWindow = false,
UseShellExecute = false,
RedirectStandardOutput = true, WindowStyle = ProcessWindowStyle.Maximized
};
return Process.Start(psi);
}