A Simple RAPI ApplicationCreating a Process

< BACK  NEXT >
[oR]

A Simple RAPI Application Creating a Process

This first RAPI sample application shows how to create a process using the CeCreateProcess RAPI function on a Windows CE application running from a Win32 application on Windows NT/98/2000. The function CeCreateProcess takes the same parameters as its desktop counterpart, CreateProcess, including those parameters that are not supported on Windows CE (Table 10.1).

Table 10.1. CeCreateProcess Creates a new process on the Windows CE device
CeCreateProcess
LPCWSTR lpApplicationName The name of the application to run, including a path. Can be NULL. Must be a Unicode string.
LPCWSTR lpCommandLine Command line to send to the application. If lpApplication-Name is NULL, lpCommandLine should contain the application's name and command line. Must be a Unicode string.
LPSECURITY_ATTRIBUTES lpProcessAttributes Not supported, use NULL.
LPSECURITY_ATTRIBUTES lpThreadAttributes Not supported, use NULL.
BOOL bInheritHandles Not supported, pass as FALSE.
DWORD dwCreationFlags Usually 0, can be CREATE_SUSPENDED to create a suspended process.
LPVOID lpEnvironment Not supported, use NULL.
LPWSTR lpCurrentDirectory Not supported, use NULL.
LPSTARTUPINFO lpStartupInfo Not supported, use NULL.
LPPROCESS_INFORMATION lpProcessInformation Pointer to a PROCESS_INFORMATION structure in which the handle to the process (hProcess), the handle to the primary thread (hThread), process id (dwProcessId), and thread identifier (dwThreadId) are returned.
BOOL Return Value TRUE for success, FALSE for failure.

CeCreateProcess returns a handle to the thread and process in the PROCESS_INFORMATION structure. These handles should be closed through a call to CeCloseHandle don't call CloseHandle since the handles are Windows CE handles. Note that application name and command line must be passed as Unicode strings regardless of how the Win32 application is compiled. You can use the "L" macro to force a string constant to be compiled as a Unicode string.

The code in Listing 10.1 shows the complete code used to initialize RAPI, make the call to CeCreateProcess, close the handles by calling CeCloseHandle, and un-initialize RAPI by calling CeRapiUninit. The application is a standard console application created using the Visual C++ application wizard. Note that you will need to include rapi.h and rapi.lib. Further, you may need to remove the WIN32_LEAN_AND_MEAN define in stadafx.h, depending on the options chosen when creating the project; otherwise, certain COM interfaces used in rapi.h will not be found. The source code can be found on the CDROM in the directory \RAPI\CreateProcess. You might need to change the name of the application being run (cmd.exe) if your Windows CE device does not support a command shell.

Listing 10.1 Creating a process on a Windows CE device using RAPI
 #include "stdafx.h" #include <iostream.h> #include <rapi.h> // Include rapi.lib into the project // WARNING: Remove #define WIN32_LEAN_AND_MEAN // from stdafx.h! void ShowRAPIError() {   int nErr = CeRapiGetError();   if(nErr == 0)     cout   "Win32 Error"            GetLastError()   endl;   else     cout   "RAPI Error"            nErr   endl; } int main(int argc, char* argv[]) {   RAPIINIT rapiInit;   HRESULT hr;   DWORD dwWaitResult;   rapiInit.cbSize = sizeof(RAPIINIT);   hr = CeRapiInitEx(&rapiInit);   if(FAILED(hr))   {     cout   "Could not initialize RAPI:"            GetLastError()   endl;     return 1;   }   dwWaitResult = WaitForSingleObject(rapiInit.heRapiInit,                10000);   if(dwWaitResult == WAIT_FAILED)   {     cout   "Could not wait on event:"            GetLastError()   endl;     return 1;   }   if(dwWaitResult == WAIT_TIMEOUT)   {     cout   "Could not connect to Windows CE Device"            endl;     return 1;   }   if(FAILED(rapiInit.hrRapiInit))   {     ShowRAPIError();     return 1;   }   PROCESS_INFORMATION pi;   if(!CeCreateProcess(L"\\windows\\cmd.exe",         NULL, NULL, NULL, FALSE,         0, NULL, NULL, NULL,         &pi))     ShowRAPIError();   else   {     if(!CeCloseHandle(pi.hProcess))       ShowRAPIError();     if(!CeCloseHandle(pi.hThread))       ShowRAPIError();   }   hr = CeRapiUninit();   if(FAILED(hr))     cout   "Could not un-initialize RAPI"   endl;   return 0; } 

You should note that CeCreateProcess could fail and return FALSE, and yet CeRapiGetError and GetLastError both return 0. This can happen if the application name is invalid.

The handles returned in the PROCESS_INFORMATION need to be used with care. These handles exist on Windows CE device, and not on the desktop. That is why CeCloseHandle is called rather than CloseHandle. For this reason, you cannot use synchronization techniques, such as calling WaitForSingleObject, on them. The following call, which attempts to wait until the process on the Windows CE device terminates, will fail.

 if(WaitForSingleObject(pi.hProcess,     INFINITE) == WAIT_FAILED)   cout   "Wait Failed"   endl; 

You can write your own RAPI functions and use CeRapiInvoke to circumvent this problem, as described later in this chapter.


< BACK  NEXT >


Windows CE 3. 0 Application Programming
Windows CE 3.0: Application Programming (Prentice Hall Series on Microsoft Technologies)
ISBN: 0130255920
EAN: 2147483647
Year: 2002
Pages: 181

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net