HOW TO:建立記錄檔

更新:2007 年 11 月

您可以建立含有關於互通性 (Interoperability)、載入程式和網路診斷資訊的記錄檔。也可以設定登錄機碼 (Registry Key) 來啟用記錄。首先,設定一個登錄機碼以啟用一般記錄,然後再為特別需要記錄的元件和選項設定個別的登錄機碼。

您可以使用下列方法設定登錄機碼:

  • 使用 Visual Studio 中的遠端登錄編輯程式。

  • 在 .NET Compact Framework 2.0 Service Pack 1 的 Remote Performance Monitor 中使用記錄選項。如需 Remote Performance Monitor 的詳細資訊,請參閱 HOW TO:監視執行階段的效能

  • 在 .NET Compact Framework 3.5 中,您可以使用記錄工具 NetCFLogging.exe 提供簡單的圖形使用者介面,以啟用和停用記錄。這個工具隨附於 .NET Compact Framework 的 Power Toys。如需詳細資訊,請參閱 .NET Compact Framework 的 Power Toy (英文)。

  • 使用 RegistryRegistryKey 類別,這兩個類別在 .NET Compact Framework 2.0 版和之後的版本中支援。

下表是記錄檔的摘要。

記錄元件

記錄檔內容

Interop

記錄 COM interop 呼叫。提供平台叫用 (Invoke) 呼叫和封送處理 (Marshaling) 的相關資訊。

錯誤

記錄所有未處理和原生的例外狀況。錯誤會記錄到記錄檔和 OutputDebugString 中。記錄檔會針對每個組件建立於目前路徑,並會套用到目前的工作階段。在發生第一次未處理或原生的例外狀況之後,此記錄檔便會被覆寫。

載入器

記錄載入程式的資訊。這個檔案標頭包含下列資訊:

  • 應用程式名稱。

  • 處理序 ID (如 Windows Embedded CE 所提供)。

  • 記錄檔建立的當地日期與時間。格式不是全域或是文化特性專屬。

  • .NET Compact Framework 版本,例如 2.0.5021.00。

  • 平台相關的資訊,例如 Windows Embedded CE v5.0.1400 (CEPC) WinCE5x86 debug Dev i386 IJITv2。

檔案會提供下列資訊:

  • 強制型轉 (Coercion) 狀態 (相容模式)。

  • 載入模組時指派給模組的信任層級。

  • 無法解析方法。

  • 無法解析型別。

  • 無法找到或載入組件或模組。

  • 順利載入組件。

  • 無效中繼資料 (Metadata) 版本。

  • 找不到平台叫用 DLL。

  • 無法在平台叫用 DLL 內找到函式。

  • 原則檔的名稱錯誤或它根本就不存在。

  • 處理原則檔期間發生嚴重錯誤。

  • Managed 組件依原則檔指示進行重新導向。

您也可以加入有關全域組件快取的資訊。

網路

記錄網路流量網路記錄檔為二進位檔,而且必須使用 .NET Compact Framework 記錄檔檢視器 Logviewer.exe 存取。在 .NET Compact Framework 3.5 和之後的版本中,記錄檔檢視器包含在 .NET Compact Framework 的 Power Toys 內。如需詳細資訊,請參閱 .NET Compact Framework 的 Power Toy (英文)。

由於網路記錄是在 Windows Sockets 層發生,因此記錄檔只會包含網路封包資訊。其中包括透過網路傳送的資料,該資料如果未經加密,可能會是機密資料。

完成項

記錄物件的類別名稱,這些物件不會在記憶體回收行程捨棄之前處置。.NET Compact Framework 3.5 (含) 以後版本中支援這個記錄檔。

物件名稱不會包含在記錄中,因為名稱無法用於 Common Language Runtime (CLR)。不過,未處置物件的類別名稱可幫助您識別這些物件。未處置物件可能在應用程式中造成效能問題。

注意事項:

