Sign in to follow this  
Followers 0
CyberSlug

Find LNK file's target

14 posts in this topic

#1 ·  Posted (edited)

Inspired by this post

Google finds some example code "which returns the Target and Arguments of a .lnk file in a CString" is available here:

http://www.codeguru.com/Cpp/COM-Tech/shell...icle.php/c1337/

What do you think?

Edited by CyberSlug

Use Mozilla | Take a look at My Disorganized AutoIt stuff | Very very old: AutoBuilder 11 Jan 2005 prototype I need to update my sig!

Share this post


Link to post
Share on other sites



Please, Please, Please.... this would be really helpful, and save me having to code around a command line util and do yet more text parsing, which is all I've been doing for weeks.

Not that I'm too desperate or anything :D - It would be nice as we can create shortcuts to be able to read them too. :huh2:

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

I know it's not perfect and the most is copied but maybe it's a beginning (and it's working so far) :huh2: :

Here's the little function I wrote:

///////////////////////////////////////////////////////////////////////////////
// FileGetShortcut()
///////////////////////////////////////////////////////////////////////////////

AUT_RESULT AutoIt_Script::F_FileGetShortcut(VectorVariant &vParams, Variant &vResult)
{
   AUT_RESULT   ret;
   IShellLink*      psl;
   IPersistFile*    ppf;
   WORD           wsz[MAX_PATH];
   Variant          *pvTemp;
   char              szGotPath[MAX_PATH];
   char              szArguments[MAX_PATH];
   char              szWorkingDir[MAX_PATH];
   char              szDescription[MAX_PATH];
   char              szIconLocation[MAX_PATH];
   int                 nIconIndex;
   int                 nShowCmd;

   ret = AUT_ERR;
   CoInitialize(NULL);
   if (SUCCEEDED(CoCreateInstance(CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER,IID_IShellLink,(LPVOID *)&psl)) )
   {
      if (SUCCEEDED(psl->QueryInterface(IID_IPersistFile,(LPVOID *) &ppf)))
      {
         MultiByteToWideChar(CP_ACP,0,vParams[0].szValue(),-1,(LPWSTR)wsz,MAX_PATH);
         if (SUCCEEDED(ppf->Load(wsz,0)))
         {
            Util_VariantArrayDim(&vResult,7);   

            psl->GetPath(szGotPath,MAX_PATH,NULL,SLGP_UNCPRIORITY);
            pvTemp = Util_VariantArrayGetRef(&vResult, 0);
            *pvTemp = szGotPath;

            psl->GetArguments(szArguments,MAX_PATH);
            pvTemp = Util_VariantArrayGetRef(&vResult, 1);
            *pvTemp = szArguments;

            psl->GetWorkingDirectory(szWorkingDir,MAX_PATH);
            pvTemp = Util_VariantArrayGetRef(&vResult, 2);
            *pvTemp = szWorkingDir;

            psl->GetDescription(szDescription,MAX_PATH);
            pvTemp = Util_VariantArrayGetRef(&vResult, 3);
            *pvTemp = szDescription;

            psl->GetIconLocation(szIconLocation,MAX_PATH,&nIconIndex);
            pvTemp = Util_VariantArrayGetRef(&vResult,4);
            *pvTemp = szIconLocation;
            pvTemp = Util_VariantArrayGetRef(&vResult,5);
            *pvTemp = nIconIndex;

            psl->GetShowCmd(&nShowCmd);
            pvTemp = Util_VariantArrayGetRef(&vResult,6);
            switch (nShowCmd)
            {
               case SW_SHOWNORMAL:
                  *pvTemp = "NORMAL";
                  break;
               case SW_SHOWMAXIMIZED:
                  *pvTemp = "MAXIMIZED";
                  break;
               default:
                  *pvTemp = "MINIMIZED";
                  break;
            }
         }
         ppf->Release();
      }
      psl->Release();
    }
    return AUT_OK;
} // FileGetShortcut()

So the line:

$shortcutinfo = FileGetShortcut(@DesktopCommonDir & "\Norton Anti Virus 2004")

would give as result for instance:

$shortcutinfo[0] -> Target -> C:\Programme\Gemeinsame Dateien\Symantec Shared\NMain.exe

$shortcutinfo[1] -> Arguments -> /dat:C:\Programme\Norton AntiVirus\navui.nsi

$shortcutinfo[2] -> WorkingDir -> C:\Programme\Norton AntiVirus

$shortcutinfo[3] -> Description -> start Norton AntiVirus 2004

$shortcutinfo[4] -> IconFile -> C:\Programme\Norton AntiVirus\NavW32.exe

$shortcutinfo[5] -> IconIndex - > 0

$shortcutinfo[6] -> ShowWindowMode -> NORMAL

Maybe we can also readout the hotkey or change it... BUT I've go to bed now (...really...) cause of working in some hours :lol:

Good night and regards

Holger :D

EDIT: forgot: @CyberSlug: thanks for the info :)

Edited by Holger

Share this post


Link to post
Share on other sites

