FIX: Don't normalize path delimiters in parameters because params like "/h" won't work.

UPD: Support environment variables in commands.
This commit is contained in:
cobines 2011-09-19 17:16:19 +00:00
commit f52d52dffb
7 changed files with 87 additions and 60 deletions

View file

@ -912,15 +912,7 @@ begin
Cmd:= MainToolBar.GetButtonX(NumberOfButton, CmdX);
Path:= MainToolBar.GetButtonX(NumberOfButton, PathX);
Param:= QuoteStr(aFile.FullPath);
if Actions.Execute(Cmd, Param) = uActs.cf_Error then
begin
Cmd:= mbExpandFileName(Cmd);
Path:= ReplaceEnvVars(Path);
ReplaceExtCommand(Path, FrameLeft, FrameRight, ActiveFrame);
if Length(Path) <> 0 then
mbSetCurrentDir(Path);
ExecCmdFork(Format('"%s" %s', [Cmd, Param]));
end;
ExecCmd(Cmd, Param, Path);
end;
finally
FreeAndNil(aFile);
@ -2740,7 +2732,7 @@ begin
if I >= 0 then
begin
sDir:= MainToolBar.GetButtonX(I, PathX);
ReplaceExtCommand(sDir, FrameLeft, FrameRight, ActiveFrame);
sDir:= PrepareParameter(sDir, FrameLeft, FrameRight, ActiveFrame, [ppoNormalizePathDelims]);
tbChangeDir.Caption := 'CD ' + sDir;
if sDir <> '' then
tbChangeDir.Visible:= true;
@ -3563,18 +3555,14 @@ end;
function TfrmMain.ExecCmd(Cmd: String; Param: String=''; StartPath: String=''): Boolean;
begin
Cmd := NormalizePathDelimiters(Cmd);
Param := NormalizePathDelimiters(Param);
Param := ReplaceEnvVars(Param);
ReplaceExtCommand(Param, FrameLeft, FrameRight, ActiveFrame);
Cmd := ReplaceEnvVars(Cmd); // For Command only replace environment variables.
Param := PrepareParameter(Param, FrameLeft, FrameRight, ActiveFrame);
if Actions.Execute(Cmd, Param) <> uActs.cf_Error then
Result:= True
else
begin
StartPath := NormalizePathDelimiters(StartPath);
StartPath := ReplaceEnvVars(StartPath);
ReplaceExtCommand(StartPath, FrameLeft, FrameRight, ActiveFrame);
StartPath := PrepareParameter(StartPath, FrameLeft, FrameRight, ActiveFrame, [ppoNormalizePathDelims]);
// Only add a space after command if there are parameters.
if Length(Param) > 0 then
@ -3966,7 +3954,7 @@ begin
Exit;
sDir := MainToolBar.GetButtonX(I, PathX);
ReplaceExtCommand(sDir, FrameLeft, FrameRight, ActiveFrame);
sDir := PrepareParameter(sDir, FrameLeft, FrameRight, ActiveFrame, [ppoNormalizePathDelims]);
Actions.cm_ChangeDir(sDir);
end;
@ -4055,6 +4043,8 @@ begin
end;
edtCommand.DroppedDown:= False;
sCmd:= ReplaceEnvVars(sCmd);
if (fspDirectAccess in ActiveFrame.FileSource.GetProperties) then
begin
iIndex:= Pos('cd ', sCmd);
@ -4694,4 +4684,4 @@ begin
end;
end.

View file

@ -73,7 +73,7 @@ begin
end;
end;
*)
ReplaceExtCommand(sOpenCmd, aFile, aFileView.CurrentPath);
sOpenCmd := PrepareParameter(sOpenCmd, aFile);
if ProcessExtCommand(sOpenCmd, aFileView.CurrentPath) then
Exit;
end;

View file

@ -581,6 +581,7 @@ begin
SplitCmdLine(sCmdLine, sFileName, sParams);
DCDebug('File: ' + sFileName + ' Params: ' + sParams + ' WorkDir: ' + wWorkDir);
sFileName:= NormalizePathDelimiters(sFileName);
wFileName:= UTF8Decode(sFileName);
wParams:= UTF8Decode(sParams);
Result := (ShellExecuteW(0, 'open', PWChar(wFileName), PWChar(wParams), PWChar(wWorkDir), SW_SHOW) > 32);
@ -1874,4 +1875,4 @@ begin
{$ENDIF}
end;
end.
end.