在某些情況下,.NET Compact Framework 會替代應用程式程式碼呼叫完成項。

這個檔案包括下列資訊:

  • 時間戳記,表示完成項在物件上執行記憶體回收行程的時間。

  • 已完成物件的類別。

追蹤

記錄 Windows Communication Foundation (WCF) 的程式碼例外狀況。在桌上型電腦上,.NET Framework 支援三種記錄類型:追蹤、訊息和事件記錄。.NET Compact Framework 上的 WCF 只支援追蹤記錄來追蹤程式碼例外狀況,但不會記錄警告和錯誤訊息。

.NET Compact Framework 3.5 (含) 以後版本中支援這個記錄檔。

根據預設,記錄檔會寫入至目錄,其中包含正要診斷的應用程式。不過,您可以利用登錄機碼指定路徑和其他選項,如下所示:

  • 將記錄檔寫入其他路徑。這需要有存取安全登錄的權限

  • 將應用程式名稱併入記錄檔名稱

  • 將處理序 ID 併入記錄檔名稱

記錄檔名稱包含下列部分,其中 component 可以是 "Interop"、"Error"、"Loader"、"Network"、"Finalizer" 或 "Trace":

netcf_application-name_component_processID.log

應用程式名稱和處理序 ID 是選擇性的,並且根據登錄設定而定。

例如,名為 MyApp.exe 之應用程式的載入器記錄檔可能命名如下:

netcf_MyApp_Loader_2066923010.log

如需如何檢查記錄檔 (例如 interop 和載入器記錄檔) 的詳細資訊,請參閱記錄檔資訊

若要啟用記錄

  • 請將下列 Enabled 機碼值設為 1:

    HKLM\Software\Microsoft\.NETCompactFramework\Diagnostics\Logging\Enabled

    您必須設定這個機碼值,才能啟用六種記錄類型:Interop、載入器、錯誤、網路、完成項和追蹤。請注意,依預設 Logging 下的子機碼值並不存在。

    您可以將此值設定為 0 (零),關閉所有記錄。

若要指定記錄檔的路徑 (選擇項)

  • 將下列 Path 機碼值設為代表記錄檔位置的字串:

    HKLM\Security\.NETCompactFramework\Diagnostics\Logging\Path

    這個機碼只能由可以寫入安全登錄的應用程式存取。如果未指定路徑,記錄檔將寫入包含應用程式的目錄。

若要將應用程式併入名稱 (選擇項)

  • 請將下列 UseApp 機碼值設為 1:

    HKLM\Software\Microsoft\.NETCompactFramework\Diagnostics\Logging\UseApp

    如果您想要執行多個應用程式並取得每個應用程式的個別記錄檔,這個機碼值會很有用。如果兩個應用程式將記錄檔寫入至同一個目錄,則第二個應用程式執行時,較舊的記錄檔會固定被較新的記錄檔覆寫。UseApp 機碼可以做為記錄檔的區別器。

若要在名稱中納入處理序 ID (選擇項)

  • 請將下列 UsePid 機碼值設為 1:

    HKLM\Software\Microsoft\.NETCompactFramework\Diagnostics\Logging\UsePid

    如果您要多次執行某個應用程式,並且為每個執行個體建立個別的記錄檔,則這個機碼會十分有用。這個設定會將處理序 ID 加入至記錄檔名稱,如此應用程式的每個執行個體就會以不同名稱建立新的記錄檔。

若要在事件發生時記錄它們 (選擇項)

  • 請將下列 Flush 機碼值設為 1:

    HKLM\Software\Microsoft\.NETCompactFramework\Diagnostics\Logging\Flush

    此值會導致 Common Language Runtime (CLR) 在記錄檔事件發生時,將它們寫入至記錄檔,而不是將其保存在緩衝區,然後在緩衝區已滿時進行寫入。這個設定會對應用程式的效能造成不良影響,而且可能稍微修改應用程式的計時。不過,對於診斷與應用程式失敗或是其他錯誤 (您想查看導致該錯誤的最後幾個事件) 相關的問題時相當有用。如果這個機碼不存在或是未設定,資料就不會寫入記錄檔,直到緩衝區已滿為止。

