問題描述:
作業系統是Win10 64位。自己寫了一個視窗應用(32位),就叫它DemoWin.exe吧,把它放到 C:\Windows\System32 檔案夾下。然後安裝了一個服務(32位),在服務裡調用CreateProcessAsUser建立 DemoWin.exe 程序。代碼如下:
dwSessionId = WTSGetActiveConsoleSessionId();
WTSQueryUserToken(dwSessionId, &hUserToken); //讀取目前登入使用者的令牌資訊
dwCreationFlags = CREATE_NEW_CONSOLE;//建立參數
ZeroMemory(&si,sizeof(STARTUPINFO));
ZeroMemory(&pi,sizeof(pi));
si.cb = sizeof(STARTUPINFO);
si.lpDesktop = "winsta0\\default"; //指定建立程序的視窗站,Windows下唯一可互動的視窗站就是WinSta0\Default
//設定目前程序的令牌資訊
if (!SetTokenInformation(hUserToken, TokenSessionId, (void*)&dwSessionId, sizeof(DWORD)))
{
dwRet = GetLastError();
return FALSE;
}
//建立程序環境塊,保證環境塊是在使用者桌面的環境下
LPVOID pEnv = NULL;
if (CreateEnvironmentBlock(&pEnv, hUserTokenDup, TRUE))
{
dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
}
//建立使用者程序
if (!CreateProcessAsUser(hUserToken, NULL, lpCommand, NULL, NULL, FALSE, dwCreationFlags, pEnv, NULL, &si, &pi))
{
dwRet = GetLastError();
return FALSE;
}
CreateProcessAsUser 失敗,傳回錯誤碼0x00000002(ERROR_FILE_NOT_FOUND)
問題原因:
剛開始以為是權限問題,後來搜尋網上才發現,原來是路徑問題。
在Windows7 64位作業系統下,VisualStudio編譯32位應用,調用CreateProcess運作System32檔案夾下檔案會失敗,GetLastError傳回值是2。查詢Error Lookup傳回資訊:系統找不到指定檔案。
其原因在于64位作業系統對于32位程式調用System32下檔案的處理方式。對于64位作業系統來說,C:\Windows\System32檔案夾不再是系統檔案夾,而是為64位作業系統預留的。當同名的64位和32位DLL同時存在于一個系統之中時,system32用于存儲32位DLL,并且這些DLL是為64位應用調用的。因為file system redirector機制的存在,SysWOW64透明化了不同位檔案的調用。
如果一個32位應用程式需要調用System32下的檔案,最好改用Sysnative這個System32的别名,否則将調用失敗。實際上,并不存在Sysnative這個檔案夾,這隻是Windows為32位應用開發者提供的一種便利,64位應用中并不能使用它。
參考資料:https://blog.csdn.net/csyounth/article/details/7847492