VC操作Windows快捷方式(自己总结)

原文链接:http://www.ccgcn.com/bbs/viewthread.php?tid=2074&extra=page%3D1


VC操作Windows快捷方式(自己总结)

VC操作Windows快捷方式(自己总结)
二个操作:新建和解析
主要用到的是COM组件。IShellLink和IPersistFile
需要添加的头函数
shobjidl.h
IPersistFile主要用到两个成员函数:
1、Save。保存内容到文件中去
2、Load。读取
Load的函数原型
HRESULT Load(
   LPCOLSTR pszFileName, //快捷方式的文件名,应该是ANSI字符
   DWORD dwMode //读取方式
  );
dwMode可取如下值:
STGM_READ:只读 
       STGM_WRITE:只写 
       STGM_READWRITE:读写
IShellLink主要成员:
1、GetArguments:获得参数信息 
2、GetDescription:获得描述信息(备注行)
3、GetHotkey:获得快捷键
4、GetIconLocation:获得图标  
5、GetIDList:获得快捷方式的目标对象的item identifier list (Windows外壳中的每个对象如文件,目录和打印机等都有唯一的item identifiler list)
6、GetPath: 获得快捷方式的目标文件或目录的全路径
7、GetShowCmd:获得快捷方式的运行方式,比如常规窗口,最大化
8、GetWorkingDirectory:获得工作目录 
9、Resolve:按照一定的搜索规则试图获得目标对象,即使目标对象已经被删除或移动,重命名
下面是对应信息的设置方法
10、SetArguments 
11、SetDescription 
12、SetHotkey
13、SetIconLocation
14、SetIDList
15、SetPath
16、SetRelativePat
17、SetShowCmd
18、SetWorkingDirectory 
一般情况操作如下:
一、初始化COM接口
二、创建IShellLink对象
三、从IShellLink对象中获取IPersistFile对象接口
四、操作IShellLink对象
五、释放IPersistFile对象接口
六、释放IShellLink对象
七、释放COM接口
示例代码:
/*
注:在桌面上创建快捷方式,快捷方式的名称为"VC创建的快捷方式",快捷方式指向应用程序"c:\aa.exe"
快捷方式的快捷键:无
快捷方式的工作目录:c:\
快捷方式的备注:VC写写捷方式
快捷方式的运行方式:常规窗口
*/
HRESULT hRet;
IShellLink *pLink;  //IShellLink对象指针
IPersistFile * ppf; //IPersisFil对象指针
WCHAR wsz[MAX_PATH];  //定义Unicode字符串
//初始化COM库
hRet = ::CoInitialize(NULL);
if ( hRet != S_OK)  //初始化COM库失败,直接返回
{
   AfxMessageBox("初始化COM库失败");
   return;
}
//创建IShellLink实例
hRet = ::CoCreateInstance(CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER,IID_IShellLink,(void**)&pLink);
if ( hRet != S_ok)
{
AfxMessageBox("创建IShellLink实例失败");
}
else
{
//创建IShellLink实例成功,继续操作

//从IShellLink对象中获取IPersistFile接口
hRet = pLink->QueryInterface(IID_IpersistFile,(void**)&ppf);
if ( hRet != S_OK)
{
  AfxMessageBox("获取IPersistFile接口失败");
}
else
{
  //获取接口成功,继续操作
  //设置快捷方式中的程序路径
  pLink->SetPath("c:\\aa.exe");
  //设置快捷方式的工作目录
  pLink->SetWorkingDirectory("c:\\");
  //确保快捷方式路径由ANSI字符串组成
  MultiByteToWideChar(
   CP_ACP,
   0,
   "C:\\Documents and Settings\\hjs\\桌面[url=file://\\vc]\\vc[/url]创建的快捷方式.lnk",
   -1,
   wsz,
   MAX_PATH
  );
  //保存快捷方式
  ppf->Save(wsz,TRUE);
}
}
//释放IPersistFile接口
ppf->Release();
//释放IShellLink对象
pLink->Release();
//释放COM接口
::CoUninitialize();
[email protected]
update ccg_members set groupid = 28 where groupid = 8

