共用方式為


常見資源管理器概念

Shell 命名空間 將Shell所管理的文件系統和其他物件組織成單一樹狀結構階層。 從概念上講,它是文件系統的更大且更具包容性的版本。

介紹

Shell的主要責任之一是管理和提供組成系統的各種物件存取權。 這些物件中最大量且最熟悉的是位於電腦磁碟驅動器上的資料夾和檔案。 不過,Shell 也會管理一些非文件系統,或 虛擬 物件。 一些範例包括:

  • 網路印表機
  • 其他網路電腦
  • 控制面板應用程式
  • 回收站

有些虛擬物件完全不涉及實體記憶體。 例如,印表機物件包含網路印表機的連結集合。 其他虛擬物件,例如回收站,可能包含儲存在磁碟驅動器上的數據,但必須以不同於一般檔案的方式處理。 例如,虛擬物件可用來代表儲存在資料庫中的數據。 就命名空間而言,資料庫中的各種專案可能會以個別物件的形式出現在Windows 檔案總管中,即使它們全都儲存在單一磁碟檔案中也一樣。

虛擬物件甚至可能位於遠端電腦上。 例如,為了方便漫遊,使用者的檔檔可能會儲存在伺服器上。 若要讓使用者從多部桌面計算機存取其檔案,他們目前使用的桌面電腦上的 [我的檔] 資料夾會指向伺服器,而不是桌面電腦的硬碟。 其路徑會包含對應的網路磁碟機或 UNC 路徑名稱。

如同檔案系統,命名空間包含兩種基本類型的物件:資料夾和檔案。 資料夾物件是樹狀結構 節點;它們是檔案物件和其他資料夾的容器。 檔案物件是樹狀結構的 樹葉;它們可以是一般磁碟檔案或虛擬物件,例如印表機連結。 不屬於檔案系統的資料夾有時稱為 虛擬資料夾

和文件系統資料夾一樣,虛擬資料夾的集合通常會因系統而異。 虛擬資料夾有三個類別:

  • 所有系統上找到的標準虛擬資料夾,例如回收站。
  • 具有標準名稱和功能的選擇性虛擬資料夾,但可能不存在於所有系統上。
  • 使用者所安裝的非標準資料夾。

不同於檔案系統資料夾,用戶無法自行建立新的虛擬資料夾。 他們只能安裝非Microsoft開發人員所建立的。 因此,虛擬資料夾的數目通常比文件系統資料夾數目少得多。 如需如何實作虛擬資料夾的討論,請參閱 命名空間延伸模組

您可以在 Windows 檔案總管的總管列中看到命名空間結構的可視化表示。 例如,下列 Windows 檔案總管的螢幕快照顯示相對簡單的命名空間。

顯示殼層命名空間檢視的螢幕快照

命名空間階層的最終根目錄是桌面。 根目錄正下方有數個虛擬資料夾,例如「我的計算機」和「回收站」。

可以看到各種磁碟驅動器的檔案系統是較大命名空間階層的子集。 這些檔案系統的根目錄是 [我的計算機] 資料夾的子資料夾。 我的電腦也包含任何連接的網路磁碟機的根目錄。 樹狀結構中的其他節點,例如[我的檔] 是虛擬資料夾。

識別命名空間物件

您必須先有識別它的方式,才能使用命名空間物件。 檔案系統中的物件可能會有名稱,例如 MyFile.htm。 因為系統中可能有其他具有該名稱的檔案,因此唯一識別檔案或資料夾需要完整路徑,例如 「C:\MyDocs\MyFile.htm」。 這個路徑基本上是文件系統根目錄中所有資料夾的已排序列表 C:\,結尾為檔案。

在命名空間的內容中,路徑仍然相當適合用來識別位於命名空間之文件系統部分的物件。 不過,它們無法用於虛擬物件。 相反地,Shell 會提供可搭配任何命名空間物件使用的替代識別方法。

項目標識碼

在資料夾内,每個物件都有 項目識別碼,它功能上等同於檔案或資料夾的名稱。 專案識別碼實際上是 SHITEMID 結構:

typedef struct _SHITEMID { 
    USHORT cb; 
    BYTE   abID[1]; 
} SHITEMID, * LPSHITEMID;

