Lazarus

Programming => General => Topic started by: SaraT on March 31, 2020, 06:54:26 pm

Title: SOLVED: Encode/decode file path ?
Post by: SaraT on March 31, 2020, 06:54:26 pm
Hello coders
The below code copy a file to another place, but the new file name has incorrect name. Please, see attached image.

How can I encode/decode the new file name?

I don't want to use another function/procedure to copy a file, just cmd.exe.

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   AProcess: TProcess;
  4. begin
  5.   AProcess := TProcess.Create(nil);
  6.   AProcess.Executable:= 'C:\Windows\System32\cmd.exe';
  7.   AProcess.Parameters.Add('/c copy "C:\Users\Username\Pictures\Sample Pictures\Chrysanthemum.jpg" "C:\Users\Username\Desktop\áéíóú.jpg"');
  8.   AProcess.Options := AProcess.Options + [poWaitOnExit];
  9.   AProcess.ShowWindow:=swoHIDE;
  10.   AProcess.Execute;
  11.   AProcess.Free;
  12. end;
Title: Re: Encode/decode file path ?
Post by: marcov on March 31, 2020, 07:26:53 pm
Some options I can quickly think of, in descending preference.


Using parameters.add() with quoted characters is somewhat dodgy.
Title: Re: Encode/decode file path ?
Post by: lucamar on March 31, 2020, 09:48:13 pm
The problem with your code, in case it isn't clear from Marco's answers, is that Lazarus pass "áéíóú" as a UTF8 string but cmd interprets it as an single-byte ANSI string.

I find that problem very frequently when creating/copying files from Linux to an NTFS or FAT partition; Windows Explorer/shell shows those"funny" characters in the file name.

As an alternative you could use UTF8ToWinCP(), in unit LazUTF8 of LazUtils, to convert the UTF8 filename to the Windows code-page.
Title: Re: Encode/decode file path ?
Post by: PascalDragon on April 01, 2020, 10:02:36 am
In addition to what the others said you should add the parameters separately:

Code: Pascal  [Select][+][-]
  1.   AProcess.Parameters.Add('/c');
  2.   AProcess.Parameters.Add('copy');
  3.   AProcess.Parameters.Add('C:\Users\Username\Pictures\Sample Pictures\Chrysanthemum.jpg');
  4.   AProcess.Parameters.Add('C:\Users\Username\Desktop\áéíóú.jpg');

TProcess will handle the quoting by itself.
Title: Re: Encode/decode file path ?
Post by: Remy Lebeau on April 01, 2020, 08:13:52 pm
The below code copy a file to another place, but the new file name has incorrect name. Please, see attached image.

Why are you using cmd.exe to copy a file?  You should instead use the Win32 API's CopyFileW() function.  Especially since you are hiding the command window anyway, so you really should use an API that is specifically designed for this purpose, not shell out to an external process.

Code: Pascal  [Select][+][-]
  1. function MyCopyFile(const Src, Dest: string): Boolean;
  2. var
  3.   wSrc, wDest: UnicodeString;
  4. begin
  5.   wSrc := UTF8Decode(Path);
  6.   wDest := UTF8Decode(Dest);
  7.   Result := CopyFileW(PWideChar(wSrc), PWideChar(wDest), True);
  8. end;
  9.  
  10. procedure TForm1.Button1Click(Sender: TObject);
  11. begin
  12.   MyCopyFile('C:\Users\Username\Pictures\Sample Pictures\Chrysanthemum.jpg', 'C:\Users\Username\Desktop\áéíóú.jpg');
  13. end;
Title: Re: Encode/decode file path ?
Post by: SaraT on April 07, 2020, 07:04:03 am
The below code copy a file to another place, but the new file name has incorrect name. Please, see attached image.

Why are you using cmd.exe to copy a file?  You should instead use the Win32 API's CopyFileW() function.  Especially since you are hiding the command window anyway, so you really should use an API that is specifically designed for this purpose, not shell out to an external process.

Code: Pascal  [Select][+][-]
  1. function MyCopyFile(const Src, Dest: string): Boolean;
  2. var
  3.   wSrc, wDest: UnicodeString;
  4. begin
  5.   wSrc := UTF8Decode(Path);
  6.   wDest := UTF8Decode(Dest);
  7.   Result := CopyFileW(PWideChar(wSrc), PWideChar(wDest), True);
  8. end;
  9.  
  10. procedure TForm1.Button1Click(Sender: TObject);
  11. begin
  12.   MyCopyFile('C:\Users\Username\Pictures\Sample Pictures\Chrysanthemum.jpg', 'C:\Users\Username\Desktop\áéíóú.jpg');
  13. end;

Thanks to all of you, guys :)
Problem solved.
TinyPortal © 2005-2018