共用方式為


Shell 命名空間簡介

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

介紹

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

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

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

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

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

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

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

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

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

殼層命名空間的檢視

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

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

識別命名空間物件

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

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

項目標識碼

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

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

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

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

項目標識碼清單

項目標識碼本身很少使用。 一般而言,它是專案標識符清單的一部分,其用途與文件系統路徑相同。 不過,項目ID清單不是用於路徑的字元串,而是 ITEMIDLIST 結構。 此結構是由一個或多個專案標識碼組成的有序序列,並以兩位元組 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,單一層級的 PIDLs,是相對於物件父資料夾的。 它們只包含物件的項目識別碼和終止 NULL。 多重層級的 PIDL 也用於許多用途。 它們包含兩個或多個項目標識碼,通常會透過一或多個子資料夾,定義從父資料夾到對象的路徑。 請注意,單層級的 PIDL 仍然可以是完全合格的 PIDL。 特別是桌面物件是桌面的子項目,因此它們的完整 PIDL 只包含一個專案識別碼。

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

分配 PIDL

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

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

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