Почему я не могу запустить командный файл из службы с помощью system () в Windows Server 2008?

У меня есть программа C ++, которая работает как служба на 64-разрядной машине с Windows Server 2008. Эта программа пытается запустить командный файл с помощью следующей команды:

system(C:\pathtofile\file.bat)

В 32-битной Windows Server 2003 это работало нормально (пакетный файл был выполнен), но в Windows Server 2008 пакетный файл не выполняется, и я получаю возвращаемое значение 0xC0000142 (у меня был пакетный файл, записывающий некоторый текст в файл как тест, чтобы увидеть, если он выполняется). Я на самом деле получаю то же возвращаемое значение, даже если пытаюсь выполнить то, чего не существует.

Я читал об изоляции сеанса 0 в Windows Server 2008, поэтому я использовал psexec для запуска командной строки в сеансе 0 в качестве того же пользователя домена, который указан как пользователь «Вход в систему» ​​для службы:

psexec -i 0 -u DOMAIN\serviceuser -p passwd cmd.exe

Затем я смог успешно выполнить командный файл из командной строки.

Пользователь домена, который указан как пользователь «Вход в систему» ​​для службы, находится в группе «Администраторы». Кроме того, если я запускаю приложение C ++ вручную (не как службу), оно запускает командный файл.

Так есть ли что-то в изоляции сеанса 0, которая делает вызов system () не работающим при работе в качестве службы? Или какое-то другое объяснение изменения поведения? Я знаю, что system () не обязательно лучший способ сделать это в любом случае, но я ищу фактическую причину, по которой это больше не работает.

1

Решение

Из того, что я теперь понимаю о проблеме, причина того, что вы не можете запустить командный файл из службы с помощью system () в Windows Server 2008, заключается в том, что Windows рассматривает любую попытку вызова cmd.exe (как это было бы для запуска вашего пакета). файл) как попытка запуска интерактивного сервиса. Из-за изоляции сеанса 0 это недопустимо и просто не удастся, даже если вы не думаете, что ваш командный файл является интерактивным или имеет графический интерфейс (который меня отбрасывал).

Я понял, как получить эффект, который искал, используя CreateProcess. Ключевым моментом здесь является то, что вы должны установить для параметра dwCreationFlags значение CREATE_NO_WINDOW. Так что мой (упрощенный) вызов в итоге выглядел примерно так:

CreateProcess(NULL,   // No module name (use command line)
L"C:\\Windows\\System32\\cmd.exe /C myfile.bat", // Call cmd.exe with /C flag
NULL,           // Process handle not inheritable
NULL,           // Thread handle not inheritable
FALSE,          // Set handle inheritance to FALSE
CREATE_NO_WINDOW,              // Use CREATE_NO_WINDOW!!!
NULL,           // Use parent's environment block
NULL,           // Use parent's starting directory
&si,            // Pointer to STARTUPINFO structure
&pi )           // Pointer to PROCESS_INFORMATION structure
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]