Collegamenti alla shell
Un collegamento shell è un oggetto dati che contiene informazioni usate per accedere a un altro oggetto nello spazio dei nomi della shell, ovvero qualsiasi oggetto visibile tramite Esplora risorse. I tipi di oggetti a cui è possibile accedere tramite i collegamenti shell includono file, cartelle, unità disco e stampanti. Un collegamento shell consente a un utente o a un'applicazione di accedere a un oggetto da qualsiasi posizione nello spazio dei nomi. L'utente o l'applicazione non deve conoscere il nome e la posizione correnti dell'oggetto.
Informazioni sui collegamenti della shell
L'utente crea un collegamento shell scegliendo il comando Crea collegamento dal menu di scelta rapida di un oggetto. Il sistema crea automaticamente un'icona per il collegamento shell combinando l'icona dell'oggetto con una piccola freccia (nota come icona di sovrapposizione del collegamento definita dal sistema) visualizzata nell'angolo inferiore sinistro dell'icona. Un collegamento shell con un'icona è detto collegamento; Tuttavia, i termini collegamento shell e collegamento vengono spesso usati in modo intercambiabile. In genere, l'utente crea collegamenti per ottenere accesso rapido agli oggetti archiviati in sottocartelle o in cartelle condivise in altri computer. Ad esempio, un utente può creare un collegamento a un documento di Microsoft Word che si trova in una sottocartella e posizionare l'icona di scelta rapida sul desktop. L'utente può quindi aprire il documento facendo doppio clic sull'icona di scelta rapida. Se il documento viene spostato o rinominato dopo la creazione del collegamento, il sistema tenterà di aggiornare il collegamento alla successiva selezione dell'utente.
Le applicazioni possono anche creare e usare collegamenti e collegamenti shell. Ad esempio, un'applicazione di elaborazione delle parole potrebbe creare un collegamento shell per implementare un elenco dei documenti usati più di recente. Un'applicazione crea un collegamento shell usando l'interfacciaIShellLinkper creare un oggetto collegamento shell. L'applicazione usa l'interfacciaIPersistFileo IPersistStream per archiviare l'oggetto in un file o in un flusso.
Nota
Non è possibile usare IShellLink per creare un collegamento a un URL.
Questa panoramica descrive l'interfaccia IShellLink e spiega come usarla per creare e risolvere i collegamenti shell dall'interno di un'applicazione basata su Microsoft Win32. Poiché la progettazione dei collegamenti shell è basata sul MODELLO COM (OLE Component Object Model), è necessario avere familiarità con i concetti di base della programmazione COM e OLE prima di leggere questa panoramica.
Risoluzione dei collegamenti
Se un utente crea un collegamento a un oggetto e il nome o la posizione dell'oggetto vengono modificati in un secondo momento, il sistema esegue automaticamente i passaggi per aggiornare o risolvere il collegamento alla successiva selezione da parte dell'utente. Tuttavia, se un'applicazione crea un collegamento shell e la archivia in un flusso, il sistema non tenta automaticamente di risolvere il collegamento. L'applicazione deve risolvere il collegamento chiamando il metodo IShellLink::Resolve.
Quando viene creato un collegamento shell, il sistema salva le informazioni sul collegamento. Quando si risolve un collegamento, automaticamente o con un chiamata IShellLink::Resolve, il sistema recupera prima il percorso associato al collegamento shell usando un puntatore all'elenco di identificatori del collegamento shell. Per altre informazioni sull'elenco di identificatori, vedere identificatori di elemento e elenchi di identificatori. Il sistema cerca l'oggetto associato in tale percorso e, se trova l'oggetto, risolve il collegamento. Se il sistema non riesce a trovare l'oggetto, chiama sul servizio Distributed Link Tracking and Object Identifiers (DLT) per individuare l'oggetto. Se il servizio DLT non è disponibile o non è in grado di trovare l'oggetto, il sistema cerca nella stessa directory un oggetto con lo stesso tempo e gli stessi attributi di creazione file, ma con un nome diverso. Questo tipo di ricerca risolve un collegamento a un oggetto rinominato.
Se il sistema non riesce ancora a trovare l'oggetto, cerca in modo ricorsivo le directory, il desktop e i volumi locali, anche se l'albero della directory cerca un oggetto con lo stesso nome o ora di creazione. Se il sistema non trova ancora una corrispondenza, viene visualizzata una finestra di dialogo che richiede all'utente una posizione. Un'applicazione può eliminare la finestra di dialogo specificando il valore SLR_NO_UI in una chiamata a IShellLink::Resolve.
Inizializzazione della libreria di oggetti componente
Prima che un'applicazione possa creare e risolvere i collegamenti, è necessario inizializzare la libreria di oggetti del componente chiamando la funzione CoInitialize. Ogni chiamata a CoInitialize richiede una chiamata corrispondente alla funzione CoUninitialize, che un'applicazione deve chiamare quando termina. La chiamata a CoUninitialize garantisce che l'applicazione non venga terminata fino a quando non ha ricevuto tutti i messaggi in sospeso.
nomi Location-Independent
Il sistema fornisce nomi indipendenti dalla posizione per i collegamenti shell a oggetti archiviati in cartelle condivise. Se l'oggetto viene archiviato localmente, il sistema fornisce il percorso locale e il nome file per l'oggetto. Se l'oggetto viene archiviato in modalità remota, il sistema fornisce un nome di risorsa di rete UNC (Universal Naming Convention) per l'oggetto. Poiché il sistema fornisce nomi indipendenti dalla posizione, un collegamento shell può fungere da nome universale per un file che può essere trasferito ad altri computer.
File di collegamento
Quando l'utente crea un collegamento a un oggetto scegliendo il comando Crea collegamento dal menu di scelta rapida dell'oggetto, Windows archivia le informazioni necessarie per accedere all'oggetto in un file di collegamento, ovvero un file binario con l'estensione del nome file .lnk. Un file di collegamento contiene le informazioni seguenti:
- Posizione (percorso) dell'oggetto a cui fa riferimento il collegamento (denominato oggetto corrispondente).
- Directory di lavoro dell'oggetto corrispondente.
- Elenco di argomenti passati dal sistema all'oggetto corrispondente quando il metodo IContextMenu::InvokeCommand viene attivato per il collegamento.
- Comando show utilizzato per impostare lo stato di visualizzazione iniziale dell'oggetto corrispondente. Si tratta di uno dei valori di SW_ descritti in ShowWindow.
- Posizione (percorso e indice) dell'icona del collegamento.
- Stringa di descrizione del collegamento.
- Scelta rapida da tastiera per il tasto di scelta rapida.
Quando un file di collegamento viene eliminato, l'oggetto corrispondente non è interessato.
Se si crea un collegamento a un altro collegamento, il sistema copia semplicemente il file di collegamento anziché creare un nuovo file di collegamento. In questo caso, i tasti di scelta rapida non saranno indipendenti l'uno dall'altro.
Un'applicazione può registrare un'estensione di file come tipo di file di collegamento. Se un file ha un'estensione di file registrata come tipo di file di collegamento, il sistema aggiunge automaticamente l'icona di sovrapposizione del collegamento definita dal sistema (una piccola freccia) all'icona del file. Per registrare un'estensione di file come tipo di file di collegamento, è necessario aggiungere il valore IsShortcut alla descrizione del Registro di sistema dell'estensione del nome file, come illustrato nell'esempio seguente. Si noti che shell deve essere riavviata per rendere effettiva l'icona di sovrapposizione. IsShortcut non ha alcun valore di dati.
HKEY_CLASSES_ROOT
.xyz
(Default) = XYZApp
XYZApp
IsShortcut
Nomi di collegamento
Il nome del collegamento, ovvero una stringa visualizzata sotto l'icona del collegamento shell, è in realtà il nome del file del collegamento stesso. L'utente può modificare la stringa di descrizione selezionandola e immettendo una nuova stringa.
Posizione dei collegamenti nello spazio dei nomi
Un collegamento può esistere sul desktop o in qualsiasi punto dello spazio dei nomi della shell. Analogamente, l'oggetto associato al collegamento può esistere anche in qualsiasi punto dello spazio dei nomi della shell. Un'applicazione può usare il metodo IShellLink::SetPath per impostare il percorso e il nome file per l'oggetto associato e il metodo IShellLink::GetPath per recuperare il percorso e il nome file correnti per l'oggetto.
Directory di lavoro collegamento
La directory di lavoro è la directory in cui l'oggetto corrispondente di un collegamento carica o archivia i file quando l'utente non identifica una directory specifica. Un file di collegamento contiene il nome della directory di lavoro per l'oggetto corrispondente. Un'applicazione può impostare il nome della directory di lavoro per l'oggetto corrispondente usando il metodo IShellLink::SetWorkingDirectory e può recuperare il nome della directory di lavoro corrente per l'oggetto corrispondente usando il metodo IShellLink::GetWorkingDirectory.
Argomenti della riga di comando collegamento
Un file di collegamento contiene argomenti della riga di comando che shell passa all'oggetto corrispondente quando l'utente seleziona il collegamento. Un'applicazione può impostare gli argomenti della riga di comando per un collegamento usando il metodo IShellLink::SetArguments. È utile impostare gli argomenti della riga di comando quando l'applicazione corrispondente, ad esempio un linker o un compilatore, accetta flag speciali come argomenti. Un'applicazione può recuperare gli argomenti della riga di comando da un collegamento usando il metodo IShellLink::GetArguments.
Collegamento mostra comandi
Quando l'utente fa doppio clic su un collegamento, il sistema avvia l'applicazione associata all'oggetto corrispondente e imposta lo stato di visualizzazione iniziale dell'applicazione in base al comando show specificato dal collegamento. Il comando show può essere uno dei valori SW_ inclusi nella descrizione della funzione ShowWindow. Un'applicazione può impostare il comando show per un collegamento usando il metodo IShellLink::SetShowCmd e può recuperare il comando show corrente usando il metodo IShellLink::GetShowCmd.
Icone di scelta rapida
Analogamente ad altri oggetti Shell, un collegamento ha un'icona. L'utente accede all'oggetto associato a un collegamento facendo doppio clic sull'icona del collegamento. Quando il sistema crea un'icona per un collegamento, usa la bitmap dell'oggetto corrispondente e aggiunge l'icona di sovrapposizione del collegamento definita dal sistema (una piccola freccia) all'angolo inferiore sinistro. Un'applicazione può impostare la posizione (percorso e indice) dell'icona di un collegamento usando il metodo IShellLink::SetIconLocation. Un'applicazione può recuperare questo percorso usando il metodo IShellLink::GetIconLocation.
Descrizioni dei tasti di scelta rapida
I collegamenti contengono descrizioni, ma l'utente non li vede mai. Un'applicazione può usare una descrizione per archiviare qualsiasi informazione di testo. Le descrizioni vengono impostate usando il metodoIShellLink::SetDescriptione recuperato usando il metodo IShellLink::GetDescription.
Tasti di scelta rapida
A un oggetto di scelta rapida può essere associato un tasto di scelta rapida. I tasti di scelta rapida consentono a un utente di premere una combinazione di tasti per attivare un tasto di scelta rapida. Un'applicazione può impostare il tasto di scelta rapida per un collegamento usando il metodo IShellLink::SetHotkey e può recuperare il tasto di scelta rapida corrente usando il metodo IShellLink::GetHotkey.
Identificatori di elemento ed elenchi di identificatori
Shell usa gli identificatori di oggetto all'interno dello spazio dei nomi della shell. Tutti gli oggetti visibili nella shell (file, directory, server, gruppi di lavoro e così via) hanno identificatori univoci tra gli oggetti all'interno della cartella padre. Questi identificatori sono denominati identificatori di elemento e hanno il SHITEMID tipo di dati come definito nel file di intestazione Shtypes.h. Un identificatore di elemento è un flusso di byte a lunghezza variabile che contiene informazioni che identificano un oggetto all'interno di una cartella. Solo l'autore di un identificatore di elemento conosce il contenuto e il formato dell'identificatore. L'unica parte di un identificatore di elemento utilizzato dalla shell è costituita dai primi due byte, che specificano le dimensioni dell'identificatore.
Ogni cartella padre ha un proprio identificatore di elemento che lo identifica all'interno della propria cartella padre. Pertanto, qualsiasi oggetto Shell può essere identificato in modo univoco da un elenco di identificatori di elemento. Una cartella padre mantiene un elenco di identificatori per gli elementi contenuti. L'elenco ha il tipo di datiITEMIDLIST. Gli elenchi di identificatori di elemento vengono allocati dalla shell e possono essere passati tra le interfacce shell, ad esempio IShellFolder. È importante ricordare che ogni identificatore in un elenco di identificatori di elemento è significativo solo nel contesto della cartella padre.
Un'applicazione può impostare l'elenco di identificatori di elemento di un collegamento usando il metodo IShellLink::SetIDList. Questo metodo è utile quando si imposta un collegamento a un oggetto che non è un file, ad esempio una stampante o un'unità disco. Un'applicazione può recuperare l'elenco di identificatori di elemento di un collegamento usando il metodo IShellLink::GetIDList.
Uso dei collegamenti shell
Questa sezione contiene esempi che illustrano come creare e risolvere i collegamenti dall'interno di un'applicazione basata su Win32. Questa sezione presuppone che tu abbia familiarità con la programmazione Win32, C++e OLE COM.
Creazione di un collegamento e di un collegamento a una cartella in un file
La funzione di esempio CreateLink nell'esempio seguente crea un collegamento. I parametri includono un puntatore al nome del file a cui collegarsi, un puntatore al nome del collegamento che si sta creando e un puntatore alla descrizione del collegamento. La descrizione è costituita dalla stringa "Shortcut to file name", dove nome file è il nome del file a cui collegarsi.
Per creare un collegamento a una cartella usando la funzione di esempio CreateLink, chiamare CoCreateInstance usando CLSID_FolderShortcut anziché CLSID_ShellLink (CLSID_FolderShortcut supporta IShellLink). Tutto l'altro codice rimane invariato.
Poiché CreateLink chiama la funzioneCoCreateInstance, si presuppone che la funzione CoInitialize sia già stata chiamata. CreateLink usa l'interfacciaIPersistFileper salvare il collegamento e l'interfaccia IShellLink per archiviare il nome e la descrizione del file.
// 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;
Risoluzione di un collegamento
Un'applicazione potrebbe dover accedere e modificare un collegamento creato in precedenza. Questa operazione viene definita risoluzione del collegamento.
La funzione ResolveIt definita dall'applicazione nell'esempio seguente risolve un collegamento. I parametri includono un handle di finestra, un puntatore al percorso del collegamento e l'indirizzo di un buffer che riceve il nuovo percorso dell'oggetto. L'handle di finestra identifica la finestra padre per le finestre di messaggio che potrebbe essere necessario visualizzare nella shell. Ad esempio, shell può visualizzare una finestra di messaggio se il collegamento è su supporti non condivisi, se si verificano problemi di rete, se l'utente deve inserire un disco floppy e così via.
La funzione ResolveIt chiama la funzioneCoCreateInstance e presuppone che la funzione CoInitialize sia già stata chiamata. Si noti che ResolveIt deve usare l'interfacciaIPersistFileper archiviare le informazioni sul collegamento. IPersistFile viene implementato dall'oggettoIShellLink. Le informazioni sul collegamento devono essere caricate prima che vengano recuperate le informazioni sul percorso, come illustrato più avanti nell'esempio. Il mancato caricamento delle informazioni sul collegamento causa l'esito negativo delle chiamate alle funzioni membro IShellLink::GetPath e 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;
}
Creazione di un collegamento a un oggetto nonfile
La creazione di un collegamento a un oggetto nonfile, ad esempio una stampante, è simile alla creazione di un collegamento a un file, ad eccezione del fatto che anziché impostare il percorso del file, è necessario impostare l'elenco di identificatori sulla stampante. Per impostare l'elenco di identificatori, chiamare il metodo IShellLink::SetIDList, specificando l'indirizzo di un elenco di identificatori.
Ogni oggetto all'interno dello spazio dei nomi della shell ha un identificatore di elemento. Shell spesso concatena gli identificatori di elemento in elenchi con terminazione Null costituiti da un numero qualsiasi di identificatori di elemento. Per altre informazioni sugli identificatori degli elementi, vedere identificatori di elemento e elenchi di identificatori.
In generale, se è necessario impostare un collegamento a un elemento che non ha un nome di file, ad esempio una stampante, si avrà già un puntatore all'interfaccia IShellFolder dell'oggetto. IShellFolder viene usato per creare estensioni dello spazio dei nomi.
Dopo aver ottenuto l'identificatore di classe per IShellFolder, è possibile chiamare la funzioneCoCreateInstance per recuperare l'indirizzo dell'interfaccia. È quindi possibile chiamare l'interfaccia per enumerare gli oggetti nella cartella e recuperare l'indirizzo dell'identificatore dell'elemento per l'oggetto cercato. Infine, è possibile usare l'indirizzo in una chiamata alla funzione membro IShellLink::SetIDList per creare un collegamento all'oggetto.