記錄檔資訊

更新:2007 年 11 月

您可以建立針對下列作業記錄動作的記錄檔:

  • 以機器碼相互操作

  • 載入程式

  • 網路

如需控制記錄及如何產生記錄檔之登錄機碼的詳細資訊,請參閱 HOW TO:建立記錄檔

本主題說明為 Interop 和載入器記錄而寫入記錄檔的輸出。

Interop 記錄檔

Interop 記錄的輸出是由在執行階段發生之 Interop 函式呼叫 (Function Call) 的簽章 (Signature) 以及錯誤訊息所組成。

.NET Compact Framework 3.5 版包含增強的 Interop 記錄支援,將於本主題稍後的封送處理一節中詳述。

函式簽章

Managed 至機器碼以及機器碼至 Managed 呼叫的簽章都會被記錄下來,並包括下列類型的呼叫:

  • 平台叫用呼叫。

  • COM Vtable 和分派呼叫。

  • 委派回呼。

Interop 記錄可以協助您在呼叫 Interop 函式呼叫,或從 Interop 函式呼叫傳回時排解疑難問題,例如當參數未如預期地初始化,或是當程式未預期地結束時。

函式簽章項目的輸出,是由針對每項 Interop 呼叫的三行所組成。第一行提供識別函式呼叫型別的旗標,並包含下列一或多個項目:

  • [pinvokeimpl]
    識別使用 DllImportAttribute 屬性的 Managed 至機器碼呼叫。

  • [Ctor]
    識別 Iinterop 組件類別的建構函式,由 型別程式庫匯入工具 (TlbImp.exe) 產生。

  • [preservesig]
    假設 Managed 及原生函式都有相同的簽章,且不會從 HRESULT 轉譯至執行階段強制的例外狀況。

  • [delegate]
    指出函式是機器碼至 Managed 的委派回呼。委派在此做為機器碼中的函式指標。

Interop 記錄檔的第二行表示 Managed 簽章。這一行會針對 Managed 至機器碼的函式呼叫,識別呼叫機器碼的 Managed 函式。這一行會針對機器碼至 Managed 的函式呼叫,識別從機器碼呼叫的 Managed 函式。

第三行表示原生簽章 (如執行階段所期待的)。這行識別每個參數的資料型別,並提供如何封送處理 Managed 物件資料的資訊。執行階段會假設正確的型別是由 DllImportAttribute 屬性所指定,或是在 COM 介面簽章定義中指定。無法指定正確的型別是常見的錯誤,因為函式會以不正確的參數值執行,所以可能造成非預期的行為。

每種型別都具有預設的封送處理型別。請注意,Managed 型別的封送處理行為,對 COM 呼叫及 DllImportAttribute,或對委派回呼呼叫有所不同。您可以使用 MarshalAsAttribute 屬性來指定預設值以外的封送處理型別。您也必須為參考型別使用 ref 關鍵字,以識別代表實質型別 (Value Type) 的指標或指標的指標之任何參數。

下表顯示平台叫用的 Interop 記錄。

行號和說明

記錄項目

1 - 函式呼叫的型別

[pinvokeimpl][preservesig]

2 - Managed 簽章

bool PlatformDetector::SystemParametersInfo(uint , uint , System.Text.StringBuilder , uint );

3 - 原生簽章

BOOLEAN (I1_WINBOOL_VAL) SystemParametersInfo(unsigned int (U4_VAL) , unsigned int (U4_VAL) , WCHAR * (STRINGBUILDER_LPWSTR) , unsigned int (U4_VAL) );

下表顯示委派回呼的 Interop 記錄。

行號和說明

記錄項目

1 - 函式呼叫的型別

[preservesig][delegate]

2 - Managed 簽章

int WndProc::Invoke(WndProc , IntPtr , uint , uint , int );

3 - 原生簽章

int (I4_VAL) (*)(INT_PTR (I_VAL) , unsigned int (U4_VAL) , unsigned int (U4_VAL) , int (I4_VAL) )

下表顯示機器碼至 Managed COM 函式呼叫的 Interop 記錄,其中,如果發生 Managed 例外狀況,執行階段會傳回失敗的 HRESULT。

行號和說明

記錄項目

1 - 函式呼叫的型別

(無旗標)

2 - Managed 簽章

int N2MDualComponentImp.IN2MDualInterface::GetInt(N2MDualComponentImp.IN2MDualInterface This);

3 - 原生簽章

HRESULT GetInt(IN2MDualInterface *(INTF_VAL) this, [retval] int (I4_VAL) retval);

深層封送處理

.NET Compact Framework 3.5 版也支援 Interop 記錄的深層封送處理。深層封送處理中,會記錄有關結構或參考型別中所含的封送處理物件之資訊。

下列記錄輸出顯示的範例,是使用結構中封送處理物件的平台叫用呼叫。深層封送處區段的第一行,指定為何呼叫深層封送處理器。此範例呼叫深層封送處理器以計算結構的大小。記錄以位元組 (Byte) 顯示每一個物件的資料型別及大小。索引值 (例如 0004) 代表指定的變數之位元組位移。

DEEP MARSHAL: Get size
struct interoplogging.MyStruct
{
0000: Int32 myVar as Int32 (4 bytes)
0004: Int32 myVar2 as Int32 (4 bytes)
0008: String myString as WCHAR[10] (20 bytes)
}
DEEP MARSHAL: Total size = 28 bytes

[pinvokeimpl][preservesig]
void  interoplogging.Form1::MyAPI(interoplogging.MyStruct );
void MyAPI(MyStruct (NONBLIT_VALUETYPE_VAL) );

DEEP MARSHAL: Managed -> Native
struct interoplogging.MyStruct
{
0000: Int32 myVar as Int32 (4 bytes)
0004: Int32 myVar2 as Int32 (4 bytes)
0008: String myString as WCHAR[10] (20 bytes)
}
DEEP MARSHAL: Total size = 28 bytes

錯誤訊息

某些情況和例外狀況可能會使錯誤訊息記錄到記錄檔中。在檢查涉及原生元件與 DLL 相互操作,卻無法使用原生原始程式碼的問題時,這些訊息尤其有用。您可以使用錯誤訊息協助解決下列問題:

  • 機器碼至 Managed 的函式呼叫。

  • 執行階段 COM 介面呼叫。呼叫執行階段所實作的 COM 介面函式時,HRESULT 錯誤可以傳回機器碼。機器碼可以使用 Managed 物件封送處理做為 COM 介面,以呼叫數種執行階段實作的介面 (包括 IUnknownIDispatchIConnectionPointContainerIEnumConnectionPointsIConnectionPoint)。從函式呼叫傳回錯誤給其中一個介面的機器碼時,執行階段會列出適當的錯誤訊息,內含 HRESULT 及任何其他相關的資訊。

  • 機器碼預期會使用不支援的功能,例如 IDispatch::GetTypeInfo

  • 未實作的介面。機器碼可能會從預期 Managed COM 物件實作其他介面的 IUnknown::QueryInterface,接收到來自該處的 E_NOINTERFACE 錯誤。在此情況下,也會提供未實作介面的 GUID。

  • Managed 例外狀況。這些例外狀況可能發生在 Managed 函式呼叫內部,而導致呼叫提前傳回。呼叫 COM 時,執行階段會將例外狀況轉換成失敗的 HRESULT 值,並將此值傳回機器碼。但是,如果委派回呼或 COM 呼叫不預期 HRESULT 傳回值,您就無法確定委派回呼是否知道發生錯誤,因此而發生非預期的行為。在機器碼至 Managed Interop 函式呼叫期間發生例外狀況時,Interop 記錄內含錯誤訊息。這個訊息可以幫助您識別需要其他錯誤處理邏輯,才能使用機器碼的 Managed 函式。下列因素可能造成 Managed 例外狀況:

    • 在 COM 介面定義或 DllImportAttribute 簽章中使用 .NET Compact Framework 不支援的型別,會造成 JIT 編譯 (Compilation) 處理流程期間發生例外狀況。通常都有可接受的替代選項,例如使用 IntPtr

    • 當無法將實際物件強制為簽章中指定的型別,或是無法將物件資料轉換為要求的型別時,在執行階段呼叫函式時便會擲回例外狀況。這種情況通常會在將原生物件轉換為 Managed 物件時發生。

    • 判斷導致建立執行階段可呼叫的包裝函式 (RCW) 或 COM 可呼叫包裝函式 (CCW) 時,造成例外狀況的原因並不容易。當 Managed 例外狀況沒有提供詳細的錯誤訊息時,Interop 記錄檔即可協助決定這些問題的原因。

與 .NET Framework 的差異

COM 互通性的實作在 .NET Compact Framework 和完整的 .NET Framework 之間存在差異。.NET Compact Framework 不支援下列各項:

  • 建立含有不具指定 GUID 介面的 CCW。

  • 為繼承自 interop 組件類別的類別建立 RCW。

  • 使用泛型方法,建立含有非泛型介面的 CCW。

RCW 通常都會在最終化時清除,不過您也可以使用 ReleaseComObjectFinalReleaseComObject 方法來釋放與物件關聯的 RCW。如果使用這些進階選項來管理物件的存留期 (Lifetime),並嘗試在釋放物件後使用該物件來進行原生 COM 呼叫,便會擲回例外狀況,而且記錄檔會包含關於例外狀況原因的錯誤訊息。

載入器記錄檔

載入器記錄檔由兩個區段組成:標頭和主體。記錄檔的標頭含有下列資料:

  • 應用程式主要可執行檔的名稱。

  • 處理序 ID,由作業系統指定。

  • 記錄檔建立的日期與時間。

  • 用來執行應用程式的 .NET Compact Framework 的版本。

  • 執行應用程式平台的相關資料。

記錄檔的本文包含您的應用程式所載入的每一個組件之診斷程式。這項資訊可以幫助您找到應用程式啟動時,類別載入器所遇到的錯誤。

記錄檔的主體含有下列資料:

  • 強制型轉 (Coercion) 狀態,指出您的應用程式是否要以回溯相容性 (Backward Compatibility) 模式執行。

  • 追蹤每次組件載入,包括載入組件的位置,以及載入何種版本。

  • 載入模組時對每個模組指定的信任層級。

  • 與應用程式關聯的任何組態檔。

  • 找不到方法、型別、組件及模組。

  • 找不到平台叫用呼叫的原生 DLL 或函式。

下表列出載入器記錄檔的範例。行號只是大約的值。

行號和說明

記錄項目

1 - 處理序

Process [\Program Files\VW\VW.exe]

2 - 處理序 ID

Process ID [0x4d9585d2]

3 - 日期

Date [2005/02/25]

4 - 時間

Time [18:33:14]

5 - .NET Compact Framework 版本

NETCF [2.0.5035.00]

6 - 平台

Platform [Windows CE v4.20.1081 (PocketPC) WinCE4ARMV4 release Beta2 ARMV4 IJITv2]

7–14 - 全域組件快取作業

GAC: Updating GAC [0x0]

GAC: Checking .gac files inside [\Windows\]

GAC: Found [Microsoft .NET CF 2.0.GAC] .gac file.

GAC: Done with the file system check. Checking the registry.

GAC: Found [Microsoft .NET CF 2.0.GAC] registry entry.

GAC: Done with the registry check. Let's compare.

GAC: Entry [Microsoft .NET CF 2.0.GAC] is up to date.

GAC: GAC is up to date.

15 - 相容模式 (0.0.0.0 表示不是相容模式)

Compatibility mode [0.0.0.0]

16 - 正在載入模組

Loading module [\Windows\GAC_mscorlib_v2_0_0_0_cneutral_1.dll]

17 - 已載入模組

Loaded [mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=969DB8053D3322AC] from [\Windows\GAC_mscorlib_v2_0_0_0_cneutral_1.dll]

記錄每一個模組的最後兩個項目 (正在載入和已載入),以識別組件及其位置。載入器記錄中指出載入模組時的任何錯誤。

錯誤範例

本節的兩個範例顯示,如何使用載入器記錄檔以判斷何時發生錯誤。

下面的範例顯示,當載入器找不到組件時所寫入的記錄項目。

Loading module [\Program Files\VW\Golf.dll]
Attempt to load [\Program Files\VW\Golf.dll] has failed (err 0x80001000).
Loading module [\Program Files\VW\Golf.exe]
Attempt to load [\Program Files\VW\Golf.exe] has failed (err 0x80001000).
Failed to load [Golf, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]

下面的範例顯示,當載入器找不到特定型別時所寫入的記錄項目。

Missing Type. Type [Cars.Jetta], Assembly [Cars].
Missing Type. Class [Cars.Jetta], Assembly [Cars, Version=5.0.0.0, 
Culture=neutral, PublicKeyToken=null].

請參閱

工作

HOW TO:建立記錄檔

HOW TO:設定執行階段版本

概念

.NET Compact Framework HOW TO 主題

其他資源

.NET Compact Framework 中的互通性

.NET Compact Framework 中的效能和診斷