CreateProcess is a little tricky to use. Thus I write the full example code here so you don’t have to worry.
Here some explanations:
Here we use either the unicode or ansicode version of CreateProcess.
Is it really necessary to fill this block with zeroes?
Yes, it is. CreateProcess uses values that are not zero as input and thus may fail if the values are incorrect.
What is the member cb for?
The size member of this structures defines which version is used. In future if new members are added, CreateProcess can determine which version (with or without the new members) is used and thus ignore the new member’s values (they aren’t there anyway).
What does this line?
The lpDesktop member defines on which windowstation (here: “winsta0″) and desktop (here: “default”) the new application is shown. The value “winsta0\default” is a default value and should be sufficient for 99% of all cases. However Windows versions older than Vista come with a bug that does not show the application on “winsta0\defaul” if not specified. This bug only occurs in some rare occasions and is fixed in Vista and Server 2008.
It is standard in C world to repeat the application path as the first (zero based) parameter. So we have to add the app name in front of the remaining parameters. Otherwise the first parameter would be recognized as the application path and thus be ignored. In this case ParamStr(0) returns application path though but ParamStr(1) returns the second parameter. Example: pCmdLine = ‘1 2 3′; In this example ParamStr(0) would be the path to exe. ParamStr(1) would be “2″ and not “1″ because “1″ is considered as the path to exe. ParamStr(0) uses GetModuleFileName as an exception.
If no additional parameters are specified we just add the application name as the first parameter.
5 Responses
Holger Flick
11|Apr|2008 1Seeing this really makes me love the Process class from .NET so much more
Christian Wimmer
11|Apr|2008 2CreateProcess is very mighty. For a simple call, ShellExecute(Ex) is just fine. We use CreateProcess mainly, if we want to control the new process accurately. In this case we have to do it right
Thaddy
14|Apr|2008 3I use CreateProcess in a similar way to call different versions form dcc32.exe and fpc.exe in my homebrewed build tool.
Here’s a q&d code snippet that can even further simplify environment block handling
unit NLDReadWriteEnvironmentBlock; // Auteur Thaddy de Koning // Freeware interface uses windows, classes, SysUtils; const // Terminator gedefinieerd als typed const // (Zoadat het een memory reference heeft) NullChar:Char = #0; type TEnvironmentBlockReader = class(Tstringlist) public constructor Create; end; TEnvironmentBlockWriter = class(TStringStream) private FClosed:Boolean; function GetBlockPtr: PAnsiChar; protected procedure Close; public procedure Add(const aValue:string);overload; procedure Add(const aToken,aValue:string);overload; Property Block:PAnsiChar read GetBlockPtr; end; implementation { TEnvironmentBlockWriter } // Is het blok gesloten? // Zoja, ga een positie terug // Schrijf de string // Schrijf terminating #0 procedure TEnvironmentBlockWriter.Add(const aValue: string); begin If FClosed then begin Seek(-1,soFromEnd); Fclosed :=False; end; WriteString(aValue); Write(NullChar,1); end; procedure TEnvironmentBlockWriter.Add(const aToken, aValue: string); begin Add(aToken+'='+aValue); end; // Block afsluiten door een extra #0 te schrijven, als gespecificeerd procedure TEnvironmentBlockWriter.Close; begin if not FClosed then begin write(NullChar,1); FClosed := True; end; end; // Als we het block uitlezen nemen we aan dat het gesloten is! function TEnvironmentBlockWriter.GetBlockPtr: PAnsiChar; begin Close; Result := PChar(DataString); end; { TEnvironmentBlockReader } constructor TEnvironmentBlockReader.Create; var FBlock, StrPtr:PChar; begin inherited; FBlock :=GetEnvironmentStrings; if FBlock <> nil then try StrPtr := FBlock; repeat Add(StrPtr); inc(StrPtr, Succ(StrLen(StrPtr))); until StrPtr^= #0; finally FreeEnvironmentStrings(Fblock); end; end; end.Christian Wimmer
14|Apr|2008 4Thank you for the code.
BTW:
You should explicitly call GetEnvironmentStringsA, the Ansi version (which returns OEM characters). Furthermore use PAnsiChar instead of PChar, since PChar will become PWideChar in future releases of Delphi.
Did you know? #6 by JEDI Windows API
15|May|2008 5[...] Find out more about CreateProcess in the post about “CreateProcess in full glory“. [...]
Leave a reply
Search
Paypal donation (EUR)
Categories
Most Viewed
Archives
Tags
ACL callback COM Conversion CreateProcess DACL Delphi dialog DidYouKnow DLL documentation Download elevation factory file Handle header HowTo interface JWA JWSCL Kernel Microsoft KillProcess Laptop mail mailinglist manifest permission Privilege Process ProcessExplorer RunEl Russinovich Service Setup Sid TerminateProcess Theme Thread Token UAC user Vista Window WindowsRecent Posts
Recent Comments
Blogroll
Pages
Meta
A design creation of Design Disease
Copyright © 2007 - JEDI Windows API - is proudly powered by WordPress
InSense 1.0 Theme by Design Disease brought to you by HostGator Web Hosting.