TOP

在桌面创建IE风格的快捷方式(无小箭头)

在桌面创建IE风格的快捷方式(无小箭头)
在桌面创建IE风格的快捷方式
This article was contributed by Sundar & Naresh 
我们如果要在桌面上建立一个快捷方式,我们通常是用IShellLink接口来生成一
个.lnk文件。用这种方式创建,我们在桌面上得到的是一个左下方还含有小箭头
的图标,右击它,你会看到正常的弹出菜单(含有复制、粘贴等)。但是你看桌面
上IE的快捷方式,你会看到它是一个正常的图标(没有小箭头),而且弹出菜单
也不同。下面我们来建立一个这种风格的快捷方式。

执行这段代码,你会在桌面上获得一个名叫"Netlinker"的图标,右击它,
你会看到一个定制的菜单(没有剪切、复制、粘贴、重命名等菜单祥)。
你甚至不能把它从桌面上删除,如果你选“属性”,它会打开IE的属性对话框

选一个图标文件 
CString shtct_ico=_T("C:\\32x32.ico");
显示IE属性对话框. 
CString shtct_prop=_T("rundll32.exe shell32.dll,Control_RunDLL inetcpl.cpl,,0");
快捷方式的名字
CString shtct_name=_T("Netlinker");
找到IE的路径并保存它. 
CRegKey m_Kiepath;
CString ie_path;
DWORD dwval;
m_Kiepath.Open(HKEY_LOCAL_MACHINE,
               "SOFTWARE\\Microsoft\\Windows\\"
               "CurrentVersion\\App Paths\\IEXPLORE.EXE");
m_Kiepath.QueryValue(ie_path.GetBuffer(1000),
                     NULL,
                     &dwval);
m_Kiepath.Close();
CString shtct_to=ie_path;
用guidgen.exe创建一个GUID并复制粘贴到这里。这是用来表现我们的快捷方式和它
的菜单项的。我用guidgen.ext创建的GUID是6270AEE4-AA41-11d4-A25D-008048B63F94。 
下面的程序在HKCR\CLSID创建这个 GUID 键,并且将快捷方式的值设为它。
CRegKey m_kdsktp;
m_kdsktp.Create(HKEY_CLASSES_ROOT,
                "CLSID\\{6270AEE4-AA41-11d4-A25D-"
                "008048B63F94}");
m_kdsktp.SetValue(shtct_name);
m_kdsktp.Close();
在这个GUID下创建DefaultIcon 键, 它是用来表现快捷方式的图标的
并把他的值设为相应的图标文件的路径. 

m_kdsktp.Create(HKEY_CLASSES_ROOT,
                "CLSID\\{6270AEE4-AA41-11d4-A25D"
                "-008048B63F94}\\DefaultIcon");
m_kdsktp.SetValue(shtct_ico);
m_kdsktp.Close();
设置右击菜单的菜单项.
设置打开菜单项 
m_kdsktp.Create(HKEY_CLASSES_ROOT,
                "CLSID\\{6270AEE4-AA41-11d4-A25D-"
                "008048B63F94}\\Shell\\Open\\Command");
m_kdsktp.SetValue(shtct_to);
m_kdsktp.Close();
设置属性菜单项. 
m_kdsktp.Create(HKEY_CLASSES_ROOT,
                "CLSID\\{6270AEE4-AA41-11d4-A25D-"
                "008048B63F94}\\Shell\\Properties\\Command");
m_kdsktp.SetValue(shtct_prop);
m_kdsktp.Close();
把原来的缺省菜单项(如复制粘贴等)去掉.
BYTE *b;
HANDLE heap;
char a[20];
m_kdsktp.Create(HKEY_CLASSES_ROOT,
                "CLSID\\{6270AEE4-AA41-11d4-A25D-"
                "008048B63F94}\\ShellFolder");
strcpy(a,"00.00.00.00");
heap=HeapCreate(0,0,0);
b=(BYTE*)HeapAlloc(heap,0,30);
sscanf(a,
       "%x.%x.%x.%x",
       &b[0],
       &b[1],
       &b[2],
       &b[3]);
