<div dir="ltr">Apologies, I forgot to include a link to just the patch...<div><br><div><a href="https://dl.dropboxusercontent.com/u/59503182/fpc/process.inc.patch">https://dl.dropboxusercontent.com/u/59503182/fpc/process.inc.patch</a><br>
</div></div><div><br></div><div>Mike T</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On 1 July 2014 16:45, Michael Thompson <span dir="ltr"><<a href="mailto:mike.cornflake@gmail.com" target="_blank">mike.cornflake@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra">G'day,</div><div class="gmail_extra"><br></div><div class="gmail_extra">I'm on Windows 8/Trunk FPC</div>
<div class="gmail_extra"><br></div><div class="gmail_extra">Been banging my head against the wall all weekend trying to get some UTF8 working with the LazUtils TProcessUTF8. By the end of that I realized no matter what I did there, I wasn't going to get anywhere.</div>
<div class="gmail_extra"><br></div><div class="gmail_extra">I've now solved my problem using only TProcess. See below for the modified TProcess.Execute (win\process.inc)</div><div class="gmail_extra"><br></div><div class="gmail_extra">
<div class="gmail_extra">Procedure TProcess.Execute;</div><div class="gmail_extra">Var</div><div class="gmail_extra"> i : Integer;</div><div class="gmail_extra"> PName,PDir,PCommandLine : PWideChar; // Changed from PChar</div>
<div class="gmail_extra"> FEnv: pointer;</div><div class="gmail_extra"> FCreationFlags : Cardinal;</div><div class="gmail_extra"> FProcessAttributes : TSecurityAttributes;</div><div class="gmail_extra"> FThreadAttributes : TSecurityAttributes;</div>
<div class="gmail_extra"> FProcessInformation : TProcessInformation;</div><div class="gmail_extra"> FStartupInfo : STARTUPINFO;</div><div class="gmail_extra"> HI,HO,HE : THandle;</div><div class="gmail_extra"> Cmd : String;</div>
<div class="gmail_extra"> </div><div class="gmail_extra">begin</div><div class="gmail_extra"> PName:=Nil;</div><div class="gmail_extra"> PCommandLine:=Nil;</div><div class="gmail_extra"> PDir:=Nil;</div><div class="gmail_extra">
</div><div class="gmail_extra"> if (FApplicationName='') and (FCommandLine='') and (FExecutable='') then</div><div class="gmail_extra"> Raise EProcess.Create(SNoCommandline);</div><div class="gmail_extra">
if (FApplicationName<>'') then</div><div class="gmail_extra"> begin</div><div class="gmail_extra"> PName:=PWideChar(UTF8Decode(FApplicationName)); // Added UTF8Decode</div><div class="gmail_extra">
PCommandLine:=PWideChar(UTF8Decode(FCommandLine));// Added UTF8Decode</div><div class="gmail_extra"> end</div><div class="gmail_extra"> else If (FCommandLine<>'') then</div><div class="gmail_extra">
PCommandLine:=PWideChar(UTF8Decode(FCommandLine)) // Added UTF8Decode</div>
<div class="gmail_extra"> else if (Fexecutable<>'') then</div><div class="gmail_extra"> begin</div><div class="gmail_extra"> Cmd:=MaybeQuoteIfNotQuoted(Executable);</div><div class="gmail_extra"> For I:=0 to Parameters.Count-1 do</div>
<div class="gmail_extra"> Cmd:=Cmd+' '+MaybeQuoteIfNotQuoted(Parameters[i]);</div><div class="gmail_extra"> PCommandLine:=PWideChar(UTF8Decode(Cmd)); // Added UTF8Decode</div><div class="gmail_extra">
end;</div><div class="gmail_extra"> If FCurrentDirectory<>'' then</div><div class="gmail_extra"> PDir:=PWideChar(UTF8Decode(FCurrentDirectory)); // Added UTF8Decode</div><div class="gmail_extra"> if FEnvironment.Count<>0 then</div>
<div class="gmail_extra"> FEnv:=StringsToPChars(FEnvironment)</div><div class="gmail_extra"> else</div><div class="gmail_extra"> FEnv:=Nil;</div><div class="gmail_extra"> Try</div><div class="gmail_extra"> FCreationFlags:=GetCreationFlags(Self);</div>
<div class="gmail_extra"> InitProcessAttributes(Self,FProcessAttributes);</div><div class="gmail_extra"> InitThreadAttributes(Self,FThreadAttributes);</div><div class="gmail_extra"> InitStartupInfo(Self,FStartUpInfo);</div>
<div class="gmail_extra"> If poUsePipes in FProcessOptions then</div><div class="gmail_extra"> CreatePipes(HI,HO,HE,FStartupInfo,Not(poStdErrToOutPut in FProcessOptions), FPipeBufferSize);</div><div class="gmail_extra">
Try</div><div class="gmail_extra"> If Not CreateProcessW(PName,PCommandLine,@FProcessAttributes,@FThreadAttributes,</div><div class="gmail_extra"> FInheritHandles,FCreationFlags,FEnv,PDir,FStartupInfo,</div>
<div class="gmail_extra"> fProcessInformation) then // Changed to CreateProcessW</div><div class="gmail_extra"> Raise EProcess.CreateFmt(SErrCannotExecute,[FCommandLine,GetLastError]);</div>
<div class="gmail_extra"> FProcessHandle:=FProcessInformation.hProcess;</div><div class="gmail_extra"> FThreadHandle:=FProcessInformation.hThread;</div><div class="gmail_extra"> FProcessID:=FProcessINformation.dwProcessID;</div>
<div class="gmail_extra"> Finally</div><div class="gmail_extra"> if POUsePipes in FProcessOptions then</div><div class="gmail_extra"> begin</div><div class="gmail_extra"> FileClose(FStartupInfo.hStdInput);</div>
<div class="gmail_extra"> FileClose(FStartupInfo.hStdOutput);</div><div class="gmail_extra"> if Not (poStdErrToOutPut in FProcessOptions) then</div><div class="gmail_extra"> FileClose(FStartupInfo.hStdError);</div>
<div class="gmail_extra"> CreateStreams(HI,HO,HE);</div><div class="gmail_extra"> end;</div><div class="gmail_extra"> end;</div><div class="gmail_extra"> FRunning:=True;</div><div class="gmail_extra">
Finally</div>
<div class="gmail_extra"> If FEnv<>Nil then</div><div class="gmail_extra"> FreeMem(FEnv);</div><div class="gmail_extra"> end;</div><div class="gmail_extra"> if not (csDesigning in ComponentState) and // This would hang the IDE !</div>
<div class="gmail_extra"> (poWaitOnExit in FProcessOptions) and</div><div class="gmail_extra"> not (poRunSuspended in FProcessOptions) then</div><div class="gmail_extra"> WaitOnExit;</div><div class="gmail_extra">
end; </div><div class="gmail_extra"><br></div><div class="gmail_extra">Basically I changed 3 x PChar to PWideChar, then when the PWideChars are being set I do it via PWideChar(UTF8Decode(<string>))</div><div class="gmail_extra">
Finally I changed CreateProcess to CreateProcessW.</div><div class="gmail_extra"><br></div><div class="gmail_extra">I had thought I was going to need to change the datatypes for FCommandline etc, but this wasn't the case.</div>
<div class="gmail_extra"><br></div><div class="gmail_extra">With the limited testing I've done, this seems to successfully enable UTF8 support within TProcess, without the end user needing to change any of their code. Also, this doesn't seem to break any existing code that uses TProcess.</div>
<div class="gmail_extra"><br></div><div class="gmail_extra">Before I submit this as a patch though, I have concerns. Mainly around a) not knowing your development plans in this area and b) me not really knowing unicode (just because this works, doesn't mean it's right).</div>
<div class="gmail_extra"><br></div><div class="gmail_extra">A summary of my concerns:</div><div class="gmail_extra">* I note in redef.inc there is already a redirect for CreateProcess to CreateProcessW. This implies to me there is already a plan in mind, and I might be cutting across that by directly calling CreateProcessW.</div>
<div class="gmail_extra">* My code doesn't take UTF16 into account. In truth, I'm not sure how to do that.</div><div class="gmail_extra">* I've only done limited testing on a Win 8 64bit PC set to Australian regional settings. Really I think I need to test this on a wide variety of regional settings and across a variety of Win OS's...</div>
</div><div class="gmail_extra"><br></div><div class="gmail_extra">Before I submit a patch based on this can anyone tell me if I'm on the wrong track? (and if so, where)</div><div class="gmail_extra"><br></div><div class="gmail_extra">
Many thanks</div><div class="gmail_extra"><br></div><div class="gmail_extra">Mike Thompson</div><div class="gmail_extra"><br></div></div>
</blockquote></div><br></div>