View file

@ -449,7 +449,7 @@ begin
sAct:= sl.Names[I];
if (SysUtils.CompareText('OPEN', sAct) = 0) or (SysUtils.CompareText('VIEW', sAct) = 0) or (SysUtils.CompareText('EDIT', sAct) = 0) then Continue;
sCmd:= sl.ValueFromIndex[I];
ReplaceExtCommand(sCmd, aFile, aFile.Path);
sCmd:= PrepareParameter(sCmd, aFile);
mi:= TMenuItem.Create(miActions);
mi.Caption:= sAct;
mi.Hint:= sCmd;

View file

@ -473,7 +473,7 @@ begin
else
begin
sCmd:= Copy(sCmd, Pos('=', sCmd) + 1, Length(sCmd));
ReplaceExtCommand(sCmd, aFile, aFile.Path);
sCmd:= PrepareParameter(sCmd, aFile);
try
with frmMain.ActiveFrame do
begin
@ -509,4 +509,4 @@ begin
end;
end.

View file

@ -1407,7 +1407,7 @@ begin
if (sViewCmd<>'') then
begin
ReplaceExtCommand(sViewCmd, aFile);
sViewCmd := PrepareParameter(sViewCmd, aFile);
ProcessExtCommand(sViewCmd, ActiveFrame.CurrentPath);
// TODO:
// If TempFileSource is used, create a wait thread that will
@ -1531,7 +1531,7 @@ begin
if (sEditCmd <> '') then
begin
ReplaceExtCommand(sEditCmd, aFile);
sEditCmd := PrepareParameter(sEditCmd, aFile);
ProcessExtCommand(sEditCmd, aFile.Path);
end
else
@ -2989,4 +2989,4 @@ begin
end;
end.

View file

