Запустите EXE-файл из службы и остановите его, отправив SIGBREAK - PullRequest
0 голосов
/ 12 октября 2011

Я написал сервис, который запускает java.exe или ruby.exe (я знаю, что есть некоторые решения, но по каким-то причинам мне нужен собственный сервис).

Сервис работает до сих пор, ясобери мои конфиги из реестра, потом запусти сервисы.Когда служба останавливается, я получаю свои процессы и отправляю .Kill ().Все идет нормально.Но я обнаружил, что .Kill () является проблемой из-за того, что ruby.exe (я использую thin для запуска службы) или java.exe (я запускаю SOLR с ним) прослушивают порт сокета tcp,Если этот порт используется, и я уничтожаю процесс, окна будут блокировать порты на 72 секунды (по замыслу).

Если я сделаю solr: start и тонкий старт из командной оболочки оболочки и остановим егос помощью Ctrl + C процессы завершаются, и порт доступен для немедленного использования.

Поэтому я предполагаю: если мне удастся отправить ctrl-c процессу, он завершится правильно.

Итак, я нашел эту ветку Как запустить exe из службы Windows и остановить службу при выходе из процесса exe? , где размещено подтверждение концепции.Но, запустив процесс из оконной службы, у меня нет windowHandle.

Я запускаю свою службу следующим образом:

m_process.StartInfo = new ProcessStartInfo
                                  {
                                      FileName = "java"
                                      , Arguments = arguments
                                      , UseShellExecute = true
                                      , WorkingDirectory = workDirectory
                                      , CreateNoWindow = false
                                  };
m_process.Start();

Где аргументы связаны с данными причала для запуска SOLR илив случае с ruby ​​я использую «тонкий запуск ruby.exe ...».

Теперь при остановке службы я попытался:

[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32")]
public static extern int SetForegroundWindow(IntPtr hwnd);
[DllImport("user32.dll", SetLastError = true)]
public static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab);

foreach (int i in m_processList)
  {
    MyLogEvent(Process.GetProcessById(i).MainModule.ModuleName);
    MyLogEvent(Process.GetProcessById(i).MainWindowTitle);
    try
    {
      IntPtr ptr = FindWindow(null, Process.GetProcessById(i).MainWindowTitle);
      {
        SetForegroundWindow(ptr);
        Thread.Sleep(1000);
        InputSimulator.SimulateModifiedKeyStroke(VirtualKeyCode.CONTROL, VirtualKeyCode.CANCEL);
        // SendKeys.Send("^{BREAK}");
        Thread.Sleep(1000);
      }
      //Process.GetProcessById(i).Kill();
    }
    catch(Exception ex)
    {
      MyLogEvent(ex.ToString());
      Process.GetProcessById(i).Kill();
    }
  }

Но поскольку у меня нет WindowTitle,Я думаю, у меня даже нет окна, я не могу распределить процесс следующим образом.

Так есть ли у кого-нибудь идея, как я могу выделить процесс и отправить ему сигнал остановки?Я могу жить, просто убивая процесс, но перезапуск службы невозможен без долгого ожидания.Спасибо за любые подсказки, советы и решения.

1 Ответ

1 голос
/ 12 октября 2011

GenerateConsoleCtrlEvent может работать

 m_process.StartInfo = new ProcessStartInfo
                              {
                                  FileName = "java"
                                  , Arguments = arguments
                                  , UseShellExecute = true
                                  , WorkingDirectory = workDirectory
                                  , CreateNoWindow = false
                              };
 var process = m_process.Start();

Когда пора убивать дочернее приложение ...

 GenerateConsoleCtrlEvent(CTRL_C_EVENT, process.Id);

членские объявления

 public const UInt32 CTRL_C_EVENT = 0;

[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GenerateConsoleCtrlEvent(uint dwCtrlEvent,
   uint dwProcessGroupId);     
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...