Проблема С++ LPTSTR с вызовом CreateProcessAsUser с помощью getenv

Я пытаюсь вызвать функцию CreateProcessAsUser. Передача постоянной строки в порядке. Попытка подобрать переменную среды с помощью char* getenv(const char name) вызывает у меня проблему.

Если я использую следующее, notepad.exe запустится.

CreateProcessAsUser(hTokenDup, _T("c:\\windows\\notepad.exe"), 
                    _T("c:\\windows\\notepad.exe"), NULL, NULL, FALSE,
                    dwCreationFlag, pEnvironment, NULL, &si, &pi);

Однако, если я использую следующее, ничего не запускается.

CreateProcessAsUser(hTokenDup, _T("MyAppName"), 
                    (LPTSTR)getenv("MYENVVAR"), NULL, NULL, FALSE,
                    dwCreationFlag, pEnvironment, NULL, &si, &pi);

Правильно ли я указал getenv и (LPTSTR)?

Я пытался использовать переменные среды пользователя и системы, содержащие c:\\windows\\notepad.exe и c:\windows\notepad.exe.

Спасибо!


person fred    schedule 01.07.2011    source источник
comment
Избавьтесь от приведения к (LPTSTR) — если компилятор выдает вам сообщение об ошибке без приведения, то вставка приведения, чтобы закрыть компилятор, неправильно. Компилятор пытается вам что-то сказать. В этом случае вы компилируете приложение Unicode и пытаетесь передать строку ANSI, когда ожидается строка Unicode — используйте _tgetenv вместо getenv.   -  person Adam Rosenfield    schedule 02.07.2011
comment
Вы знаете, удалось ли getenv?   -  person Billy ONeal    schedule 02.07.2011
comment
Используйте _wgetenv() для решения вашей проблемы, подчеркивание-t является архаичным. Лучше всего установить для второго аргумента значение NULL, а для третьего аргумента — аргументы exepath + +. Это гарантирует, что некоторые программы C, которые полагаются на argv[0], являющийся путем к программе, не перестанут работать. CreateProcess — это ракетостроение.   -  person Hans Passant    schedule 02.07.2011


Ответы (2)


Третий параметр, lpCommandLine, равен LPTSTR, что означает, что это должна быть память с возможностью записи. Вам нужно скопировать командную строку в записываемую строку перед вызовом CreateProcessAsUser.

В документации для getenv указано:

Небезопасно изменять значение переменной среды с помощью возвращенного указателя.

Поэтому вы не можете передать это как параметр lpCommandLine для CreateProcessAsUser.

Ваш первый вызов CreateProcessAsUser тоже кажется неверным, поскольку вы также не передаете доступную для записи память для lpCommandLine.

Конечно, наиболее вероятно, что ваша непосредственная проблема заключается в том, что вы смешиваете ANSI и Unicode. Если ваше приложение использует Unicode, вам нужно вызвать _wgetenv или _tgetenv, если вы действительно хотите ориентироваться как на ANSI, так и на Unicode из одного и того же источника. Но убедитесь, что вы скопировали его в доступный для записи буфер, прежде чем передавать его дальше.

Наконец, как заметил Адам, каждый раз, когда вы пишете состав, велика вероятность того, что вы совершаете ошибку.

person David Heffernan    schedule 01.07.2011
comment
Ах, хороший звонок, я забыл, что функции *getenv возвращают только для чтения, но не const указатели. О том, почему CreateProcessAsUser и CreateProcess требуются командные строки с возможностью записи, см. Почему функция CreateProcess изменяет свою входную командную строку?. - person Adam Rosenfield; 02.07.2011

getenv() всегда будет возвращать char* независимо от того, какой набор символов настроен для использования вашим приложением. Вместо этого попробуйте использовать _tgetenv(), так как он настраивается между char* и wchar_t* по мере необходимости.

person Darryl    schedule 01.07.2011