Interop 記錄

啟用 interop 記錄

  • 請將下列 Enabled 機碼值設為 1:

    HKLM\Software\Microsoft\.NETCompactFramework\Diagnostics\Logging\Interop\Enabled

錯誤記錄

啟用錯誤記錄

  • 請將下列 Enabled 值設為 1:

    HKLM\Software\Microsoft\.NETCompactFramework\Diagnostics\Logging\Error\Enabled

Loader 記錄

啟用載入器記錄

  • 將下列 Enabled 值設為 1,可啟用載入器的記錄,或是將它設為 2,可啟用載入器和全域組件快取的記錄:

    HKLM\Software\Microsoft\.NETCompactFramework\Diagnostics\Logging\Loader\Enabled

Networking 記錄

啟用網路記錄

  • 請將下列 Enabled 值設為 1:

    HKLM\Software\Microsoft\.NETCompactFramework\Diagnostics\Logging\Networking\Enabled

    網路記錄檔是二進位檔,而且必須使用 .NET Compact Framework 記錄檔檢視器 Logviewer.exe 讀取,該檢視器會將記錄檔從二進位格式轉譯成人工可讀取的格式。在 .NET Compact Framework 3.5 (含) 以後版本中,記錄檔檢視器會包含在 .NET Compact Framework 的 Power Toys 中。您可以從 .NET Compact Framework 下載網頁 (英文) 下載這個工具。

完成項記錄

啟用完成項記錄

  • 請將下列 Enabled 值設為 1:

    HKLM\Software\Microsoft\.NETCompactFramework\Diagnostics\Logging\Finalizer\Enabled

追蹤記錄

啟用 WCF 追蹤記錄

  • 請將下列 Enabled 值設為 1:

    HKLM\Software\Microsoft\.NETCompactFramework\Diagnostics\Logging\WCF\Enabled

範例

您可以使用遠端登錄編輯程式設定登錄機碼值,或是撰寫將設定這些值的應用程式。本章節中的範例包含下列方法,可用於處理必要的登錄工作:

  • EnableLogging 方法會啟用一般記錄,並且包含一些參數,可指定記錄檔替代路徑、指定應用程式名稱和處理序 ID 是否將加入記錄檔名稱中,以及指定是否將在事件發生時加以記錄。

  • SetInteropLogging、SetLoaderLogging 和 SetNetworkLogging 方法會將對應的 Enabled 機碼值設為 1,以啟用記錄該元件。

  • DisableLogging 方法會停用所有記錄

  • WriteLogSettings 方法會遞迴地檢查 Logging 子機碼下的機碼值,然後將它們的名稱和值寫入至記錄檔。記錄檔會命名為 logsettings.txt,並且位於包含範例應用程式的目錄中。

' This method enables general logging. It contains parameters
' to specify a path, and Boolean values of true to include
' the application name, process ID, and events in the log.
Private Sub EnableLogging(ByVal useApp As Boolean, ByVal usePid As Boolean, ByVal useFlush As Boolean) 
    ' Specify values for setting the registry.
    Dim userRoot As String = "HKEY_LOCAL_MACHINE"
    Dim subkey As String = "SOFTWARE\Microsoft\.NETCompactFramework\Diagnostics\Logging"
    Dim keyName As String = userRoot + "\" + subkey

    ' Set the Enabled registry value.
    Registry.SetValue(keyName, "Enabled", 1)

    If useApp = True Then
        Registry.SetValue(keyName, "UseApp", 1)
    Else
        Registry.SetValue(keyName, "UseApp", 0)
    End If 
    If usePid = True Then
        Registry.SetValue(keyName, "UsePid", 1)
    Else
        Registry.SetValue(keyName, "UsePid", 0)
    End If 
    If useFlush = True Then
        Registry.SetValue(keyName, "UseFlush", 1)
    Else
        Registry.SetValue(keyName, "UseFlush", 0)
    End If