@ -29,12 +29,29 @@ interface
uses
Classes, SysUtils, uFile, uFileView;
procedure ReplaceExtCommand(var sCmd: String;
leftPanel: TFileView;
rightPanel: TFileView;
activePanel: TFileView); overload;
type
TPrepareParameterOption = (ppoNormalizePathDelims);
TPrepareParameterOptions = set of TPrepareParameterOption;
procedure ReplaceExtCommand(var sCmd:String; aFile: TFile; ActiveDir: String=''); overload;
function PrepareParameter(sParam: String;
leftPanel: TFileView;
rightPanel: TFileView;
activePanel: TFileView;
options: TPrepareParameterOptions = []): String; overload;
function PrepareParameter(sParam: String;
aFile: TFile;
options: TPrepareParameterOptions = []): String; overload;
{en
Replace variable parameters that depend on files in panels.
}
function ReplaceVarParams(sSourceStr: String;
leftPanel: TFileView;
rightPanel: TFileView;
activePanel: TFileView): String; overload;
{en
Replace variable parameters that depend on the file in active dir.
}
function ReplaceVarParams(sSourceStr: String; aFile: TFile): String; overload;
function ProcessExtCommand(sCmd:String; ActiveDir: String): Boolean;
function ShellExecuteEx(sCmd, sFileName, sActiveDir: String): Boolean;
@ -44,6 +61,30 @@ uses
Process, UTF8Process, uDCUtils, uShowForm, uGlobs, uOSUtils,
uFileSystemFileSource;
function PrepareParameter(sParam: String;
leftPanel: TFileView;
rightPanel: TFileView;
activePanel: TFileView;
options: TPrepareParameterOptions = []): String;
begin
Result := sParam;
if ppoNormalizePathDelims in Options then
Result := NormalizePathDelimiters(Result);
Result := ReplaceEnvVars(Result);
Result := ReplaceVarParams(Result, leftPanel, rightPanel, activePanel);
Result := Trim(Result);
end;
function PrepareParameter(sParam: String; aFile: TFile; options: TPrepareParameterOptions = []): String;
begin
Result := sParam;
if ppoNormalizePathDelims in Options then
Result := NormalizePathDelimiters(Result);
Result := ReplaceEnvVars(Result);
Result := ReplaceVarParams(Result, aFile);
Result := Trim(Result);
end;
(*
Functions (without parameters they give output for all selected files):
%f - only filename
@ -86,10 +127,10 @@ uses
- if only 1 file selected : -first <file_1>
- if 2 (or more) files selected: -first <file_1> -second <file_2>
*)
procedure ReplaceExtCommand(var sCmd: String;
leftPanel: TFileView;
rightPanel: TFileView;
activePanel: TFileView);
function ReplaceVarParams(sSourceStr: String;
leftPanel: TFileView;
rightPanel: TFileView;
activePanel: TFileView): String;
type
TFunctType = (ftNone, ftName, ftDir, ftPath, ftSingleDir);
TStatePos = (spNone, spPercent, spFunction, spPrefix, spPostfix,
@ -170,7 +211,7 @@ var
begin
// Copy [parseStartIndex .. limit - 1].
if limit > parseStartIndex then
sOutput := sOutput + Copy(sCmd, parseStartIndex, limit - parseStartIndex);
sOutput := sOutput + Copy(sSourceStr, parseStartIndex, limit - parseStartIndex);
parseStartIndex := index;
end;
@ -213,7 +254,7 @@ var
state.pos := spComplete
else
begin
state.sFileIndex := state.sFileIndex + sCmd[index];
state.sFileIndex := state.sFileIndex + sSourceStr[index];
state.pos := spIndex;
end;
end;
@ -251,18 +292,18 @@ begin
ResetState(state);
while index <= Length(sCmd) do
while index <= Length(sSourceStr) do
begin
case state.pos of
spNone:
if sCmd[index] = '%' then
if sSourceStr[index] = '%' then
begin
state.pos := spPercent;
state.functStartIndex := index;
end;
spPercent:
case sCmd[index] of
case sSourceStr[index] of
'f':
begin
state.funct := ftName;
@ -288,7 +329,7 @@ begin
end;
spFunction:
case sCmd[index] of
case sSourceStr[index] of
'l':
begin
state.files := leftFiles;
@ -328,7 +369,7 @@ begin
end;
spSide:
case sCmd[index] of
case sSourceStr[index] of
'0'..'9':
ProcessNumber;
'{':
@ -338,7 +379,7 @@ begin
end;
spIndex:
case sCmd[index] of
case sSourceStr[index] of
'0'..'9':
ProcessNumber;
'{':
@ -348,7 +389,7 @@ begin
end;
spPrefix, spPostfix:
case sCmd[index] of
case sSourceStr[index] of
'}':
begin
if state.pos = spPostfix then
@ -363,15 +404,15 @@ begin
begin
case state.pos of
spPrefix:
state.prefix := state.prefix + sCmd[index];
state.prefix := state.prefix + sSourceStr[index];
spPostfix:
state.postfix := state.postfix + sCmd[index];
state.postfix := state.postfix + sSourceStr[index];
end;
end;
end;
spGotPrefix:
case sCmd[index] of
case sSourceStr[index] of
'{':
ProcessOpenBracket;
else
@ -392,7 +433,7 @@ begin
else
AddParsedText(index);
sCmd := sOutput;
Result := sOutput;
finally
if Assigned(leftFiles) then
@ -402,16 +443,11 @@ begin
end;
end;
procedure ReplaceExtCommand(var sCmd:String; aFile: TFile; ActiveDir: String);
function ReplaceVarParams(sSourceStr: String; aFile: TFile): String;
begin
with aFile do
begin
sCmd:= GetCmdDirFromEnvVar(sCmd);
sCmd:= StringReplace(sCmd,'%f',QuoteStr(Name),[rfReplaceAll]);
sCmd:= StringReplace(sCmd,'%d',QuoteStr(Path),[rfReplaceAll]);
sCmd:= StringReplace(sCmd,'%p',QuoteStr(Path + Name),[rfReplaceAll]);
sCmd:= Trim(sCmd);
end;
Result := StringReplace(sSourceStr,'%f',QuoteStr(aFile.Name),[rfReplaceAll]);
Result := StringReplace(Result ,'%d',QuoteStr(aFile.Path),[rfReplaceAll]);
Result := StringReplace(Result ,'%p',QuoteStr(aFile.FullPath),[rfReplaceAll]);
end;
function ProcessExtCommand(sCmd:String; ActiveDir: String): Boolean;
@ -487,7 +523,7 @@ begin
sCommand:= gExts.GetExtActionCmd(aFile, sCmd);
if sCommand <> '' then
begin
ReplaceExtCommand(sCommand, aFile, sActiveDir);
sCommand := PrepareParameter(sCommand, aFile);
Result:= ProcessExtCommand(sCommand, sActiveDir);
end;