셸 링크

Shell 링크는 셸 네임스페이스의 다른 개체에 액세스하는 데 사용되는 정보, 즉 Windows Explorer 통해 표시되는 모든 개체를 포함하는 데이터 개체입니다. 셸 링크를 통해 액세스할 수 있는 개체 유형에는 파일, 폴더, 디스크 드라이브 및 프린터가 포함됩니다. 셸 링크를 사용하면 사용자 또는 애플리케이션이 네임스페이스의 어디에서나 개체에 액세스할 수 있습니다. 사용자 또는 애플리케이션은 개체의 현재 이름과 위치를 알 필요가 없습니다.

사용자는 개체의 바로 가기 메뉴에서 바로 가기 만들기 명령을 선택하여 셸 링크를 만듭니다. 시스템은 아이콘의 왼쪽 아래 모서리에 나타나는 작은 화살표(시스템 정의 링크 오버레이 아이콘이라고 함)와 개체의 아이콘을 결합하여 셸 링크에 대한 아이콘을 자동으로 만듭니다. 아이콘이 있는 셸 링크를 바로 가기라고 합니다. 그러나 셸 링크와 바로 가기라는 용어는 종종 서로 바꿔서 사용됩니다. 일반적으로 사용자는 하위 폴더 또는 다른 컴퓨터의 공유 폴더에 저장된 개체에 빠르게 액세스할 수 있는 바로 가기를 만듭니다. 예를 들어 사용자는 하위 폴더에 있는 Microsoft Word 문서에 대한 바로 가기를 만들고 바탕 화면에 바로 가기 아이콘을 배치할 수 있습니다. 그러면 사용자가 바로 가기 아이콘을 두 번 클릭하여 문서를 열 수 있습니다. 바로 가기를 만든 후 문서가 이동되거나 이름이 바뀐 경우 시스템은 다음에 사용자가 바로 가기를 선택할 때 바로 가기를 업데이트하려고 시도합니다.

애플리케이션은 셸 링크 및 바로 가기를 만들고 사용할 수도 있습니다. 예를 들어 워드 프로세싱 애플리케이션은 셸 링크를 만들어 가장 최근에 사용한 문서 목록을 구현할 수 있습니다. 애플리케이션은 IShellLink 인터페이스를 사용하여 Shell 링크 개체를 만들어 Shell 링크를 만듭니다. 애플리케이션은 IPersistFile 또는 IPersistStream 인터페이스를 사용하여 개체를 파일 또는 스트림에 저장합니다.

참고

IShellLink를 사용하여 URL에 대한 링크를 만들 수 없습니다.

 

이 개요에서는 IShellLink 인터페이스를 설명하고 이를 사용하여 Microsoft Win32 기반 애플리케이션 내에서 Shell 링크를 만들고 resolve 방법을 설명합니다. 셸 링크 디자인은 OLE COM(구성 요소 개체 모델)을 기반으로 하므로 이 개요를 읽기 전에 COM 및 OLE 프로그래밍의 기본 개념을 잘 알고 있어야 합니다.

사용자가 개체에 대한 바로 가기를 만들고 개체의 이름 또는 위치가 나중에 변경되면 시스템은 다음에 사용자가 바로 가기를 선택할 때 자동으로 업데이트 또는 resolve 단계를 수행합니다. 그러나 애플리케이션이 셸 링크를 만들어 스트림에 저장하는 경우 시스템은 자동으로 링크를 resolve 시도하지 않습니다. 애플리케이션은 IShellLink::Resolve 메서드를 호출하여 링크를 resolve 합니다.

Shell 링크를 만들면 시스템에서 링크에 대한 정보를 저장합니다. 자동으로 또는 IShellLink::Resolve 호출을 사용하여 링크를 확인할 때 시스템은 먼저 셸 링크의 식별자 목록에 대한 포인터를 사용하여 셸 링크와 연결된 경로를 검색합니다. 식별자 목록에 대한 자세한 내용은 항목 식별자 및 식별자 목록을 참조하세요. 시스템은 해당 경로에서 연결된 개체를 검색하고 개체를 찾으면 링크를 확인합니다. 시스템에서 개체를 찾을 수 없는 경우 DLT(Distributed Link Tracking) 및 DLT(개체 식별자 ) 서비스를 호출하여 개체를 찾습니다. DLT 서비스를 사용할 수 없거나 개체를 찾을 수 없는 경우 시스템은 파일 생성 시간과 특성이 동일하지만 이름이 다른 개체에 대해 동일한 디렉터리를 찾습니다. 이 유형의 검색은 이름이 변경된 개체에 대한 링크를 확인합니다.