End Sub

' This method sets the Enabled key value to 1
' so that logging for Interoperability is enabled.
Private Sub SetInteropLogging(ByVal logOn As Boolean) 
    ' Specify values for setting the registry.
    Dim userRoot As String = "HKEY_LOCAL_MACHINE"
    Dim subkey As String = "Software\Microsoft\.NETCompactFramework\Diagnostics\Logging\Interop"
    Dim keyName As String = userRoot + "\" + subkey

    Dim logSet As Integer
    If logOn = True Then
        logSet = 1
    Else
        logSet = 0
    End If 
    ' Set the registry value.
    Try
        Registry.SetValue(keyName, "Enabled", logSet)
        If logOn = True Then
            MessageBox.Show("Interop Logging On")
        Else
            MessageBox.Show("Interop Logging Off")
        End If
    Catch ex As System.Exception
        MessageBox.Show(ex.Message)
    End Try

End Sub


' This method sets the Enabled key value to 1
' so that logging for class loading is enabled.
Private Sub SetLoaderLogging(ByVal logOn As Boolean) 
    ' Specify values for setting the registry.
    Dim userRoot As String = "HKEY_LOCAL_MACHINE"
    Dim subkey As String = "Software\Microsoft\.NETCompactFramework\Diagnostics\Logging\Loader"
    Dim keyName As String = userRoot + "\" + subkey

    Dim logSet As Integer
    If logOn = True Then
        logSet = 1
    Else
        logSet = 0
    End If 
    ' Set the registry value.
    Try
        Registry.SetValue(keyName, "Enabled", logSet)
        If logOn = True Then
            MessageBox.Show("Loader Logging On")
        Else
            MessageBox.Show("Loader Loggin Off")
        End If
    Catch ex As System.Exception
        MessageBox.Show(ex.Message)
    End Try

End Sub


' This method sets the Enabled key value to 1,
' so that logging for networking is enabled.
Private Sub SetNetworkLogging(ByVal logOn As Boolean) 
    ' Specify values for setting the registry.
    Dim userRoot As String = "HKEY_LOCAL_MACHINE"
    Dim subkey As String = "Software\Microsoft\.NETCompactFramework\Diagnostics\Logging\Networking"
    Dim keyName As String = userRoot + "\" + subkey

    Dim logSet As Integer
    If logOn = True Then
        logSet = 1
    Else
        logSet = 0
    End If 
    ' Set the registry value.
    Try
        Registry.SetValue(keyName, "Enabled", logSet)
        If logOn = True Then
            MessageBox.Show("Networking Logging On")
        Else
            MessageBox.Show("Networking Logging Off")
        End If
    Catch ex As System.Exception
        MessageBox.Show(ex.Message)
    End Try

End Sub


' This method disables all logging.
Private Sub DisableLogging() 
    ' Specify values for setting the registry.
    Dim userRoot As String = "HKEY_LOCAL_MACHINE"
    Dim subkey As String = "SOFTWARE\Microsoft\.NETCompactFramework\Diagnostics\Logging"
    Dim keyName As String = userRoot + "\" + subkey

    ' Set the Enabled registry value.
    Registry.SetValue(keyName, "Enabled", 0)
    MessageBox.Show("Logging Disabled")

End Sub


