I have a problem with quotes in parameters. I use
ShowMessage(ParamStr(1)); to display the first parameter. But I don't
know how to form the parameter, so that it displays 1"2.
I've already tried these three methods - but none of them outputs
exactly what I want. Do I have to make modifications in the
GetParamStr() function? Or which other alternatives are available
(replacing,...)?
application.exe "1""2" //outputs 12
application.exe "1"2" //outputs 12
application.exe "1\"2" //outputs 1\2
Thanks in advance for your help!
Best regards,
Tim
> I have a problem with quotes in parameters.
ParamStr() can't handle quotations in parameters like you are trying
to use. You will have to call GetCommandLine() and then manually
parse the parameters.
> I don't know how to form the parameter, so that it displays 1"2.
You can't if you use ParamStr().
> application.exe "1""2" //outputs 12
> application.exe "1"2" //outputs 12
> application.exe "1\"2" //outputs 1\2
ParamStr() strips out quotations from a parameter.
ParamStr() (and indirectly, ParamCount()) needs to be seriously
rewritten by Borland/CodeGear, in my opinion. It is horribly
inaccurate. It doesn't even follow the same parsing rules that
Microsoft uses at the command prompt. See QC #3946, #27451, and
#43340 for more details.
Gambit
For easy parsing, I like to call CommandLineToArgvW. Use GetCommandLineW
to get the original Unicode command line from the OS.
--
Rob
> ParamStr() can't handle quotations in parameters like you are
> trying to use. You will have to call GetCommandLine()
> and then manually parse the parameters.
Here is some code I just write to do that, based on parsing rules that
are documented at MSDN:
function GetNextParam(var CmdLine: PChar; Buffer: PChar; Len:
PInteger): Boolean;
var
InQuotedStr, IsOdd: Boolean;
NumSlashes, NewLen, I: Integer;
begin
Result := False;
if Len <> nil then Len^ := 0;
if CmdLine = nil then Exit;
while (CmdLine^ <= ' ') and (CmdLine^ <> #0) do
CmdLine := CharNext(CmdLine);
if CmdLine^ = #0 then Exit;
InQuotedStr := False;
NewLen := 0;
repeat
if CmdLine^ = '\' then
begin
NumSlashes := 0;
repeat
Inc(NumSlashes);
CmdLine := CharNext(CmdLine);
until CmdLine^ <> '\';
if CmdLine^ = '"' then
begin
IsOdd := (NumSlashes mod 2) <> 0;
NumSlashes := NumSlashes div 2;
Inc(NewLen, NumSlashes);
if IsOdd then Inc(NewLen);
if Buffer <> nil then
begin
for I := 0 to NumSlashes-1 do
begin
Buffer^ := '\';
Inc(Buffer);
end;
if IsOdd then
begin
Buffer^ := '"';
Inc(Buffer);
end;
end;
if IsOdd then CmdLine := CharNext(CmdLine);
end else
begin
Inc(NewLen, NumSlashes);
if Buffer <> nil then
begin
for I := 0 to NumSlashes-1 do
begin
Buffer^ := '\';
Inc(Buffer);
end;
end;
end;
Continue;
end;
if CmdLine^ <> '"' then
begin
if (CmdLine^ <= ' ') and (not InQuotedStr) then Break;
Inc(NewLen);
if Buffer <> nil then
begin
Buffer^ := CmdLine^;
Inc(Buffer);
end;
end else
InQuotedStr := not InQuotedStr;
CmdLine := CharNext(CmdLine);
until CmdLine^ = #0;
if Len <> nil then Len^ := NewLen;
Result := True;
end;
function GetParamStr(Index: Integer): String;
var
Buffer: array[0..MAX_PATH] of Char;
CmdLine, P: PChar;
Len: Integer;
begin
Result := '';
if Index <= 0 then
begin
Len := GetModuleFileName(0, Buffer, MAX_PATH+1);
SetString(Result, Buffer, Len);
end else
begin
CmdLine := GetCommandLine;
GetNextParam(CmdLine, nil, nil);
repeat
Dec(Index);
if Index = 0 then Break;
if not GetNextParam(CmdLine, nil, nil) then Exit;
until False;
P := CmdLine;
if GetNextParam(P, nil, @Len) then
begin
SetLength(Result, Len);
GetNextParam(CmdLine, PChar(Result), nil);
end;
end;
end;
function GetParamCount: Integer;
var
CmdLine: PChar;
begin
Result := 0;
CmdLine := GetCommandLine;
GetNextParam(CmdLine, nil, nil);
while GetNextParam(CmdLine, nil, nil) do Inc(Result);
end;
Gambit
These functions work perfectly.
Thank you very much for all your help!
Best regards,
Tim