Liens d’interpréteur de commandes

Un lien Shell est un objet de données qui contient des informations utilisées pour accéder à un autre objet dans l’espace de noms de l’interpréteur de commandes, c’est-à-dire tout objet visible via Windows Explorer. Les types d’objets accessibles via des liens Shell incluent les fichiers, les dossiers, les lecteurs de disque et les imprimantes. Un lien Shell permet à un utilisateur ou à une application d’accéder à un objet à partir de n’importe où dans l’espace de noms. L’utilisateur ou l’application n’a pas besoin de connaître le nom actuel et l’emplacement de l’objet.

L’utilisateur crée un lien Shell en choisissant la commande Créer un raccourci dans le menu contextuel d’un objet. Le système crée automatiquement une icône pour le lien Shell en combinant l’icône de l’objet avec une petite flèche (appelée icône de superposition de lien définie par le système) qui s’affiche dans le coin inférieur gauche de l’icône. Un lien Shell qui a une icône est appelé raccourci ; toutefois, les termes lien et raccourci shell sont souvent utilisés de manière interchangeable. En règle générale, l’utilisateur crée des raccourcis pour accéder rapidement aux objets stockés dans des sous-dossiers ou dans des dossiers partagés sur d’autres ordinateurs. Par exemple, un utilisateur peut créer un raccourci vers un document Microsoft Word qui se trouve dans un sous-dossier et placer l’icône de raccourci sur le bureau. L’utilisateur peut ensuite ouvrir le document en double-cliquant sur l’icône de raccourci. Si le document est déplacé ou renommé après la création du raccourci, le système tente de mettre à jour le raccourci la prochaine fois que l’utilisateur le sélectionnera.

Les applications peuvent également créer et utiliser des liens et des raccourcis Shell. Par exemple, une application de traitement de texte peut créer un lien Shell pour implémenter une liste des derniers documents utilisés. Une application crée un lien Shell à l’aide de l’interface IShellLink pour créer un objet de lien Shell. L’application utilise l’interface IPersistFile ou IPersistStream pour stocker l’objet dans un fichier ou un flux.

Notes

Vous ne pouvez pas utiliser IShellLink pour créer un lien vers une URL.

 

Cette vue d’ensemble décrit l’interface IShellLink et explique comment l’utiliser pour créer et résoudre des liens Shell à partir d’une application Microsoft Win32. Étant donné que la conception des liens shell est basée sur le modèle COM (Component Object Model) OLE, vous devez vous familiariser avec les concepts de base de la programmation COM et OLE avant de lire cette vue d’ensemble.

Si un utilisateur crée un raccourci vers un objet et que le nom ou l’emplacement de l’objet est modifié ultérieurement, le système prend automatiquement des mesures pour mettre à jour ou résoudre le raccourci la prochaine fois que l’utilisateur le sélectionne. Toutefois, si une application crée un lien Shell et le stocke dans un flux, le système ne tente pas automatiquement de résoudre le lien. L’application doit résoudre le lien en appelant la méthode IShellLink::Resolve .

Lorsqu’un lien Shell est créé, le système enregistre des informations sur le lien. Lors de la résolution d’un lien (automatiquement ou avec un appel IShellLink::Resolve ), le système récupère d’abord le chemin d’accès associé au lien Shell à l’aide d’un pointeur vers la liste d’identificateurs du lien Shell. Pour plus d’informations sur la liste des identificateurs, consultez Identificateurs d’éléments et Listes d’identificateurs. Le système recherche l’objet associé dans ce chemin et, s’il trouve l’objet, résout le lien. Si le système ne trouve pas l’objet, il appelle le service DLT (Distributed Link Tracking and Object Identifiers ) pour localiser l’objet. Si le service DLT n’est pas disponible ou ne trouve pas l’objet, le système recherche dans le même répertoire un objet avec la même heure de création de fichier et les mêmes attributs, mais avec un nom différent. Ce type de recherche résout un lien vers un objet qui a été renommé.

Si le système ne trouve toujours pas l’objet, il recherche les répertoires, le bureau et les volumes locaux, en recherchant de manière récursive dans l’arborescence de répertoires un objet portant le même nom ou le même temps de création. Si le système ne trouve toujours pas de correspondance, il affiche une boîte de dialogue invitant l’utilisateur à entrer un emplacement. Une application peut supprimer la boîte de dialogue en spécifiant la valeur SLR_NO_UI dans un appel à IShellLink::Resolve.

Initialisation de la bibliothèque d’objets de composants

Pour qu’une application puisse créer et résoudre des raccourcis, elle doit initialiser la bibliothèque d’objets de composant en appelant la fonction CoInitialize . Chaque appel à CoInitialize nécessite un appel correspondant à la fonction CoUninitialize , qu’une application doit appeler lorsqu’elle se termine. L’appel à CoUninitialize garantit que l’application ne s’arrête pas tant qu’elle n’a pas reçu tous ses messages en attente.

noms de Location-Independent

Le système fournit des noms indépendants de l’emplacement pour les liens De l’interpréteur de commandes vers des objets stockés dans des dossiers partagés. Si l’objet est stocké localement, le système fournit le chemin d’accès local et le nom de fichier de l’objet. Si l’objet est stocké à distance, le système fournit un nom de ressource réseau UNC (Universal Naming Convention) pour l’objet. Étant donné que le système fournit des noms indépendants de l’emplacement, un lien Shell peut servir de nom universel pour un fichier qui peut être transféré vers d’autres ordinateurs.

Lorsque l’utilisateur crée un raccourci vers un objet en choisissant la commande Créer un raccourci dans le menu contextuel de l’objet, Windows stocke les informations dont il a besoin pour accéder à l’objet dans un fichier de liaison, un fichier binaire qui a l’extension de nom de fichier .lnk. Un fichier de liens contient les informations suivantes :

  • Emplacement (chemin) de l’objet référencé par le raccourci (appelé objet correspondant).
  • Répertoire de travail de l’objet correspondant.
  • Liste d’arguments que le système transmet à l’objet correspondant lorsque la méthode IContextMenu::InvokeCommand est activée pour le raccourci.
  • Commande show utilisée pour définir l’état d’affichage initial de l’objet correspondant. Il s’agit de l’une des valeurs SW_ décrites dans ShowWindow.
  • Emplacement (chemin et index) de l’icône du raccourci.
  • Chaîne de description du raccourci.
  • Raccourci clavier du raccourci.

Lorsqu’un fichier de lien est supprimé, l’objet correspondant n’est pas affecté.

Si vous créez un raccourci vers un autre raccourci, le système copie simplement le fichier de liaison au lieu de créer un fichier de lien. Dans ce cas, les raccourcis ne seront pas indépendants les uns des autres.

Une application peut inscrire une extension de nom de fichier en tant que type de fichier de raccourci. Si un fichier a une extension de nom de fichier qui a été inscrite en tant que type de fichier de raccourci, le système ajoute automatiquement l’icône de superposition de lien définie par le système (une petite flèche) à l’icône du fichier. Pour inscrire une extension de nom de fichier en tant que type de fichier de raccourci, vous devez ajouter la valeur IsShortcut à la description du Registre de l’extension de nom de fichier, comme illustré dans l’exemple ci-dessous. Notez que l’interpréteur de commandes doit être redémarré pour que l’icône de superposition prenne effet. IsShortcut n’a aucune valeur de données.

HKEY_CLASSES_ROOT
   .xyz
      (Default) = XYZApp
   XYZApp
      IsShortcut

Noms de raccourcis

Le nom du raccourci, qui est une chaîne qui apparaît sous l’icône de lien Shell, est en fait le nom de fichier du raccourci lui-même. L’utilisateur peut modifier la chaîne de description en la sélectionnant et en entrant une nouvelle chaîne.

Emplacement des raccourcis dans l’espace de noms

Un raccourci peut exister sur le bureau ou n’importe où dans l’espace de noms de l’interpréteur de commandes. De même, l’objet associé au raccourci peut également exister n’importe où dans l’espace de noms de l’interpréteur de commandes. Une application peut utiliser la méthode IShellLink::SetPath pour définir le chemin d’accès et le nom de fichier de l’objet associé, et la méthode IShellLink::GetPath pour récupérer le chemin d’accès et le nom de fichier actuels de l’objet.

Répertoire de travail contextuel

Le répertoire de travail est le répertoire dans lequel l’objet correspondant d’un raccourci charge ou stocke des fichiers lorsque l’utilisateur n’identifie pas un répertoire spécifique. Un fichier de liaison contient le nom du répertoire de travail de l’objet correspondant. Une application peut définir le nom du répertoire de travail de l’objet correspondant à l’aide de la méthode IShellLink::SetWorkingDirectory et peut récupérer le nom du répertoire de travail actuel pour l’objet correspondant à l’aide de la méthode IShellLink::GetWorkingDirectory .

Arguments de ligne de commande de raccourci

Un fichier de lien contient des arguments de ligne de commande que l’interpréteur de commandes transmet à l’objet correspondant lorsque l’utilisateur sélectionne le lien. Une application peut définir les arguments de ligne de commande d’un raccourci à l’aide de la méthode IShellLink::SetArguments . Il est utile de définir des arguments de ligne de commande lorsque l’application correspondante, telle qu’un éditeur de liens ou un compilateur, prend des indicateurs spéciaux comme arguments. Une application peut récupérer les arguments de ligne de commande à partir d’un raccourci à l’aide de la méthode IShellLink::GetArguments .

Commandes d’affichage de raccourci

Lorsque l’utilisateur double-clique sur un raccourci, le système démarre l’application associée à l’objet correspondant et définit l’état d’affichage initial de l’application en fonction de la commande show spécifiée par le raccourci. La commande show peut être l’une des valeurs SW_ incluses dans la description de la fonction ShowWindow . Une application peut définir la commande show pour un raccourci à l’aide de la méthode IShellLink::SetShowCmd et peut récupérer la commande show actuelle à l’aide de la méthode IShellLink::GetShowCmd .

Icônes de raccourci

Comme d’autres objets Shell, un raccourci comporte une icône. L’utilisateur accède à l’objet associé à un raccourci en double-cliquant sur l’icône du raccourci. Lorsque le système crée une icône pour un raccourci, il utilise l’image bitmap de l’objet correspondant et ajoute l’icône de superposition de lien définie par le système (une petite flèche) dans le coin inférieur gauche. Une application peut définir l’emplacement (chemin et index) d’une icône de raccourci à l’aide de la méthode IShellLink::SetIconLocation . Une application peut récupérer cet emplacement à l’aide de la méthode IShellLink::GetIconLocation .

Descriptions des raccourcis

Les raccourcis ont des descriptions, mais l’utilisateur ne les voit jamais. Une application peut utiliser une description pour stocker des informations de texte. Les descriptions sont définies à l’aide de la méthode IShellLink::SetDescription et récupérées à l’aide de la méthode IShellLink::GetDescription .

Raccourcis clavier

Un objet de raccourci peut être associé à un raccourci clavier. Les raccourcis clavier permettent à un utilisateur d’appuyer sur une combinaison de touches pour activer un raccourci. Une application peut définir le raccourci clavier d’un raccourci à l’aide de la méthode IShellLink::SetHotkey et peut récupérer le raccourci clavier actuel à l’aide de la méthode IShellLink::GetHotkey .

Identificateurs d’élément et listes d’identificateurs

L’interpréteur de commandes utilise des identificateurs d’objet dans l’espace de noms de l’interpréteur de commandes. Tous les objets visibles dans l’interpréteur de commandes (fichiers, répertoires, serveurs, groupes de travail, etc.) ont des identificateurs uniques parmi les objets de leur dossier parent. Ces identificateurs sont appelés identificateurs d’élément et ont le type de données SHITEMID tel que défini dans le fichier d’en-tête Shtypes.h. Un identificateur d’élément est un flux d’octets de longueur variable qui contient des informations qui identifient un objet dans un dossier. Seul le créateur d’un identificateur d’élément connaît le contenu et le format de l’identificateur. La seule partie d’un identificateur d’élément que l’interpréteur de commandes utilise est les deux premiers octets, qui spécifient la taille de l’identificateur.

Chaque dossier parent a son propre identificateur d’élément qui l’identifie dans son propre dossier parent. Ainsi, tout objet Shell peut être identifié de manière unique par une liste d’identificateurs d’élément. Un dossier parent conserve une liste d’identificateurs pour les éléments qu’il contient. La liste a le type de données ITEMIDLIST . Les listes d’identificateurs d’élément sont allouées par l’interpréteur de commandes et peuvent être passées entre les interfaces Shell, telles que IShellFolder. Il est important de se rappeler que chaque identificateur d’une liste d’identificateurs d’élément n’est significatif que dans le contexte de son dossier parent.

Une application peut définir la liste d’identificateurs d’élément d’un raccourci à l’aide de la méthode IShellLink::SetIDList . Cette méthode est utile lors de la définition d’un raccourci vers un objet qui n’est pas un fichier, tel qu’une imprimante ou un lecteur de disque. Une application peut récupérer la liste d’identificateurs d’élément d’un raccourci à l’aide de la méthode IShellLink::GetIDList .

Cette section contient des exemples qui montrent comment créer et résoudre des raccourcis à partir d’une application Win32. Cette section suppose que vous êtes familiarisé avec la programmation Win32, C++ et OLE COM.

Création d’un raccourci et d’un raccourci de dossier vers un fichier

L’exemple de fonction CreateLink dans l’exemple suivant crée un raccourci. Les paramètres incluent un pointeur vers le nom du fichier à lier, un pointeur vers le nom du raccourci que vous créez et un pointeur vers la description du lien. La description se compose de la chaîne « Raccourci vers le nom de fichier », où nom de fichier est le nom du fichier auquel établir un lien.

Pour créer un raccourci de dossier à l’aide de l’exemple de fonction CreateLink, appelez CoCreateInstance à l’aide de CLSID_FolderShortcut, au lieu de CLSID_ShellLink (CLSID_FolderShortcut prend en charge IShellLink). Tout le code reste le même.

Étant donné que CreateLink appelle la fonction CoCreateInstance , il est supposé que la fonction CoInitialize a déjà été appelée. CreateLink utilise l’interface IPersistFile pour enregistrer le raccourci et l’interface IShellLink pour stocker le nom et la description du fichier.

// 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; 

Résolution d’un raccourci

Une application peut avoir besoin d’accéder à un raccourci créé précédemment et de le manipuler. Cette opération est appelée résolution du raccourci.

La fonction ResolveIt définie par l’application dans l’exemple suivant résout un raccourci. Ses paramètres incluent un handle de fenêtre, un pointeur vers le chemin du raccourci et l’adresse d’une mémoire tampon qui reçoit le nouveau chemin d’accès à l’objet. Le handle de fenêtre identifie la fenêtre parente pour toutes les boîtes de message que l’interpréteur de commandes peut avoir à afficher. Par exemple, l’interpréteur de commandes peut afficher une boîte de message si le lien se trouve sur un média non partagé, si des problèmes réseau se produisent, si l’utilisateur doit insérer une disquette, etc.

La fonction ResolveIt appelle la fonction CoCreateInstance et suppose que la fonction CoInitialize a déjà été appelée. Notez que ResolveIt doit utiliser l’interface IPersistFile pour stocker les informations de lien. IPersistFile est implémenté par l’objet IShellLink . Les informations de lien doivent être chargées avant que les informations de chemin d’accès ne soient récupérées, comme indiqué plus loin dans l’exemple. L’échec du chargement des informations de lien entraîne l’échec des appels aux fonctions membres IShellLink::GetPath et IShellLink::GetDescription .

// 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; 
}

Création d’un raccourci vers un objet Nonfile

La création d’un raccourci vers un objet sans fichier, tel qu’une imprimante, est similaire à la création d’un raccourci vers un fichier, à ceci près que, au lieu de définir le chemin d’accès au fichier, vous devez définir la liste d’identificateurs sur l’imprimante. Pour définir la liste d’identificateurs, appelez la méthode IShellLink::SetIDList en spécifiant l’adresse d’une liste d’identificateurs.

Chaque objet dans l’espace de noms de l’interpréteur de commandes a un identificateur d’élément. L’interpréteur de commandes concatène souvent les identificateurs d’élément dans des listes terminées par un caractère Null comprenant n’importe quel nombre d’identificateurs d’élément. Pour plus d’informations sur les identificateurs d’élément, consultez Identificateurs d’élément et listes d’identificateurs.

En général, si vous devez définir un raccourci vers un élément qui n’a pas de nom de fichier, tel qu’une imprimante, vous disposez déjà d’un pointeur vers l’interface IShellFolder de l’objet. IShellFolder est utilisé pour créer des extensions d’espace de noms.

Une fois que vous disposez de l’identificateur de classe pour IShellFolder, vous pouvez appeler la fonction CoCreateInstance pour récupérer l’adresse de l’interface. Vous pouvez ensuite appeler l’interface pour énumérer les objets dans le dossier et récupérer l’adresse de l’identificateur d’élément pour l’objet que vous recherchez. Enfin, vous pouvez utiliser l’adresse dans un appel à la fonction membre IShellLink::SetIDList pour créer un raccourci vers l’objet.