Lazarus

Programming => General => Topic started by: NicCo on June 22, 2019, 04:42:55 pm

Title: RunCommand and UTF8 argument ?
Post by: NicCo on June 22, 2019, 04:42:55 pm
Hi,
I would like to use RunCommand and an argument with accent so UTF8 is needed.
Example : RunCommand('aprogram.exe',['"'+FileWithSpaceAndAccent+'"'],S,[poWaitOnExit, poNoConsole])
Is there a way to do that ?
I need also to get the output and perhaps the output will need UTF8 ?
Thank you !
Title: Re: RunCommand and UTF8 argument ?
Post by: marcov on June 22, 2019, 10:55:49 pm
Some unicode work has been done in trunk/3.2 branches.
Title: Re: RunCommand and UTF8 argument ?
Post by: NicCo on June 22, 2019, 11:22:05 pm
Thank you, I must install it to test ? lazarus-2.1.0-61198M-fpc-3.2.0-beta-20190511-win64.exe
Title: Re: RunCommand and UTF8 argument ?
Post by: lucamar on June 23, 2019, 01:06:12 am
In the mean time, you may also try to implement it with TProcessUTF8. It's basicaly the same as TProcess (which IIRC is what RunCommand uses internally) but using UTF8.

As the docs say:
Quote from: Reference for unit UTF8Process (LazUtils)
TProcessUTF8
Implements a version of FPC TProcess that allows UTF-8-encoded arguments
Title: Re: RunCommand and UTF8 argument ?
Post by: NicCo on June 23, 2019, 10:59:09 am
Thank you but when I try to use TProcessUTF8, I can't use Options like poWaitOnExit or poNoConsole, or I don't find how to use it.
Title: Re: RunCommand and UTF8 argument ?
Post by: Zoran on June 23, 2019, 02:11:28 pm
Thank you but when I try to use TProcessUTF8, I can't use Options like poWaitOnExit or poNoConsole, or I don't find how to use it.

Code: Pascal  [Select]
  1. ProcessUTF8_1.Options := ProcessUTF8_1.Options + [poWaitOnExit, poNoConsole];

Read here: https://wiki.freepascal.org/Executing_External_Programs (https://wiki.freepascal.org/Executing_External_Programs)
Title: Re: RunCommand and UTF8 argument ?
Post by: NicCo on June 23, 2019, 04:14:32 pm
Thank you, I believe this is what I tried but I'll try again.
Title: Re: RunCommand and UTF8 argument ?
Post by: lucamar on June 23, 2019, 05:09:10 pm
TProcessUTF8 inherits from TProcess, so whatever TProcess has, TProcessUTF8 has it too.

If what you mean is that you can't access the enumeration, sets, etc. identifiers declared in process.pas, then just add process to your uses clause ... although I don't think it's needed.
Title: Re: RunCommand and UTF8 argument ?
Post by: NicCo on June 23, 2019, 10:22:20 pm
When I use TProcess, I can compile without problem. When I replace Process by UTF8Process and TProcess by TProcessUTF8, I can't compile :
Compilation du projet - Cible : Test.exe : Code de sortie 1 - Erreurs : 3
principale.pas(78,43) Error: Identifier not found "poWaitOnExit"
principale.pas(78,57) Error: Identifier not found "poUsePipes"
principale.pas(78,69) Error: Identifier not found "poNoConsole"
But lucamar was right, if I add Process I can compile so there is a missing declaration into UTF8Process ?
Thank you
Title: Re: RunCommand and UTF8 argument ?
Post by: lucamar on June 23, 2019, 11:11:49 pm
But lucamar was right, if I add Process I can compile so there is a missing declaration into UTF8Process ?

