2015-07-01 2 views
0

Я работаю над установщиком, который копирует файлы в Program Files, а затем запускает службу (через один из файлов, которые были скопированы). При первой установке это будет работать без проблем, но проблемы начнут возникать при запуске установщика, и служба уже запущена на машине. Это связано с тем, что установщик пытается заменить файлы, которые уже существуют в Program Files, но один из этих файлов используется службой Windows, поэтому его нельзя заменить, если служба не остановлена.API ServiceController не узнает, что служба остановлена ​​

Поэтому я решил использовать API ServiceController для остановки службы при начале установки, установки файлов (перезаписи существующих файлов) и начала обслуживания снова. Существует очень мало кода, но здесь это:

Instantiate ServiceController:

try 
{ 
    service = new ServiceController(serviceName); 
} 
catch (InvalidOperationException ioe) 
{ 
    // ... 
} 

Остановка службы:

if (service.Status != ServiceControllerStatus.Stopped) 
{ 
    service.Stop(); 
} 

Тогда ждать службу, чтобы остановить и установить файлы :

service.WaitForStatus(ServiceControllerStatus.Stopped); 
// install files... 

И, наконец, перезапустить службу:

service.Start(); 

С помощью этого кода метод service.WaitForStatus() будет просто ждать вечно (или дольше, чем я готов ждать как минимум - до часа). Странно, что я могу запустить этот код, напишите service.Status() в журнал, проверьте службу вручную, чтобы убедиться, что она остановлена, проверьте журнал и посмотрите, что ServiceController считает, что служба все еще запущена.

Сначала я подумал, что этот вопрос с service.Stop() поэтому я попытался создать пару Process объектов, которые получили PID службы, а затем убили задание, которое останавливает службу немедленно, но до сих пор ServiceController не распознают, что служба имеет остановился. Если я удалю метод service.WaitForStatus() из своего кода, будет создано исключение, поскольку установщик пытается перезаписать файл, который используется службой.

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

Почему ServiceController не признает, что услуга прекращена? Есть ли решение или обходное решение этой проблемы? Я работаю с .NET 2.0, поэтому все, что требует выше, к сожалению, не является для меня вариантом. Приветствия.

ответ

0

Этот ответ может быть не соответствующим вашему вопросу, но может дать представление. Я также столкнулся пару вопроса при остановке услуг с помощью «ServiceController», а также, как указано в этой статье Read EricJ reply, я осуществил, как показано ниже

service.Stop(); 

service.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromMinutes(5)); 

ServiceController ждет в течение 5 минут, чтобы остановить службу, если не бросает TimeoutException где я m вызывает команду TaskKill, чтобы убить процесс. Ниже приведен код

using (Process process = new Process()) 
      { 
       try 
       { 
        string arguments = "/F /T /IM {0}"; 
        process.StartInfo.FileName = "taskkill"; 
        process.StartInfo.Arguments = string.Format(arguments, processName); ; 
        process.StartInfo.UseShellExecute = false; 
        process.StartInfo.RedirectStandardOutput = true; 
        process.StartInfo.RedirectStandardError = true; 

        StringBuilder output = new StringBuilder(); 
        StringBuilder error = new StringBuilder(); 

        using (AutoResetEvent outputWaitHandle = new AutoResetEvent(false)) 
        using (AutoResetEvent errorWaitHandle = new AutoResetEvent(false)) 
        { 
         process.OutputDataReceived += (sender, e) => 
         { 
          if (e.Data == null) 
          { 
           outputWaitHandle.Set(); 
          } 
          else 
          { 
           output.AppendLine(e.Data); 
          } 
         }; 
         process.ErrorDataReceived += (sender, e) => 
         { 
          if (e.Data == null) 
          { 
           errorWaitHandle.Set(); 
          } 
          else 
          { 
           error.AppendLine(e.Data); 
          } 
         }; 

         process.Start(); 
         process.BeginOutputReadLine(); 
         process.BeginErrorReadLine(); 

         if (process.WaitForExit(timeout) && 
          outputWaitHandle.WaitOne(timeout) && 
          errorWaitHandle.WaitOne(timeout)) 
         { 
          if (process.ExitCode == 0) 
           // Success Message 
         } 
         else 
         { 
          // Fail Message 
         } 
        } 
        if (!string.IsNullOrEmpty(output.ToString())) 
         //Out put 

        if (!string.IsNullOrEmpty(error.ToString())) 
         //Error out put 
       } 
       catch (Exception ex) 
       { 
        Comments = ex.Message; 
        //Exception logging 
       } 
      } 
Смежные вопросы