從 Excel 2002 Visual Basic for Applications 連接至 Managed 元件
作者:Dennis Angeline、Misha Shneerson 及 Siew-Moi Khor
Microsoft Corporation 適用於:
Microsoft® Office XP 摘要:學習如何建立在 Office XP 文件背後擔任程式碼角色的 Managed 元件。此項技術乃透過內含視覺化設計工具的 Excel 2002 工作表簡報來呈現。本文中也將探討部份關於此類實作的安全性考量。(列印共 14 頁) 請至 MSDN 下載專區 (英文) 下載或瀏覽 odc_xlnet.exe。
http://msdn.microsoft.com/downloads/default.asp?URL=/downloads/sample.asp?url=/msdn-files/027/002/067/msdncompositedoc.xml 簡介
您可以使用由 Common Language Runtime 所提供的「元件物件模式 (COM)」interop 服務從 COM 使用 Managed 程式碼,或反過來從 Managed 應用程式使用 COM 程式碼。 本文中所涵蓋的範例「區段檢視工具」就是個示範的例子。「區段檢視工具」是一種可由 COM 用戶端透過其 COM 相似的介面所利用的 Managed 元件。它示範了使用 COM interop 服務從 COM 使用 Managed 程式碼,或反過來從 Managed 應用程式中使用 COM 元件的方法。 在本文中還將討論與使用如「區段檢視工具」範例中所示的方法來實作解決方案相關的安全性考量。我們假設讀者已熟悉 Microsoft® Office XP Visual Basic® for Applications (VBA) 和 Microsoft .NET 技術。 系統需求
為執行範例,您的電腦上將需要安裝下列軟體: Microsoft Windows® XP 或 Microsoft Windows 2000 及相關的 Service Pack (SP)
Microsoft Office XP 及相關的 SP
Microsoft .NET Framework (英文) 及相關的 SP
此外,如果希望檢視範例程式碼,同時還需要安裝 Microsoft Visual Studio® .NET。如果希望編譯該解決方案,也將需要在您的機器上安裝 Microsoft Office XP Primary Interop Assemblies (PIA) (英文) 。
執行未簽署的 VBA 巨集
範例下載中的 Microsoft Excel 2002 巨集和元件都尚未經過簽署。若要執行未簽署的 Excel 2002 VBA 巨集,在 Excel 2002 [安全性] 對話方塊中的安全性設定 (在 [工具] 功能表,指向 [巨集],再按一下 [安全性]) 必須設定為 [中],並清除 [信任所有已安裝的增益集和範本] 核取方塊。強烈建議您僅在測試環境進行此項設定。完成測試之後,將安全性層級設回 [高]。 注意 將安全性層級設為 [中],並清除 [信任所有已安裝的增益集和範本] 核取方塊,會讓使用者在被提示時有機會啟用或停用未簽署的 COM 增益集和 VBA 巨集。如果您的安全性層級設為 [高],且 [信任所有已安裝的增益集和範本] 核取方塊已清除,則所有未簽署的 COM 增益集和 VBA 巨集將自動停用。因此,強烈建議所有使用者將他們的安全性層級設為 [高],並清除 [信任所有已安裝的增益集和範本] 核取方塊。
進行試驗
若要試驗一下「區段檢視工具」範例,請先下載與本文相關的範例檔 (odc_xlnet.exe),然後執行此自動解壓縮的封裝,將「區段檢視工具」的範例方案解壓縮到您的本機電腦上。
如何安裝範例
若要安裝「區段檢視工具」範例,請執行 <安裝路徑>\Setup\Release 目錄中的 SegmentInExcel.msi。
附註 為了成功完成安裝,目標機器上需要先安裝有 .NET Framework (英文)。
http://msdn.microsoft.com/downloads/sample.asp?url=/msdn-files/027/001/829/msdncompositedoc.xml 安裝程式會在使用者的機器上安裝必要的檔案。它也將在登錄中註冊必要的組件,讓 COM 得以存取那些使用一般 COM 載入的應用程式程式設計介面 (API)。 如 [圖 1] 所示,預設的安裝位置是 C:\Program Files\WidgetWare\SegmentViewer。您可以另外選擇將元件安裝在不同的目錄中。
[圖 1] 安裝目錄選擇對話方塊 如何使用區段檢視工具
在執行範例中所包含的 Excel 巨集之前,請確認您的 Excel 2002 安全性設定已依照〈執行未簽署的 VBA 巨集〉小節所討論般地正確設定。 一旦元件安裝之後,請從安裝目錄開啟 SampleSeg.xls Excel 檔案。SampleSeg.xls 檔案包含一家虛構的公司嘗試提供石油管線系統的成本預估,如下 [圖 2] 所示。
[圖 2] SampleSeg.xls 試算表 試算表包含關於石油管線內四個部份的資訊 (每個部份以綠色顯示)。第一部份包含九個區段。該石油管線部份的每個區段都有不同類型的防護物或護板,而一些區段則沒有任何護板。 金屬護板每尺的費用乃視所使用的護板類型而定,其中「輕型 (Lite)」是最便宜而「超重型 (Ultra Heavy)」則是最貴的。另一種最便宜的方案是不使用任何護板。 因此,建造石油管線任一部份的費用深受所使用的護板以及使用該類型護板的區段長度所影響。 與在表格式表單中編輯規格不同,「區段檢視工具」讓使用者使用圖形工具來操控石油管線。只要選取石油管線的部份,再按一下滑鼠右鍵,即可啟動「區段檢視工具」。 例如,選取儲存格 B13 到 B22,然後按一下右鍵。當按下右鍵時,應該會顯示「區段檢視工具」。如果「區段檢視工具」沒有顯示出來,那麼則可能是沒有正確安裝「區段檢視工具」的元件。
[圖 3] 「區段檢視工具」元件 一旦「區段檢視工具」啟動後,您可以拖曳區段分隔線來變更區段的長度。您也可以在區段上按一下右鍵來變更該區段任一部份的護板類型,如 [圖 4] 所示。您還可以顯示每個區段的長度。 當在圖形影像上進行變更時,Excel 試算表上表格內數值會同時更新。
[圖 4] 「區段檢視工具」快顯功能表選項 這些都是怎麼運作的?
「區段檢視工具」範例方案包含三個不同的專案。Managed 元件乃是以 Microsoft C# 語言寫成。 若要在 Visual Studio .NET 整合式開發環境 (IDE) 中檢視範例程式碼,請開啟位於 <安裝路徑>\ 資料夾中的 SegmentInExcel.sln 檔案。
Segment 控制項元件
Segment.csproj 專案 (位於 <安裝路徑>\Segment\ 資料夾) 包含 Segment 控制項本身的程式碼。Segment 控制項對 Excel 一無所知,而且只是用於管理區段的圖形工具。它可以曾經用於與 Excel 無關的其他專案。
Windows Form 元件
SegmentInExcel.csproj 專案 (位於 <安裝路徑>\SegmentInExcel\ 資料夾) 包含一個主控 Segment 控制項以及與 Excel 互動的表單。它屬安裝過程中註冊 COM interop 作業的工具的一部份。 在此範例中,我們從一小段 VBA 程式碼程式常式開始,將 SegmentInExcel 專案的功能與 Excel 文件相連接起來。當 SampleSeg.xls 檔案開啟時,活頁簿的 Workbook_Open 事件就會引發。之後我們自訂的程式碼會將 SegmentInExcel.WorkbookConnect 物件初始化為標準的 COM 元件。接下來它會呼叫 BindToEvents 方法,這允許 Managed 元件連結到 Excel 事件。下列的 VBA 程式碼片段描述這是如何達成的: Private Sub Workbook_Open()
...
Dim SegmentViewer As New SegmentInExcel.WorkbookConnect
SegmentViewer.BindToEvents ThisWorkbook
...
End Sub BindToEvents 方法會註冊 Excel 工作表中所有產生的按右鍵事件。當發生按右鍵時,即會呼叫 WorkbookConnect.OnRightClick 方法。OnRightClick 方法會擷取目前的選取範圍,建立 SegmentViewer 元件,將該選取範圍傳遞至 SegmentViewer 元件並接著顯示表單。下列從 WorkbookConnect.cs 檔案取得的程式碼片段描述這是如何達成的: public void BindToEvents(Workbook workbook)
{
worksheet = (Worksheet) workbook.Sheets[1];
worksheet.BeforeRightClick =
new DocEvents_BeforeRightClickEventHandler(OnRightClick);
}
internal void OnRightClick(Range target, ref bool cancel)
{
try
{
if (target.Rows.Count < 2)
return; cancel = true;
SegmentViewer sv = new SegmentViewer();
sv.SetRanges(target);
sv.ShowDialog();
}
catch (Exception e)
{
MessageBox.Show(e.Message, "Segment Viewer");
}
} SegmentViewer 表單 (請參閱 SegmentViewer.cs 檔案) 會剖析選取範圍並建立 Segment 物件的陣列,該陣列會傳至控制項 (請參閱 Control.cs 和 Segment.cs 檔案) 以顯示成從下列 Segment.cs 檔案取得的程式碼片段: ...
Segment[] Segs = new Segment[RowCount];
for (int r = 1; r <= RowCount; r )
{
Segs[r - 1] = new Segment(
(ArmorType)GetInt(ContentRng, GetAddr(3, r)),
GetInt(ContentRng, GetAddr(1, r)),
GetInt(ContentRng, GetAddr(2, r)));
}
this.SegmentCtrl.SetSegments(Segs);
... 當拖曳分隔線時,控制項會在「區段檢視工具」引發事件,並再一次使用透過 COM interop 公開的 Excel 物件模型來更新 Excel 工作表上目前選取範圍中的值。 範例程式碼在程式的每個非瑣碎的步驟中都有大量的註解和說明。若要了解「區段檢視工具」控制項是如何運作的,請參閱 Control.cs 和 Segment.cs 檔案。
安裝專案
安裝專案中的第三個專案,即建置 setup.exe 的專案。安裝專案會在使用者的機器上安裝 Segment.dll 和 SegmentInExcel.dll 組件。它還會在登錄中建立項目,讓 SegmentInExcel.WorkbookConnect 物件得以從 COM 建立。安裝專案也會登錄相對應的類型程式庫以允許自動化。 Segment.dll 和 SegmentInExcel.dll 組件都放置在使用者機器上的相同資料夾中。這允許 Common Language Runtime 在 Segment.dll 組件從 SegmentInExcel.dll 組件呼叫時不需要將 Segment.dll 放入全域組件快取 (GAC) 中即可定位。 在此範例方案中用到的四個 Office XP PIA: Microsoft.Office.Interop.Excel.dll
Microsoft.Vbe.Interop.dll
Office.dll
Stdole.dll
它們已裝入安裝專案中,所以我們不需要要求使用者在他們的機器上安裝 Office XP PIA。這種依存 Office XP PIA 的方法是推薦使用的部署方案。透過這種方式分散的方案將會自動安裝並註冊全域組件快取 (GAC) 中所需的 Office XP PIA。它也將減少使用者機器上重複的 Office XP PIA 數量。 如需關於如何將 Office XP PIA 加入安裝專案的詳細資訊,請參閱 Microsoft Office XP Primary Interop Assemblies (PIA) (英文) 讀我檔案中的〈Distributing solutions that rely on the Office XP PIAs〉。 安裝專案還會指定「啟動狀況」,這可確認是否已安裝 .NET Framework。如果使用者尚未安裝,將會收到錯誤訊息。 安全性考量,可能的安全性攻擊
下列 [表 1] 說明當載入增益集和巨集時 Office XP 應用程式的行為。它示範 Office 如何檢查元件其發行者的身分以及根據明確信任作出決策來降低載入懷有惡意元件的風險。 下表列出 Microsoft Office XP [安全性] 對話方塊 ([工具] 功能表的 [巨集] 子功能表) 中可用的安全性設定及其相對應的行為。
[表 1] Microsoft Office XP 安全性設定矩陣
Office XP 安全性設定選項 |
安全性層級 |
[信任所有已安裝的增益集和範本] 核取方塊 |
已數位簽署 |
從受信任的來源 |
Office XP 將 |
高 |
已清除 |
是 |
是 |
無訊息地載入增益集或巨集 |
是 |
否 |
提示啟用或停用增益集或巨集 |
否 |
不適用 |
不載入增益集或巨集 |
中 |
已清除 |
是 |
是 |
無訊息地載入增益集或巨集 |
是 |
否 |
提示啟用或停用增益集或巨集 |
否 |
不適用 |
提示啟用或停用增益集或巨集 |
低 |
已清除 |
是或否 |
是或否 |
無訊息地載入增益集或巨集 |
高、中或低 |
已選取 |
是或否 |
是或否 |
無訊息地載入增益集或巨集 |
附註 [安全性] 對話方塊中的可用性和其中的選項乃視特定 Office 應用程式而異。此外,特定的 Office 應用程式只從特定目錄無訊息地載入已簽署的增益集和巨集,以及已註冊的 COM 增益集和智慧標籤識別元。詳細資訊,請參閱《Microsoft Office XP Macro Security White Paper》(英文)。 為了幫助您更了解在本文中所呈現之部份與實作技術相關的安全性議題,我們將使用類推法。 在此類推法中我們會將 Office 安全性模型比做私人派對。在此特別派對的入口有一位保全警衛。保全警衛會檢查每位賓客的身分,而且只有那些在賓客名單 (亦即,由主人信任且核准的) 上的賓客才允許進場。保全警衛將不會檢查賓客所攜帶的物品,因為他信任已出示其身份的重要證明的賓客。 讓我們假設其中一位賓客帶了一些很酷的玩具,他並沒有任何惡意,只是想要在派對裡面賣弄一下。在這位特別的賓客參與派對的一些時候,他拿出這些新酷的玩具並開始展示給每個人看。這都只是為了好玩,也是他認為舉行派對的目的。 現在想像一下如果有人在參加派對的路途中將他的玩具調換成非常有害的玩具。既然沒有人會檢查它是否是原來的玩具,所以最後很有可能變得非常危險。 Office 巨集和增益集有可能會發生非常類似的事情。Office XP 載入 VBA 巨集 (簽署或未簽署) 的與否跟上列 [表 1] 所示之使用者的安全性層級設定密切相關。但是一旦允許他們執行,就沒有人會注意他們進行的動作,而且檢查他們只使用核准的元件完全是增益集的責任。以類推做比喻,VBA 巨集就像「受信任的賓客」,而 Managed 程式碼即「原來的元具」,「置換的玩具」就是惡意替換的 Managed 程式碼。 這類情況不會發生在「區段檢視工具」中。在上面所呈現的 VBA 巨集中,我們在未確認模組完整性的情況下就從另一個模組 (在此例中為 Managed 元件中的模組) 載入並執行類別,亦即,並沒有進行任何驗證來檢查該模組是否已遭受擅改。的確,除了明白控制 Common Language Runtime 進行這類的驗證以外別無其他簡單的方法,如下列專門的文章:《Deployment of Managed COM Add-Ins in Office XP》(英文)。 要強調的是,發生這類攻擊性的可能性其實非常渺茫。這是因為組件在安裝並於電腦上註冊之後,若要進行這類的攻擊,攻擊者將需要存取前述機器的實體磁碟才能將該組件以他自己的組件取代。而就這類情況而言,如果惡意攻擊者有能力危害一部機器並可存取該本機磁碟的,那麼他基本上就已經可以執行更具破壞性的行為,例如實際將 Excel.exe 取代為他本身懷有惡意的 Excel 應用程式版本。 採用此處所呈現的技術與否完全取決於您本身。您需要作有智慧的判斷並決定在貴公司中,您是否可以將此項技術的簡化轉換成保衛應用程式的小優勢。 結論
Common Language Runtime 所提供的「元件物件模型 (COM)」interop 服務可從 COM 使用 Managed 程式碼,或同樣從 Managed 應用程式使用 COM 程式碼。不過,如先前討論過的,目前仍存在一些在實作這類方案時應該納入考慮因素的安全性考量。 以下是一些關於 PIA、.NET 安全性、.NET 和 COM interop 等等之類文章,您可以從中取得相關資T的快速連結: