Partilhar via


Shell Links

Um de link do Shell é um objeto de dados que contém informações usadas para acessar outro objeto no namespace do Shell, ou seja, qualquer objeto visível através do Windows Explorer. Os tipos de objetos que podem ser acessados por meio de links do Shell incluem arquivos, pastas, unidades de disco e impressoras. Um link do Shell permite que um usuário ou um aplicativo acesse um objeto de qualquer lugar no namespace. O usuário ou aplicativo não precisa saber o nome atual e o local do objeto.

O usuário cria um link do Shell escolhendo o comando Create Shortcut no menu de atalho de um objeto. O sistema cria automaticamente um ícone para o link do Shell combinando o ícone do objeto com uma pequena seta (conhecida como ícone de sobreposição de link definido pelo sistema) que aparece no canto inferior esquerdo do ícone. Um link do Shell que tem um ícone é chamado de atalho; no entanto, os termos link e atalho do Shell são frequentemente usados de forma intercambiável. Normalmente, o usuário cria atalhos para obter acesso rápido a objetos armazenados em subpastas ou em pastas compartilhadas em outros computadores. Por exemplo, um usuário pode criar um atalho para um documento do Microsoft Word que está localizado em uma subpasta e colocar o ícone de atalho na área de trabalho. O usuário pode então abrir o documento clicando duas vezes no ícone de atalho. Se o documento for movido ou renomeado após a criação do atalho, o sistema tentará atualizar o atalho na próxima vez que o usuário selecioná-lo.

Os aplicativos também podem criar e usar links e atalhos do Shell. Por exemplo, um aplicativo de processamento de texto pode criar um link do Shell para implementar uma lista dos documentos usados mais recentemente. Um aplicativo cria um link do Shell usando a interfaceIShellLink dopara criar um objeto de link do Shell. O aplicativo usa o IPersistFile ou interface IPersistStream para armazenar o objeto em um arquivo ou fluxo.

Observação

Não é possível usar IShellLink para criar um link para uma URL.

 

Esta visão geral descreve o interface IShellLink e explica como usá-lo para criar e resolver links do Shell de dentro de um aplicativo baseado no Microsoft Win32. Como o design de links do Shell é baseado no COM (Component Object Model) OLE, você deve estar familiarizado com os conceitos básicos de programação COM e OLE antes de ler esta visão geral.

Se um usuário criar um atalho para um objeto e o nome ou o local do objeto for alterado posteriormente, o sistema tomará medidas automaticamente para atualizar ou resolver o atalho na próxima vez que o usuário selecioná-lo. No entanto, se um aplicativo cria um link do Shell e o armazena em um fluxo, o sistema não tenta resolver automaticamente o link. O aplicativo deve resolver o link chamando o IShellLink::Resolve método.

Quando um link do Shell é criado, o sistema salva informações sobre o link. Ao resolver um link, automaticamente ou com uma chamada de IShellLink::Resolve, o sistema primeiro recupera o caminho associado ao link do Shell usando um ponteiro para a lista de identificadores do link do Shell. Para obter mais informações sobre a lista de identificadores, consulte Identificadores de item e Listas de identificadores. O sistema procura o objeto associado nesse caminho e, se encontrar o objeto, resolve o link. Se o sistema não conseguir localizar o objeto, ele acionará o serviço Distributed Link Tracking and Object Identifiers (DLT), se disponível, para localizar o objeto. Se o serviço DLT não estiver disponível ou não conseguir localizar o objeto, o sistema procurará no mesmo diretório um objeto com o mesmo tempo de criação de arquivo e atributos, mas com um nome diferente. Esse tipo de pesquisa resolve um link para um objeto que foi renomeado.

Se o sistema ainda não conseguir encontrar o objeto, ele pesquisa os diretórios, a área de trabalho e os volumes locais, procurando recursivamente na árvore de diretórios um objeto com o mesmo nome ou tempo de criação. Se o sistema ainda não encontrar uma correspondência, ele exibirá uma caixa de diálogo solicitando ao usuário um local. Um aplicativo pode suprimir a caixa de diálogo especificando o valor SLR_NO_UI em uma chamada para IShellLink::Resolve.

Inicialização da biblioteca de objetos do componente

Antes que um aplicativo possa criar e resolver atalhos, ele deve inicializar a biblioteca de objetos do componente chamando a funçãoCoInitialize. Cada chamada para CoInitialize requer uma chamada correspondente para a funçãoCoUninitialize, que um aplicativo deve chamar quando for encerrado. A chamada para CoUninitialize garante que o aplicativo não seja encerrado até que tenha recebido todas as suas mensagens pendentes.

Location-Independent Nomes

O sistema fornece nomes independentes de local para links do Shell para objetos armazenados em pastas compartilhadas. Se o objeto for armazenado localmente, o sistema fornecerá o caminho local e o nome do arquivo para o objeto. Se o objeto for armazenado remotamente, o sistema fornecerá um nome de recurso de rede UNC (Convenção de Nomenclatura Universal) para o objeto. Como o sistema fornece nomes independentes de local, um link do Shell pode servir como um nome universal para um arquivo que pode ser transferido para outros computadores.

Quando o usuário cria um atalho para um objeto escolhendo o comando Criar de atalho no menu de atalho do objeto, o Windows armazena as informações necessárias para acessar o objeto em um arquivo de link — um arquivo binário que tem a extensão de nome de arquivo .lnk. Um arquivo de link contém as seguintes informações:

  • O local (caminho) do objeto referenciado pelo atalho (chamado de objeto correspondente).
  • O diretório de trabalho do objeto correspondente.
  • A lista de argumentos que o sistema passa para o objeto correspondente quando o método IContextMenu::InvokeCommand é ativado para o atalho.
  • O comando show usado para definir o estado show inicial do objeto correspondente. Este é um dos SW_ valores descritos em ShowWindow.
  • A localização (caminho e índice) do ícone do atalho.
  • A cadeia de caracteres de descrição do atalho.
  • O atalho de teclado para o atalho.

Quando um arquivo de link é excluído, o objeto correspondente não é afetado.

Se você criar um atalho para outro atalho, o sistema simplesmente copiará o arquivo de link em vez de criar um novo arquivo de link. Neste caso, os atalhos não serão independentes uns dos outros.

Um aplicativo pode registrar uma extensão de nome de arquivo como um tipo de arquivo de atalho. Se um arquivo tiver uma extensão de nome de arquivo que tenha sido registrada como um tipo de arquivo de atalho, o sistema adicionará automaticamente o ícone de sobreposição de link definido pelo sistema (uma pequena seta) ao ícone do arquivo. Para registrar uma extensão de nome de arquivo como um tipo de arquivo de atalho, você deve adicionar o valor IsShortcut à descrição do Registro da extensão de nome de arquivo, conforme mostrado no exemplo abaixo. Observe que o Shell deve ser reiniciado para que o ícone de sobreposição entre em vigor. IsShortcut não tem valor de dados.

HKEY_CLASSES_ROOT
   .xyz
      (Default) = XYZApp
   XYZApp
      IsShortcut

Nomes de atalho

O nome do atalho, que é uma cadeia de caracteres que aparece abaixo do ícone de link do Shell, é na verdade o nome do arquivo do próprio atalho. O usuário pode editar a string de descrição selecionando-a e inserindo uma nova string.

Localização dos atalhos no namespace

Um atalho pode existir na área de trabalho ou em qualquer lugar no namespace do Shell. Da mesma forma, o objeto associado ao atalho também pode existir em qualquer lugar no namespace do Shell. Um aplicativo pode usar o método IShellLink::SetPath para definir o caminho e o nome do arquivo para o objeto associado e o método IShellLink::GetPath para recuperar o caminho atual e o nome do arquivo para o objeto.

Diretório de trabalho de atalho

O diretório de trabalho é o diretório onde o objeto correspondente de um atalho carrega ou armazena arquivos quando o usuário não identifica um diretório específico. Um arquivo de link contém o nome do diretório de trabalho para o objeto correspondente. Um aplicativo pode definir o nome do diretório de trabalho para o objeto correspondente usando o métodoIShellLink::SetWorkingDirectory e pode recuperar o nome do diretório de trabalho atual para o objeto correspondente usando o métodoIShellLink::GetWorkingDirectory.

Argumentos de linha de comando de atalho

Um arquivo de link contém argumentos de linha de comando que o Shell passa para o objeto correspondente quando o usuário seleciona o link. Um aplicativo pode definir os argumentos de linha de comando para um atalho usando o métodoIShellLink::SetArguments. É útil definir argumentos de linha de comando quando o aplicativo correspondente, como um vinculador ou compilador, usa sinalizadores especiais como argumentos. Um aplicativo pode recuperar os argumentos de linha de comando de um atalho usando o métodoIShellLink::GetArguments.

Comandos de apresentação de atalho

Quando o usuário clica duas vezes em um atalho, o sistema inicia o aplicativo associado ao objeto correspondente e define o estado inicial show do aplicativo com base no comando show especificado pelo atalho. O comando show pode ser qualquer um dos SW_ valores incluídos na descrição da funçãoShowWindow. Um aplicativo pode definir o comando show para um atalho usando o método IShellLink::SetShowCmd e pode recuperar o comando show atual usando o método IShellLink::GetShowCmd.

Ícones de atalho

Como outros objetos do Shell, um atalho tem um ícone. O usuário acessa o objeto associado a um atalho clicando duas vezes no ícone do atalho. Quando o sistema cria um ícone para um atalho, ele usa o bitmap do objeto correspondente e adiciona o ícone de sobreposição de link definido pelo sistema (uma pequena seta) no canto inferior esquerdo. Um aplicativo pode definir o local (caminho e índice) do ícone de um atalho usando o métodoIShellLink::SetIconLocation. Um aplicativo pode recuperar esse local usando o método IShellLink::GetIconLocation.

Descrições de atalhos

Os atalhos têm descrições, mas o usuário nunca as vê. Um aplicativo pode usar uma descrição para armazenar qualquer informação de texto. As descrições são definidas usando o métodoIShellLink::SetDescriptione recuperadas usando o métodoIShellLink::GetDescription.

Atalho Atalhos de teclado

Um objeto de atalho pode ter um atalho de teclado associado a ele. Os atalhos de teclado permitem que um usuário pressione uma combinação de teclas para ativar um atalho. Um aplicativo pode definir o atalho de teclado para um atalho usando o método IShellLink::SetHotkey e pode recuperar o atalho de teclado atual usando o método IShellLink::GetHotkey.

Identificadores de item e listas de identificadores

O Shell usa identificadores de objeto dentro do namespace do Shell. Todos os objetos visíveis no Shell (arquivos, diretórios, servidores, grupos de trabalho e assim por diante) têm identificadores exclusivos entre os objetos dentro de sua pasta pai. Esses identificadores são chamados de identificadores de item e têm o SHITEMID tipo de dados, conforme definido no arquivo de cabeçalho Shtypes.h. Um identificador de item é um fluxo de bytes de comprimento variável que contém informações que identificam um objeto dentro de uma pasta. Apenas o criador de um identificador de item conhece o conteúdo e o formato do identificador. A única parte de um identificador de item que o Shell usa são os dois primeiros bytes, que especificam o tamanho do identificador.

Cada pasta pai tem seu próprio identificador de item que a identifica dentro de sua própria pasta pai. Assim, qualquer objeto Shell pode ser identificado exclusivamente por uma lista de identificadores de item. Uma pasta pai mantém uma lista de identificadores para os itens que contém. A lista tem o ITEMIDLIST tipo de dados. As listas de identificadores de item são alocadas pelo Shell e podem ser passadas através de interfaces do Shell, como IShellFolder. É importante lembrar que cada identificador em uma lista de identificadores de item só é significativo dentro do contexto de sua pasta pai.

Um aplicativo pode definir a lista de identificadores de item de um atalho usando o métodoIShellLink::SetIDList. Esse método é útil ao definir um atalho para um objeto que não é um arquivo, como uma impressora ou unidade de disco. Um aplicativo pode recuperar a lista de identificadores de item de um atalho usando o métodoIShellLink::GetIDList.

Esta seção contém exemplos que demonstram como criar e resolver atalhos de dentro de um aplicativo baseado em Win32. Esta seção pressupõe que você esteja familiarizado com a programação Win32, C++ e OLE COM.

Criando um atalho e um atalho de pasta para um arquivo

A função de exemplo CreateLink no exemplo a seguir cria um atalho. Os parâmetros incluem um ponteiro para o nome do arquivo ao qual vincular, um ponteiro para o nome do atalho que você está criando e um ponteiro para a descrição do link. A descrição consiste na cadeia de caracteres, "Atalho para nome de arquivo", onde nome de arquivo é o nome do arquivo ao qual vincular.

Para criar um atalho de pasta usando a função de exemplo CreateLink, chame CoCreateInstance usando CLSID_FolderShortcut, em vez de CLSID_ShellLink (CLSID_FolderShortcut suporta IShellLink). Todos os outros códigos permanecem os mesmos.

Como CreateLink chama a funçãoCoCreateInstance, supõe-se que a funçãoCoInitialize já tenha sido chamada. CreateLink usa o interface IPersistFile para salvar o atalho e o IShellLink interface para armazenar o nome e a descrição do arquivo.

// CreateLink - Uses the Shell's IShellLink and IPersistFile interfaces 
//              to create and store a shortcut to the specified object. 
//
// Returns the result of calling the member functions of the interfaces. 
//
// Parameters:
// lpszPathObj  - Address of a buffer that contains the path of the object,
//                including the file name.
// lpszPathLink - Address of a buffer that contains the path where the 
//                Shell link is to be stored, including the file name.
// lpszDesc     - Address of a buffer that contains a description of the 
//                Shell link, stored in the Comment field of the link
//                properties.

#include "stdafx.h"
#include "windows.h"
#include "winnls.h"
#include "shobjidl.h"
#include "objbase.h"
#include "objidl.h"
#include "shlguid.h"

HRESULT CreateLink(LPCWSTR lpszPathObj, LPCSTR lpszPathLink, LPCWSTR lpszDesc) 
{ 
    HRESULT hres; 
    IShellLink* psl; 
 
    // Get a pointer to the IShellLink interface. It is assumed that CoInitialize
    // has already been called.
    hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl); 
    if (SUCCEEDED(hres)) 
    { 
        IPersistFile* ppf; 
 
        // Set the path to the shortcut target and add the description. 
        psl->SetPath(lpszPathObj); 
        psl->SetDescription(lpszDesc); 
 
        // Query IShellLink for the IPersistFile interface, used for saving the 
        // shortcut in persistent storage. 
        hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf); 
 
        if (SUCCEEDED(hres)) 
        { 
            WCHAR wsz[MAX_PATH]; 
 
            // Ensure that the string is Unicode. 
            MultiByteToWideChar(CP_ACP, 0, lpszPathLink, -1, wsz, MAX_PATH); 
            
            // Add code here to check return value from MultiByteWideChar 
            // for success.
 
            // Save the link by calling IPersistFile::Save. 
            hres = ppf->Save(wsz, TRUE); 
            ppf->Release(); 
        } 
        psl->Release(); 
    } 
    return hres; 

Resolvendo um atalho

Um aplicativo pode precisar acessar e manipular um atalho que foi criado anteriormente. Esta operação é referida como resolver o atalho.

A função ResolveIt definida pelo aplicativo no exemplo a seguir resolve um atalho. Seus parâmetros incluem uma alça de janela, um ponteiro para o caminho do atalho e o endereço de um buffer que recebe o novo caminho para o objeto. O identificador de janela identifica a janela pai para quaisquer caixas de mensagem que o Shell possa precisar exibir. Por exemplo, o Shell pode exibir uma caixa de mensagem se o link estiver em mídia não compartilhada, se ocorrerem problemas de rede, se o usuário precisar inserir um disquete e assim por diante.

A função ResolveIt chama a funçãoCoCreateInstance e assume que a função CoInitialize já foi chamada. Observe que ResolveIt precisa usar o IPersistFile interface para armazenar as informações do link. IPersistFile é implementado pelo IShellLink objeto. As informações do link devem ser carregadas antes que as informações de caminho sejam recuperadas, o que é mostrado posteriormente no exemplo. Falha ao carregar as informações de link faz com que as chamadas para o IShellLink::GetPath e IShellLink::GetDescription funções de membro falhem.

// ResolveIt - Uses the Shell's IShellLink and IPersistFile interfaces 
//             to retrieve the path and description from an existing shortcut. 
//
// Returns the result of calling the member functions of the interfaces. 
//
// Parameters:
// hwnd         - A handle to the parent window. The Shell uses this window to 
//                display a dialog box if it needs to prompt the user for more 
//                information while resolving the link.
// lpszLinkFile - Address of a buffer that contains the path of the link,
//                including the file name.
// lpszPath     - Address of a buffer that receives the path of the link
                  target, including the file name.
// lpszDesc     - Address of a buffer that receives the description of the 
//                Shell link, stored in the Comment field of the link
//                properties.

#include "stdafx.h"
#include "windows.h"
#include "shobjidl.h"
#include "shlguid.h"
#include "strsafe.h"
                            
HRESULT ResolveIt(HWND hwnd, LPCSTR lpszLinkFile, LPWSTR lpszPath, int iPathBufferSize) 
{ 
    HRESULT hres; 
    IShellLink* psl; 
    WCHAR szGotPath[MAX_PATH]; 
    WCHAR szDescription[MAX_PATH]; 
    WIN32_FIND_DATA wfd; 
 
    *lpszPath = 0; // Assume failure 

    // Get a pointer to the IShellLink interface. It is assumed that CoInitialize
    // has already been called. 
    hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl); 
    if (SUCCEEDED(hres)) 
    { 
        IPersistFile* ppf; 
 
        // Get a pointer to the IPersistFile interface. 
        hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf); 
        
        if (SUCCEEDED(hres)) 
        { 
            WCHAR wsz[MAX_PATH]; 
 
            // Ensure that the string is Unicode. 
            MultiByteToWideChar(CP_ACP, 0, lpszLinkFile, -1, wsz, MAX_PATH); 
 
            // Add code here to check return value from MultiByteWideChar 
            // for success.
 
            // Load the shortcut. 
            hres = ppf->Load(wsz, STGM_READ); 
            
            if (SUCCEEDED(hres)) 
            { 
                // Resolve the link. 
                hres = psl->Resolve(hwnd, 0); 

                if (SUCCEEDED(hres)) 
                { 
                    // Get the path to the link target. 
                    hres = psl->GetPath(szGotPath, MAX_PATH, (WIN32_FIND_DATA*)&wfd, SLGP_SHORTPATH); 

                    if (SUCCEEDED(hres)) 
                    { 
                        // Get the description of the target. 
                        hres = psl->GetDescription(szDescription, MAX_PATH); 

                        if (SUCCEEDED(hres)) 
                        {
                            hres = StringCbCopy(lpszPath, iPathBufferSize, szGotPath);
                            if (SUCCEEDED(hres))
                            {
                                // Handle success
                            }
                            else
                            {
                                // Handle the error
                            }
                        }
                    }
                } 
            } 

            // Release the pointer to the IPersistFile interface. 
            ppf->Release(); 
        } 

        // Release the pointer to the IShellLink interface. 
        psl->Release(); 
    } 
    return hres; 
}

Criando um atalho para um objeto não arquivo

Criar um atalho para um objeto que não seja de arquivo, como uma impressora, é semelhante a criar um atalho para um arquivo, exceto que, em vez de definir o caminho para o arquivo, você deve definir a lista de identificadores para a impressora. Para definir a lista de identificadores, chame o IShellLink::SetIDList método, especificando o endereço de uma lista de identificadores.

Cada objeto dentro do namespace do Shell tem um identificador de item. O Shell geralmente concatena identificadores de item em listas terminadas em nulo que consistem em qualquer número de identificadores de item. Para obter mais informações sobre identificadores de item, consulte Identificadores de item e listas de identificadores.

Em geral, se você precisar definir um atalho para um item que não tenha um nome de arquivo, como uma impressora, você já terá um ponteiro para a interfaceIShellFolderdo objeto. IShellFolder é usado para criar extensões de namespace.

Depois de ter o identificador de classe para IShellFolder, você pode chamar a função CoCreateInstance para recuperar o endereço da interface. Em seguida, você pode chamar a interface para enumerar os objetos na pasta e recuperar o endereço do identificador de item para o objeto que você está procurando. Finalmente, você pode usar o endereço em uma chamada para a função de membroIShellLink::SetIDList para criar um atalho para o objeto.