Not missing, it's just that UTF8Process does the same as you: uses the declarations from Process; it could not be otherwise if they are to remain compatible.
Title: Re: RunCommand and UTF8 argument ?
Post by: NicCo on June 24, 2019, 10:25:01 am
No problem, thank you :)
I can use TProcess but now I have an issue with large output and poWaitOnExit :(
Title: Re: RunCommand and UTF8 argument ?
Post by: marcov on June 24, 2019, 12:22:34 pm
Afaik with lazarus GUI applications and utf8 default it should simply work with FPC 3.2.
Title: Re: RunCommand and UTF8 argument ?
Post by: NicCo on June 24, 2019, 12:29:48 pm
Thank you, I'll try FPC 3.2.

I perhaps found a workaround :

Before : RunCommand('aprogram.exe',['"'+FileWithSpaceAndAccent+'"'],S,[poWaitOnExit, poNoConsole])
After : RunCommand('aprogram.exe',[AnsiQuotedStr(UTF8ToWinCP(FileWithSpaceAndAccent),'"')],S,[poWaitOnExit, poNoConsole])
Title: Re: RunCommand and UTF8 argument ?
Post by: lucamar on June 24, 2019, 05:23:57 pm
Code: [Select]
AnsiQuotedStr(UTF8ToWinCP(FileWithSpaceAndAccent)
Will that work if the file name contains quotes? For example, a file named:
My "serious" stuff.doc

It's (probably) a "forbidden" name in Windows but it's a perfectly normal one in *nix. In fact I just created one with:
Code: [Select]
cat - > My\ \"serious\"\ stuff.txt
Title: Re: RunCommand and UTF8 argument ?
Post by: NicCo on June 24, 2019, 06:36:40 pm
Windows doesn't support filename with "\ / : * ? " < > |" and I use Windows only so no problem ;)
Title: Re: RunCommand and UTF8 argument ?
Post by: lucamar on June 24, 2019, 07:33:57 pm
I'll have to try it myself, then :)

ETA:

OK, made a small "with vs. without" test of using AnsiQuotedString and, as I suspected, it makes Linux commands fail. Good to know. :)

Oh, BTW, the Spanish message from "cat"  in the image means: "No such file or directory"

And for those who don' know, "cat filename" is roughly equvalent to "type filename" or "copy filename con" in Windows.
Title: Re: RunCommand and UTF8 argument ?
Post by: NicCo on June 24, 2019, 09:24:24 pm
Thank you for the test, interesting ;)
Title: Re: RunCommand and UTF8 argument ?
Post by: NicCo on June 25, 2019, 02:04:59 pm
A last question if I want to use Process/UTF8Process : is there a way to keep WaitOnExit (or an equivalent) and Large Output ?
Title: Re: RunCommand and UTF8 argument ?
Post by: marcov on June 25, 2019, 02:09:01 pm
In 3.2+ the body of runcommand is part of tprocess, and parametrised with some events.

But afaik some runcommands have an options parameter, so that should be possible without coding even.

Afaik it should be possible to reimplement tutf8process on top of 3.2 tprocess and reduce to almost nothing.
Title: Re: RunCommand and UTF8 argument ?
Post by: NicCo on June 26, 2019, 02:51:52 pm
Thank you marcov, I'm trying FPC 3.2 and you're right for accent. I can use RunCommand and accentued string without any issue and without my workaround.
Now I'm searching how can I get real time output with RunCommand...
Title: Re: RunCommand and UTF8 argument ?
Post by: marcov on June 26, 2019, 03:01:00 pm
Now I'm searching how can I get real time output with RunCommand...

Runcommands are fairly small stubs in 3.2+, something like:

Code: Pascal  [Select]
  1. function RunCommand(const exename:TProcessString;const commands:array of TProcessString;out outputstring:string; Options : TProcessOptions = []):boolean;
  2. Var
  3.     p : TProcess;
  4.     i,
  5.     exitstatus : integer;
  6.     ErrorString : String;
  7. begin
  8.   p:=TProcess.create(nil);
  9.   if Options<>[] then
  10.     P.Options:=Options - ForbiddenOptions;
  11.   p.Executable:=exename;
  12.   if high(commands)>=0 then
  13.    for i:=low(commands) to high(commands) do
  14.      p.Parameters.add(commands[i]);
  15.   try
  16.     result:=p.RunCommandLoop(outputstring,errorstring,exitstatus)=0;
  17.   finally
  18.     p.free;
  19.   end;
  20.   if exitstatus<>0 then result:=false;
  21. end;
  22.  

Runcommandloop is the core "large output" routine, but calls virtual methods in TProcess, so they can be overriden.

Code: [Select]
    function ReadInputStream(p:TInputPipeStream;var BytesRead:integer;var DataLength:integer;var Data:string;MaxLoops:integer=10):boolean; virtual;
    function ReadInputStream(p:TInputPipeStream;data:TStream;MaxLoops:integer=10):boolean; virtual;

Override these like this

function ReadInputStream(p:TInputPipeStream;var BytesRead:integer;var DataLength:integer;var Data:string;MaxLoops:integer=10):boolean; { overridein header}
begin
  inherited;
   if datalength>0 then
     myevent(data,datalength);
end;

You can also assign an onidle event without overriding


Title: Re: RunCommand and UTF8 argument ?
Post by: NicCo on June 26, 2019, 03:28:50 pm
I'm sorry for the question but how can I use overriding in a project ?
I tried to use your override example but I get Error: Identifier not found "TInputPipeStream"
I just copy and paste the function into my project...
Title: Re: RunCommand and UTF8 argument ?
Post by: lucamar on June 26, 2019, 07:00:48 pm
Again, you need to add to your uses clause the unit where TInputPipeStream is declared, which IIRC is the FCL's Pipes.

General process to solve "Identifier not found" problems:
Title: Re: RunCommand and UTF8 argument ?
Post by: NicCo on June 30, 2019, 09:56:19 pm
Thank you, I'll look at this ;)