시스템에서 여전히 개체를 찾을 수 없는 경우 디렉터리, 데스크톱 및 로컬 볼륨을 검색하여 디렉터리 트리에서 동일한 이름 또는 생성 시간을 가진 개체를 재귀적으로 찾습니다. 시스템에서 여전히 일치하는 항목을 찾지 못하면 사용자에게 위치를 묻는 대화 상자가 표시됩니다. 애플리케이션은 IShellLink::Resolve 호출에서 SLR_NO_UI 값을 지정하여 대화 상자를 표시하지 않을 수 있습니다.

구성 요소 개체 라이브러리 초기화

애플리케이션이 바로 가기를 만들고 resolve 전에 CoInitialize 함수를 호출하여 구성 요소 개체 라이브러리를 초기화해야 합니다. CoInitialize를 호출할 때마다 애플리케이션이 종료할 때 호출해야 하는 CoUninitialize 함수에 대한 해당 호출이 필요합니다. CoUninitialize를 호출하면 애플리케이션이 보류 중인 메시지를 모두 받을 때까지 종료되지 않습니다.

Location-Independent 이름

시스템은 공유 폴더에 저장된 개체에 대한 Shell 링크에 대한 위치 독립적 이름을 제공합니다. 개체가 로컬로 저장된 경우 시스템은 개체의 로컬 경로와 파일 이름을 제공합니다. 개체가 원격으로 저장되면 시스템에서 개체에 대한 UNC(범용 명명 규칙) 네트워크 리소스 이름을 제공합니다. 시스템에서 위치 독립적 이름을 제공하기 때문에 셸 링크는 다른 컴퓨터로 전송할 수 있는 파일의 범용 이름으로 사용될 수 있습니다.

사용자가 개체의 바로 가기 메뉴에서 바로 가기 만들기 명령을 선택하여 개체에 대한 바로 가기를 만들 때 Windows는 .lnk 파일 이름 확장명을 가진 이진 파일인 링크 파일에 개체에 액세스하는 데 필요한 정보를 저장합니다. 링크 파일에는 다음 정보가 포함됩니다.

  • 바로 가기에서 참조하는 개체의 위치(경로)입니다(해당 개체라고 함).
  • 해당 개체의 작업 디렉터리입니다.
  • 바로 가기에 대해 IContextMenu::InvokeCommand 메서드가 활성화될 때 시스템에서 해당 개체에 전달하는 인수 목록입니다.
  • 해당 개체의 초기 표시 상태를 설정하는 데 사용되는 show 명령입니다. 이는 ShowWindow에 설명된 SW_ 값 중 하나입니다.
  • 바로 가기 아이콘의 위치(경로 및 인덱스)입니다.
  • 바로 가기의 설명 문자열입니다.
  • 바로 가기 키의 바로 가기 키입니다.

링크 파일이 삭제되면 해당 개체는 영향을 받지 않습니다.

다른 바로 가기에 대한 바로 가기를 만드는 경우 시스템은 새 링크 파일을 만드는 대신 링크 파일을 복사합니다. 이 경우 바로 가기는 서로 독립적이지 않습니다.

애플리케이션은 파일 이름 확장명을 바로 가기 파일 형식으로 등록할 수 있습니다. 파일에 바로 가기 파일 형식으로 등록된 파일 이름 확장명인 경우 시스템은 자동으로 시스템 정의 링크 오버레이 아이콘(작은 화살표)을 파일 아이콘에 추가합니다. 파일 이름 확장명을 바로 가기 파일 형식으로 등록하려면 아래 예제와 같이 파일 이름 확장명 레지스트리 설명에 IsShortcut 값을 추가해야 합니다. 오버레이 아이콘이 적용되려면 셸을 다시 시작해야 합니다. IsShortcut에는 데이터 값이 없습니다.

HKEY_CLASSES_ROOT
   .xyz
      (Default) = XYZApp
   XYZApp
      IsShortcut

바로 가기 이름

셸 링크 아이콘 아래에 표시되는 문자열인 바로 가기의 이름은 실제로 바로 가기 자체의 파일 이름입니다. 사용자는 설명 문자열을 선택하고 새 문자열을 입력하여 편집할 수 있습니다.

네임스페이스의 바로 가기 위치

바로 가기는 바탕 화면이나 셸 네임스페이스의 어디에나 있을 수 있습니다. 마찬가지로 바로 가기와 연결된 개체도 셸의 네임스페이스에 존재할 수 있습니다. 애플리케이션은 IShellLink::SetPath 메서드를 사용하여 연결된 개체의 경로와 파일 이름을 설정하고, IShellLink::GetPath 메서드를 사용하여 개체의 현재 경로와 파일 이름을 검색할 수 있습니다.

바로 가기 작업 디렉터리

작업 디렉터리 는 사용자가 특정 디렉터리를 식별하지 않을 때 바로 가기의 해당 개체가 파일을 로드하거나 저장하는 디렉터리입니다. 링크 파일에는 해당 개체의 작업 디렉터리 이름이 포함됩니다. 애플리케이션은 IShellLink::SetWorkingDirectory 메서드를 사용하여 해당 개체의 작업 디렉터리 이름을 설정할 수 있으며 IShellLink::GetWorkingDirectory 메서드를 사용하여 해당 개체의 현재 작업 디렉터리 이름을 검색할 수 있습니다.

바로 가기 명령줄 인수

링크 파일에는 사용자가 링크를 선택할 때 셸이 해당 개체에 전달하는 명령줄 인수가 포함되어 있습니다. 애플리케이션은 IShellLink::SetArguments 메서드를 사용하여 바로 가기에 대한 명령줄 인수를 설정할 수 있습니다. 링커 또는 컴파일러와 같은 해당 애플리케이션이 특수 플래그를 인수로 사용하는 경우 명령줄 인수를 설정하는 것이 유용합니다. 애플리케이션은 IShellLink::GetArguments 메서드를 사용하여 바로 가기에서 명령줄 인수를 검색할 수 있습니다.

바로 가기 표시 명령

사용자가 바로 가기를 두 번 클릭하면 시스템은 해당 개체와 연결된 애플리케이션을 시작하고 바로 가기로 지정된 show 명령에 따라 애플리케이션의 초기 표시 상태를 설정합니다. show 명령은 ShowWindow 함수 설명에 포함된 SW_ 값일 수 있습니다. 애플리케이션은 IShellLink::SetShowCmd 메서드를 사용하여 바로 가기에 대한 show 명령을 설정할 수 있으며 IShellLink::GetShowCmd 메서드를 사용하여 현재 show 명령을 검색할 수 있습니다.

바로 가기 아이콘

다른 Shell 개체와 마찬가지로 바로 가기에는 아이콘이 있습니다. 사용자는 바로 가기 아이콘을 두 번 클릭하여 바로 가기와 연결된 개체에 액세스합니다. 시스템에서 바로 가기 아이콘을 만들 때 해당 개체의 비트맵을 사용하고 시스템 정의 링크 오버레이 아이콘(작은 화살표)을 왼쪽 아래 모서리에 추가합니다. 애플리케이션은 IShellLink::SetIconLocation 메서드를 사용하여 바로 가기 아이콘의 위치(경로 및 인덱스)를 설정할 수 있습니다. 애플리케이션은 IShellLink::GetIconLocation 메서드를 사용하여 이 위치를 검색할 수 있습니다.

바로 가기 설명

바로 가기에는 설명이 있지만 사용자는 해당 설명을 볼 수 없습니다. 애플리케이션은 설명을 사용하여 텍스트 정보를 저장할 수 있습니다. 설명은 IShellLink::SetDescription 메서드를 사용하여 설정되고 IShellLink::GetDescription 메서드를 사용하여 검색됩니다.

바로 가기 키 바로 가기 키

바로 가기 개체에는 바로 가기 키가 연결되어 있을 수 있습니다. 바로 가기 키를 사용하면 키 조합을 눌러 바로 가기를 활성화할 수 있습니다. 애플리케이션은 IShellLink::SetHotkey 메서드를 사용하여 바로 가기 키의 바로 가기 키를 설정할 수 있으며 IShellLink::GetHotkey 메서드를 사용하여 현재 바로 가기 키를 검색할 수 있습니다.

항목 식별자 및 식별자 목록

Shell은 Shell의 네임스페이스 내에서 개체 식별자를 사용합니다. Shell에 표시되는 모든 개체(파일, 디렉터리, 서버, 작업 그룹 등)에는 부모 폴더 내의 개체 간에 고유한 식별자가 있습니다. 이러한 식별자는 항목 식별자라고 하며 Shtypes.h 헤더 파일에 정의된 대로 SHITEMID 데이터 형식을 갖습니다. 항목 식별자는 폴더 내의 개체를 식별하는 정보를 포함하는 가변 길이 바이트 스트림입니다. 항목 식별자의 작성자만 식별자의 콘텐츠와 형식을 알고 있습니다. 셸에서 사용하는 항목 식별자의 유일한 부분은 식별자의 크기를 지정하는 처음 두 바이트입니다.

각 부모 폴더에는 자체 부모 폴더 내에서 식별하는 고유한 항목 식별자가 있습니다. 따라서 모든 Shell 개체는 항목 식별자 목록으로 고유하게 식별할 수 있습니다. 부모 폴더는 포함된 항목의 식별자 목록을 유지합니다. 목록에 ITEMIDLIST 데이터 형식이 있습니다. 항목 식별자 목록은 셸에 의해 할당되며 IShellFolder와 같은 셸 인터페이스에 전달될 수 있습니다. 항목 식별자 목록의 각 식별자는 부모 폴더의 컨텍스트 내에서만 의미가 있음을 기억해야 합니다.

애플리케이션은 IShellLink::SetIDList 메서드를 사용하여 바로 가기의 항목 식별자 목록을 설정할 수 있습니다. 이 방법은 바로 가기를 프린터 또는 디스크 드라이브와 같이 파일이 아닌 개체로 설정할 때 유용합니다. 애플리케이션은 IShellLink::GetIDList 메서드를 사용하여 바로 가기의 항목 식별자 목록을 검색할 수 있습니다.

이 섹션에는 Win32 기반 애플리케이션 내에서 바로 가기를 만들고 resolve 방법을 보여 주는 예제가 포함되어 있습니다. 이 섹션에서는 Win32, C++및 OLE COM 프로그래밍에 익숙하다고 가정합니다.

파일에 대한 바로 가기 및 폴더 바로 가기 만들기

다음 예제의 CreateLink 샘플 함수는 바로 가기를 만듭니다. 매개 변수에는 연결할 파일 이름에 대한 포인터, 만들려는 바로 가기 이름에 대한 포인터 및 링크 설명에 대한 포인터가 포함됩니다. 설명은 " 파일 이름 바로 가기" 문자열로 구성됩니다. 여기서 파일 이름은 연결할 파일의 이름입니다.

CreateLink 샘플 함수를 사용하여 폴더 바로 가기를 만들려면 CLSID_ShellLink 대신 CLSID_FolderShortcut 사용하여 CoCreateInstance 를 호출합니다(CLSID_FolderShortcut IShellLink 지원). 다른 모든 코드는 동일하게 유지됩니다.

CreateLink는 CoCreateInstance 함수를 호출하므로 CoInitialize 함수가 이미 호출된 것으로 간주됩니다. CreateLink는 IPersistFile 인터페이스를 사용하여 바로 가기 및 IShellLink 인터페이스를 저장하여 파일 이름과 설명을 저장합니다.

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

바로 가기 해결

애플리케이션은 이전에 만든 바로 가기에 액세스하고 조작해야 할 수 있습니다. 이 작업을 바로 가기 확인이라고 합니다.

다음 예제의 애플리케이션 정의 ResolveIt 함수는 바로 가기를 확인합니다. 해당 매개 변수에는 창 핸들, 바로 가기 경로에 대한 포인터 및 개체에 대한 새 경로를 수신하는 버퍼의 주소가 포함됩니다. 창 핸들은 셸이 표시해야 할 수 있는 메시지 상자의 부모 창을 식별합니다. 예를 들어 링크가 공유되지 않은 미디어에 있는 경우, 네트워크 문제가 발생하는 경우, 플로피 디스크를 삽입해야 하는 경우 셸에서 메시지 상자를 표시할 수 있습니다.

ResolveIt 함수는 CoCreateInstance 함수를 호출하고 CoInitialize 함수가 이미 호출되었다고 가정합니다. ResolveIt는 IPersistFile 인터페이스를 사용하여 링크 정보를 저장해야 합니다. IPersistFileIShellLink 개체에 의해 구현됩니다. 경로 정보를 검색하기 전에 링크 정보를 로드해야 합니다. 이 정보는 예제의 뒷부분에 나와 있습니다. 링크 정보를 로드하지 못하면 IShellLink::GetPathIShellLink::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; 
}

비파일 개체에 대한 바로 가기 만들기

프린터와 같은 파일 없는 개체에 대한 바로 가기를 만드는 것은 파일 경로를 설정하는 대신 식별자 목록을 프린터로 설정해야 한다는 점을 제외하고 파일에 대한 바로 가기를 만드는 것과 비슷합니다. 식별자 목록을 설정하려면 식별자 목록의 주소를 지정하여 IShellLink::SetIDList 메서드를 호출합니다.

Shell의 네임스페이스 내의 각 개체에는 항목 식별자가 있습니다. 셸은 항목 식별자를 임의의 수의 항목 식별자로 구성된 null로 끝나는 목록에 연결하는 경우가 많습니다. 항목 식별자에 대한 자세한 내용은 항목 식별자 및 식별자 목록을 참조하세요.

일반적으로 프린터와 같이 파일 이름이 없는 항목으로 바로 가기를 설정해야 하는 경우 개체의 IShellFolder 인터페이스에 대한 포인터가 이미 있습니다. IShellFolder 는 네임스페이스 확장을 만드는 데 사용됩니다.

IShellFolder에 대한 클래스 식별자가 있으면 CoCreateInstance 함수를 호출하여 인터페이스의 주소를 검색할 수 있습니다. 그런 다음 인터페이스를 호출하여 폴더의 개체를 열거하고 검색할 개체의 항목 식별자 주소를 검색할 수 있습니다. 마지막으로 IShellLink::SetIDList 멤버 함수에 대한 호출에서 주소를 사용하여 개체에 대한 바로 가기를 만들 수 있습니다.