Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Verknüpfung vollstädnig auslesen (https://www.delphipraxis.net/128498-verknuepfung-vollstaednig-auslesen.html)

virus82 30. Jan 2009 22:18


Verknüpfung vollstädnig auslesen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallöle,

ich suche eine Methode um eine lnk.Datei komplett auszulesen. Ich habe schon die Suchfunktion genutzt und auch etwas passendes gefunden.

Verknüpfung (lnk) vollstädnig auslesen

Funktioniert auch super mit "normalen" Verknüpfungen, aber mit einigen nicht. Wenn man eine Verknüpfung mit dem Ordner Systemsteuerung oder Systemsteuerung/Software anlegt und diese dann mit der im Link beschrieben Funktion (ShellLink.GetPath) versucht einzulesen bleibt der Path leer.

z.B.:
Systemsteuerung.lnk
Software.lnk

Ich benutze WinXP SP3 und Delphi 7 Enterprise

Jemand ne Idee oder nen Anhaltspunkt?

Im Anhang die Systemsteuerung.lnk und die Software.lnk

virus82 21. Okt 2009 07:51

Re: Verknüpfung vollstädnig auslesen
 
Hmm ... sieht so aus als hätte keiner ne Idee.

himitsu 21. Okt 2009 08:07

Re: Verknüpfung vollstädnig auslesen
 
Bei solchen Links steht dort nicht der Pfad drinen, sondern nur irgendwie 'ne ID und den Pfad muß man sich dann vermutlich irgendwo aus der Registry raussuchen

keine Anhnung, ob das IShellLink automatisch macht (anscheinend ja nicht), bzw. ob man dafür noch irgendwas "einstellen" muß,

oder ob man da selber iegendwie anders rangehn muß.


[edit]
hmmm ... bei Systemsteuerung.lnk stimmt's

aber im SoftwreLink steht der Pfad drinnen :gruebel:


ansonsten dürfte sich bestimmt irgendwo bei MS/MSDN eine Definition dieser Datei finden lassen,
zum selberauslesen :angel2:

virus82 27. Okt 2009 13:47

Re: Verknüpfung vollstädnig auslesen
 
Hmm ... ok, das mit der ID hab ich mir auch schon gedacht, nur wie kann ich von solch einer Verknüpfung die ID auslesen?

Auch die Verknüpfungen von Microsoft Office 2003 im Startmenü scheinen keinen normalen Verknüpfungen zu sein.

MarcoWarm 27. Okt 2009 14:04

Re: Verknüpfung vollstädnig auslesen
 
Solche Verküpfungen lassen sich nur via IShellLink.GetIdList rausbekommen.

mehr dazu hier http://msdn.microsoft.com/en-us/libr...8VS.85%29.aspx und
hier MSDN-Library durchsuchenITEMIDLIST Structure

Gruß
Marco

virus82 28. Okt 2009 08:57

Re: Verknüpfung vollstädnig auslesen
 
OK, soweit so gut, Leider kenne ich mich damit überhaupt nicht aus. Und aus der MSDN werd ich auch nicht wirklich schlau. Wie kann man denn jetzt so ne ItemIDList in nen lesbaren String umwandeln?

virus82 4. Nov 2009 23:27

Re: Verknüpfung vollstädnig auslesen
 
Kann mir jemand weiterhelfen mit dem IDItem?

MarcoWarm 5. Nov 2009 07:52

Re: Verknüpfung vollstädnig auslesen
 
Da kommt man ganz schön ins Schwitzen mit ItemIDList :gruebel:

Colin Wilson hat mal eine Unit geschrieben um erweiterte Folder Infos rauszubekommen, damit hab ich einen, auf dem Desktop liegenden Systemsteuerungslink auflösen könnnen.
die Unit gibts hier - > http://www.google.com/codesearch/p?hl=de&sa=N&cd=4&ct=rc#xZxB14YhmSA/files/d10/LowLevel100.zip|LowLevel100/Source/unitFolderUtils.pas&q=SHBindToParent%20lang:pascal

Suche nach GetFolderName und NextID. Die musst du dir zuvor noch in den implementation Teil holen. Damit kannst du die ItemIDList durchgehen und dir den namen holen.

Gruß
Marco

virus82 5. Nov 2009 19:28

Re: Verknüpfung vollstädnig auslesen
 
Da hast du Recht da kann man ganz schön ins Schwitzen kommen. Schon mal Danke, schaue ich mir an.

MarcoWarm 6. Nov 2009 09:07

Re: Verknüpfung vollstädnig auslesen
 
So... ausgeschwitzt ;-)

hier kommt nun ein Beispiel, wie man von jeder Verknüpfung einen voll qualifizierten Namen und Pfad bekommt:

Delphi-Quellcode:
uses ComObj, ActiveX, ShlObj;

const
  IID_IShellItem: TGUID = '{43826d1e-e718-42ee-bc55-a1e261c37bfe}';

type
  {$EXTERNALSYM IShellItem}
  IShellItem = interface(IUnknown)
  ['{43826d1e-e718-42ee-bc55-a1e261c37bfe}']
    function BindToHandler(pbc: IBindCtx; const rbhid: TGUID; const riid: TIID;
      out ppvOut): HResult; stdcall;
    function GetParent(out ppsi: IShellItem): HResult; stdcall;
    function GetDisplayName(sigdnName: DWord;
      out ppszName: POleStr): HResult; stdcall;
    function GetAttributes(sfgaoMask: ULong;
      out psfgaoAttribs: ULong): HResult; stdcall;
    function Compare(psi: IShellItem; hint: DWord;
      out piOrder: Integer): HResult; stdcall;
  end;

