/trunk/UserDetect2/UD2_Main.pas |
---|
101,7 → 101,7 |
{$R *.dfm} |
uses |
ShellAPI, Clipbrd, Math, AlphaNumSort, UD2_Utils, UD2_TaskProperties, UD2_Parsing; |
ShellAPI, Clipbrd, Math, AlphaNumSort, UD2_Utils, UD2_TaskProperties; |
type |
TUD2ListViewEntry = class(TObject) |
212,8 → 212,9 |
LNG_TASK_NOT_EXISTS = 'The task "%s" does not exist in the INI file.'; |
LNG_NOTHING_MATCHES = 'No identification string matches to your environment. No application was launched. Please check the Task Definition File.'; |
var |
slCmds: TStringList; |
i: integer; |
cmds: TUD2CommandArray; |
cmd: string; |
begin |
if not ud2.TaskExists(ShortTaskName) then |
begin |
223,20 → 224,26 |
Exit; |
end; |
SetLength(cmds, 0); |
cmds := ud2.GetCommandList(ShortTaskName); |
slCmds := TStringList.Create; |
try |
ud2.GetCommandList(ShortTaskName, slCmds); |
if (Length(cmds) = 0) and ud2.ReadMetatagBool(ShortTaskName, TagWarnIfNothingMatches, DefaultWarnIfNothingMatches) then |
if (slCmds.Count = 0) and ud2.ReadMetatagBool(ShortTaskName, TagWarnIfNothingMatches, DefaultWarnIfNothingMatches) then |
begin |
MessageDlg(LNG_NOTHING_MATCHES, mtWarning, [mbOK], 0); |
ExitCode := EXITCODE_TASK_NOTHING_MATCHES; |
end; |
for i := Low(cmds) to High(cmds) do |
for i := 0 to slCmds.Count-1 do |
begin |
UD2_RunCMD(cmds[i]); |
cmd := slCmds.Strings[i]; |
if cmd = '' then continue; |
UD2_RunCMD(cmd, SW_NORMAL); // Idea: Let SW_NORMAL be configurable by the user? |
end; |
finally |
slCmds.Free; |
end; |
end; |
procedure TUD2MainForm.FormDestroy(Sender: TObject); |
var |
381,14 → 388,8 |
end; |
procedure TUD2MainForm.Button1Click(Sender: TObject); |
var |
cmd: TUD2Command; |
begin |
cmd.executable := ud2.IniFileName; |
cmd.runAsAdmin := false; |
cmd.runInOwnDirectory := false; |
cmd.windowMode := SW_NORMAL; |
UD2_RunCMD(cmd); |
UD2_RunCMD(ud2.IniFileName, SW_NORMAL); |
end; |
procedure TUD2MainForm.Button2Click(Sender: TObject); |
401,19 → 402,14 |
procedure TUD2MainForm.URLLabelClick(Sender: TObject); |
var |
cmd: TUD2Command; |
s: string; |
begin |
cmd.executable := TLabel(Sender).Caption; |
if Pos('@', cmd.executable) > 0 then |
cmd.executable := 'mailto:' + cmd.executable |
s := TLabel(Sender).Caption; |
if Pos('@', s) > 0 then |
s := 'mailto:' + s |
else |
cmd.executable := 'http://' + cmd.executable; |
cmd.runAsAdmin := false; |
cmd.runInOwnDirectory := false; |
cmd.windowMode := SW_NORMAL; |
UD2_RunCMD(cmd); |
s := 'http://' + s; |
UD2_RunCMD(s, SW_NORMAL); |
end; |
procedure TUD2MainForm.TasksPopupMenuPopup(Sender: TObject); |
533,10 → 529,7 |
begin |
ExitCode := EXITCODE_OK; |
if ParamStr(3) <> '' then |
begin |
UD2_RunCMD(UD2P_DecodeCommand(ParamStr(3))); |
end; |
if ParamStr(3) <> '' then UD2_RunCMD(ParamStr(3), SW_NORMAL); // Idea: SW_NORMAL changeable via parameter |
end |
else |
begin |
577,28 → 570,23 |
procedure TUD2MainForm.Button5Click(Sender: TObject); |
var |
idTerm: string; |
cmds: TUD2CommandArray; |
sCmds: string; |
i: integer; |
slCmd: TStrings; |
begin |
// TODO xxx: Auch eine Möglichkeit geben, einfach nur "Testecho(abc)" einzugeben und es kommt was bei raus |
if InputQuery('Enter example term', 'Example: Testecho(abc):abc=calc.exe', idTerm) then |
begin |
SetLength(cmds, 0); |
cmds := ud2.CheckTerm(idTerm); |
sCmds := ''; |
for i := Low(cmds) to High(cmds) do |
begin |
sCmds := sCmds + cmds[i].executable + #13#10; |
end; |
if Length(cmds) = 0 then |
slCmd := TStringList.Create; |
try |
ud2.CheckTerm(idTerm, slCmd); |
if slCmd.Count = 0 then |
ShowMessage('No commands would be executed.') |
else |
showmessage('Following commands would be executed:' + #13#10#13#10 + sCmds); |
showmessage('Following commands would be executed:' + #13#10#13#10 + slCmd.Text); |
finally |
slCmd.Free; |
end; |
end; |
LoadDetectedIDs; |
end; |
/trunk/UserDetect2/UD2_Obj.pas |
---|
10,7 → 10,7 |
uses |
Windows, SysUtils, Classes, IniFiles, Contnrs, Dialogs, UD2_PluginIntf, |
UD2_PluginStatus, UD2_Utils, UD2_Parsing; |
UD2_PluginStatus, UD2_Utils; |
type |
TUD2IdentificationEntry = class; |
77,11 → 77,10 |
property LoadedPlugins: TObjectList{<TUD2Plugin>} read FLoadedPlugins; |
property IniFile: TMemIniFile read FIniFile; |
procedure GetAllDetectedIDs(outSL: TStrings); |
function FulfilsEverySubterm(conds: TUD2TDFConditionArray; slIdNames: TStrings=nil): boolean; overload; |
function FulfilsEverySubterm(idTerm: WideString; slIdNames: TStrings=nil): boolean; overload; |
function CheckTerm(idTermAndCmd: string; slIdNames: TStrings=nil): TUD2CommandArray; |
function FulfilsEverySubterm(idTerm: WideString; slIdNames: TStrings=nil): boolean; |
procedure CheckTerm(idTermAndCmd: string; commandSLout: TStrings; slIdNames: TStrings=nil); |
function FindPluginByMethodNameOrGuid(idMethodName: string): TUD2Plugin; |
function GetCommandList(ShortTaskName: string): TUD2CommandArray; |
procedure GetCommandList(ShortTaskName: string; outSL: TStrings); |
procedure HandlePluginDir(APluginDir, AFileMask: string); |
procedure GetTaskListing(outSL: TStrings); |
constructor Create(AIniFileName: string); |
251,18 → 250,18 |
{ TUD2IdentificationEntry } |
procedure TUD2IdentificationEntry.GetIdNames(sl: TStrings); |
var |
cond: TUD2TDFCondition; |
begin |
cond.idMethodName := Plugin.IdentificationMethodName; |
cond.idStr := IdentificationString; |
cond.dynamicDataUsed := DynamicDataUsed; |
cond.dynamicData := DynamicData; |
sl.Add(UD2_CondToStr(cond)); |
cond.idMethodName := Plugin.PluginGUIDString; |
sl.Add(UD2_CondToStr(cond)); |
if DynamicDataUsed then |
begin |
sl.Add(Plugin.IdentificationMethodName+'('+DynamicData+'):'+IdentificationString); |
sl.Add(Plugin.PluginGUIDString+'('+DynamicData+'):'+IdentificationString); |
end |
else |
begin |
sl.Add(Plugin.IdentificationMethodName+':'+IdentificationString); |
sl.Add(Plugin.PluginGUIDString+':'+IdentificationString); |
end; |
end; |
constructor TUD2IdentificationEntry.Create(AIdentificationString: WideString; |
APlugin: TUD2Plugin); |
443,19 → 442,18 |
end; |
end; |
function TUD2.FulfilsEverySubterm(conds: TUD2TDFConditionArray; slIdNames: TStrings=nil): boolean; |
begin |
result := FulfilsEverySubterm(UD2_CondsToStr(conds), slIdNames); |
end; |
function TUD2.FulfilsEverySubterm(idTerm: WideString; slIdNames: TStrings=nil): boolean; |
const |
CASE_SENSITIVE_FLAG = '$CASESENSITIVE$'; |
var |
x, a, b: TArrayOfString; |
i: integer; |
p: TUD2Plugin; |
idName: WideString; |
cleanUpStringList: boolean; |
conds: TUD2TDFConditionArray; |
cond: TUD2TDFCondition; |
idName: string; |
caseSensitive: boolean; |
dynamicData: string; |
idMethodName: string; |
begin |
cleanUpStringList := slIdNames = nil; |
try |
465,19 → 463,40 |
GetAllDetectedIDs(slIdNames); |
end; |
conds := UD2P_ParseConditions(idTerm); |
SetLength(x, 0); |
if Pos(':', idTerm) = 0 then |
begin |
// Exclude stuff like "Description" |
result := false; |
Exit; |
end; |
x := SplitString('&&', idTerm); |
result := true; |
for i := Low(conds) to High(conds) do |
for i := Low(x) to High(x) do |
begin |
cond := conds[i]; |
idName := x[i]; |
if cond.dynamicDataUsed then |
/// --- Start Dynamic Extension |
// xxxxxx ( xxxxx ): xxxxxxxxxxxx |
// xxxxx ( xx:xx ): xxxxx:xxx(x) |
// xxxxxxxxxxxx : xxxxx(xxx)xx |
SetLength(a, 0); |
a := SplitString('(', idName); |
if (Length(a) >= 2) and (Pos(':', a[0]) = 0) then |
begin |
p := FindPluginByMethodNameOrGuid(cond.idMethodName); |
SetLength(b, 0); |
b := SplitString('):', a[1]); |
if Length(b) >= 2 then |
begin |
dynamicData := b[0]; |
idMethodName := a[0]; |
p := FindPluginByMethodNameOrGuid(idMethodName); |
if Assigned(p) then |
begin |
if p.InvokeDynamicCheck(cond.dynamicData) then |
if p.InvokeDynamicCheck(dynamicData) then |
begin |
// Reload the identifications |
slIdNames.Clear; |
485,12 → 504,23 |
end; |
end; |
end; |
end; |
idName := UD2_CondToStr(cond); |
/// --- End Dynamic Extension |
if (not cond.caseSensitive and (slIdNames.IndexOf(idName) = -1)) or |
(cond.caseSensitive and (IndexOf_CS(slIdNames, idName) = -1)) then |
if Pos(CASE_SENSITIVE_FLAG, idName) >= 1 then |
begin |
idName := StringReplace(idName, CASE_SENSITIVE_FLAG, '', [rfReplaceAll]); |
caseSensitive := true; |
end |
else |
begin |
caseSensitive := false; |
end; |
if (not caseSensitive and (slIdNames.IndexOf(idName) = -1)) or |
(caseSensitive and (IndexOf_CS(slIdNames, idName) = -1)) then |
begin |
result := false; |
break; |
end; |
519,15 → 549,11 |
end; |
end; |
function TUD2.GetCommandList(ShortTaskName: string): TUD2CommandArray; |
procedure TUD2.GetCommandList(ShortTaskName: string; outSL: TStrings); |
var |
i, j, l: integer; |
i: integer; |
slSV, slIdNames: TStrings; |
tmpCmds: TUD2CommandArray; |
begin |
SetLength(result, 0); |
SetLength(tmpCmds, 0); |
slIdNames := TStringList.Create; |
try |
GetAllDetectedIDs(slIdNames); |
537,14 → 563,8 |
FIniFile.ReadSectionValues(ShortTaskName, slSV); |
for i := 0 to slSV.Count-1 do |
begin |
tmpCmds := CheckTerm(slSV.Strings[i], slIdNames); |
for j := Low(tmpCmds) to High(tmpCmds) do |
begin |
l := Length(result); |
SetLength(result, l+1); |
result[l] := tmpCmds[j]; |
CheckTerm(slSV.Strings[i], outSL, slIdNames); |
end; |
end; |
finally |
slSV.Free; |
end; |
553,13 → 573,12 |
end; |
end; |
function TUD2.CheckTerm(idTermAndCmd: string; slIdNames: TStrings=nil): TUD2CommandArray; |
procedure TUD2.CheckTerm(idTermAndCmd: string; commandSLout: TStrings; slIdNames: TStrings=nil); |
var |
nameVal: TArrayOfString; |
idTerm, cmd: string; |
slIdNamesCreated: boolean; |
ent: TUD2TDFEntry; |
begin |
SetLength(result, 0); |
slIdNamesCreated := false; |
try |
if not Assigned(slIdNames) then |
569,11 → 588,18 |
GetAllDetectedIDs(slIdNames); |
end; |
if not UD2P_ParseTdfLine(idTermAndCmd, ent) then Exit; |
if FulfilsEverySubterm(ent.ids, slIdNames) then |
begin |
result := ent.commands; |
end; |
SetLength(nameVal, 0); |
// We are doing the interpretation of the line ourselves, because |
// TStringList.Values[] would not allow multiple command lines with the |
// same key (idTerm) |
// TODO xxx: big problem when we want to check environment variables, since our idTerm would contain '=' ! |
nameVal := SplitString('=', idTermAndCmd); |
if Length(nameVal) < 2 then exit; |
idTerm := nameVal[0]; |
cmd := nameVal[1]; |
if FulfilsEverySubterm(idTerm, slIdNames) then commandSLout.Add(cmd); |
finally |
if slIdNamesCreated then slIdNames.Free; |
end; |
/trunk/UserDetect2/UD2_Parsing.pas |
---|
7,13 → 7,6 |
// TODO: use this for better object oriented programming |
// TODO : WideStrings idName: WideString; ??? |
const |
// Prefixes for UD2_RunCmd() |
UD2_RUN_IN_OWN_DIRECTORY_PREFIX = '$RIOD$'; |
UD2_RUN_AS_ADMIN = '$ADMIN$'; |
type |
TUD2Command = record |
executable: string; |
38,157 → 31,55 |
end; |
TUD2TDFEntryArray = array of TUD2TDFEntry; |
// Split |
function UD2P_ParseConditions(idTerm: string): TUD2TDFConditionArray; |
function UD2P_ParseTdfLine(idTermAndCmd: string; var entry: TUD2TDFEntry): boolean; |
function UD2P_DecodeCommand(line: string): TUD2Command; |
function UD2P_DecodeCondition(idName: string; var cond: TUD2TDFCondition): boolean; |
// Merge |
function UD2_CondToStr(cond: TUD2TDFCondition): string; |
function UD2_CondsToStr(conds: TUD2TDFConditionArray): string; |
implementation |
uses |
UD2_Utils; |
function UD2_CondsToStr(conds: TUD2TDFConditionArray): string; |
var |
i: integer; |
function ParseTdfLine(line: string; var entry: TUD2TDFEntry): boolean; |
begin |
result := ''; |
for i := Low(conds) to High(conds) do |
begin |
if result <> '' then result := result + '&&'; |
result := result + UD2_CondToStr(conds[i]); |
end; |
end; |
// TODO: xxxxx |
function UD2_CondToStr(cond: TUD2TDFCondition): string; |
begin |
if cond.dynamicDataUsed then |
begin |
result := cond.idMethodName+'('+cond.dynamicData+'):'+cond.idStr; |
end |
else |
begin |
result := cond.idMethodName+':'+cond.idStr; |
end; |
end; |
(* |
entry.idName: string; |
entry.idValue: string; |
entry.dynamicDataUsed: Boolean; |
entry.dynamicData: string; |
entry.caseSensitive: boolean; |
entry.commands: TUD2CommandArray; |
*) |
function UD2P_DecodeCommand(line: string): TUD2Command; |
begin |
result.runAsAdmin := Pos(UD2_RUN_AS_ADMIN, line) >= 1; |
if result.runAsAdmin then |
begin |
line := StringReplace(line, UD2_RUN_AS_ADMIN, '', [rfReplaceAll]); |
end; |
// ReadSectionValues |
result.runInOwnDirectory := Pos(UD2_RUN_IN_OWN_DIRECTORY_PREFIX, line) >= 1; |
if result.runInOwnDirectory then |
begin |
line := StringReplace(line, UD2_RUN_IN_OWN_DIRECTORY_PREFIX, '', [rfReplaceAll]); |
end; |
result.executable := line; |
result.WindowMode := SW_NORMAL; // TODO (future): make it configurable |
(* |
nameVal := SplitString('=', idTermAndCmd); |
if Length(nameVal) < 2 then exit; |
idTerm := nameVal[0]; |
cmd := nameVal[1]; |
*) |
end; |
function UD2P_DecodeCondition(idName: string; var cond: TUD2TDFCondition): boolean; |
const |
CASE_SENSITIVE_FLAG = '$CASESENSITIVE$'; |
var |
a, b: TArrayOfString; |
function ParseCommandLine(line: string; var cmd: TUD2Command): boolean; |
begin |
result := false; |
cond.caseSensitive := Pos(CASE_SENSITIVE_FLAG, idName) >= 1; |
if cond.caseSensitive then |
if Pos(UD2_RUN_AS_ADMIN, line) >= 1 then |
begin |
idName := StringReplace(idName, CASE_SENSITIVE_FLAG, '', [rfReplaceAll]); |
end; |
line := StringReplace(line, UD2_RUN_AS_ADMIN, '', [rfReplaceAll]); |
cmd.runAsAdmin := true; |
end |
else cmd.runAsAdmin := false; |
/// --- Start Dynamic Extension |
// xxxxxx ( xxxxx ): xxxxxxxxxxxx |
// xxxxx ( xx:xx ): xxxxx:xxx(x) |
// xxxxxxxxxxxx : xxxxx(xxx)xx |
SetLength(a, 0); |
a := SplitString('(', idName); |
if (Length(a) >= 2) and (Pos(':', a[0]) = 0) then |
if Pos(UD2_RUN_IN_OWN_DIRECTORY_PREFIX, line) >= 1 then |
begin |
SetLength(b, 0); |
b := SplitString('):', a[1]); |
if Length(b) >= 2 then |
begin |
cond.idMethodName := a[0]; |
cond.idStr := b[1]; |
cond.dynamicDataUsed := true; |
cond.dynamicData := b[0]; |
result := true; |
Exit; |
end; |
end; |
/// --- End Dynamic Extension |
line := StringReplace(line, UD2_RUN_IN_OWN_DIRECTORY_PREFIX, '', [rfReplaceAll]); |
cmd.runInOwnDirectory := true; |
end |
else cmd.runInOwnDirectory := false; |
if not result then |
begin |
a := SplitString(':', idName); |
if Length(a) >= 2 then |
begin |
cond.idMethodName := a[0]; |
cond.idStr := a[1]; |
cond.dynamicDataUsed := false; |
cond.dynamicData := ''; |
result := true; |
Exit; |
end; |
end; |
end; |
cmd.executable := line; |
function UD2P_ParseConditions(idTerm: string): TUD2TDFConditionArray; |
var |
cond: TUD2TDFCondition; |
x: TArrayOfString; |
i, l: integer; |
idName: string; |
begin |
SetLength(x, 0); |
x := SplitString('&&', idTerm); |
SetLength(result, 0); |
for i := Low(x) to High(x) do |
begin |
idName := x[i]; |
if UD2P_DecodeCondition(idName, cond) then |
begin |
l := Length(result); |
SetLength(result, l+1); |
result[l] := cond; |
end; |
end; |
end; |
cmd.windowMode := SW_NORMAL; // TODO (future): make it configurable |
function UD2P_ParseTdfLine(idTermAndCmd: string; var entry: TUD2TDFEntry): boolean; |
var |
nameVal: TArrayOfString; |
idTerm, cmd: string; |
begin |
result := false; |
// Split conditions and command |
nameVal := SplitString('=', idTermAndCmd); // TODO: problem... "=" could be inside dynamicData... |
if Length(nameVal) < 2 then exit; |
idTerm := nameVal[0]; |
cmd := nameVal[1]; |
// Decode conditions |
entry.ids := UD2P_ParseConditions(idTerm); |
// Decode command |
SetLength(entry.commands, 1); |
entry.commands[0] := UD2P_DecodeCommand(cmd); |
result := true; |
end; |
/trunk/UserDetect2/UD2_TaskProperties.pas |
---|
37,7 → 37,7 |
{$R *.dfm} |
uses |
UD2_Utils, UD2_Main, UD2_Parsing, ShellAPI; |
UD2_Utils, UD2_Main, ShellAPI; |
procedure TUD2TaskPropertiesForm.LoadExecutableFilesList; |
resourcestring |
44,30 → 44,31 |
LNG_RIOD = 'Run in own directory'; |
LNG_ADMIN = 'Run as admin'; |
var |
sl: TStringList; |
i: integer; |
flags: string; |
cmds: TUD2CommandArray; |
cmd: TUD2Command; |
cmdLine, flags: string; |
begin |
//fud2.GetCommandList(AShortTaskName, ListBox1.Items); |
ListBox1.Clear; |
cmds := fud2.GetCommandList(FShortTaskName); |
for i := Low(cmds) to High(cmds) do |
sl := TStringList.Create; |
try |
fud2.GetCommandList(FShortTaskName, sl); |
for i := 0 to sl.Count-1 do |
begin |
cmd := cmds[i]; |
cmdLine := sl.Strings[i]; |
flags := ''; |
if cmd.runAsAdmin then |
if Pos(UD2_RUN_AS_ADMIN, cmdLine) >= 1 then |
begin |
cmdLine := StringReplace(cmdLine, UD2_RUN_AS_ADMIN, '', [rfReplaceAll]); |
if flags <> '' then flags := flags + ', '; |
flags := flags + LNG_ADMIN; |
end; |
if cmd.runInOwnDirectory then |
if Pos(UD2_RUN_IN_OWN_DIRECTORY_PREFIX, cmdLine) >= 1 then |
begin |
cmdLine := StringReplace(cmdLine, UD2_RUN_IN_OWN_DIRECTORY_PREFIX, '', [rfReplaceAll]); |
if flags <> '' then flags := flags + ', '; |
flags := flags + LNG_RIOD; |
end; |
77,9 → 78,12 |
flags := ' [' + flags + ']'; |
end; |
ListBox1.Items.Add(cmd.executable + flags); |
ListBox1.Items.Add(cmdLine + flags); |
end; |
finally |
sl.Free; |
end; |
end; |
procedure TUD2TaskPropertiesForm.LoadIcon; |
var |
130,14 → 134,8 |
end; |
procedure TUD2TaskPropertiesForm.Button1Click(Sender: TObject); |
var |
cmd: TUD2Command; |
begin |
cmd.executable := fud2.IniFileName; |
cmd.runAsAdmin := false; |
cmd.runInOwnDirectory := false; |
cmd.windowMode := SW_NORMAL; |
UD2_RunCMD(cmd); |
UD2_RunCMD(fud2.IniFileName, SW_NORMAL); |
end; |
end. |
/trunk/UserDetect2/UD2_Utils.pas |
---|
9,7 → 9,7 |
{$INCLUDE 'UserDetect2.inc'} |
uses |
Windows, SysUtils, Dialogs, ShellAPI, Classes, UD2_Parsing; |
Windows, SysUtils, Dialogs, ShellAPI, Classes; |
const |
EXITCODE_OK = 0; |
28,11 → 28,16 |
IconIndex: integer; |
end; |
const |
// Prefixes for UD2_RunCmd() |
UD2_RUN_IN_OWN_DIRECTORY_PREFIX = '$RIOD$'; |
UD2_RUN_AS_ADMIN = '$ADMIN$'; |
function SplitString(const aSeparator, aString: string; aMax: Integer = 0): TArrayOfString; |
function BetterInterpreteBool(str: string): boolean; |
function GetOwnCmdName: string; |
function ExpandEnvStr(const szInput: string): string; |
procedure UD2_RunCMD(cmd: TUD2Command); |
procedure UD2_RunCMD(cmdLine: string; WindowMode: integer=SW_NORMAL); |
function SplitIconString(IconString: string): TIconFileIdx; |
// function GetHTML(AUrl: string): string; |
procedure VTS_CheckUpdates(VTSID, CurVer: string); |
193,7 → 198,7 |
end; |
end; |
procedure UD2_RunCMD(cmd: TUD2Command); |
procedure UD2_RunCMD(cmdLine: string; WindowMode: integer=SW_NORMAL); |
// Discussion: http://stackoverflow.com/questions/32802679/acceptable-replacement-for-winexec/32804669#32804669 |
// Version 1: http://pastebin.com/xQjDmyVe |
// --> CreateProcess + ShellExecuteEx |
212,7 → 217,6 |
cmdFile, cmdArgs, cmdDir: string; |
p: integer; |
sei: TShellExecuteInfo; |
cmdLine: string; |
begin |
// We need a function which does following: |
// 1. Replace the Environment strings, e.g. %SystemRoot% |
222,7 → 226,7 |
// 5. Runs non-EXE files (e.g. "Letter.doc") |
// 6. Commands with white spaces (e.g. "C:\Program Files\xyz.exe") must be enclosed in quotes. |
cmdLine := ExpandEnvStr(cmd.executable); |
cmdLine := ExpandEnvStr(cmdLine); |
// Split command line from argument list |
if Copy(cmdLine, 1, 1) = '"' then |
258,13 → 262,17 |
ZeroMemory(@sei, SizeOf(sei)); |
if cmd.runAsAdmin then |
if Pos(UD2_RUN_AS_ADMIN, cmdLine) >= 1 then |
begin |
cmdLine := StringReplace(cmdLine, UD2_RUN_AS_ADMIN, '', [rfReplaceAll]); |
sei.lpVerb := 'runas'; |
end; |
if cmd.runInOwnDirectory then |
if Pos(UD2_RUN_IN_OWN_DIRECTORY_PREFIX, cmdLine) >= 1 then |
begin |
cmdLine := StringReplace(cmdLine, UD2_RUN_IN_OWN_DIRECTORY_PREFIX, '', [rfReplaceAll]); |
cmdFile := ExtractFileName(cmdLine); |
cmdDir := ExtractFilePath(cmdLine); |
end |
281,7 → 289,7 |
{$ENDIF} |
if cmdArgs <> '' then sei.lpParameters := PChar(cmdArgs); |
if cmdDir <> '' then sei.lpDirectory := PChar(cmdDir); |
sei.nShow := cmd.windowMode; |
sei.nShow := WindowMode; |
if ShellExecuteEx(@sei) then Exit; |
{$IFNDEF PREFER_SHELLEXECUTEEX_MESSAGES} |
if not CheckLastOSCall(false) then ExitCode := EXITCODE_RUN_FAILURE; |
466,18 → 474,16 |
end; |
function IndexOf_CS(aStrings: TStrings; aToken: String): Integer; |
// Source: http://www.delphipraxis.net/888928-post15.html |
var |
i: Integer; |
begin |
Result := -1; |
for i := 0 to aStrings.Count-1 do |
begin |
if aStrings[i] = aToken then |
begin |
for i := 0 to aStrings.Count do |
if aStrings[i]=aToken then begin |
Result := i; |
Break; |
end; |
end; |
end; |
end. |