RegSetValueEx(m_kdsktp.m_hKey,
              "Attributes",
              0,
              REG_BINARY,
              b,
              4);
HeapFree(heap, 0, b);
HeapDestroy(heap);
m_kdsktp.Close();
接下来我们添加一个引用到
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Desktop\Namespace
这样它将只显示在桌面上。
m_kdsktp.Create(HKEY_LOCAL_MACHINE,
                "SOFTWARE\\Microsoft\\Windows\\"
                "CurrentVersion\\Explorer\\Desktop\\"
                "NameSpace\\{6270AEE4-AA41-11d4-A25D-"
                "008048B63F94}");
m_kdsktp.SetValue("Netlink");
m_kdsktp.Close();
我们对Shell作了改动,我们要通知系统,这个改动才会马上表现出来.
SHChangeNotify(SHCNE_ASSOCCHANGED,SHCNF_FLUSHNOWAIT, 0, 0);
[email protected]
update ccg_members set groupid = 28 where groupid = 8

TOP

VC操作Windows快捷方式

VC操作Windows快捷方式
主要用到的是COM组件。IShellLink和IPersistFile
需要添加的头函数
shobjidl.h
IPersistFile主要用到两个成员函数:
1、Save。保存内容到文件中去
2、Load。读取
Load的函数原型
HRESULT Load(
             LPCOLSTR pszFileName, //快捷方式的文件名,应该是ANSI字符
             DWORD dwMode //读取方式
             );
dwMode可取如下值:
STGM_READ:只读 
STGM_WRITE:只写 
STGM_READWRITE:读写

1.新建
引用:
/*注:在桌面上创建快捷方式,快捷方式的名称为"VC创建的快捷方式",快捷方式指向应用程序"c:\aa.exe"
快捷方式的快捷键:无
快捷方式的工作目录:c:\
快捷方式的备注:VC写写捷方式
快捷方式的运行方式:常规窗口*/
HRESULT hRet;
IShellLink *pLink;  //IShellLink对象指针
IPersistFile * ppf; //IPersisFil对象指针
WCHAR wsz[MAX_PATH];  //定义Unicode字符串
//初始化COM库
hRet = ::CoInitialize(NULL);
if (hRet != S_OK)  //初始化COM库失败,直接返回
{
  AfxMessageBox("初始化COM库失败");
  return;
}
//创建IShellLink实例
hRet = ::CoCreateInstance(CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER,IID_IShellLink,(void**)&pLink);
if (hRet != S_ok)
{
  AfxMessageBox("创建IShellLink实例失败");
}
else
{
  //创建IShellLink实例成功,继续操作

  //从IShellLink对象中获取IPersistFile接口
  hRet = pLink->QueryInterface(IID_IpersistFile,(void**)&ppf);
  if (hRet != S_OK)
  {
    AfxMessageBox("获取IPersistFile接口失败");
  }
  else
  {
    //获取接口成功,继续操作
    //设置快捷方式中的程序路径
    pLink->SetPath("c:\\aa.exe");
    //设置快捷方式的工作目录
    pLink->SetWorkingDirectory("c:\\");
    //确保快捷方式路径由ANSI字符串组成
    MultiByteToWideChar(
      CP_ACP,
      0,
      "C:\\Documents and Settings\\hjs\\桌面[url=file://\\vc]\\vc[/url]创建的快捷方式.lnk",
      -1,
      wsz,
      MAX_PATH
      );
    //保存快捷方式
    ppf->Save(wsz,TRUE);
  }
}
//释放IPersistFile接口
ppf->Release();
//释放IShellLink对象
pLink->Release();
//释放COM接口
::CoUninitialize();

//创建快捷方式   

