diff --git a/packages/fcl-process/src/win/process.inc b/packages/fcl-process/src/win/process.inc index 37d5e7a970..09584d79f8 100644 --- a/packages/fcl-process/src/win/process.inc +++ b/packages/fcl-process/src/win/process.inc @@ -68,7 +68,7 @@ Function GetCreationFlags(P : TProcess) : Cardinal; begin With P do begin - Result:=0; + Result:=CREATE_UNICODE_ENVIRONMENT; if poNoConsole in FProcessOptions then Result:=Result or Detached_Process; if poNewConsole in FProcessOptions then @@ -87,10 +87,19 @@ begin end; end; -Function StringsToPChars(List : TStrings): pointer; +function WStrAsUniquePWideChar(var s: UnicodeString): PWideChar; +begin + UniqueString(s); + if s<>'' then + Result:=PWideChar(s) + else + Result:=nil; +end; + +Function StringsToWChars(List : TStrings): pointer; var - EnvBlock: string; + EnvBlock: UnicodeString; I: Integer; begin @@ -98,8 +107,8 @@ begin For I:=0 to List.Count-1 do EnvBlock := EnvBlock + List[i] + #0; EnvBlock := EnvBlock + #0; - GetMem(Result, Length(EnvBlock)); - CopyMemory(Result, @EnvBlock[1], Length(EnvBlock)); + GetMem(Result, Length(EnvBlock)*2); + CopyMemory(Result, @EnvBlock[1], Length(EnvBlock)*2); end; Procedure InitProcessAttributes(P : TProcess; Var PA : TSecurityAttributes); @@ -116,7 +125,7 @@ begin TA.nLength := SizeOf(TA); end; -Procedure InitStartupInfo(P : TProcess; Var SI : STARTUPINFOA); +Procedure InitStartupInfo(P : TProcess; Var SI : STARTUPINFOW); Const SWC : Array [TShowWindowOptions] of Cardinal = @@ -179,7 +188,7 @@ begin end; -Procedure CreatePipes(Var HI,HO,HE : Thandle; Var SI : TStartupInfoA; CE : Boolean; APipeBufferSize : Cardinal); +Procedure CreatePipes(Var HI,HO,HE : Thandle; Var SI : TStartupInfoW; CE : Boolean; APipeBufferSize : Cardinal); begin CreatePipeHandles(SI.hStdInput,HI, APipeBufferSize); @@ -215,44 +224,45 @@ begin Result:=S; end; + Procedure TProcess.Execute; Var i : Integer; - PName,PDir,PCommandLine : PChar; + WName,WDir,WCommandLine : UnicodeString; + PWName,PWDir,PWCommandLine : PWideChar; FEnv: pointer; FCreationFlags : Cardinal; FProcessAttributes : TSecurityAttributes; FThreadAttributes : TSecurityAttributes; FProcessInformation : TProcessInformation; - FStartupInfo : STARTUPINFOA; + FStartupInfo : STARTUPINFOW; HI,HO,HE : THandle; Cmd : String; - -begin - PName:=Nil; - PCommandLine:=Nil; - PDir:=Nil; - + + begin + WName:=''; + WCommandLine:=''; + WDir:=''; if (FApplicationName='') and (FCommandLine='') and (FExecutable='') then Raise EProcess.Create(SNoCommandline); if (FApplicationName<>'') then begin - PName:=Pchar(FApplicationName); - PCommandLine:=Pchar(FCommandLine); + WName:=FApplicationName; + WCommandLine:=FCommandLine; end else If (FCommandLine<>'') then - PCommandLine:=Pchar(FCommandLine) - else if (Fexecutable<>'') then + WCommandLine:=FCommandLine + else if (FExecutable<>'') then begin Cmd:=MaybeQuoteIfNotQuoted(Executable); For I:=0 to Parameters.Count-1 do Cmd:=Cmd+' '+MaybeQuoteIfNotQuoted(Parameters[i]); - PCommandLine:=PChar(Cmd); + WCommandLine:=Cmd; end; If FCurrentDirectory<>'' then - PDir:=Pchar(FCurrentDirectory); + WDir:=FCurrentDirectory; if FEnvironment.Count<>0 then - FEnv:=StringsToPChars(FEnvironment) + FEnv:=StringsToWChars(FEnvironment) else FEnv:=Nil; Try @@ -263,8 +273,13 @@ begin If poUsePipes in FProcessOptions then CreatePipes(HI,HO,HE,FStartupInfo,Not(poStdErrToOutPut in FProcessOptions), FPipeBufferSize); Try - If Not CreateProcess (PName,PCommandLine,@FProcessAttributes,@FThreadAttributes, - FInheritHandles,FCreationFlags,FEnv,PDir,FStartupInfo, + // Beware: CreateProcess can alter the strings + // Beware: nil is not the same as a pointer to a #0 + PWName:=WStrAsUniquePWideChar(WName); + PWCommandLine:=WStrAsUniquePWideChar(WCommandLine); + PWDir:=WStrAsUniquePWideChar(WDir); + If Not CreateProcessW (PWName,PWCommandLine,@FProcessAttributes,@FThreadAttributes, + FInheritHandles,FCreationFlags,FEnv,PWDir,FStartupInfo, fProcessInformation) then Raise EProcess.CreateFmt(SErrCannotExecute,[FCommandLine,GetLastError]); FProcessHandle:=FProcessInformation.hProcess;