Recent

Author Topic: SOLVED: Encode/decode file path ?  (Read 667 times)

SaraT

  • Jr. Member
  • **
  • Posts: 86
  • A little student
SOLVED: Encode/decode file path ?
« 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;
« Last Edit: April 07, 2020, 07:02:15 am by SaraT »

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 8455
  • FPC developer.
Re: Encode/decode file path ?
« Reply #1 on: March 31, 2020, 07:26:53 pm »
Some options I can quickly think of, in descending preference.

  • best use windows api CopyFile() or some lazarus fileutil routine to copy, and not the shell
  • any for simple cases use Executeprocess() instead of TProcess
  • FPC 3.2.x+ Use TProcess from unit processunicode instead of unit process
  • FPC 3.0.x and - Use TProcessUTF8

Using parameters.add() with quoted characters is somewhat dodgy.

lucamar

  • Hero Member
  • *****
  • Posts: 2917
Re: Encode/decode file path ?
« Reply #2 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.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.8/FPC 3.0.4 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

PascalDragon

  • Hero Member
  • *****
  • Posts: 1692
  • Compiler Developer
Re: Encode/decode file path ?
« Reply #3 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.

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 787
    • Lebeau Software
Re: Encode/decode file path ?
« Reply #4 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;
« Last Edit: April 01, 2020, 08:33:50 pm by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

SaraT

  • Jr. Member
  • **
  • Posts: 86
  • A little student
Re: Encode/decode file path ?
« Reply #5 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