當您將如 Microsoft Office 應用程式的應用程式自動化時,對於 Office
應用程式物件之屬性與方法的呼叫,必須與這些物件在某些方面有所關聯。將屬性與方法呼叫,和實作這些屬性與方法的物件連接的程序,一般稱為
繫結。在 Visual C# 之中,可以使用 2 種類型的繫結,分別是
早期繫結和
晚期繫結。您所選擇的繫結類型可能影響到您程式的許多面向,包括效能、彈性與可維護性。
本文將說明並比較 Visual C#
自動化用戶端的早期與晚期繫結,並提供範例程式碼以示範這兩種類型的繫結。
早期繫結
在早期繫結,Visual C# 使用與特定 Office
應用程式相關的可用型別資訊,直接繫結到其需要使用的方法或屬性。編譯器可以執行型別和語法檢查,以確定將正確的數目與參數類型傳送到方法或屬性,而且傳回的值會是預期的型別。由於在執行時間呼叫屬性或方法需要的工作較少,有時候早期繫結會較為迅速;不過,儘管早期繫結可能比較快,跟晚期繫結相較起來,兩者的差別卻常微不足道。
因為可能引入版本相容的問題,早期繫結的確有少許的缺陷。例如,假設一部自動化伺服器 (如 Microsoft Excel 2002),引入在 Excel
2000 中所沒有的新方法或屬性,或是對現存的屬性或方法進行變更。這些變更可能會改變物件的二進位配置,並對運用 Excel 2002 型別資訊自動化
Excel 2000 的 Visual C# 應用程式造成問題。如果要避免早期繫結的這項問題,我們通常建議您在開發與測試自動化用戶端時,使用要支援之
Office 應用程式最早版本的型別資訊。
下列步驟將示範如何使用早期繫結建立自動化用戶端。請注意,如這些步驟所示範的,您在進行早期繫結時,需要參考自動化用戶端的型別程式庫。
建立使用早期繫結的自動化用戶端
- 啟動 Microsoft Visual Studio .NET。在 [檔案] 功能表中,按一下 [新增],再按一下 [專案]。從 Visual C# 專案類型中,選擇 [Windows 應用程式]。依照預設,會建立 Form1。
- 在 [Microsoft Excel Object Library] 中新增參考。如果要執行這項操作,請遵循下列步驟:
- 按一下 [專案] 功能表上的 [加入參考]。
- 在 [COM] 索引標籤上找出 [Microsoft Excel Object Library],然後按一下 [選取]。
注意 Office 2003 包含「主要的 Interop 組件」(PIA)。Office XP 不包含
PIA,不過這些組件可以由下載取得。
如需有關 Office XP PIA 的詳細資訊,請按一下下面的文件編號,檢視「Microsoft
知識庫」中的文件:328912?
(http://support.microsoft.com/kb/328912/
)
Microsoft Office XP primary interop assemblies (PIAs) are available for download
- 按一下 [加入參考] 對話方塊中的 [確定] 以接受您的選擇。如果您收到提示要求產生您所選取程式庫的包裝函式,請按一下 [是]。
- 在 [檢視] 功能表上,選取 [工具箱] 以顯示 [工具箱],並在 Form1 新增一個按鈕。
- 按兩下 [Button1]。表單的程式碼視窗會出現。
- 在程式碼視窗中,將下列程式碼
private void button1_Click(object sender, System.EventArgs e)
{
}
取代為:
private void button1_Click(object sender, System.EventArgs e)
{
Excel.Application objApp;
Excel._Workbook objBook;
Excel.Workbooks objBooks;
Excel.Sheets objSheets;
Excel._Worksheet objSheet;
Excel.Range range;
try
{
// Instantiate Excel and start a new workbook.
objApp = new Excel.Application();
objBooks = objApp.Workbooks;
objBook = objBooks.Add( Missing.Value );
objSheets = objBook.Worksheets;
objSheet = (Excel._Worksheet)objSheets.get_Item(1);
range = objSheet.get_Range("A1", Missing.Value);
range.set_Value(Missing.Value, "Hello, World!" );
//Return control of Excel to the user.
objApp.Visible = true;
objApp.UserControl = true;
}
catch( Exception theException )
{
String errorMessage;
errorMessage = "Error: ";
errorMessage = String.Concat( errorMessage, theException.Message );
errorMessage = String.Concat( errorMessage, " Line: " );
errorMessage = String.Concat( errorMessage, theException.Source );
MessageBox.Show( errorMessage, "Error" );
}
}
- 捲動到程式碼視窗的頂端。將下列一行加到 Using 指示詞清單的結尾:
using System.Reflection;
using Excel = Microsoft.Office.Interop.Excel;
using System.Reflection;
using Excel = Microsoft.Office.Interop.Excel;
晚期繫結
相對於早期繫結,晚期繫結要等到執行階段,才會將屬性與方法呼叫繫結到其所關聯的物件。如果要執行這項操作,目標物件必須實作特殊的
COM 介面:
IDispatch。
IDispatch::GetIDsOfNames 方法會讓 Visual C# 詢問物件有關其所支援的方法和屬性,然後
IDispatch::Invoke 方法便會讓 Visual C#
呼叫這些方法和屬性。這種型態的晚期繫結的優點是能夠移除與早期繫結相連的某些版本相依性。然而,這種繫結也有一個缺點,即是移除了自動化程式碼完整性編譯時間檢查,而且沒有提供
Intellisense 功能,以至於無法對方法和屬性的呼叫提供修正的線索。
如果要在 Visual C# 中使用晚期繫結,請使用
System.Type.InvokeMember 方法。這個方法會呼叫
IDispatch::GetIDsOfNames 和
IDispatch::Invoke,以繫結自動化伺服器的方法和屬性。
建立使用晚期繫結的自動化用戶端
- 啟動 Microsoft Visual Studio .NET。在 [檔案] 功能表中,按一下 [新增],再按一下 [專案]。從 Visual C# 專案類型中,選擇 [Windows 應用程式]。依照預設,會建立 Form1。
- 在 [檢視] 功能表上,選擇 [工具箱] 以顯示 [工具箱],並在 Form1 新增一個按鈕。
- 按兩下 [Button1]。表單的程式碼視窗會出現。
- 在程式碼視窗中,將下列程式碼
private void button1_Click(object sender, System.EventArgs e)
{
}
取代為:
private void button1_Click(object sender, System.EventArgs e)
{
object objApp_Late;
object objBook_Late;
object objBooks_Late;
object objSheets_Late;
object objSheet_Late;
object objRange_Late;
object[] Parameters;
try
{
// Get the class type and instantiate Excel.
Type objClassType;
objClassType = Type.GetTypeFromProgID("Excel.Application");
objApp_Late = Activator.CreateInstance(objClassType);
//Get the workbooks collection.
objBooks_Late = objApp_Late.GetType().InvokeMember( "Workbooks",
BindingFlags.GetProperty, null, objApp_Late, null );
//Add a new workbook.
objBook_Late = objBooks_Late.GetType().InvokeMember( "Add",
BindingFlags.InvokeMethod, null, objBooks_Late, null );
//Get the worksheets collection.
objSheets_Late = objBook_Late.GetType().InvokeMember( "Worksheets",
BindingFlags.GetProperty, null, objBook_Late, null );
//Get the first worksheet.
Parameters = new Object[1];
Parameters[0] = 1;
objSheet_Late = objSheets_Late.GetType().InvokeMember( "Item",
BindingFlags.GetProperty, null, objSheets_Late, Parameters );
//Get a range object that contains cell A1.
Parameters = new Object[2];
Parameters[0] = "A1";
Parameters[1] = Missing.Value;
objRange_Late = objSheet_Late.GetType().InvokeMember( "Range",
BindingFlags.GetProperty, null, objSheet_Late, Parameters );
//Write "Hello, World!" in cell A1.
Parameters = new Object[1];
Parameters[0] = "Hello, World!";
objRange_Late.GetType().InvokeMember( "Value", BindingFlags.SetProperty,
null, objRange_Late, Parameters );
//Return control of Excel to the user.
Parameters = new Object[1];
Parameters[0] = true;
objApp_Late.GetType().InvokeMember( "Visible", BindingFlags.SetProperty,
null, objApp_Late, Parameters );
objApp_Late.GetType().InvokeMember( "UserControl", BindingFlags.SetProperty,
null, objApp_Late, Parameters );
}
catch( Exception theException )
{
String errorMessage;
errorMessage = "Error: ";
errorMessage = String.Concat( errorMessage, theException.Message );
errorMessage = String.Concat( errorMessage, " Line: " );
errorMessage = String.Concat( errorMessage, theException.Source );
MessageBox.Show( errorMessage, "Error" );
}
}
- 捲動到程式碼視窗的頂端。將下列一行加入到 Using 指示詞清單的結尾:
如需相關資訊,請造訪下列 Microsoft Developer Network (MSDN) 網站:
如需有關繫結的詳細資訊,請按一下下面的文件編號,檢視「Microsoft 知識庫」中的文件:
245115?
(http://support.microsoft.com/kb/245115/
)
INFO: Using Early Binding and Late Binding in Automation
244167?
(http://support.microsoft.com/kb/244167/
)
INFO: Writing Automation Clients for Multiple Office Versions
247579?
(http://support.microsoft.com/kb/247579/
)
INFO: Use DISPID Binding to Automate Office Applications Whenever Possible