We help IT Professionals succeed at work.

Windows shortcut location resolution on double click open

When a shortcut file is double-clicked in Windows, the shell dereferences the shortcut and launches the application associated with the file type from the dereferenced shortcut, in other words the path to the actual file. The application receives the dereferenced path instead of the path to the shortcut.

In our application, the user is saving shortcuts to image files as well as updated image files. That is, shortcut files are used to categorize an image file; e.g. "roses", "large\flowers", "floral". The image file itself is stored in a hidden directory.

When a user double-clicks a shortcut and the shell launches our editing/viewing application to display the image, the application correctly displays the image but all path information to the shortcut from which the application was launched is lost.

The question is how to obtain a path to the shortcut file which initiated the application. In other words, is their a way to capture the path to the shortcut file that is double clicked before it is dereferenced by the Shell.

The application is a proprietary app of which we are writing all of the code, so we are flexible with any solution down to a code level.
Comment
Watch Question

ChrisSr. Systems Engineer
CERTIFIED EXPERT

Commented:
You mean running the app from a network location? yes, you can just change the path
whatIhave.png

Author

Commented:
Let me try to explain the problem in greater detail.

The application that we have is designed to work from a directory of "Hidden" binary files. These files are editable from within our appliaction but not meant to be accessed directly by the user. Therefore during the creation or editing of these files they are saved into a "hidden" and protected directory that is unknown to the user and simultaneously a "shortcut (lnk) file is created by our app that the user has full control over with regards to path location as well as the file name. The hidden and protected file that this shortcut points to has a GUID name that is assigned by our application . All of the interaction that the user has with these GUID named files is via the shortcut that they give a readable name to as well as control the destination folder.

When the user double clicks on a shortcut file that they created thru our app, the system Shell launches our app and loads the hidden file...so far so good. The problem arises when the user then wants to save their changes. When opening the file thru the shortcut and a double click the Shell launches the app and inserts the path of the Hidden file and therefore dereferences the path to the shortcut. The location for the hidden/protected files are hard coded so we are really only concerned with the path to the shortcut which is what the user interacts with but has been lost thru the double click.

What we need to be able to do is to capture the location of the shortcut that was double clicked from the Windows shell prior to it being dereferenced.

If the user "drags" the shortcut file onto an open instance of the application we are OK as we can capture the location of the original shortcut file when we resolve the location to the "hidden/protected" file during the "drag". We need to be able to do this as well during a "double-click"
Ark
CERTIFIED EXPERT

Commented:
Imports System.Runtime.InteropServices

Public Class Shortcut
    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
    Structure STARTUPINFO
        Public cb As Integer
        Public lpReserved As String
        Public lpDesktop As String
        Public lpTitle As String
        Public dwX As Integer
        Public dwY As Integer
        Public dwXSize As Integer
        Public dwYSize As Integer
        Public dwXCountChars As Integer
        Public dwYCountChars As Integer
        Public dwFillAttribute As Integer
        Public dwFlags As Integer
        Public wShowWindow As Short
        Public cbReserved2 As Short
        Public lpReserved2 As Integer
        Public hStdInput As Integer
        Public hStdOutput As Integer
        Public hStdError As Integer
    End Structure
    <DllImport("kernel32.dll", EntryPoint:="GetStartupInfoW")>
    Private Shared Sub GetStartupInfo(ByRef lpStartupInfo As STARTUPINFO)
    End Sub
    Private Const STARTF_TITLEISLINKNAME = &H800

    Public Shared Function GetLinkPath() As String
        Dim info As New STARTUPINFO
        GetStartupInfo(info)
        If (info.dwFlags And STARTF_TITLEISLINKNAME) = STARTF_TITLEISLINKNAME Then
            Return info.lpTitle
        Else
            Return ""
        End If
    End Function
End Class

Open in new window

CERTIFIED EXPERT
Commented:
Oops, sorry, c# version:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication1
{
     class Shortcut
    {
        [DllImport("kernel32.dll", SetLastError = true, EntryPoint = "GetStartupInfoA")]
        static extern void GetStartupInfo(ref STARTUPINFO lpStartupInfo);

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct STARTUPINFO
        {
            public uint cb;
            public string lpReserved;
            public string lpDesktop;
            public string lpTitle;
            public uint dwX;
            public uint dwY;
            public uint dwXSize;
            public uint dwYSize;
            public uint dwXCountChars;
            public uint dwYCountChars;
            public uint dwFillAttribute;
            public uint dwFlags;
            public ushort wShowWindow;
            public ushort cbReserved2;
            public IntPtr lpReserved2;
            public IntPtr hStdInput;
            public IntPtr hStdOutput;
            public IntPtr hStdError;
        }
        const int STARTF_TITLEISLINKNAME = 0x800;

        public static string GetLinkPath()
        {
            STARTUPINFO info=new STARTUPINFO();
            GetStartupInfo(ref info);
            if ((info.dwFlags & STARTF_TITLEISLINKNAME) == STARTF_TITLEISLINKNAME) return info.lpTitle;
            return string.Empty;
        }
     }
}

Open in new window

Explore More ContentExplore courses, solutions, and other research materials related to this topic.