Выполнить команду оболочки из сервиса

3

Я пытаюсь выполнить команду оболочки из созданной мной службы С#. Однако эта команда, похоже, не выполняется. Как стандартное консольное приложение, оно отлично работает, поэтому я знаю, что нет проблемы с самой командой или как она выполняется в коде. Может ли кто-нибудь сказать мне, почему это не сработает? Пожалуйста, имейте в виду, что я довольно новичок в С#, так что это может быть просто вопросом моей неопытности. Ниже приведен код из самой службы:

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
        }

    }
}
  • 1
    Является ли процесс, который вы запускаете, интерактивным (т.е. имеет ли он пользовательский интерфейс?). Если это так, это плохая новость - проверьте эту похожую ветку, в которой есть отличная информация stackoverflow.com/questions/4147821/…
  • 0
    Кстати, если это интерактивный процесс, вы все равно можете запустить его из службы, но для этого требуется использовать Win32 API, а не встроенную функциональность Process в .Net.
Показать ещё 3 комментария
Теги:
service

1 ответ

0

Если это приложение Windows, которое требует рабочего стола, вы в значительной степени SOL. Если это стандартное консольное приложение, вам необходимо перенаправить стандартный ввод, стандартный вывод и стандартную ошибку. Вам также необходимо установить для свойства ProcessStartInfo UseShellExecute значение false: вы не можете запустить оболочку ОС (cmd.exe), поскольку для этого требуется доступ к рабочему столу... и, кроме того, вы не можете перенаправить стандартный ввод с этим свойством, установленным на true.

Стандартный вход обычно подключается к клавиатуре. У вашей службы нет доступа к клавиатуре. Стандартная и стандартная ошибка обычно подключаются к окну консоли cmd.exe.

Как только у вас есть стандартный вывод и стандартная ошибка перенаправлена, вам нужно подключить обработчик к этим событиям Process объекта:

  • Exited. При завершении процесса.
  • OutputDataReceived. Поднят, когда данные записываются на стандартный вывод процесса (в действительности, происходит, когда любые буферы в выходном потоке очищаются, поэтому он может отставать от фактической операции записи).
  • ErrorDataReceived. Поднято, когда данные записываются в стандартную ошибку.

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

some-command 2>&1

перенаправить stdout и stderr в один и тот же дескриптор файла.

  • 0
    Эта конкретная утилита не требует рабочего стола. Это просто стандартное консольное приложение, которое выполняется с использованием нескольких аргументов, которые я указал с помощью myProcess.StartInfo.Arguments = "controlvm test setlinkstate1 off". Извините, но ваше объяснение немного над моей головой. Не могли бы вы рассказать мне немного об этом?
  • 0
    Это то, что я говорю. Если вы не укажете UseShellExecute = false ; , ваш исполняемый процесс будет запущен под экземпляром CMD.EXE. Для этого требуется рабочий стол, а ваша служба не имеет к нему доступа.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню