共用方式為


Shell 命名空間簡介

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 檔案總管在顯示資料夾內容時所使用的名稱。 如需如何處理顯示名稱的詳細資訊,請參閱 從資料夾取得資訊

專案識別碼清單

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

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

pidl 的圖解

PIDL

針對殼層 API,命名空間物件通常是透過 其 ITEMIDLIST 結構的指標來識別,或指向專案識別碼清單的指標, (PIDL) 。 為了方便起見,PIDL 一詞通常會參考這份檔中的結構本身,而不是它的指標。

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

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

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

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

配置 PIDL

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

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

使用 CoTaskMemAlloc 函式來配置 PIDL,而 CoTaskMemFree 函式則會解除配置。