Solved

File links in Delphi

Posted on 2000-03-28
10
203 Views
Last Modified: 2010-04-04
I am opening a file using assignfile as a text file. I need to have multiple copies of the file available in different locations. Rather than copy the file several times, I would rather uses NT links to point to the original file. I guess that when I open the link in Delphi as a text file, I'll just get the link contents, and not the file. How do I extract the file location information from the link as a Delphi text file ?
0
Comment
Question by:sparkido
  • 5
  • 3
  • 2
10 Comments
 
LVL 13

Accepted Solution

by:
Epsylon earned 100 total points
ID: 2663817
You can use this to find the path to the file:


procedure TForm1.Button1Click(Sender: TObject);
var
  s1,s2,s3:String;
begin
  GetLinkInfo('c:\windows\start menu\programs\windows explorer.lnk',
              s1,s2,s3);
  ShowMessage('File: '+s1+#13+'Target: '+s2+#13+'Working: '+s3);
end;

procedure TForm1.GetLinkInfo(ALnk: String;
                             var AFile, APath, AWork: String);
const
  // took this TGUID from OLE2.pas
  IID_IPersistFile: TGUID = (D1:$0000010B;
                             D2:$0000;
                             D3:$0000;
                             D4:($C0,$00,$00,$00,$00,$00,$00,$46));
  // Missing from Windows.pas
  MB_ERR_INVALID_CHARS = $00000008;
var
  fShellLink   : IShellLink;
  fPersistFile : IPersistFile;
  fFindData    : TWin32FindData;
  fWideBuf     : array[0..MAX_PATH] of WideChar;
  fBuf         : array[0..MAX_PATH] of Char;
  hResx        : hResult;
  WideLen      : Integer;
begin
  // get an interface pointer to the IShellLink interface
  hResx := CoCreateInstance(CLSID_ShellLink,
                            nil,
                            CLSCTX_INPROC_SERVER,
                            IID_IShellLinkA,
                            fShellLink);
  if SUCCEEDED(hResx) then
  begin
    // get an interface pointer to the IPersistFile interface
    // of IShellLink
    hResx := fShellLink.QueryInterface(IID_IPersistFile,
                                       fPersistFile);
    if SUCCEEDED(hResx) then
    begin
      // convert the link file pathname to a PWideChar
      WideLen := MultiByteToWideChar(CP_ACP,
                                     MB_ERR_INVALID_CHARS,
                                     pChar(ALnk),
                                     Length(ALnk),
                                     @fWideBuf,
                                     MAX_PATH);
      if WideLen = 0 then
      begin
        ShowMessage('MultiByteToWideChar FAILED');
        Exit;
      end;
      // terminate our widechar at the length returned
      fWideBuf[WideLen] := #0;
      // initialize the IShellLink object from its disk image
      hResx := fPersistFile.Load(@fWideBuf,
                                 STGM_READ or
                                 STGM_SHARE_DENY_NONE);
      if SUCCEEDED(hResx) then
      begin
        // get target file & path
        fShellLink.GetPath(@fBuf,
                           MAX_PATH,
                           fFindData,
                           0);
        AFile := fFindData.cFileName;
        APath := StrPas(fBuf);
        // get target directory
        fShellLink.GetWorkingDirectory(@fBuf,
                                       Max_Path);
        AWork := StrPas(fBuf);
      end;
    end;
  end;
end;
0
 
LVL 20

Expert Comment

by:Madshi
ID: 2664419
Hi Epsylon, do you mind if I shorten your source a bit? I'm always a bit sad, if I see code that doesn't use all the Delphi goodies...

procedure TForm1.GetLinkInfo(ALnk: String;
                             var AFile, APath, AWork: String);
var fShellLink : IShellLink;
    fFindData  : TWin32FindData;
    fBuf       : array [0..MAX_PATH] of Char;
begin
  fShellLink := CreateComObject(CLSID_ShellLink) as IShellLink;
  if (fShellLink as IPersistFile).Load(PWideChar(wideString(ALnk)), 0) = 0 then begin
    fShellLink.GetPath(fBuf, MAX_PATH, fFindData, 0);
    AFile := fFindData.cFileName;
    APath := fBuf;
    fShellLink.GetWorkingDirectory(fBuf, MAX_PATH);
    AWork := fBuf;
  end;
end;

Okay, that were just some little changes, but together they make a difference, don't you think so?   :-)

Regards, Madshi.
0
 
LVL 13

Expert Comment

by:Epsylon
ID: 2664560
Hi Madshi, I copy-pasted that code from a PAQ    :o)
Looks a lot better this way!
0
 

Author Comment

by:sparkido
ID: 2664733
I get an exception when I run the code on

if (fShellLink as IPersistFile).Load(PWideChar(wideString(ALnk)), 0) = 0 then begin ...

What format should ALnk take, full path and filename ???


0
 
LVL 20

Expert Comment

by:Madshi
ID: 2664826
ALnk should be the exact file name, e.g. 'c:\windows\startmenu\programs\winword.lnk'.

Which exception do you get? It works fine for me.

Perhaps you need to add CoInitialize(nil) in your project's initialization.
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

Author Comment

by:sparkido
ID: 2669586
I actual get an access violation.
I can't find any docs on FShellLink, so I'm struggling to work out why.
0
 

Author Comment

by:sparkido
ID: 2669805
Ignore the last comment, I got it working. Thanks very much.

Submit an answer.
0
 
LVL 20

Expert Comment

by:Madshi
ID: 2669846
You can accept Eps comment as the answer. There's a link in the top right of each comment with which you can convert a comment into an answer.
0
 

Author Comment

by:sparkido
ID: 2669870
Ignore the last comment, I got it working. Thanks very much.

Submit an answer.
0
 

Author Comment

by:sparkido
ID: 2669877
Spotted that after I had posted !! (twice!!)
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Windows Drag & Drop Location 2 85
Delphi OLE Error 8 84
Convert Jpg /PNG To GIF 5 102
Delphi IDE crash without error message ... 7 60
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now