abID 成員是對象的標識碼。 未定義 abID 的長度,而且其值是由包含 對象的資料夾所決定。 因為資料夾指派 abID 值的方式沒有標準定義,所以它們只會對相關聯的資料夾物件有意義。 應用程式應該只將它們視為識別特定資料夾中物件的令牌。 由於 abID 長度會有所不同,cb 成員會以位元組為單位來保存 SHITEMID 結構的大小。

由於專案標識碼不適用於顯示用途,所以包含對象的資料夾通常會將顯示名稱指派給它。 這是 Windows 檔案總管顯示資料夾內容時所使用的名稱。 如需了解如何處理顯示名稱的更多資訊,請參閱 從資料夾取得資訊

項目標識碼清單

項目標識碼本身很少使用。 一般而言,它是專案標識符清單的一部分,其用途與文件系統路徑相同。 不過,項目 ID 清單不是用於路徑的字串,而是 ITEMIDLIST 結構。 此結構是一個或多個項目 ID 的排序序列,以兩位元組 NULL終止。 項目 ID 清單中的每個項目 ID 都會對應至命名空間物件。 其順序會定義命名空間中的路徑,就像檔系統路徑一樣。

下圖顯示對應至 C:\MyDocs\MyFile.htm之 ITEMIDLIST 結構的圖解表示法。 每個項目識別碼的顯示名稱會顯示在上面。 abID 成員的不同寬度是任意的;它們說明這個成員的大小可能會有所不同的事實。

pidl 示意圖

PIDLs

針對 Shell API,命名空間物件通常是透過其 ITEMIDLIST 結構的指標或專案標識符清單 (PIDL) 的指標來識別。 為了方便起見,在這份文件中,PIDL 一般指的是結構本身,而不是指向它的指標。

上圖所示的 PIDL 稱為 完整的,又稱為 絕對的PIDL。 完整的 PIDL 會從桌面開始,並包含路徑中所有中繼資料夾的專案識別碼。 它會以物件的項目識別碼結尾,後面接著終止的雙位元組 NULL。 完整的 PIDL 類似於完全限定路徑,並唯一識別 Shell 命名空間中的物件。

很少使用完整的 PIDL。 許多函式和方法需要 相對 PIDL。 相對 PIDL 的根目錄是資料夾,而不是桌面。 如同相對路徑,組成 結構的專案標識碼系列會定義兩個對象之間命名空間中的路徑。 雖然它們不會唯一識別物件,但它們通常小於完整的 PIDL,而且足以用於許多用途。

最常使用的相對 PIDLs 單一層級 PIDL是相對於物件的父資料夾。 它們只包含物件的項目 ID 和終止符 NULL。 多重層級的 PIDL 也用於許多用途。 它們包含兩個或多個項目標識碼,通常會透過一或多個子資料夾,定義從父資料夾到對象的路徑。 請注意,單一層級 PIDL 仍然可以是完整的 PIDL。 尤其是,桌面物件是桌面的子物件,因此其完整 PIDL 只包含一個項目識別碼。

取得資料夾標識碼中所述,Shell API 提供數種方式來擷取物件的 PIDL。 擁有它之後,您通常會在呼叫其他Shell API 函式和方法時使用它來識別物件。 在此內容中,PIDL 的內部內容不透明且無關緊要。 基於此討論的目的,請將 PIDL 視為代表特定命名空間物件的令牌,並著重於如何將它們用於一般工作。

分配 PIDL

雖然 PIDL 與路徑有一些相似之處,但使用它們需要稍微不同的方法。 主要差異在於如何為其配置和解除分配記憶體。

如同為路徑配置的字串,必須為 PIDL 配置記憶體。 如果應用程式建立 PIDL,它必須配置足夠的記憶體給 ITEMIDLIST 結構。 針對這裡討論的大部分案例,Shell 會建立 PIDL 並處理記憶體配置。 不論是什麼配置了 PIDL,應用程式通常都負責在不再需要 PIDL 時將其解除分配。

使用 CoTaskMemAlloc 函式來配置 PIDL,並使用 CoTaskMemFree 函式來解除分配。