So we have a 3rd party tool that we can't recompile but it uses this ParamStr(Index: Integer) to get command line arguments. I have tried everything I can find on the internet but it will not accept double quote character. I have used escape characters, etc, and created a test app to streamline the testing process and pin down the problem to this function.
Has anyone ever successfully passed double quotes through the command line parameters with this function?
Edit: I've posted my test app below. The processfromcommandline function is from the 3rd party library.
An example input for this would be like this:
"file1.adb file2.adb -p4THISISAPASSWORD"
The password is directly after the -p4. Our password is 'encrypted' and will look something more like this
file1.adb file2.adb -p4$/.;}{3"aG13Sz/"9@;.'
The test app outputs the string it gets using ShowMessage so you can see what delphi is doing.So my input would be something
unit Main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, clipbrd;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
FParams: Boolean;
FAbort: Boolean;
FAppPath: String;
FLogPath: String;
FSuccess: Boolean;
FSourceFile: String;
FDestFile: String;
FParamCount: Integer;
FPassword4: String;
FKeyFile4: String;
FIVFile4: String;
FPassword5: String;
FKeyFile5: String;
FIVFile5: String;
procedure ProcessFromCommandLine;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.ProcessFromCommandLine;
var bTo4: boolean;
i,l,sz: Integer;
s: String;
buf: PAnsiChar;
begin
bTo4 := False;
for i := 1 to FParamCount do
begin
s := ParamStr(i);
//s := getCommandLine;
l := Length(s);
if (i = 1) then
FSourceFile := s
else
if (i = 2) and (Pos('-',s) = 0) then
FDestFile := s
else
if (l > 3) and ((Pos('-p4',s) > 0) or (Pos('/p4',s) > 0)) then
begin
ShowMessage('uh' + s);
FPassword4 := Copy(s,4,l-3);
end
else
if (l > 3) and ((Pos('-p5',s) > 0) or (Pos('/p5',s) > 0)) then
FPassword5 := Copy(s,4,l-3)
else
if (l > 3) and ((Pos('-i4',s) > 0) or (Pos('/i4',s) > 0)) then
FIVFile4 := Copy(s,4,l-3)
else
if (l > 3) and ((Pos('-i5',s) > 0) or (Pos('/i5',s) > 0)) then
FIVFile5 := Copy(s,4,l-3)
else
if (l > 3) and ((Pos('-k4',s) > 0) or (Pos('/k4',s) > 0)) then
FKeyFile4 := Copy(s,4,l-3)
else
if (l > 3) and ((Pos('-k5',s) > 0) or (Pos('/k5',s) > 0)) then
FKeyFile5 := Copy(s,4,l-3)
else
if (l > 2) and ((Pos('-l',s) > 0) or (Pos('/l',s) > 0)) then
FLogPath := Copy(s,3,l-2)
else
if (s = '-4') then
bTo4 := True
else
if (s = '-5') then
bTo4 := False;
end;
Clipboard.AsText := FPassword4;
ShowMessage(FPassword4);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FParamCount := ParamCount;
FParams := (FParamCount >= 1);
if (FParams) then
ProcessFromCommandLine;
end;
end.
ParamStr()
strips off "
quote chars, even in an embedded quoted string, as in your example. Thus
-p4$/.;}{3"aG13Sz/"9@;.'
Gets returned as
-p4$/.;}{3aG13Sz/9@;.'
This is hard coded behavior, you can't change it without altering the RTL's source code.
Even Microsoft does the same thing (see the 2nd and 4th examples), but at least it supports embedded "
chars escaped as \"
. ParamStr()
does not support any kind of escaping syntax at all!
In fact, ParamStr()
has a few bugs 1 related to its quote handling (such as quoted empty parameters, ""
, are ignored completely), so I would suggest using the Win32 GetCommandLine()
to get the raw command line data and then parse it yourself however you want.
1: bug which were originally logged in the old Quality Central bug tracker, but were never ported to the newer Quality Portal bug tracker, and QC has since been decommissioned and is now offline.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With