詳解COM Add In的LoadBehavior及其妙用


 Office的所有COM Add In,包括用Shared Add In模板和VSTO Add In模板創建的,都會在注冊表里面存儲一些信息。

對於當前用戶安裝的Add In,以Excel為例,對應的注冊表鍵值存儲於:My Computer/HKCU/Software/Microsoft/Office/Addins/AddInName

機器級別的Add In存儲於:My Computer/HKLM/Software/Microsoft/Office/Addins/AddInName

普通的Shared Add In 鍵下面有3個值,DescriptionFriendlyNameLoadBehavior

VSTO Add In多出兩個鍵值:CommandLineSafeManifestManifest是用來指向自定義代碼所處的dll位置的,CommandLineSafe用來指示Add In是不是命令行安全的,會不會顯示在COM Add In Dialog里面。DescriptionFriendlyName就是Add In的描述和顯示的名字,沒啥好說的。

LoadBehavior是這篇文章的主角。LoadBehavior指示了該Add In的裝載行為,它可以由以下幾個值組合而成: (前兩個中的一個+后三個中的一個)

0   = Disconnect

不裝載

1   = Connected

裝載

2   = Bootload

啟動程序時裝載

8   = DemandLoad

需要時裝載

16 = ConnectFirstTime

第一次啟動時裝載

也就是說,當LoadBehavior02816的時候,Add In不裝載;當其為1+2=3的時候,裝載並且每次Office程序啟動時都裝載;當其為9的時候,裝載,但只當用戶需要時裝載;17的時候,裝載,只有第一次啟動的時候裝載。如果我們不去改動,一般而言,正常工作的Add InLoadBehavior3,但如果當Add In啟動的時候發生異常,這個Add In會被軟禁用(Soft Disabled)LoadBehavior的值會被改為0+2=2Add In將不被裝載。注意,雖然這里的值是2,表示啟動時裝載,但事實上,其是由0+2所得,大的前提決定了不裝載。

 

那我說的LoadBehavior的妙用在何處呢?這源於最近碰到的一個問題,有人問我,能不能用代碼來獲取Office中被硬禁用(Hard Disable)COM Add In,或者至少知道,有沒有被硬禁用的Add In?這個問題有點棘手,因為Office對象模型中,根本找不到任何信息。Google甚至都找不到,有人有類似的要求。

           在給出解決方案前,有必要講述一下,上面提到的硬禁用和軟禁用的區別。首先,硬禁用和軟禁用的表象就不一樣,被軟禁用的Add In會出現在COM Add-Ins對話框中,只不過前面的Checkbox不會被勾上。被硬禁用的Add In雖然也會出現在COM Add-Ins對話框中,但它們會被單獨再列到另外一個叫Disabled Items的對話框里面。下面是COM Add-Ins對話框和Disabled Items對話框的截圖。由下面的圖可以看出來ExcelAddInExcelAddIn1是被用戶手動禁用,或者被軟禁用的;ExcelAddIn2則是被硬禁用的。

                                                                                               

 

 

 

COM Add-Ins對話框截圖

 

 

 

Disabled Items對話框截圖

那是什么導致Add In被軟禁用和硬禁用的呢?為了模擬出問題,並解決,我也必須讓自己的機器上出現一個被軟禁用,一個被硬禁用的Add In

                軟禁用:當Add In在構造函數或者Startup event handle函數里面拋出一個沒有處理的異常的時候,系統將該Add In軟禁用,將其LoadBehavior值改為2。要重現一個軟禁用很簡單,在Startup event handle里面拋出一個異常就可以了,代碼如下:

                private void ThisAddIn_Startup(object sender, System.EventArgs e)

        {

           throw new Exception("Make the Add in disabled");

        }

                硬禁用:發生在,Add In裝載時由於嚴重的錯誤導致應用程序關閉,或者在構造函數或Startup event handle函數執行時,強行關掉Visual Studio Debugger時。這將導致再一次啟動應用程序的時候,Office向用戶詢問是否硬禁用當前Add In。方法同樣很簡單,用一個MessageBox停住Startup event handle函數的執行過程,然后強行關掉Visual Studio,下次程序(本例Excel)啟動時,選擇禁用Add In

                private void ThisAddIn_Startup(object sender, System.EventArgs e)

        {

            MessageBox.Show("Stop here");

        }

 

                接下來,看看上面問題的解決方案。在Office對象模型中,Application對象有個COMAddIns屬性,它是一個集合,包括了當前應用程序中所有注冊過的COM Add In,無論這個Add In是否激活。我們可以在這個集合中循環,得到每個COMAddIn的句柄,而COMAddIn又暴露了一些有用的屬性,比如Connect屬性。當Connect返回true時,說明這個Add In是激活的,如果返回false,說明這個Add In未激活,有可能是被用戶手動禁用了,還有可能是被軟禁用或硬禁用了。但是COMAddIn的屬性只告訴我們這么多,通過Office對象模型,我們無法分辨,應用程序中是否存在被硬禁用的Add In,如果有,哪些是被硬禁用的Add In。通過查看硬禁用的Add In在注冊表中LoadBehavior的值,驚奇地發現,硬禁用的Add In,其LoadBehavior值竟然為3!這樣我們就可以結合COMAddIns集合和注冊表里LoadBehavior的信息來判斷哪些COM Add In是被硬禁用的,哪些是由於軟禁用或者其它原因未被裝載的。實現的代碼如下:       

private void ThisAddIn_Startup(object sender, System.EventArgs e)

        {

            RegistryKey key = null;

 

            foreach(Office.COMAddIn cAddin in this.Application.COMAddIns)

            {

                if (!cAddin.Connect)

                {

                    try

                    {

                        key = Registry.LocalMachine;

                        key = key.OpenSubKey("Software").OpenSubKey("Microsoft")

                        .OpenSubKey("Office").OpenSubKey("Excel").OpenSubKey("Addins")

                        .OpenSubKey(cAddin.ProgId);

                        if (Convert.ToInt32(key.GetValue("LoadBehavior")) == 3)

                        {

                            MessageBox.Show(cAddin.ProgId + " is disabled!");

                        }

                        else

                        {

                            MessageBox.Show(cAddin.ProgId + " is not loaded!");

                        }

                    }

                    catch(Exception ex)

                    {

                        key = Registry.CurrentUser;

                        key = key.OpenSubKey("Software").OpenSubKey("Microsoft")

                        .OpenSubKey("Office").OpenSubKey("Excel").OpenSubKey("Addins")

                        .OpenSubKey(cAddin.ProgId);

                        if (Convert.ToInt32(key.GetValue("LoadBehavior")) == 3)

                        {

                            MessageBox.Show(cAddin.ProgId + " is disabled!");

                        }

                        else

                        {

                            MessageBox.Show(cAddin.ProgId + " is not loaded!");

                        }

                    }

                }

            }

        }

 

PS:如何顯示COM Add-insDisabled Items對話框?(沒有中文的Office,所以菜單和按鈕都按英文版中的寫法,對照着應該很好找到)

  • ·         COM Add-ins對話框:
    • o   Office 2007Office Button->Excel Options->Add-Ins Tab->Choose Item COM Add-ins in theManage DropDownList->Click Button Go
    • o   Office 2003Right Click the Menu->Click Customize… Button->In Commands Tab->ToolsCategorie->Drag COM Add-Ins Command to one of the tool bar->Click the new added COM Add-ins Button

 

  • ·         Disabled Items對話框:
    • o   Office 2007Office Button->Excel Options->Add-Ins Tab->Choose Item Disabled Items in theManage DropDownList->Click Button Go
    • o   Office 2003Menu Help->About Microsoft Office Excel->Disabled Items

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM