HanDs
管理员

[Visual Studio文章] VC++实现解析快捷方式 



桌面上那些五颜六色的图标可能大家非常熟悉吧?不知大家注意到没有,这些图标都有一个共同的特点,在每个图标的左下角都有一个非常小的箭头。这个箭头就是用来表明该图标是一个快捷方式的。快捷方式是Windows提供的一种快速启动程序、打开文件或文件夹的方法。他是应用程序的快速连接。 他的扩展名为.lnk。
一般来说快捷方式就是一种用于快速启动程序的命令行。它和程序既有区别又有联系。打个简单的比方,如果把程序比作一台电视机的话,快捷方式就像是一只遥控板。通过遥控板我们可以轻松快捷地控制电视的开关、频道的选择等。没有了遥控板我们还可以走到电视机面前进行操作,只是没有遥控那么方便罢了,并不会影响到电视机的使用。但没有了电视机,遥控板显然是无所作为。快捷方式也是一样,当快捷方式配合实际安装的程序时,非常便利。删除了快捷方式我们还可以通过“我的电脑”去找到目标程序,去运行它。而当程序被删除后,光有一个快捷方式就会毫无用处。自己桌面上的快捷方式复制到别人的计算机上,可能无法正常使用。

//

#include "stdafx.h"
#include <stdlib.h>
#include <windows.h>

typedef struct _LNKHEAD
{
 DWORD  dwID;
 DWORD  dwGUID[4];
 DWORD  dwFlags;
 DWORD  dwFileAttributes;
 FILETIME dwCreationTime;
 FILETIME dwModificationTime;
 FILETIME dwLastaccessTime;
 DWORD  dwFileLen;
 DWORD  dwIconNum;
 DWORD  dwWinStyle;
 DWORD  dwHotkey;
 DWORD  dwReserved1;
 DWORD  dwReserved2;
}LNKHEAD, *PLNKHEAD;

typedef struct _FILELOCATIONINFO
{
 DWORD  dwSize;
 DWORD  dwFirstOffset;
 DWORD  dwFlags;
 DWORD  dwOffsetOfVolume;
 DWORD  dwOffsetOfBasePath;
 DWORD  dwOffsetOfNetworkVolume;
 DWORD  dwOffsetOfRemainingPath;
}FILELOCATIONINFO, *PFILELOCATIONINFO;

typedef struct _LOCALVOLUMETAB
{
 DWORD  dwSize;
 DWORD  dwTypeOfVolume;
 DWORD  dwVolumeSerialNumber;
 DWORD  dwOffsetOfVolumeName;
 char  strVolumeName[0];
}LOCALVOLUMETAB, *PLOCALVOLUMETAB;

typedef struct _NETWORKVOLUMETAB
{
 DWORD  dwSize;
 DWORD  dwUnknown1;
 DWORD  dwOffsetOfNetShareName;
 DWORD  dwUnknown2;
 DWORD  dwUnknown3;
 char  strNetShareName[0];
}NETWORKVOLUMETAB, *PNETWORKVOLUMETAB;

#define LNK_HASIDLIST 0x1
#define LNK_FILEDIR  0x2
#define LNK_HASDES  0x4
#define LNK_HASPATH  0x8
#define LNK_HASWORKDIR 0x10
#define LNK_HASCMD  0x20

#define LNK_LOCALVOLUME 0x1
#define LNK_NETSHARE 0x2

void AnalyseShortCut(const char *pFileName)
{
 FILE   *file;
 unsigned short usLenTemp;
 int    iSize;
 LNKHEAD   head;
 FILELOCATIONINFO fileLocationInfo;
 char   szDescription[1024]; //快捷方式所指向的文件描述
 char   szFilePath[1024];    //快捷方式所指向的文件
 char   szCommand[1024];
 WCHAR   wszTemp[512];
 char*   pDest;
 DWORD   dwFlags;
 int    p;
 

 if((file = fopen(pFileName, "rb")) == NULL)
    {
  return;
    }

 // head
 iSize = sizeof(LNKHEAD);
 if (fread(&head, 1, iSize, file) != iSize)
    {
  goto errorExit;
    }

 dwFlags = head.dwFlags;
 
 if(dwFlags & LNK_HASIDLIST)
 {
  // The Shell Item Id List
  if(fread(&usLenTemp, 2, 1, file) != 1)
  {
   goto errorExit;
  }
  //fread(&szCommand, usLenTemp, 1, file);
  fseek(file, usLenTemp, SEEK_CUR);
 }
 

 p = ftell(file);
 // file location info
 if(fread(&fileLocationInfo, sizeof(fileLocationInfo), 1, file) != 1)
 {
  goto errorExit;
 }

 //fread(&szCommand, fileLocationInfo.dwSize - sizeof(fileLocationInfo), 1, file);

 fseek(file, fileLocationInfo.dwOffsetOfBasePath +  p, SEEK_SET);
 
 
 if(fileLocationInfo.dwFlags & LNK_NETSHARE)
 {
  iSize = fileLocationInfo.dwOffsetOfNetworkVolume - fileLocationInfo.dwOffsetOfBasePath;
 }
 else
 {
  iSize = fileLocationInfo.dwOffsetOfRemainingPath - fileLocationInfo.dwOffsetOfBasePath;
 }
 
 

 if(fread(&szCommand, 1, iSize, file) != iSize)
 {
  goto errorExit;
 }

 pDest = strupr(szCommand);
 if(NULL == strstr(pDest, ".EXE"))
 {
  goto errorExit;
 }

 sprintf(szFilePath, "\"%s\"", szCommand);
 
 fseek(file, fileLocationInfo.dwSize +  p, SEEK_SET);

 if(dwFlags & LNK_HASDES)
 {
  // skip Description string
  if(fread(&usLenTemp, 2, 1, file) != 1)
  {
   goto errorExit;
  }
  if(fread(&wszTemp, sizeof(WCHAR), usLenTemp, file) != usLenTemp)
  {
   goto errorExit;
  }
  wszTemp[usLenTemp] = '\0';
  WideCharToMultiByte( CP_ACP, 0, wszTemp, -1,
   szDescription, 512, NULL, NULL );
  //fseek(file, usLenTemp*2, SEEK_CUR);
 }

 if(dwFlags & LNK_HASPATH)
 {
  // skip Relative path
  if(fread(&usLenTemp, 2, 1, file) != 1)
  {
   goto errorExit;
  }

  if(fread(&wszTemp, sizeof(WCHAR), usLenTemp, file) != usLenTemp)
  {
   goto errorExit;
  }
  wszTemp[usLenTemp] = '\0';
  WideCharToMultiByte( CP_ACP, 0, wszTemp, -1,
   szCommand, 512, NULL, NULL );
  //fseek(file, usLenTemp*2, SEEK_CUR);
 }
 
 if(dwFlags & LNK_HASWORKDIR)
 {
  // skip Working directory
  if(fread(&usLenTemp, 2, 1, file) != 1)
  {
   goto errorExit;
  }

  if(fread(&wszTemp, sizeof(WCHAR), usLenTemp, file) != usLenTemp)
  {
   goto errorExit;
  }
  wszTemp[usLenTemp] = '\0';
  WideCharToMultiByte( CP_ACP, 0, wszTemp, -1,
   szCommand, 512, NULL, NULL );
  //fseek(file, usLenTemp*2, SEEK_CUR);
 }

 if(dwFlags & LNK_HASCMD)
 {
  // Command line arguments
  if(fread(&usLenTemp, 2, 1, file) != 1)
  {
   goto errorExit;
  }

  if(fread(&wszTemp, sizeof(WCHAR), usLenTemp, file) != usLenTemp)
  {
   goto errorExit;
  }
  wszTemp[usLenTemp] = '\0';
  WideCharToMultiByte( CP_ACP, 0, wszTemp, -1,
   szCommand, 512, NULL, NULL );
  strcat(szFilePath, " ");
  strcat(szFilePath, szCommand);
 }

 _splitpath(pFileName,NULL,NULL,szDescription,NULL);

errorExit:
 fclose(file);
}

int main(int argc, char* argv[])
{
 AnalyseShortCut("C:\\Documents and Settings\\Administrator\\Desktop\\Windows Media Player.lnk");
 printf("Hello World!\n");
 return 0;
}


学习中请遵守法律法规,本网站内容均来自于互联网,本网站不负担法律责任
VC + + 实现解析快捷方式
#1楼
发帖时间:2016-7-9   |   查看数:0   |   回复数:0
游客组
快速回复