' This method recursively examines the keys
' under the Logging subkey and writes their
' key names and values to a log file. It saves
' the information in "logsettings.txt", located
' in the directory that contains this example
' application.
Private Sub WriteLoggingSettings() 
    Dim sw As New StreamWriter("logsettings.txt", False)
    sw.WriteLine("General Logging Settings:")
    Dim rkLogging As RegistryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\.NETCompactFramework\Diagnostics\Logging")
    Dim valNames As String() = rkLogging.GetValueNames()
    Dim x As Integer
    For x = 0 To valNames.Length
        sw.WriteLine(valNames(x).ToString() + ": " + rkLogging.GetValue(valNames(x)).ToString())
    Next x

    sw.WriteLine()
    sw.WriteLine("Interop Logging:")
    Dim rkInterop As RegistryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\.NETCompactFramework\Diagnostics\Logging\Interop")
    Dim interopNames As String() = rkInterop.GetValueNames()

    For x = 0 To interopNames.Length
        sw.WriteLine(interopNames(x).ToString() + ": " + rkInterop.GetValue(interopNames(x)).ToString())
    Next x

    sw.WriteLine()
    sw.WriteLine("Loader Logging:")
    Dim rkLoader As RegistryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\.NETCompactFramework\Diagnostics\Logging\Loader")
    Dim loaderNames As String() = rkLoader.GetValueNames()
    For x = 0 To loaderNames.Length
        sw.WriteLine(loaderNames(x).ToString() + ": " + rkLoader.GetValue(loaderNames(x)).ToString())
    Next x

    sw.WriteLine()
    sw.WriteLine("Networking Logging:")
    Dim rkNetworking As RegistryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\.NETCompactFramework\Diagnostics\Logging\Networking")
    Dim netNames As String() = rkNetworking.GetValueNames()
    For x = 0 To netNames.Length
        sw.WriteLine(netNames(x).ToString() + ": " + rkNetworking.GetValue(netNames(x)).ToString())
    Next x
    sw.Close()
End Sub
// This method enables general logging. It contains parameters
// to specify a path, and Boolean values of true to include
// the application name, process ID, and events in the log.
private void EnableLogging(bool useApp, bool usePid, bool useFlush)
{
    // Specify values for setting the registry.
    string userRoot = "HKEY_LOCAL_MACHINE";
    string subkey = "SOFTWARE\\Microsoft\\.NETCompactFramework\\Diagnostics\\Logging";
    string keyName = userRoot + "\\" + subkey;

    // Set the Enabled registry value.
    Registry.SetValue(keyName, "Enabled", 1);

    if (useApp == true)
        Registry.SetValue(keyName, "UseApp", 1);
    else
        Registry.SetValue(keyName, "UseApp", 0);

    if (usePid == true)
        Registry.SetValue(keyName, "UsePid", 1);
    else
        Registry.SetValue(keyName, "UsePid", 0);

    if (useFlush == true)
        Registry.SetValue(keyName, "UseFlush", 1);
    else
        Registry.SetValue(keyName, "UseFlush", 0);
}

// This method sets the Enabled key value to 1
// so that logging for Interoperability is enabled.
private void SetInteropLogging(bool logOn)
{
    // Specify values for setting the registry.
    string userRoot = "HKEY_LOCAL_MACHINE";
    string subkey = "Software\\Microsoft\\.NETCompactFramework\\Diagnostics\\Logging\\Interop";
    string keyName = userRoot + "\\" + subkey;

    int logSet;
    if(logOn == true)
      logSet = 1;
    else
      logSet = 0;

    // Set the registry value.
    try
    {
     Registry.SetValue(keyName, "Enabled", logSet);
     if(logOn == true)
        MessageBox.Show("Interop Logging On");
     else
        MessageBox.Show("Interop Logging Off");
     }
     catch(System.Exception ex)
     {
        MessageBox.Show(ex.Message);
     }
}

// This method sets the Enabled key value to 1
// so that logging for class loading is enabled.
private void SetLoaderLogging(bool logOn)
{
    // Specify values for setting the registry.
    string userRoot = "HKEY_LOCAL_MACHINE";
    string subkey = "Software\\Microsoft\\.NETCompactFramework\\Diagnostics\\Logging\\Loader";
    string keyName = userRoot + "\\" + subkey;

    int logSet;
    if(logOn == true)
    logSet = 1;
    else
    logSet = 0;

    // Set the registry value.
    try
    {
        Registry.SetValue(keyName, "Enabled", logSet);
        if(logOn == true)
        MessageBox.Show("Loader Logging On");
        else
        MessageBox.Show("Loader Logging Off");
    }
    catch(System.Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

  // This method sets the Enabled key value to 1
  // so that logging for networking is enabled.
  private void SetNetworkLogging(bool logOn)
  {
    // Specify values for setting the registry.
    string userRoot = "HKEY_LOCAL_MACHINE";
    string subkey = "Software\\Microsoft\\.NETCompactFramework\\Diagnostics\\Logging\\Networking";
    string keyName = userRoot + "\\" + subkey;

    int logSet;
    if(logOn == true)
      logSet = 1;
    else
      logSet = 0;

    // Set the registry value.
    try
    {
         Registry.SetValue(keyName, "Enabled", logSet);
         if(logOn == true)
            MessageBox.Show("Networking Logging On");
         else
            MessageBox.Show("Networking Loggin Off");
     }
     catch(System.Exception ex)
     {
        MessageBox.Show(ex.Message);
     }
  }

// This method disables all logging.
private void DisableLogging()
{
    // Specify values for setting the registry.
    string userRoot = "HKEY_LOCAL_MACHINE";
    string subkey = "SOFTWARE\\Microsoft\\.NETCompactFramework\\Diagnostics\\Logging";
    string keyName = userRoot + "\\" + subkey;

    // Set the Enabled registry value.
    Registry.SetValue(keyName, "Enabled", 0);
    MessageBox.Show("Logging Disabled");
}

// This method recursively examines the keys
// under the Logging subkey and writes their
// key names and values to a log file. It saves
// the information in "logsettings.txt" located
// in the directory that contains this 
// example application.
private void WriteLoggingSettings()
{
    StreamWriter sw = new StreamWriter("logsettings.txt",false);
    sw.WriteLine("General Logging Settings:");
    RegistryKey rkLogging = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\.NETCompactFramework\\Diagnostics\\Logging");
    string[] valNames = rkLogging.GetValueNames();
    for (int x = 0; x < valNames.Length; x++)
    {
        sw.WriteLine(valNames[x].ToString() + ": " + rkLogging.GetValue(valNames[x]).ToString());
    }

    sw.WriteLine();
    sw.WriteLine("Interop Logging:");
    RegistryKey rkInterop = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\.NETCompactFramework\\Diagnostics\\Logging\\Interop");
    string[] interopNames = rkInterop.GetValueNames();
    for (int x = 0; x < interopNames.Length; x++)
    {
        sw.WriteLine(interopNames[x].ToString() + ": " + rkInterop.GetValue(interopNames[x]).ToString());
    }

    sw.WriteLine();
    sw.WriteLine("Loader Logging:");
    RegistryKey rkLoader = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\.NETCompactFramework\\Diagnostics\\Logging\\Loader");
    string[] loaderNames = rkLoader.GetValueNames();
    for (int x = 0; x < loaderNames.Length; x++)
    {
        sw.WriteLine(loaderNames[x].ToString() + ": " + rkLoader.GetValue(loaderNames[x]).ToString());
    }

    sw.WriteLine();
    sw.WriteLine("Networking Logging:");
    RegistryKey rkNetworking = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\.NETCompactFramework\\Diagnostics\\Logging\\Networking");
    string[] netNames = rkNetworking.GetValueNames();
    for (int x = 0; x < netNames.Length; x++)
    {
        sw.WriteLine(netNames[x].ToString() + ": " + rkNetworking.GetValue(netNames[x]).ToString());
    }
   sw.Close();
}

編譯程式碼

這個範例需要下列命名空間的參考:

請參閱

概念

記錄檔資訊

其他資源

.NET Compact Framework 中的效能和診斷