Я пытаюсь запустить приложение с графическим интерфейсом из службы Windows. Но когда я вызываю функцию CreateEnvironmentBlock (), она на некоторое время зависает, а затем вылетает диалоговое окно с сообщением «SampleService.exe перестал работать и был закрыт. Из-за проблемы приложение перестало работать правильно. Windows сообщит вам, если решение доступно. » Ниже мой код.
DWORD dwSessionId = 0; // Session ID
HANDLE hToken = NULL; // Active session token
HANDLE hDupToken = NULL; // Duplicate session token
WCHAR szErr[1024] = {0};
STARTUPINFO* startupInfo;
PROCESS_INFORMATION processInformation;
PWTS_SESSION_INFO pSessionInfo = 0;
DWORD dwCount = 0;
LPVOID lpEnvironment = NULL; // Environtment block
OutputDebugString(_T("My Sample Service: startApplication: Entry"));
// Get the list of all terminal sessions
WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &dwCount);
int dataSize = sizeof(WTS_SESSION_INFO);
// look over obtained list in search of the active session
for (DWORD i = 0; i < dwCount; ++i)
{
WTS_SESSION_INFO si = pSessionInfo[i];
if (WTSActive == si.State)
{
// If the current session is active – store its ID
dwSessionId = si.SessionId;
break;
}
}
OutputDebugString(_T("My Sample Service: startApplication: freewtsmemory"));
WTSFreeMemory(pSessionInfo);
OutputDebugString(_T("My Sample Service: startApplication: WTSQueryUserToken"));
// Get token of the logged in user by the active session ID
BOOL bRet = WTSQueryUserToken(dwSessionId, &hToken);
if (!bRet)
{
swprintf(szErr, _T("WTSQueryUserToken Error: %d"), GetLastError());
OutputDebugString(szErr);
return false;
}
OutputDebugString(_T("My Sample Service: startApplication: duplicatetokenex"));
// Get duplicate token from the active logged in user's token
bRet = DuplicateTokenEx(hToken, // Active session token
TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, // Desired access
NULL, // Token attributes
SecurityImpersonation, // Impersonation level
TokenPrimary, // Token type
&hDupToken); // New/Duplicate token
if (!bRet)
{
swprintf(szErr, _T("DuplicateTokenEx Error: %d"), GetLastError());
OutputDebugString(szErr);
return false;
}
// Get all necessary environment variables of logged in user
// to pass them to the process
OutputDebugString(_T("My Sample Service: startApplication: createenvironmentblock"));
try{
bRet = CreateEnvironmentBlock(&lpEnvironment, hDupToken, FALSE);
}
catch( const exception &e)
{
swprintf(szErr, _T("CreateEnvironmentBlock Exception: %s"), e);
OutputDebugString(szErr);
return false;
}
if(!bRet)
{
swprintf(szErr, _T("CreateEnvironmentBlock Error: %d"), GetLastError());
OutputDebugString(szErr);
return false;
}// Initialize Startup and Process info
startupInfo->cb = sizeof(STARTUPINFO);
OutputDebugString(_T("My Sample Service: startApplication: createprocess"));
// Start the process on behalf of the current user
BOOL returnCode = CreateProcessAsUser(hDupToken,
NULL,
L"C:\\KM\\TEST.exe",
NULL,
NULL,
FALSE,
NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT,
lpEnvironment,
NULL,
startupInfo,
&processInformation);
if( !returnCode)
{
swprintf(szErr, _T("CreateProcessAsUser Error: %d"), GetLastError());
OutputDebugString(szErr);
return false;
}
CloseHandle(hDupToken);
return true;
Он показывает «My Sample Service: startApplication: createenvironmentblock» в отладочном виде и остановленном сервисе. пожалуйста, помогите мне в этом вопросе. пожалуйста, обратите внимание, что я использую Windows Vista.
С Уважением,
KM.
Вам нужно инициализировать указатели, прежде чем вы сможете использовать их определенным образом.
STARTUPINFO* startupInfo;
...
startupInfo->cb = sizeof(STARTUPINFO);
Эта ошибка могла бы быть более очевидной, если бы ваши переменные были объявлены ближе к месту их использования. Если вы следуете некоторому правилу, согласно которому переменные могут быть объявлены только в начале функции, вы можете рассмотреть возможность создания большего количества функций.
И, что стоит, при устранении подобных проблем вы всегда можете подключить отладчик Visual Studio к процессу службы, а не полагаться на OutputDebugString
, Просто убедитесь, что сервисный процесс — это последняя вещь, созданная Visual Studio, и процесс, файлы символов и исходный код должны быть выровнены.
Других решений пока нет …