BOOL   CreateLink(
                     LPSTR   szPath,//快捷方式的目标应用程序名   
                     LPSTR   szLink)//快捷方式的数据文件名(*.lnk)   
{   
  HRESULT   hres;   
  IShellLink   *   psl;   
  IPersistFile*   ppf;   
  WORD   wsz[MAX_PATH];   

  //创建一个IShellLink实例   
  hres = CoCreateInstance(CLSID_ShellLink,NULL, CLSCTX_INPROC_SERVER,IID_IShellLink,(void   **)&psl);   
  if(FAILED(hres)) return   FALSE;   

  //设置目标应用程序   
  psl ->SetPath(szPath);   

  //设置快捷键(此处设为Shift+Ctrl+'R')   
  psl->SetHotkey(MAKEWORD('R', HOTKEYF_SHIFT   |HOTKEYF_CONTROL));   

  //从IShellLink获取其IPersistFile接口   

  //用于保存快捷方式的数据文件   (*.lnk)   
  hres = psl->QueryInterface(IID_IPersistFile,(void**)&ppf);   
  if(FAILED(hres))  return   FALSE;   

  //   确保数据文件名为ANSI格式   
  MultiByteToWideChar(CP_ACP,0,szLink,-1,wsz,MAX_PATH); 

  //调用IPersistFile::Save   

  //保存快捷方式的数据文件   (*.lnk)   
  hres=ppf->Save(wsz,STGM_READWRITE);   

  //释放IPersistFile和IShellLink接口   

  ppf->Release();   

  psl->Release();   

  return   TRUE;   

}
2.解析快捷方式:
引用:
HRESULT   ResolveIt(HWND   hwnd,   LPCSTR   lpszLinkFile,   LPSTR   lpszPath)     
{     
  HRESULT   hres;     
  IShellLink*   psl;     
  char   szGotPath[MAX_PATH];     
  char   szDescription[MAX_PATH];     
  WIN32_FIND_DATA   wfd;     

  *lpszPath=0;   //   assume   failure     

  //   Get   a   pointer   to   the   IShellLink   interface.     
  hres=CoCreateInstance(&CLSID_ShellLink,   NULL,     
    CLSCTX_INPROC_SERVER,   &IID_IShellLink,   &psl);     
  if   (SUCCEEDED(hres))   {     
    IPersistFile*   ppf;     

    //   Get   a   pointer   to   the   IPersistFile   interface.     
    hres=psl->lpVtbl->QueryInterface(psl,   &IID_IPersistFile,     
      &ppf);     
    if   (SUCCEEDED(hres))   {     
      WORD   wsz[MAX_PATH];     

      //   Ensure   that   the   string   is   Unicode.     
      MultiByteToWideChar(CP_ACP,   0,   lpszLinkFile,   -1,   wsz,     
        MAX_PATH);     

      //   Load   the   shortcut.     
      hres=ppf->lpVtbl->Load(ppf,   wsz,   STGM_READ);     
      if   (SUCCEEDED(hres))   {     

        //   Resolve   the   link.     
        hres=psl->lpVtbl->Resolve(psl,   hwnd,   SLR_ANY_MATCH);     
        if   (SUCCEEDED(hres))   {     

          //   Get   the   path   to   the   link   target.     
          hres=psl->lpVtbl->GetPath(psl,   szGotPath,     
            MAX_PATH,   (WIN32_FIND_DATA   *)&wfd,     
            SLGP_SHORTPATH   );     
          if   (!SUCCEEDED(hres)     
            HandleErr(hres);   //   application-defined   function     

          //   Get   the   description   of   the   target.     
          hres=psl->lpVtbl->GetDescription(psl,     
            szDescription,   MAX_PATH);     
          if   (!SUCCEEDED(hres))     
            HandleErr(hres);     
          lstrcpy(lpszPath,   szGotPath);     
        }     
      }     
      //   Release   the   pointer   to   the   IPersistFile   interface.     
      ppf->lpVtbl->Release(ppf);     
    }     
    //   Release   the   pointer   to   the   IShellLink   interface.     
    psl->lpVtbl->Release(psl);     
  }     
  return   hres;     
}
3.修改Link 图标
引用:
UINT __stdcall ChangeDeskTopIconLink(MSIHANDLE hInstall)
{
#ifdef  RA2HP_Dubeg
  System::Windows::Forms::MessageBox::Show("ChangeDeskTopIconLink");
#endif
  HRESULT hres;
  IShellLink *psl = NULL;
  IPersistFile *pPf = NULL;
  WCHAR wsz[MAX_PATH];
  TCHAR buf[MAX_PATH];
  TCHAR szPath[MAX_PATH];
  TCHAR allusers[MAX_PATH];
  int id;
  LPITEMIDLIST pidl;
  ::CoInitialize(NULL);
  hres = CoCreateInstance(CLSID_ShellLink,
    NULL,
    CLSCTX_INPROC_SERVER,
    IID_IShellLink,
    (LPVOID*)&psl);
  if(FAILED(hres))
    goto cleanup;
  hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&pPf);
  if(FAILED(hres))
    goto cleanup;

  memcpy(allusers, OSVersion::getPath_UsersPublic(), MAX_PATH);
  //GetEnvironmentVariable(TEXT("USERPROFILE"),allusers,MAX_PATH);
  _stprintf_s(wsz,TEXT("%s%s"),allusers,TEXT("\\Desktop\\Remote Access to HP Network 5.0.lnk"));

  TCHAR tmp[MAX_PATH];
  TCHAR filename[MAX_PATH];

  TCHAR* pBuffer = NULL;
  //memset(sProgramfiles, 0, MAX_PATH);
  size_t len;
  errno_t err = _wdupenv_s(&pBuffer,&len,L"programfiles");  // find the root
  if(err) return 1;
  _stprintf_s(filename,TEXT("%s%s"),pBuffer,TEXT("\\RA2HP\\RA2HP.ico"));


  hres = pPf->Load(wsz, STGM_READ);
  if(FAILED(hres))
    goto cleanup;
  hres = psl->Resolve(NULL, SLR_UPDATE);
  if(FAILED(hres))
    goto cleanup;
  hres = psl->SetIconLocation(filename, 0);
  if(FAILED(hres))
    goto cleanup;

  pPf->Save(wsz, TRUE);
  //change icon in starmenu
  ITEMIDLIST* pidlm = NULL; 
  SHGetSpecialFolderLocation(NULL, CSIDL_COMMON_PROGRAMS, &pidlm);
  TCHAR bufm[MAX_PATH];
  SHGetPathFromIDList(pidlm, bufm);
  lstrcat(bufm,TEXT("\\")); 
  lstrcat(bufm,TEXT("Remote Access to HP Network 5.0.lnk")); 
  WCHAR   wszm[MAX_PATH];     
  wmemcpy(wszm,bufm,MAX_PATH);
  hres = pPf->Load(wszm, STGM_READ);
  if(FAILED(hres))
    goto cleanup;
  hres = psl->Resolve(NULL, SLR_UPDATE);
  if(FAILED(hres))
    goto cleanup;
  hres = psl->SetIconLocation(filename, 0);
  if(FAILED(hres))
    goto cleanup;

  pPf->Save(wszm, TRUE);

cleanup:
  if(pPf)
    pPf->Release();
  if(psl)
    psl->Release();
  ::CoUninitialize();
  return 0;
}
[email protected]
update ccg_members set groupid = 28 where groupid = 8

TOP

.lnk file format

it's been a while since i've messed with that, but i dug up the following
source code. it has been so long that i can't remember if this was the file
i got working, so someone should test it out (i don't have time). however,
it basically decodes the windows .lnk file format to find out what it is a
shortcut to, and determines if that is a directory (i was going to write a
unix type ln command using .lnk file formats.....). there are 2 files here.
one is a c version, the other is a c++ version.... hope this helps....
-donald murray
============================================
c version
============================================
#include <windows.h>
#include <windowsx.h>
#include <objbase.h>
#include <shlobj.h>
#include <stdio.h>
#include <initguid.h>
#include <string.h>
main(int ac, char *av[])
{
  IShellLink *psl;
  HRESULT hres;
  WIN32_FIND_DATA wfd;
  char szgotpath[MAX_PATH];
  IPersistFile *ppf;
  if (ac != 2)
  {
    printf("syntax: ln <pathname>\n");
    return 0;
  }
  hres = coinitialize(NULL);
  if (!SUCCEEDED(hres))
    printf("could not open the com library\n");
  hres = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
    &IID_IShellLink, (LPVOID *)&psl);
  if (SUCCEEDED(hres))
  {
    hres = psl->lpvtbl->queryinterface(psl, &IID_IPersistFile, &ppf);
    if (SUCCEEDED(hres))
    {
      WORD wsz[MAX_PATH];
      MultiByteToWideChar(CP_ACP, 0, av[1], -1, wsz, MAX_PATH);
      hres = ppf->lpvtbl->load(ppf, wsz, STGM_READ);
      if (SUCCEEDED(hres))
      {
        hres = psl->lpvtbl->resolve(psl, 0, SLR_ANY_MATCH);
        if (SUCCEEDED(hres))
        {
          strcpy(szgotpath, av[1]);
          hres = psl->lpvtbl->GetPath(psl, szgotpath, MAX_PATH,
            (WIN32_FIND_DATA *)&wfd, SLGP_SHORTPATH );
          if (!SUCCEEDED(hres))
            printf("GetPath failed!\n");
          printf("this points to %s\n", wfd.cfilename);
          if (wfd.dwfileattributes & file_attribute_directory)
            printf("this is a directory\n");
        }
      }
      else
        printf("IPersistFile load error\n");
      ppf->lpvtbl->release(ppf);
    }
    else
      printf("queryinterface error\n");
    psl->lpvtbl->release(psl);
  }
  else
    printf("CoCreateInstance error - hres = %08x\n", hres);
  return 0;
}

==================================
c++ version
==================================
#include <windowsx.h>
#include <objbase.h>
#include <shlobj.h>
#include <stdio.h>
#include <initguid.h>
#include <stdlib.h>
#include <io.h>
#include <string.h>

// this program should print out whether the file is a link and where it
// points to and whether it is a directory or not.
//
main(int ac, char *av[])
{
  if (ac != 2)
  {
    printf("syntax: ln <pathname>\n");
    return 0;
  }
  IShellLink *psl;                            // pointer to IShellLink i/f
  HRESULT hres;
  WIN32_FIND_DATA wfd;
  char szgotpath[MAX_PATH];
  // get pointer to the IShellLink interface.
  hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
    IID_IShellLink, (LPVOID *)&psl);
  if (SUCCEEDED(hres))
  {
    // get pointer to the IPersistFile interface.
    IPersistFile *ppf;
    hres = psl->QueryInterface(IID_IPersistFile, (LPVOID *)&ppf);
    if (SUCCEEDED(hres))
    {
      WORD wsz[MAX_PATH];
      // ensure string is unicode.
      MultiByteToWideChar(CP_ACP, 0, av[1], -1, wsz, MAX_PATH);
      // load the shell link
      hres = ppf->load(wsz, STGM_READ);
      if (SUCCEEDED(hres))
      {
        // resolve the link.
        hres = psl->resolve(0, SLR_ANY_MATCH);
        //                  ^
        // using 0 instead -| of hwnd, as hwnd is only used if
        // interface needs to prompt for more information. should use
        // hwnd from current console in the long run.
        if (SUCCEEDED(hres))
        {
          strcpy(szgotpath, av[1]);
          hres = psl->GetPath(szgotpath, MAX_PATH, (WIN32_FIND_DATA *)&wfd, SLGP_SHORTPATH );
          if (!SUCCEEDED(hres))
            printf("GetPath failed!\n");
          printf("this points to %s\n", wfd.cFileName);
          if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            printf("this is a directory\n");
        }
      }
      else
        printf("IPersistFile load error\n");
      ppf->release();
    }
    else
      printf("queryinterface error\n");
    psl->release();
  }
  else
    printf("CoCreateInstance error - hres = %08x\n", hres);
  return 0;
}

你可能感兴趣的:(VC操作Windows快捷方式(自己总结))