Getting commandline info (exe name, path and any parameters) from a registry string value that may include quoted strings

I'm getting a command line string from the registry, but it's coming in a variety of different formats:

Sometimes the full path and name is enclosed in double quotes, but not always.
    example - "C:\Program Files\My Apps\Foo.exe"

Sometimes there are  parameters (outside the quotes - if they exist) but not always.
    example - "C:\Program Files\My Apps\Foo.exe" -onbootup

The parameters (if any) may have a leading char like  - or \ but not always.
   example - C:\Program Files\My Apps\Foo.exe startup

I need a way to break these strings down to extract the information as separate items, something like ParamStr does. although the string supplied is a widestring not an ansichar.

TIA Nick
nickglasierAsked:
Who is Participating?
 
TheRealLokiSenior DeveloperCommented:
I just wrote this procedure
it returns "filename" (without quotes) and a Tstringlist with each param

e.g.
  sl := TStringList.create;
  s := 'C:\Program Files\My Apps\Foo.exe startup';
  GuessFilenameAndParameters(s, filename, sl);
  showmessage('filename = ' + filename);
  showmessage(''params are :- ' + #13#10 + sl.text;

works for
C:\Program Files\My Apps\Foo.exe
"C:\Program Files\My Apps\Foo.exe"
C:\Program Files\My Apps\Foo.exe startup
"C:\Program Files\My Apps\Foo.exe" startup
C:\Program Files\My Apps\Foo.exe startup test
"C:\Program Files\My Apps\Foo.exe startup" test
C:\Program Files\My Apps\Foo.exe startup test "part three"
"C:\Program Files\My Apps\Foo.exe startup" test "part three"


procedure GuessFilenameAndParameters(CommandLine: string; var Filename: string; var ResultParams: TStringList);
var
  i: integer;
  s: string;
  appfoundat: integer;
begin
  ResultParams.Clear;
  ResultParams.Delimiter := ' ';
  ResultParams.DelimitedText := CommandLine;
  Filename := '';
  appfoundat := -1;
  i := Pred(ResultParams.Count);
  while (i >= 0) do
  begin // find 1st "field" that has a . in the 4th to last character
      s := ResultParams[i];
      if (length(S) > 4) and (s[length(s)-3] = '.') then
        appfoundat := i;
      dec(i);
  end;
  if appfoundat <> -1 then
  begin
      i := 0;
      for i := 0 to appfoundat do
      begin
          Filename := Filename + ResultParams[0] + ' ';
          ResultParams.Delete(0);
      end;
      Delete(Filename, length(Filename), 1); // remove last space
  end;
end;
0
 
LMuadDIbCommented:
check out this link:
http://immortals.fake.hu/delphiportal/modules.php?name=News&file=article&sid=382

I use the code myself to do all my cmd line parsing.
It does not matter the ordering of the params passed.
Im not sure how it will do with file paths and spaces though

function GetParamVal(const TaggedParm: string;
  IgnoreCase: boolean = true): string;
var
  Cmd: string;
  i, Len: integer;
  Comp1, Comp2: string;
begin
  Cmd := '';
  Comp1 := TaggedParm + '=';
  if IgnoreCase then
    Comp1 := UpperCase(Comp1);

  Len := length(Comp1);

  for i := 1 to ParamCount do
  begin
    Comp2 := copy(ParamStr(i), 1, Len);
    if IgnoreCase then
      Comp2 := UpperCase(Comp2);
    if (Comp1 = Comp2) then
    begin
      Cmd := trim(copy(ParamStr(i), Len + 1, length(ParamStr(i))));
      break;
    end;
  end;

  Result := UpperCase(Cmd);
end;
0
 
nickglasierAuthor Commented:


LMuadDib's answer requires knowledge of the parameter's tags which is not a controllable factor.

TheRealLoki's answer is the best of these two, and works really well for ansi or pascal strings, but doesn't deal with the widestrings issue. I tried changing the TStringlist for a jcl WideStringList object, but it doesn't have either a delimiter or a delimited text property. Any further ideas?

If no further answers are available I'll award the points to TheRealLoki.

 
0
 
TheRealLokiSenior DeveloperCommented:
sure, i just assumed you were using Delphi 7 since your question didn't state.
I made a very simple TDelimitedStringList based on Delphi 5's TStringList so I could have "Delimiters' ni Delphi 5.
you can use that too if you like.
you can download it from here https://sourceforge.net/project/showfiles.php?group_id=168004&package_id=192765
you do not need to "install it" just put it in a directory on Delphi's search path (or in your project dir)
and make the following changes to my original code posted above

*add*
uses DelimitedStringList;

*Change* _all_ refrences to "TStringList" to TDelimitedStringList in my code above.

*Replace*
    ResultParams.Delimiter := ' ';
with
    ResultParams.Delimiters.Add(' ');

As for the widestring, can't you just convert the widestring to a string? eg. s := wides;
0
 
nickglasierAuthor Commented:
Hi TheRealLoki,

I am using Delphi 7, the absence of Delimiter and DelimitedText properties is in the jcl widestringlist object.  Right now I'm using the jcl libraries WideStringToStringEx and StringToWideStringEx functions to convert, and hoping nothing gets lost in the translation.

Nick
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.