Reputation: 59
I have two processes in my app. 1. "myService.exe" which is a windows service. 2. "myApp.exe" which is located in the same directory as "myService.exe".
This process is spawned by "myService.exe" using the CreateProcessAsUser api. We have to use this api instead of directly starting the process (using system call) as we need to access the current user's vpn profiles.
When I hard code the path of "myApp.exe", it works fine and process is created but the same path got by getting current directory of "myService.exe" is not creating the process and returning the errorcode 2 (File Not Found).
I'm using Visual Studio 2008. The project is compiled in ASCII mode and not Unicode in code below. I tried using Unicode api's (without the 'A' in the end). It didn't work either.
The problem isn't in getting the current path. It is verified that the path is not the System32 folder.
HANDLE hToken;
LPSTR exePath = GetCommandLineA();
string exePathStr = exePath;
char fileExeChar[256];
strcpy(fileExeChar,exePathStr.c_str());
string serverExe = "myService.exe";
for(unsigned int i=0;i<exePathStr.length()-(serverExe.length() + 1);i++)
{
fileLocation += fileExeChar[i];// removing the service.exe from the path
}
LPSTR fileLocationLp = const_cast<LPSTR>(fileLocation.c_str());
LPCSTR progName = (LPCSTR)"myapp.exe";
char errStr[100];
DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
STARTUPINFO si;
PROCESS_INFORMATION pi;
int k = WTSQueryUserToken (WTSGetActiveConsoleSessionId (), &hToken);
ZeroMemory( &si, sizeof( STARTUPINFO ) );
si.cb = sizeof( STARTUPINFO );
si.lpDesktop = (LPSTR)"winsta0\\default";
ZeroMemory( &pi,sizeof(pi));
if ( !CreateProcessAsUserA(
hToken,
progName,
fileLocationLp,
NULL,
NULL,
FALSE,
dwCreationFlag,
NULL,
NULL,
&si,
&pi
) )
{
sprintf(errStr, "CreateProcessAsUser Failed %d\n", GetLastError());
}
else
{
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
CloseHandle(hToken);
}
Upvotes: 2
Views: 9089
Reputation: 121961
Windows Services, by default, execute in the System32
directory. This is why it cannot find the other executable when the absolute path of it is not specified. You can confirm this by obtaining the GetCurrentDirectory()
from the Windows Service.
To resolve this (assuming the Windows Service and the other executable reside in the same directory):
GetModuleFileName()
, passing NULL
as the first argument.CreateProcessAsUser()
or change directory of the Windows Service using SetCurrentDirectory()
Upvotes: 5