function SHBindToParent(pidl : PItemIdList; const riid : TIID; out ppv; var ppidlLast : PItemIdList) : Hresult; stdcall; external 'shell32.dll';
function SHCreateShellItem(pidlParent: PItemIDList; psfParent: IShellFolder; pidl: PItemIDList; out ppsi: IShellItem): HResult stdcall; external 'shell32.dll';

type
  TFolderNameType = (fnNormal, fnInFolder, fnForEditing, fnForAddressBar, fnForParsing);

function GetFolderName (folder : IShellFolder; pidl : PItemIDList; tp : TFolderNameType) : WideString; overload;
var
  t : DWORD;
  str : TStrRet;
begin
  case tp of
    fnInfolder     : t := SHGDN_INFOLDER;
    fnForEditing   : t := SHGDN_FOREDITING;
    fnForAddressBar : t := SHGDN_FORADDRESSBAR;
    fnForPARSING   : t := SHGDN_FORPARSING;
    else
      t := SHGDN_NORMAL;
  end;

  if Succeeded (folder.GetDisplayNameOf(pidl, t, str)) then
  case str.uType of
    STRRET_CSTR  : result := str.cStr;
    STRRET_WSTR  : begin
                      result := str.pOleStr;
                      CoTaskMemFree (str.pOleStr)
                    end;
    STRRET_OFFSET : result := PChar (pidl) + str.uOffset;
    else result := ''
  end
  else
    result := ''
end;

function ReadLnkFile(const LnkFileName: String; out Path, Arguments, WorkingDirectory, Description: String; out HotKey: Word; out ShowCmd: Integer; out IconPath: String; out IconIndex: Integer; out ItemIDList: PItemIDList): Boolean;
var
  ShellLink: IShellLink;
  PersistFile: IPersistFile;
  FileInfo: TWin32FindData;
begin
  Result:=False;
  if SUCCEEDED(CoCreateInstance(CLSID_ShellLink, nil, CLSCTX_INPROC_SERVER, IShellLink, ShellLink)) then
  begin
    PersistFile := ShellLink as IPersistFile;
    if SUCCEEDED(PersistFile.Load(StringToOleStr(LnkFileName), STGM_READ)) then
    with ShellLink do
    begin
      SetLength(Path, MAX_PATH + 1);
      if SUCCEEDED(GetPath(PChar(Path), MAX_PATH, FileInfo, SLR_ANY_MATCH)) then
      begin
        Path := PChar(Path);
        Result := True;
        SetLength(Arguments, MAX_PATH +  1);
        GetArguments(PChar(Arguments), MAX_PATH);
        Arguments := PChar(Arguments);
        SetLength(WorkingDirectory, MAX_PATH + 1);
        GetWorkingDirectory(PChar(WorkingDirectory), MAX_PATH);
        WorkingDirectory := PChar(WorkingDirectory);
        SetLength(Description, MAX_PATH + 1);
        GetDescription(PChar(Description), MAX_PATH);
        Description := PChar(Description);
        GetHotkey(HotKey);
        GetShowCmd(ShowCmd);
        SetLength(IconPath, MAX_PATH + 1);
        GetIconLocation(PChar(IconPath), MAX_PATH, IconIndex);
        IconPath := PChar(IconPath);
        if IconPath = '' then
          IconPath := Path;
        if not Succeeded(GetIDList(ItemIDList)) then
          ItemIDList:=nil;
      end
      else
        Path := '';
    end;
  end;
end;

function GetPathFromLnkFileEx(const ALnkFileName: string; out APathEx, AParsingPath : String ): Boolean;
var
  Path, Arguments, WorkingDirectory, Description: String;
  HotKey: Word;
  ShowCmd: Integer;
  IconPath: String;
  IconIndex: Integer;
  ItemIDList: PItemIDList;

  ItemIDListLast : PItemIDList;

  ShellFolder: IShellFolder;
  ShellItem,
  ShellItem2: IShellItem;

  PName : PWideChar;
begin
   Result:=False;
   ReadLnkFile(ALnkFileName, Path, Arguments, WorkingDirectory, Description, HotKey, ShowCmd, IconPath, IconIndex, ItemIDList);

  if assigned(ItemIDList) then
    if Succeeded(SHBindToParent(ItemIDList, IID_IShellFolder, ShellFolder, ItemIDListLast)) then
    begin
      Result:=True;
      AParsingPath:=GetFolderName(ShellFolder, ItemIDListLast, fnForParsing);

      if Succeeded(SHCreateShellItem(ItemIDList, ShellFolder, ItemIDListLast, ShellItem)) then
      begin
        APathEx:='';

        while Succeeded(ShellItem.GetParent(ShellItem2)) do
        begin
          if Assigned(ShellItem2) then
          begin
            ShellItem2.GetDisplayName(0, PName);
            APathEx:='\'+WideString(PName)+APathEx;
            CoTaskMemFree(PName);
            ShellItem:=ShellItem2;
          end
          else
            Break;
        end;
      end;
    end;
end;
aufgerufen wird das ganze so:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  Path,                 //Der Pfad relativ zum Desktop (human readable)
  ParsingPath : string; //Der Pfad, wie er im System gehalten wird .. entweder Dateipfad oder eine Liste von GUIDs.
begin
  GetPathFromLnkFileEx('C:\Users\MaWarm\Desktop\abc.lnk', Path, ParsingPath );
  Caption:=Path+' - '+ParsingPath
end;
Ich hoffe, das hilft jemandem
Gruß
Marco


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:58 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz