HINSTANCE res = ShellExecute(m_hWnd,"open","e:\\a.chm",NULL,"e:\\",SW_SHOWMAXIMIZED);
是的,后台服务启动前台与用户交互的程序,这个没问题,就是某些早期类似自动化的东西运行没有结果,比如HINSTANCE res = ShellExecute(m_hWnd,"open","e:\\a.chm",NULL,"e:\\",SW_SHOWMAXIMIZED);返回值是成功的,但帮助文件a.chm并不会打开,还有比这个更重要的,也没法改的东西也不能运行
{
DWORD dwRet = 0;
PROCESS_INFORMATION pi ;
STARTUPINFO si ;
DWORD dwSessionId ;
HANDLE hUserToken = NULL;
HANDLE hUserTokenDup = NULL;
HANDLE hPToken = NULL;
HANDLE hProcess = NULL;
DWORD dwCreationFlags ; HMODULE hInstKernel32 = NULL;
typedef DWORD (WINAPI * WTSGetActiveConsoleSessionIdPROC)();
WTSGetActiveConsoleSessionIdPROC WTSGetActiveConsoleSessionId = NULL; hInstKernel32 = LoadLibrary ("Kernel32.dll" ); if (!hInstKernel32 )
{
return FALSE ;
} OutputDebugString("LaunchAppIntoDifferentSession 1\n" );
WTSGetActiveConsoleSessionId = (WTSGetActiveConsoleSessionIdPROC )GetProcAddress( hInstKernel32,"WTSGetActiveConsoleSessionId" );
// Log the client on to the local computer.
dwSessionId = WTSGetActiveConsoleSessionId (); do
{
WTSQueryUserToken( dwSessionId ,&hUserToken );
dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
ZeroMemory( &si , sizeof( STARTUPINFO ) );
si.cb = sizeof( STARTUPINFO );
si.lpDesktop = "winsta0\\default" ;
ZeroMemory( &pi , sizeof( pi) );
TOKEN_PRIVILEGES tp ;
LUID luid ; if( !::OpenProcessToken ( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY
| TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_SESSIONID
| TOKEN_READ | TOKEN_WRITE , &hPToken ) )
{
dwRet = GetLastError ();
break;
}
else; if ( !LookupPrivilegeValue ( NULL, SE_DEBUG_NAME, &luid ) )
{
dwRet = GetLastError ();
break;
}
else;
tp.PrivilegeCount =1;
tp.Privileges [0].Luid = luid;
tp.Privileges [0].Attributes = SE_PRIVILEGE_ENABLED; if( !DuplicateTokenEx ( hPToken, MAXIMUM_ALLOWED, NULL , SecurityIdentification , TokenPrimary, & hUserTokenDup ) )
{
dwRet = GetLastError ();
break;
}
else; //Adjust Token privilege
SetTokenInformation ( hUserTokenDup,TokenSessionId ,(void*)& dwSessionId,sizeof (DWORD) ); if( !AdjustTokenPrivileges ( hUserTokenDup, FALSE, &tp , sizeof(TOKEN_PRIVILEGES ), (PTOKEN_PRIVILEGES) NULL, NULL ) )
{
dwRet = GetLastError ();
break;
}
else; LPVOID pEnv =NULL;
if( CreateEnvironmentBlock ( &pEnv, hUserTokenDup, TRUE ) )
{
dwCreationFlags|=CREATE_UNICODE_ENVIRONMENT ;
}
else pEnv =NULL; // Launch the process in the client's logon session.
if( CreateProcessAsUser ( hUserTokenDup, // client's access token
NULL, // file to execute
lpCommand, // command line
NULL, // pointer to process SECURITY_ATTRIBUTES
NULL, // pointer to thread SECURITY_ATTRIBUTES
TRUE, // handles are not inheritable
dwCreationFlags,// creation flags
pEnv, // pointer to new environment block
lpWorkDir, // name of current directory
& si, // pointer to STARTUPINFO structure
& pi // receives information about new process
) )
{
}
else
{
dwRet = GetLastError ();
break;
}
}
while( 0 ); //Perform All the Close Handles task
if( NULL != hUserToken )
{
CloseHandle( hUserToken );
}
else; if( NULL != hUserTokenDup)
{
CloseHandle( hUserTokenDup );
}
else; if( NULL != hPToken )
{
CloseHandle( hPToken );
}
else; return dwRet ;
}
EnablePrivilege(hUserTokenDup,SE_ASSIGNPRIMARYTOKEN_NAME);
EnablePrivilege(hUserTokenDup,SE_LOCK_MEMORY_NAME);
EnablePrivilege(hUserTokenDup,SE_INCREASE_QUOTA_NAME);
EnablePrivilege(hUserTokenDup,SE_UNSOLICITED_INPUT_NAME);
EnablePrivilege(hUserTokenDup,SE_MACHINE_ACCOUNT_NAME);
EnablePrivilege(hUserTokenDup,SE_TCB_NAME);
EnablePrivilege(hUserTokenDup,SE_SECURITY_NAME);
EnablePrivilege(hUserTokenDup,SE_TAKE_OWNERSHIP_NAME);
EnablePrivilege(hUserTokenDup,SE_LOAD_DRIVER_NAME); EnablePrivilege(hUserTokenDup,SE_SYSTEM_PROFILE_NAME);
EnablePrivilege(hUserTokenDup,SE_SYSTEMTIME_NAME);
EnablePrivilege(hUserTokenDup,SE_PROF_SINGLE_PROCESS_NAME);
EnablePrivilege(hUserTokenDup,SE_INC_BASE_PRIORITY_NAME);
EnablePrivilege(hUserTokenDup,SE_CREATE_PAGEFILE_NAME);
EnablePrivilege(hUserTokenDup,SE_CREATE_PERMANENT_NAME);
EnablePrivilege(hUserTokenDup,SE_BACKUP_NAME);
EnablePrivilege(hUserTokenDup,SE_RESTORE_NAME);
EnablePrivilege(hUserTokenDup,SE_SHUTDOWN_NAME);
EnablePrivilege(hUserTokenDup,SE_DEBUG_NAME); EnablePrivilege(hUserTokenDup,SE_AUDIT_NAME);
EnablePrivilege(hUserTokenDup,SE_SYSTEM_ENVIRONMENT_NAME);
EnablePrivilege(hUserTokenDup,SE_CHANGE_NOTIFY_NAME);
EnablePrivilege(hUserTokenDup,SE_REMOTE_SHUTDOWN_NAME);
EnablePrivilege(hUserTokenDup,SE_UNDOCK_NAME);
EnablePrivilege(hUserTokenDup,SE_SYNC_AGENT_NAME);
EnablePrivilege(hUserTokenDup,SE_ENABLE_DELEGATION_NAME);
EnablePrivilege(hUserTokenDup,SE_MANAGE_VOLUME_NAME);
EnablePrivilege(hUserTokenDup,SE_IMPERSONATE_NAME);
EnablePrivilege(hUserTokenDup,SE_CREATE_GLOBAL_NAME); EnablePrivilege(hUserTokenDup,SE_TRUSTED_CREDMAN_ACCESS_NAME);
EnablePrivilege(hUserTokenDup,SE_RELABEL_NAME);
EnablePrivilege(hUserTokenDup,SE_INC_WORKING_SET_NAME);
EnablePrivilege(hUserTokenDup,SE_TIME_ZONE_NAME);
EnablePrivilege(hUserTokenDup,SE_CREATE_SYMBOLIC_LINK_NAME);35个许可基本都是成功的BOOL EnablePrivilege(HANDLE hToken, LPCTSTR lpszPrivilegeName)
{
TOKEN_PRIVILEGES tkp = {0};
BOOL bRet = LookupPrivilegeValue( NULL, lpszPrivilegeName, &tkp.Privileges[0].Luid );
if(!bRet) return FALSE; tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
bRet = AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL ); return bRet;
}
被启动的进程里的 ShellExecute 不能执行是环境块的问题吗? ShellExecute里的参数给的是全路径,参数本身不依赖环境块
在服务中CreateProcessAsUser 启动过一个win32 console application,然后再console application中启动你的GUI窗口程序。