CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3

Hybrid View

  1. #1
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    [RESOLVED] How to resolve symbolic file system links

    I have written a small app that deals with files of any kind. So far, I can pick the file to process using a file open dialog or drop it on the app's Form. Everything basically works fine, but while the dialog resolves symbolic links (.lnk files) for me implicitly (after setting the appropriate property, of course), my app will process the .lnk file itself rather than the file it points to when I drop it on the app.

    So I'll have to resolve the link myself in that case. But how would I do that the .NET way? Neither an MSDN search nor Google gave me any satisfying results so far.

    I once did the same thing in an MFC app a long time ago and I remember I had to employ some COM stuff for that, and found that unnecessarily complicated. I suppose there is another way to do that with the CLR. If not, I would appreciate a pointer to some description an how to do it the old-fashioned way too, but please including instructions on how to use that COM stuff from the .NET environment.

    TIA
    Last edited by Eri523; October 6th, 2010 at 12:17 AM.

  2. #2
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: How to resolve symbolic file system links

    In the meantime I did some more digging on MSDN, quite deelply. That was not really easy because search terms like "resolve", "shell", "link" and "shortcut" appear to be quite common, but not only in the context I'm looking for.

    One of my first bets was the code I found at http://social.msdn.microsoft.com/For...-fbe81b939bf9/, which appears to be C#. I tried to translate and integrate it into the function where I need it. This is the result:

    Code:
    System::Void Form1::DoCount(String ^strInfile) {
    /*
      // Resolve .lnk files, if necessary traversing >1 indirections:
      if (!String::Compare(Path::GetExtension(strInfile), ".lnk", true)) {
        WshShell shell;
        do {
          WshShortcut ^shortcut = (WshShortcut ^)shell.CreateShortcut(strInfile);
          strInfile = shortcut->TargetPath;
        } while (!String::Compare(Path::GetExtension(strInfile), ".lnk", true));
      }
    */
    
      DoCount(gcnew FileStream(strInfile,FileMode::Open, FileAccess::Read));
    }
    The relevant part is commented out now because it fails to compile for the simple reason that I don't know in which namespace to find WshShell and WshShortcut. This appears to be Windows Scripting Host stuff and I don't really like using it: It reminds me to using Scripting.FileSystemObject in VB/VBA which is also discouraged. But it was the first promising trace of info I found.

    I also came across http://social.msdn.microsoft.com/for...7-9D0697EFE888. The code there obviously is native C++ and uses COM like I did myself many years ago. But like down then, I find this solution overly complicated and don't yet know how to adapt or integrate it into my C++/CLI program.

    Does anyone have any clue on how to further proceed from here? Any help is really appreciated.

    TIA
    Last edited by Eri523; May 20th, 2011 at 05:13 PM.
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  3. #3
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Resolved Re: How to resolve symbolic file system links

    Ok, in the meantime I got the function I posted above working. It only required these modifications:
    1. Add a COM reference to "Windows Script Host Object Model" to the project. (This has been mentioned along with the VB .NET sample on the second page I linked to, I just missed it.)
    2. Add a using namespace IWshRuntimeLibrary; directive.
    3. Apply some minor changes to the function itself.

    The function now looks like this:

    Code:
    System::Void Form1::DoCount(String ^strInfile) {
      // Resolve .lnk files, if necessary traversing >1 indirections:
      if (!String::Compare(Path::GetExtension(strInfile), ".lnk", true)) {
        WshShell ^shell = gcnew WshShell;
        do {
          WshShortcut ^shortcut = (WshShortcut ^)shell->CreateShortcut(strInfile);
          strInfile = shortcut->TargetPath;
        } while (!String::Compare(Path::GetExtension(strInfile), ".lnk", true));
      }
    
      DoCount(gcnew FileStream(strInfile,FileMode::Open, FileAccess::Read));
    }
    There are, however, some minor questions remaining, sorted in order of decreasing relevance:
    1. The Local Copy property of the COM reference is set to True by default. This led to creation of a file named Interop.IWshRuntimeLibrary.1.0.dll in my target directory. (I'm not sure whether this actually is a copy of something at all, as it carries a current creation and modification date.) As this is only a toy app it's no real issue, but would I have to distribute that file along with my app and would I be allowed to do so?
    2. Is it legitimate to use the WSH infrastructure in a .NET app like that?
    3. Is it actually required to use a loop here, IOW are chained links possible in Windows at all? At least I couldn't create one with Windows Explorer: Drag-dropping a link with Shift+Ctrl held merely created a copy of that link.
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured