共用方式為


應用程式使用者模型識別碼 (AppUserModelIDs)

應用程式使用者模型標識碼 (AppUserModelIDs) 是由 Windows 7 和更新版本中的任務列廣泛使用,以將進程、檔案和視窗與特定應用程式產生關聯。 在某些情況下,就足以依賴系統指派給進程的內部AppUserModelID。 不過,擁有多個進程的應用程式或主進程中執行的應用程式可能需要明確識別自己,以便將其其他不同的視窗分組在單一任務欄按鈕下,並控制該應用程式的跳躍清單內容。

Application-Defined 和 System-Defined AppUserModelIDs

某些應用程式不會宣告明確的 AppUserModelID。 它們是選擇性的。 在此情況下,系統會使用一系列啟發學習法來指派內部AppUserModelID。 不過,避免這些計算有效能優點,而明確的AppUserModelID是保證確切用戶體驗的唯一方法。 因此,強烈建議設定明確的標識碼。 應用程式無法擷取系統指派的AppUserModelID。

如果應用程式使用明確的 AppUserModelID,它也必須將相同的 AppUserModelID 指派給所有執行中的視窗或進程、快捷方式和檔案關聯。 它也必須在透過 ICustomDestinationList自定義其跳躍清單時使用該 AppUserModelID,並在任何 呼叫 SHAddToRecentDocs時使用。

注意

如果應用程式沒有明確的 AppUserModelID,則必須從應用程式內呼叫 IApplicationDestinationsIApplicationDocumentListsICustomDestinationList 方法,以及 SHAddToRecentDocs。 如果從另一個進程呼叫這些方法,例如安裝程式或卸載程式,系統就無法產生正確的 AppUserModelID,而且這些呼叫不會有任何作用。

 

下列專案描述需要明確AppUserModelID的常見案例。 它們也會指出應該使用多個明確 AppUserModelID 的情況。

  • 具有多個模式且使用者顯示為個別應用程式的UI的單一可執行檔,應該將不同的AppUserModelID指派給每個模式。 例如,使用者視為獨立體驗的一部分,他們可以釘選並從任務欄分別從任務欄啟動,而應用程式的其他部分應該有自己的 AppUserModelID,與主要體驗不同。

  • 具有不同自變數的多個快捷方式,全都會導致使用者看到相同應用程式時,應該對所有快捷方式使用一個 AppUserModelID。 例如,Windows Internet Explorer 針對不同模式有不同的快捷方式(例如啟動不含附加元件),但應該全都以單一 Internet Explorer 實例的形式向用戶顯示。

  • 做為主機進程的可執行檔,並以應用程式身分執行目標內容,必須 註冊為主應用程式,之後就可以將不同的AppUserModelID指派給它所裝載的每個感知體驗。 或者,主機進程可以允許裝載的程式設定其 AppUserModelID。 不論是哪一種情況,主機進程都必須保留AppUserModelID本身或裝載應用程式來源的記錄。 在此情況下,沒有目標內容,主機進程沒有主要用戶體驗。 範例包括 Windows 遠端應用程式整合在本機 (RAIL) 應用程式、Java 執行時間、RunDLL32.exe或 DLLHost.exe。

    在現有的裝載應用程式的情況下,系統會嘗試識別個別體驗,但新的應用程式應該使用明確的 AppUserModelID 來保證預期的用戶體驗。

  • 對使用者合作或鏈結的進程是相同應用程式的一部分,應該將相同的 AppUserModelID 套用至每個進程。 範例包括具有啟動器程式(鏈結)和Microsoft Windows Media Player 的遊戲,其具有在一個進程中執行的初次執行/設定體驗,以及在另一個進程中執行的主要應用程式(合作式)。

  • 殼層命名空間延伸模組做為個別應用程式,用於流覽和管理 Windows 檔案總管中的內容,應該在其資料夾屬性中指派 AppUserModelID。 例如控制面板。

  • 在部署架構之類的虛擬化環境中,虛擬化環境應該將不同的AppUserModelID指派給它所管理的每個應用程式。 在這些情況下,應用程式啟動器會使用中繼程式來設定環境,然後將作業交給不同的進程來執行應用程式。 請注意,這會導致系統無法將執行中的目標進程關聯回快捷方式,因為快捷方式指向中繼進程。

    如果有任何應用程式有多個視窗、快捷方式或進程,該應用程式指派的AppUserModelID也應該套用至虛擬化環境的每個部分。

    這種情況的範例是 ClickOnce 架構,可代表其管理的應用程式正確指派 AppUserModelID。 如同在所有這類環境中,由 ClickOnce 部署和管理的應用程式不應自行指派明確的 AppUserModelID,因為這樣做會與 ClickOnce 所指派的 AppUserModelID 發生衝突,並導致非預期的結果。

如何形成 Application-Defined AppUserModelID

應用程式必須以下列格式提供其AppUserModelID。 它不能超過 128 個字元,而且不能包含空格。 每個區段都應該以pascal大小寫。

CompanyName.ProductName.SubProduct.VersionInformation

CompanyNameProductName 應一律使用,而 SubProductVersionInformation 部分是選擇性的,取決於應用程式的需求。 SubProduct 允許由數個子應用程式組成的主要應用程式,為每個子應用程式及其相關聯的視窗提供個別的任務列按鈕。 VersionInformation 可讓兩個版本的應用程式共存,同時被視為離散實體。 如果應用程式不打算以這種方式使用,則應該省略 VersionInformation,讓升級的版本可以使用與其取代的版本相同的 AppUserModelID。

指派 AppUserModelID 的位置

當應用程式使用一或多個明確的 AppUserModelID 時,它應該在下列位置和情況中套用這些 AppUserModelID:

  • 在應用程式的快捷方式檔案的 System.AppUserModel.ID 屬性中。 快捷方式(作為 IShellLink、CLSID_ShellLink或.lnk檔案)可透過整個殼層中使用的 IPropertyStore 和其他屬性設定機制來支持屬性。 這可讓任務列識別釘選的適當快捷方式,並確保屬於進程的視窗與該任務欄按鈕適當相關聯。

    注意

    建立該快捷方式時,應該將 System.AppUserModel.ID 屬性套用至快捷方式。 使用 Microsoft Windows Installer (MSI) 安裝應用程式時,MsiShortcutProperty 數據表可讓 AppUserModelID 在安裝期間建立時套用至快捷方式。

     

  • 做為任何應用程式執行中視窗的屬性。 這可以透過下列兩種方式之一來設定:

    1. 如果一個進程擁有的不同視窗需要不同的 AppUserModelID 來控制任務欄群組,請使用 SHGetPropertyStoreForWindow) 來擷取視窗的屬性存放區,並將 AppUserModelID 設定為 window 屬性。
    2. 如果進程中的所有視窗都使用相同的 AppUserModelID,則 SetCurrentProcessExplicitAppUserModelID,在程式上設定 AppUserModelID。 應用程式必須在應用程式呈現任何UI之前,呼叫 SetCurrentProcessExplicitAppUserModelID,以在應用程式的初始啟動例程期間設定其 AppUserModelID、進行任何作其跳躍清單,或發出或讓系統進行任何呼叫 SHAddToRecentDocs

    視窗層級 AppUserModelID 會覆寫進程層級的 AppUserModelID。

    當應用程式在視窗層級設定明確的 AppUserModelID 時,應用程式可以為其任務列按鈕提供其重新啟動命令的詳細數據。 若要提供該資訊,會使用下列屬性:

    注意

    如果應用程式有啟動應用程式的快捷方式,應用程式應該將AppUserModelID套用為快捷方式的屬性,而不是使用重新啟動屬性。 在此情況下,快捷方式的命令行、圖示和文字會用來提供與重新啟動屬性相同的資訊。

     

    視窗層級明確的 AppUserModelID 也可以使用 System.AppUserModel.PreventPinning 屬性來指定它不應該可供釘選或重新啟動。

  • 在自定義或更新的呼叫中(ICustomDestinationList)、擷取(IApplicationDocumentLists),或清除 (IApplicationDestinations) 應用程式的跳躍清單。

  • 在檔案關聯註冊中(透過其 ProgID),如果應用程式使用系統自動產生的 最近頻繁 目的地清單。 SHAddToRecentDocs會參考此關聯資訊。 在透過 ICustomDestinationList::AppendCategoryIShellItem 目的地新增至自定義跳躍清單時,也會使用這項資訊。

  • 在任何呼叫中,應用程式會直接 SHAddToRecentDocs。 如果應用程式相依於一般檔案對話框來呼叫 SHAddToRecentDocs,則只有在為整個進程設定 AppUserModelID 時,這些呼叫才能推斷明確的 AppUserModelID。 如果應用程式在其視窗上設定 AppUserModelIDs 而不是進程,則應用程式必須對其本身 SHAddToRecentDo cs 進行所有呼叫,並具有明確的 AppUserModelID,以及防止通用檔案對話框進行自己的呼叫。 每次開啟專案時,都必須這麼做,以確保應用程式跳躍清單 最近頻繁 區段都正確無誤。

下列專案描述常見案例,以及在這些案例中套用明確AppUserModelID的位置。

  • 當單一進程包含多個應用程式時,請使用 SHGetPropertyStoreForWindow 來擷取視窗的屬性存放區,並將 AppUserModelID 設定為 window 屬性。
  • 當應用程式使用多個進程時,請將 AppUserModelID 套用至每個進程。 不論您在每個進程上使用相同的 AppUserModelID,取決於您是否希望每個進程都顯示為主要應用程式的一部分,還是顯示為個別實體。
  • 若要將特定視窗與相同進程中的集合分開,請使用視窗的屬性存放區,將單一 AppUserModelID 套用至您想要分隔的視窗,然後將不同的 AppUserModelID 套用至進程。 該進程中未明確加上視窗層級 AppUserModelID 標籤的任何視窗都會繼承進程的 AppUserModelID。
  • 如果檔類型與應用程式相關聯,請在檔類型的 ProgID 註冊中指派 AppUserModelID。 如果以不同的模式啟動單一可執行檔,而用戶顯示為不同的應用程式,則每個模式都需要個別的 AppUserModelID。 在此情況下,檔類型必須有多個 ProgID 註冊,每個註冊都有不同的 AppUserModelID。
  • 當有多個快捷方式位置時,使用者可以從中啟動應用程式(在 桌面或其他地方的 [開始] 功能表、桌面或其他地方)擷取快捷方式的屬性存放區,以將單一 AppUserModelID 套用至所有快捷方式做為快捷方式屬性。
  • 當應用程式對 SHAddToRecentDocs 進行明確呼叫時,請在呼叫中使用 AppUserModelID。 當一般檔案對話框用來開啟或儲存盤案時,代表應用程式呼叫對話框 SHAddToRecentDocs。 該呼叫可以從進程推斷明確的AppUserModelID。 不過,如果明確套用 AppUserModelID 做為視窗屬性,則通用檔案對話框無法判斷正確的 AppUserModelID。 在此情況下,應用程式本身必須明確呼叫 SHAddToRecentDocs,並提供正確的 AppUserModelID。 此外,應用程式必須防止一般檔案對話方塊代表其呼叫 SHAddToRecentDocs,方法是在 IFileOpenDialogIFileSaveDialogGetOptions 方法中設定 FOS_DONTADDTORECENT 旗標。

將應用程式註冊為主機進程

應用程式可以設定 IsHostApp 登錄專案,讓可執行檔案的進程被任務欄視為主機進程。 這會影響其群組和預設的跳躍清單專案。

下列範例顯示必要的登錄專案。 請注意,專案未指派值;其存在是所有必要專案。 這是REG_NULL值。

HKEY_CLASSES_ROOT
   Applications
      example.exe
         IsHostApp

如果進程本身或用來啟動進程的快捷方式檔案具有明確的 AppUserModelID,則會忽略主機進程清單,並由任務欄將應用程式視為一般應用程式。 應用程式執行中的視窗會分組在單一任務列按鈕下,而且應用程式可以釘選到任務列。

如果只有執行中的進程可執行檔名稱是已知的,但沒有明確的 AppUserModelID,而且該可執行檔位於主機進程清單中,則每個進程實例都會被視為任務欄群組的個別實體。 與進程任何特定實例相關聯的任務欄按鈕不會顯示進程新實例的釘選/取消釘選選項或啟動圖示。 此程式也不符合納入 \[開始\] 功能表 \[最常使用\] 列表的 \[開始\] \[MFU\] 清單中。 不過,如果進程是透過包含啟動自變數的快捷方式啟動(通常是要裝載為「應用程式」的目標內容),系統就可以判斷身分識別,而且可以釘選並重新啟動應用程式。

任務欄釘選和最近/常用清單的排除清單

應用程式、進程和視窗可以選擇自己無法釘選到任務欄,或包含在 [開始] 功能表的 [] 功能表的 MFU 清單中。 有三種機制可以達成此目的:

  1. 將 NoStartPage 專案新增至應用程式的註冊,如下所示:

    HKEY_CLASSES_ROOT
       Applications
          Example.exe
             NoStartPage
    

    會忽略與 NoStartPage 專案相關聯的數據。 只需要有專案存在。 因此,NoStartPage 的理想類型是REG_NONE。

    請注意,任何使用明確的 AppUserModelID 會覆寫 NoStartPage 專案。 如果明確的 AppUserModelID 套用至快捷方式、進程或視窗,它就會變成可釘選,且符合 [開始] 功能表 MFU 清單 資格。

  2. 在視窗和快捷方式上設定 System.AppUserModel.PreventPinning 屬性。 這個屬性必須在窗口上設定,才能 PKEY_AppUserModel_ID 屬性。

  3. 將明確的 AppUserModelID 新增為下列登錄子機碼下的值,如下所示:

    HKEY_LOCAL_MACHINE
       Software
          Microsoft
             Windows
                CurrentVersion
                   Explorer
                      FileAssociation
                         NoStartPageAppUserModelIDs
                            AppUserModelID1
                            AppUserModelID2
                            AppUserModelID3
    

    每個專案都是具有 AppUserModelID 名稱的REG_NULL值。 此清單中找到的任何 AppUserModelID 都無法釘選,且無法包含在 [開始] 選單 MFU 清單中。

請注意,某些可執行檔及其名稱中包含特定字串的快捷方式會自動排除在 MFU 列表中釘選和包含。

注意

套用明確的 AppUserModelID,即可覆寫此自動排除。

 

如果下列任何一個字串,不論大小寫為何,都包含在快捷方式名稱中,則程式無法釘選,而且不會顯示在最常使用的清單中(不適用於 Windows 10):

  • 文件
  • 幫助
  • 安裝
  • 詳細資訊
  • 閱讀我
  • 讀取第一個
  • 自述檔
  • 刪除
  • 設置
  • 支援
  • 新功能

下列程式清單無法釘選,而且會從最常用的清單中排除。

  • Applaunch.exe
  • Control.exe
  • Dfsvc.exe
  • Dllhost.exe
  • Guestmodemsg.exe
  • Hh.exe
  • Install.exe
  • Isuninst.exe
  • Lnkstub.exe
  • Mmc.exe
  • Mshta.exe
  • Msiexec.exe
  • Msoobe.exe
  • Rundll32.exe
  • Setup.exe
  • St5unst.exe
  • Unwise.exe
  • Unwise32.exe
  • Werfault.exe
  • Winhlp32.exe
  • Wlrmdr.exe
  • Wuapp.exe

上述清單會儲存在下列登錄值中。

注意

應用程式不應修改這些清單。 針對相同的體驗,使用先前列出的其中一個排除清單方法。

 

HKEY_LOCAL_MACHINE
   Software
      Microsoft
         Windows
            CurrentVersion
               Explorer
                  FileAssociation
                     AddRemoveApps
                     HostApps

SetCurrentProcessExplicitAppUserModelID

GetCurrentProcessExplicitAppUserModelID

任務列延伸模組

ICustomDestinationList::SetAppID

IApplicationDocumentLists::SetAppID

IApplicationDestinations::SetAppID

SHGetPropertyStoreForWindow