@CyberSlug/Chris_1013: what do you think? which information are important for a link-query?

I'd primarily want to see target and arguments, but why not put it all into an array?

"I'm not even supposed to be here today!" -Dante (Hicks)

Share this post


Link to post
Share on other sites

@emmanuel: I wrote it so, that it returns an array  :huh2:

At the moment I have some problems to readout the Hotkey, so I don't know what the return value for the hotkey should be!?  :D

guh! of course it does, sorry, my brain must have froze up looking at the code... I like it... The hotkey's not that important to me, I don't think any of my users take advantage of it.

"I'm not even supposed to be here today!" -Dante (Hicks)

Share this post


Link to post
Share on other sites

I haven't tried the code, but what you have looks great to me :D

While you are at it, could you add two features to FileCreateShortcut? (See remarks in the help file for details: FileCreateShortcut cannot set the window state or icon index.)


Use Mozilla | Take a look at My Disorganized AutoIt stuff | Very very old: AutoBuilder 11 Jan 2005 prototype I need to update my sig!

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Edit: added (like in the original-sample) if you don't take ".lnk" in the shortcutfilename then ".lnk" will be added to the filename.

If there is an error the result is 1 and @error will be set to 1:

///////////////////////////////////////////////////////////////////////////////
// FileGetShortcut()
///////////////////////////////////////////////////////////////////////////////

AUT_RESULT AutoIt_Script::F_FileGetShortcut(VectorVariant &vParams, Variant &vResult)
{
    AUT_RESULT  ret;
    IShellLink*  psl;
    IPersistFile*   ppf;
    WORD    wsz[MAX_PATH];
    Variant     *pvTemp;
    char    *szLink = "";
    char    szGotPath[MAX_PATH];
    char    szArguments[MAX_PATH];
    char    szWorkingDir[MAX_PATH];
    char    szDescription[MAX_PATH];
    char    szIconLocation[MAX_PATH];
    int    nIconIndex;
    int    nShowCmd;

    strcpy(szLink,vParams[0].szValue());
    
    if (strstr(szLink,".lnk") == NULL)
  strcat(szLink,".lnk");

    SetFuncErrorCode(1);
    if (Util_DoesFileExist(szLink))
    {
  ret = AUT_ERR;
  CoInitialize(NULL);
  if( SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *)&psl)) )
  {
    if (SUCCEEDED(psl->QueryInterface( IID_IPersistFile, (LPVOID *) &ppf)))
    {
    MultiByteToWideChar(CP_ACP,0,szLink,-1,(LPWSTR)wsz,MAX_PATH);
    if (SUCCEEDED(ppf->Load(wsz,0)))
    {
        Util_VariantArrayDim(&vResult,7);   

        psl->GetPath(szGotPath,MAX_PATH,NULL,SLGP_UNCPRIORITY);
        pvTemp = Util_VariantArrayGetRef(&vResult,0);
        *pvTemp = szGotPath;

        psl->GetArguments(szArguments,MAX_PATH);
        pvTemp = Util_VariantArrayGetRef(&vResult,1);
        *pvTemp = szArguments;

        psl->GetWorkingDirectory(szWorkingDir,MAX_PATH);
        pvTemp = Util_VariantArrayGetRef(&vResult,2);
        *pvTemp = szWorkingDir;

        psl->GetDescription(szDescription,MAX_PATH);
        pvTemp = Util_VariantArrayGetRef(&vResult,3);
        *pvTemp = szDescription;

        psl->GetIconLocation(szIconLocation,MAX_PATH,&nIconIndex);
        pvTemp = Util_VariantArrayGetRef(&vResult,4);
        *pvTemp = szIconLocation;
        pvTemp = Util_VariantArrayGetRef(&vResult,5);
        *pvTemp = nIconIndex;

        psl->GetShowCmd(&nShowCmd);
        pvTemp = Util_VariantArrayGetRef(&vResult,6);
        switch (nShowCmd)
        {
      case SW_SHOWNORMAL:
        *pvTemp = "NORMAL";
        break;
      case SW_SHOWMAXIMIZED:
        *pvTemp = "MAXIMIZED";
        break;
      default:
        *pvTemp = "MINIMIZED";
        break;
        }
        SetFuncErrorCode(0);
    }
    ppf->Release();
    }
    psl->Release();
  }
  CoUninitialize();
    }

    return AUT_OK;
} // FileGetShortcut()

The changing for FileCreateShortcut could be like to this:

FileCreateShortcut ( "file", "lnk" [, "workdir", "args", "desc", "icon", "hotkey", "iconindex", "windowstate"] )

I'm working on so you could use @SW_MAXIMIZE and @SW_MINIMZE ...

Edited by Holger

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

And here is the modified FileCreateShortCut:

///////////////////////////////////////////////////////////////////////////////
// FileCreateShortcut()
// Creates a shortcut (.lnk) toi a file
// FileCreateShortcut(<file>,<lnk>[,<workdir>,<args>,<desc>,<icon>,<hotkey>,<iconindex>,<windowstate>])
///////////////////////////////////////////////////////////////////////////////

