Вопрос по API
Нужна помощь с функцией CreateProcessWithLogonW
Почему то на компе где установлена среда C++ Builder она работает,
компилю проект со всеми библиотеками. На другом компе, программа запускается работает, но функция CreateProcessWithLogonW нет, не запускается.
С чем это может быть связано? Библиотеки? Инклюды добавлял windows.h результат тот же.
Про политики вряд ли на обоих компах с полными правами админа запускал. На обоих win7 максималка на одном 32x на другом 64x.
А может ли разрядность ос как то на работу функции влиять?
Где напечатано
Requirements
Minimum supported client - Windows XP [desktop apps only]
Minimum supported server - Windows Server 2003 [desktop apps only]
Про 7 ни слова.
Да может, но без документации(CreateProcessWithLogonW для 7 х64) трудно говорить, что-да-как.
Впиши в stdafx #define _WIN32_WINNT 0x0500 перед всеми инклудами
Что такое stdafx??
Это Windows 2000 // определение ядра _WIN32_WINNT_WIN2K (0x0500)
Windows 7 // определение ядра _WIN32_WINNT_WIN7 (0x0601)
родственная тема. Материал к ней в msdn.
Эти дефайны майкрософтовские, может в билдере не быть. Но, похоже, для XP это сработало. Попробуйте тоже xp-шные дефайны:
Про stdafx.h в билдере забудьте. Это пребилды из студии. Если интересно - читайте.
Дефайны впишите перед инклудами в main.cpp. Думаю, достаточно. И поройтесь еще в настройках целевой платформы в билдере, наверняка там такое есть (сам им не пользуюсь).
Если все это не поможет, тогда ручная загрузка из dll. Ваша ф-ция находится в Advapi32.dll. Кстати, неспроста 32. Выясните где ее на 64-битной платформе искать. Есть ли вообще.. Надежда на режим совместимости с xp или как его там правильно зовут.
Когда-то была
Эти дефайны майкрософтовские, может в билдере не быть. Но, похоже, для XP это сработало. Попробуйте тоже xp-шные дефайны:
Код:
#define WINVER 0x0501
#define _WIN32_WINNT 0x0501
#define _WIN32_WINNT 0x0501
Дефайны впишите перед инклудами в main.cpp. Думаю, достаточно. И поройтесь еще в настройках целевой платформы в билдере, наверняка там такое есть (сам им не пользуюсь).
Если все это не поможет, тогда ручная загрузка из dll. Ваша ф-ция находится в Advapi32.dll. Кстати, неспроста 32. Выясните где ее на 64-битной платформе искать. Есть ли вообще.. Надежда на режим совместимости с xp или как его там правильно зовут.
На компьютере B локально в моей программе функция CreateProcessWithLogonW не работает
На компьютере С локально в моей программе функция CreateProcessWithLogonW работает.
Когда цепляюсь через RDP с компа B на комп A, то на компе A функция CreateProcessWithLogonW в моей программе не работает.
Когда цепляюсь через RDP с компа С на комп А, то на компе А функция CreateProcessWithLogonW в моей программе работает.
Как так, что такого передается через RDP??
Куда кстати 32-битный комп исчез..
GetLastError выдает ошибку 1326, не могу чет описание найти ее.
если профиль руками создаешь то все работает. Почему может не создаваться профиль? то есть не происходит логирования.
кроме psexec, runas.
Я уже нашел что за ошибка, трабла в том что если у пользователя например User1 нет профиля (новый пользователь), то при попытке запустить приложение от имени User1 вываливается с ошибкой 1326, если профиль есть то без проблем отрабатывает. То есть конкретно в логине и пароле ошибок нет.
Цитата: Patr1ot
Я уже нашел что за ошибка, трабла в том что если у пользователя например User1 нет профиля (новый пользователь), то при попытке запустить приложение от имени User1 вываливается с ошибкой 1326, если профиль есть то без проблем отрабатывает. То есть конкретно в логине и пароле ошибок нет.
По умолчанию, функция CreateProcessWithLogonW не загружает заданный профиль пользователя в ключ системного реестра HKEY_USERS. Это означает, что доступ к информации в ключе системного реестра HKEY_CURRENT_USER, не может достичь результатов совместимых с нормальным интерактивным входом в систему. Это является вашей ответственностью загрузить древо системного реестра пользователя в HKEY_USERS перед вызовом CreateProcessWithLogonW, используя, или LOGON_WITH_PROFILE, или вызывая функцию LoadUserProfile.
источник
P/S
По ходу CreateProcessWithLogonW должна работать с 7 - 8
To compile an application that uses this function, define _WIN32_WINNT as 0x0500 or later.
For more information, see Using the Windows Headers.
For more information, see Using the Windows Headers.
sorry - мой bag.
Хотел спросить версию C++ Builder and OS ?
P.S. Для получения описания ошибки с переводом можно использовать примерно такую ф-цию (немного переделал из примера в MSDN - см. printError):
Код:
//С использованием материала http://msdn.microsoft.com/en-us/library/windows/desktop/ms686701(v=vs.85).aspx
//(изменил реализацию)
void printError(const char* msg) {
DWORD eNum = GetLastError();
const int BUF_SZ = 1024; //должно хватить
char sysMsg[BUF_SZ];
FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, eNum,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
sysMsg, BUF_SZ, NULL );
sysMsg[strlen(sysMsg)-2] = '\0'; //затираем лишнии символы, обрывая нулем
printf("\nВНИМАНИЕ: %s завершилась неудачно с ошибкой %lu (%s)", msg, eNum, sysMsg);
}
//(изменил реализацию)
void printError(const char* msg) {
DWORD eNum = GetLastError();
const int BUF_SZ = 1024; //должно хватить
char sysMsg[BUF_SZ];
FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, eNum,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
sysMsg, BUF_SZ, NULL );
sysMsg[strlen(sysMsg)-2] = '\0'; //затираем лишнии символы, обрывая нулем
printf("\nВНИМАНИЕ: %s завершилась неудачно с ошибкой %lu (%s)", msg, eNum, sysMsg);
}
Можно еще так - с передачей буфера по ссылке и номера ошибки:
Код:
//описание системной ошибки по ее номеру
template< int BUF_SZ > //размер буфера для описания
void errorDescription(DWORD errorNum, char (&descr)[BUF_SZ]) {
FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, errorNum,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
descr, BUF_SZ, NULL );
descr[strlen(descr)-2] = '\0'; //затираем лишнии символы, обрывая нулем
}
template< int BUF_SZ > //размер буфера для описания
void errorDescription(DWORD errorNum, char (&descr)[BUF_SZ]) {
FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, errorNum,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
descr, BUF_SZ, NULL );
descr[strlen(descr)-2] = '\0'; //затираем лишнии символы, обрывая нулем
}
Код:
DWORD er = GetLastError();
char descEr[1024]; //с запасом
errorDescription(er, descEr);
char descEr[1024]; //с запасом
errorDescription(er, descEr);
1)С.Х. Дьюхэрст. «Скользкие места С++. Как избежать проблем при проектировании и компиляции ваших программ», 2006, «Совет 5».
2)http://forum.codenet.ru/q73579
Первое нужно прогу запускать от имени администратора. ИМХО UAC.
Второе, при внесение данных в переменные ( значения Login, Password, command line ), нужно указывать L"Login " , L"Password"
Тогда все ок, и профиль создается.
P.S а подскажите что эта L дает перед текстом?
Без проблем работает Windows 7, 8 , Server 2008, Server 2012 Любой архитектуры
Это литерал для типа wchar_t - массива.
Буковка W в конце имени Api-функций недвусмысленно намекает, что ф-ция для работы c wchar_t.
CreateProcessWithLogonW. Для нее насколько знаю ansi-варианта нет.
Думал вы знаете..
А это литерал для wchar_t символа (например a):
L'a'; //одинарные кавычки
С русскими буквами могут быть проблемы. Исходник лучше делать в utf-8 тогда. См. здесь, например.