2016-03-16 4 views
1

Я использую это для вызова powershell, но даже если я использую CREATE_NO_WINDOW, этот код является C & P из моего предыдущего вызова system(). Но это не работает. обновленный код (до сих пор не работает):Как вызвать powershell в C++ без окна

LPWSTR PSPath = env(_TEXT("SystemRoot")); 
LPWSTR TEMP2 = env(_TEXT("TEMP")); 
LPWSTR HOMEDRIVE = env(_TEXT("HOMEDRIVE")); 
LPWSTR PSPathexe = (_TEXT("%s\\system32\\WindowsPowerShell\\v1.0\\powershell.exe -Executionpolicy bypass -File \"%s\\psscript.ps1\" -Filename psscript -Folderpath \"%s\\deployment\""),PSPath,TEMP2, HOMEDRIVE); 
STARTUPINFO si; 
PROCESS_INFORMATION pi; 

ZeroMemory(&si, sizeof(si)); 
si.cb = sizeof(si); 
ZeroMemory(&pi, sizeof(pi)); 

CreateProcess(NULL, PSPathexe, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi); 
+0

Вы пытались использовать опцию '-WindowStyle Hidden'? –

+0

Да, все еще не работает. И я нашел ошибку, раньше был вызов system() для powershell. Приведенный выше код даже не работает =/ – Marabunta

+0

Инициализация указателя на non-'const' с литералом недействительна с C++ 11, набор правил, который определяет этот бит. По крайней мере, два аргумента «CreateProcess», где вы предоставляете 0, не принимают 0, согласно документации Microsoft, которая является набором правил, который определяет бит * этого *. ** читать документацию **. –

ответ

1

Во-первых, линия

LPWSTR command=(_TEXT("powershell.exe -Executionpolicy bypass -File \"%deploy%\\psscript.ps1\" -Filename psscript -Folderpath \"%HOMEDRIVE%\\deployment\"")); 

& hellip; имеет три серьезные проблемы:

  • LPWSTR макрос Microsoft, которая расширяется до wchar_t*, в то время как инициализатор сводится к буквальным, который представляет собой массив символов const. Это удаление const было устаревшим в C++ 98 уже (первый стандарт C++) и было удалено – теперь недействительно – в C++ 11.

  • _TEXT - макрос Microsoft, который добавляет префикс L к литералу, если задан макрокоманда _UNICODE. Это было когда-то частью схемы обеспечения совместимости с Windows 95, пока Layer для Unicode не был введен в 2000 году. Сейчас мы находимся Через 16 лет после этого устаревшим, и к началу, вы просто получите ошибку компиляции если вы не определяете _UNICODE, потому что вы не используете схему везде, если требуется.

  • %HOMEDRIVE% в строке является синтаксисом интерпретатора команд для расширения переменной окружения. Я не уверен на 100%, только 99,8% или около того, но, насколько я помню, CreateProcess не обладает этой функциональностью.

Проблема типа (первая точка пули) может быть исправлена ​​с использованием локального массива, например.

wchar_t command[] = L"notepad.exe"; 

Отметьте, что CreateProcess требует, чтобы это можно было писать. Таким образом, даже с компилятором, который принимает исходное объявление, вы должны быть выключены в Неопределенное поведение Земля, с кодом, потенциально пытающимся изменить литерал.

Проблема переменных окружения может быть устранена путем расширения этой переменной до построения командной строки. Для этого я бы использовал std::wstring. Это помогает с конкатенацией и тому подобным.


Затем вызов

CreateProcess(NULL, command, NULL, NULL, NULL, CREATE_NO_WINDOW, NULL, NULL, NULL, NULL); 

& hellip; предоставляет NULL аргумент, в котором возвращаются обработчики процессов и потоков, а также аргумент, определяющий информацию о запуске. Это не сработает. Прочтите документацию.


Советы:

  1. Если вы попробуете CreateProcess с некоторой простой задачей в виду, например,запустив «Блокнот», вы можете узнать, как правильно называть его с меньшими усилиями.

  2. Вы можете найти ShellExecute или ShellExecuteEx предпочтительнее основного CreateProcess (оговорке: Я не проверил, поддерживают ли они без окон исполнения, но это, скорее всего, они делают).

Смежные вопросы