AUT_RESULT AutoIt_Script::F_FileCreateShortcut(VectorVariant &vParams, Variant &vResult)
{
    uint    iNumParams = vParams.size();
    bool    bShift, bControl, bAlt, bWin;
    UINT    mods = 0;
    UINT    vk;
    AUT_RESULT  ret;
    IShellLink*  psl;
    IPersistFile*  ppf;
    WORD    wsz[MAX_PATH];
    int     nShowCmd;

    ret = AUT_ERR;
    CoInitialize(NULL);
    if( SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *)&psl)) )
    {
  psl->SetPath(vParams[0].szValue());
  if ( iNumParams > 2 )
    psl->SetWorkingDirectory(vParams[2].szValue());
  if ( iNumParams > 3 )
    psl->SetArguments(vParams[3].szValue());
  if ( iNumParams > 4 )
    psl->SetDescription(vParams[4].szValue());
  if ( iNumParams > 5 )
    psl->SetIconLocation(vParams[5].szValue(),0);
  if ( iNumParams > 6 )
  {
    if ( strlen(vParams[6].szValue()) > 0 )
    {
    // Get the virtual key code and modifiers
    if (m_oSendKeys.GetSingleVKandMods(vParams[6].szValue(), vk, bShift, bControl, bAlt, bWin) == true)
    {
        if (bShift)
      mods |= HOTKEYF_SHIFT;

        // Make sure that CTRL+ALT is selected (otherwise invalid)
        mods |= HOTKEYF_CONTROL|HOTKEYF_ALT;
    
        psl->SetHotkey((WORD)(vk | (mods << 8)));   // Vk in low 8 bits, mods in high 8 
    }
    }
  }
  if ( iNumParams > 7 )
    psl->SetIconLocation(vParams[5].szValue(),vParams[7].nValue());
  if ( iNumParams > 8 )
  {
    nShowCmd = vParams[8].nValue();
    switch (nShowCmd)
    {
    case SW_MAXIMIZE:
        nShowCmd = SW_SHOWMAXIMIZED;
        break;
    case SW_MINIMIZE:
        nShowCmd = SW_SHOWMINNOACTIVE;
        break;
    default:
        nShowCmd = SW_SHOWNORMAL;
        break;
    }
    psl->SetShowCmd(nShowCmd);
  }

  if( SUCCEEDED(psl->QueryInterface(IID_IPersistFile,(LPVOID *)&ppf)) )
  {
    MultiByteToWideChar(CP_ACP,0,vParams[1].szValue(),-1,(LPWSTR)wsz,MAX_PATH);
    if ( FAILED(ppf->Save((LPCWSTR)wsz,TRUE)) )
    vResult = 0;
    ppf->Release();
  }
  psl->Release();
    }
    else
  vResult = 0;          // Error, default is 1

    CoUninitialize();
    
    return  AUT_OK;

} // FileCreateShortcut()

Maybe there are bugs in it, I tested it...but...you know...no warrenty, cause I've only here at the moment XP SP1 :D

You could use it then like:

FileCreateShortcut ( "file", "lnk" [, "workdir", "args", "desc", "icon", "hotkey", "iconindex", "windowstate"] )

For 'windowstate' you could use @SW_MAXIMIZE or @SW_MINIMZE.

sample:

$result = FileCreateShortcut(@WindowsDir & "\Explorer.exe",@DesktopDir & "\Shortcut Test.lnk",@WindowsDir,"/e,c:\","This is an Explorer link;-)",@SystemDir & "\shell32.dll","","15",@SW_MINIMIZE)

Regards Holger :huh2:

Edited by Holger

Share this post


Link to post
Share on other sites

The FileCreateShortCut modification works great (after I remembered increase the parameter count in script.cpp) :D

Haven't tried FileGetShortcut, but I hope it gets added to AutoIt soon :huh2:


Use Mozilla | Take a look at My Disorganized AutoIt stuff | Very very old: AutoBuilder 11 Jan 2005 prototype I need to update my sig!

Share this post


Link to post
Share on other sites

Seb submitted some icon index/state stuff a while ago but I never got around to it but I think I will add these changes in. They seem simple enough and I can see a few uses for reading a shortcuts properties.

Share this post


Link to post
Share on other sites

This is sounding good. We're probably going to stick with an external tool for the project we're working on at the moment, as this allows editting of shortcuts in place. Thanks for all your help with setting this up. I think we really do need hot key reading if at all possible to make this feature complete for modification of shortcuts with FileGetShortcut and FileCreateShortcut.

Share this post


Link to post
Share on other sites

#14 ·  Posted (edited)

I'm playing a little bit around and maybe it's easier as I thought to get the Hotkey :) stay tune...I'm working on it right now :D

Ahhh, forgot... the result for the hotkey would then like this for instance: "+^!s" what means SHIFT + CTRL + ALT + 'S'... so you could use it later for Re-FileCreateShortcut...

Stay tune (I hope that is the right english to wait for an update :huh2: )

Edited by Holger

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0