//Delphi-Library.de - Die ausführbare Datei eines "advertised shortcut" ermitteln //http://www.delphi-library.de/topic_51393.html&sid=2b3c4a2a855c0d6d668dc5afb6a29bf2 unit getAdvShortcut; interface uses Forms, ShlObj, ComObj, ActiveX, CommCtrl, Windows, SysUtils; {...} procedure getExecData(lnkName : String; var execName, execDir, execArgs : String); implementation {...} type TCharArray = Array[0..MAX_PATH] of Char; //Hier gefunden: http://www.swissdelphicenter.ch/de/showcode.php?id=970 type PShellLinkInfoStruct = ^TShellLinkInfoStruct; TShellLinkInfoStruct = record FullPathAndNameOfLinkFile: TCharArray; FullPathAndNameOfFileToExecute: TCharArray; ParamStringsOfFileToExecute: TCharArray; FullPathAndNameOfWorkingDirectroy: TCharArray; Description: TCharArray; FullPathAndNameOfFileContiningIcon: TCharArray; IconIndex: Integer; HotKey: Word; ShowCommand: Integer; FindData: TWIN32FINDDATA; end; // Hat Mathias Simmack hier verwendet, um die hier demonstrierte Funktion zu vewrenden: // http://www.delphi-forum.de/viewtopic.php?t=27628 const MsiDllName = 'msi.dll'; INSTALLSTATE_ABSENT = 2; // uninstalled INSTALLSTATE_LOCAL = 3; // installed on local drive INSTALLSTATE_SOURCE = 4; // run from source, CD or net INSTALLSTATE_SOURCEABSENT = -4; // run from source, source is unavailable INSTALLSTATE_NOTUSED = -7; // component disabled INSTALLSTATE_INVALIDARG = -2; // invalid function argument INSTALLSTATE_UNKNOWN = -1; // unrecognized product or feature type INSTALLSTATE = LongInt; TMsiGetShortcutTarget = function(szShortcutTarget, szProductCode, szFeatureId, szComponentCode: PAnsiChar): uint; stdcall; TMsiGetComponentPath = function(szProduct, szComponent: PAnsiChar; lpPathBuf: PAnsiChar; pcchBuf: pdword): INSTALLSTATE; stdcall; var MsiGetShortcutTarget : TMsiGetShortcutTarget = nil; MsiGetComponentPath : TMsiGetComponentPath = nil; MsiDll : dword = 0; //Hier gefunden: http://www.swissdelphicenter.ch/de/showcode.php?id=970 procedure GetLinkInfo(lpShellLinkInfoStruct: PShellLinkInfoStruct); var ShellLink: IShellLink; PersistFile: IPersistFile; AnObj: IUnknown; begin //Interface-Objekte holen AnObj := CreateComObject(CLSID_ShellLink); ShellLink := AnObj as IShellLink; PersistFile := AnObj as IPersistFile; // Datei öffnen und Objekt initialisieren PersistFile.Load(PWChar(WideString(lpShellLinkInfoStruct^.FullPathAndNameOfLinkFile)), 0); with ShellLink do begin // Pfad und Dateiname ermitteln GetPath(lpShellLinkInfoStruct^.FullPathAndNameOfFileToExecute, SizeOf(lpShellLinkInfoStruct^.FullPathAndNameOfLinkFile), lpShellLinkInfoStruct^.FindData, SLGP_UNCPRIORITY); // Arbeitsverzeichnis ermitteln GetWorkingDirectory(lpShellLinkInfoStruct^.FullPathAndNameOfWorkingDirectroy, SizeOf(lpShellLinkInfoStruct^.FullPathAndNameOfWorkingDirectroy)); // Befehlszeilen-Argumente ermitteln GetArguments(lpShellLinkInfoStruct^.ParamStringsOfFileToExecute, SizeOf(lpShellLinkInfoStruct^.ParamStringsOfFileToExecute)); end; end; // Ermittelt den Namen der ausführbaren Datei (execName), das Arbeitsverzeichnis (execDir) und // die Befehlszeilen-Argumente (execArgs) aus einer übergebenen Verknüpfung. procedure getExecData(lnkName : String; var execName, execDir, execArgs : String); var LinkInfo: TShellLinkInfoStruct; aFile : TCharArray; prodCode, featureId, compCode : TCharArray; aPath : TCharArray; pathLength : DWord; begin FillChar(LinkInfo, SizeOf(LinkInfo), #0); StrCopy(@aFile, PChar(lnkName)); LinkInfo.FullPathAndNameOfLinkFile := aFile; GetLinkInfo(@LinkInfo); //Informationen eines non-advertised Shortcut ermitteln execName := LinkInfo.FullPathAndNameOfFileToExecute; execDir := LinkInfo.FullPathAndNameOfWorkingDirectroy; execArgs := LinkInfo.ParamStringsOfFileToExecute; ZeroMemory(@prodCode, sizeOf(prodCode)); ZeroMemory(@featureId, sizeOf(featureId)); ZeroMemory(@compCode, sizeOf(compCode)); if MsiGetShortcutTarget(aFile, prodCode, featureId, compCode) = ERROR_SUCCESS then //advertised shortcut? begin pathLength := sizeOf(aPath); ZeroMemory(@aPath, sizeOf(aPath)); if MsiGetComponentPath(prodCode, compCode, aPath, @pathLength) = INSTALLSTATE_LOCAL then //Anwendung ausführbar? execName := aPath; //Pfad auf die ausführbare Datei setzen end; end; // Hat Mathias Simmack hier verwendet, um die hier demonstrierte Funktion zu vewrenden: // http://www.delphi-forum.de/viewtopic.php?t=27628 initialization MsiDll := GetModuleHandle(MsiDllName); if(MsiDll = 0) then MsiDll := LoadLibrary(MsiDllName); if(MsiDll <> 0) then begin MsiGetShortcutTarget := GetProcAddress(MsiDll, 'MsiGetShortcutTargetA'); MsiGetComponentPath := GetProcAddress(MsiDll, 'MsiGetComponentPathA'); if(@MsiGetShortcutTarget = nil) or (@MsiGetComponentPath = nil) then begin FreeLibrary(MsiDll); MsiDll := 0; end; end; finalization if(MsiDll <> 0) then FreeLibrary(MsiDll); end.