如何:创建日志文件

更新:2007 年 11 月

您可以创建日志文件,并使其包含与互操作性、程序加载和网络有关的诊断信息。通过设置注册表项,可以启用日志记录。首先,设置一个注册表项以启用常规日志记录,然后针对所需的日志记录组件和选项来设置注册表项。

可以使用下列方法设置注册表项:

  • 使用 Visual Studio 中的远程注册表编辑器。

  • 在 .NET Compact Framework 2.0 Service Pack 1 中,使用远程性能监视器中的日志记录选项。有关远程性能监视器的更多信息,请参见如何:在运行时监视性能

  • 在 .NET Compact Framework 3.5 中,可以使用日志记录工具 NetCFLogging.exe,该工具提供了用于启用和禁用日志记录的简单的图形用户界面。此工具包括在 Power Toys for .NET Compact Framework 中。有关更多信息,请参见 Power Toys for .NET Compact Framework

  • 使用 RegistryRegistryKey 类,.NET Compact Framework 2.0 版及更高版本支持这些类。

下表对这些日志文件进行了总结。

日志记录组件

日志文件内容

互操作

记录 COM 互操作调用。提供有关平台调用和封送处理的信息。

错误

记录所有未处理的异常和本机异常。将错误记录到日志文件和 OutputDebugString 中。将为位于当前路径的每个程序集创建日志文件,并将其应用于当前会话。在第一次出现未处理的异常或本机异常之后,将覆盖日志文件。

加载程序

记录有关程序加载的信息。文件标头包含下列信息:

  • 应用程序名称。

  • 进程 ID(由 Windows Embedded CE 提供)。

  • 创建日志文件的本地日期和时间。其格式不是全局性的,而是区域性特定的。

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

  • 与平台相关的信息,例如 Windows Embedded CE v5.0.1400 (CEPC) WinCE5x86 debug Dev i386 IJITv2。

文件提供以下信息:

  • 强制状态(兼容性模式)。

  • 加载模块时为模块指定的信任级别。

  • 解析方法时失败。

  • 解析类型时失败。

  • 查找或加载程序集或模块时失败。

  • 程序集加载成功。

  • 无效的元数据版本。

  • 查找平台调用 DLL 时失败。

  • 在平台调用 DLL 中查找函数时失败。

  • 策略文件的名称,或者指出缺少该文件的事实。

  • 策略文件处理过程中的主要错误。

  • 托管程序集基于策略的重定向。

此外,还可以包括有关全局程序集缓存的信息。

网络

记录网络流量。网络日志文件是二进制文件,如果没有 .NET Compact Framework 日志查看器 Logviewer.exe,则无法访问该文件。在 .NET Compact Framework 3.5 及更高版本中,该日志查看器包含在 Power Toys for .NET Compact Framework 中。有关更多信息,请参见 Power Toys for .NET Compact Framework

由于网络日志记录发生在 Windows 套接字层,因此日志文件只包含网络数据包信息。这包括通过网络发送的数据,其中有些可能是敏感数据,因而需要进行加密。

终结器

记录在垃圾回收器丢弃对象之前未释放这些对象的类名。.NET Compact Framework 3.5 及更高版本支持此日志。

对象名不包含在日志中,原因是这些名称对于公共语言运行时 (CLR) 不可用。但是,未释放的对象的类名有助于识别这些对象。未释放的对象在应用程序中可能造成性能问题。

说明:

某些情况下,调用终结器的是 .NET Compact Framework 而不是应用程序代码。

此文件包含以下信息:

  • 指示终结器何时对对象运行垃圾回收器的时间戳。

  • 被终结对象的类。

跟踪

记录 Windows Communication Foundation (WCF) 的代码异常。桌面 .NET Framework 支持三种日志记录:跟踪、消息处理和事件日志记录。.NET Compact Framework 上的 WCF 只支持通过跟踪日志记录来跟踪代码异常,但它不记录警告和错误消息。

.NET Compact Framework 3.5 及更高版本支持此日志。

默认情况下,系统会将日志文件写入包含被诊断的应用程序的目录。但是,您可以使用注册表项指定路径和其他选项,如下所示:

  • 使用其他路径写入日志文件。这需要安全注册表的访问权限。

  • 在日志文件名中包含应用程序名称。

  • 在日志文件名中包含进程 ID。

日志文件名由以下几部分组成,其中组件 可以是“互操作”、“错误”、“加载程序”或“网络”、“终结器”或“跟踪”:

netcf_应用程序名称_组件_进程 ID.log

应用程序名称和进程 ID 为可选项,它们基于注册表设置。

例如,对于名为 MyApp.exe 的应用程序,其加载程序日志文件可命名如下:

netcf_MyApp_Loader_2066923010.log

有关如何检查互操作日志文件和加载程序日志文件等日志文件的信息,请参见日志文件信息

启用日志记录

  • 将以下 Enabled 项的值设置为 1:

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

    必须设置此项值才能启用六种日志记录:互操作、加载程序、错误、网络、终结器和跟踪。请注意,默认情况下,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

    设置此值后,公共语言运行时 (CLR) 便会在事件发生时立即将日志事件写入日志文件,而不是先将事件保存在缓冲区中,并在写满缓冲区时才写入日志文件。此设置会给应用程序的性能带来负面影响,并可能稍稍修改应用程序的计时。但是,它有助于诊断与应用程序故障或其他错误有关的问题,因为您可能需要查看导致错误的最后几个事件。如果不存在或未设置此项,则系统将只有在写满缓冲区后,才会向日志文件写入数据。

互操作日志记录

启用互操作日志记录

  • 将以下 Enabled 项的值设置为 1:

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

错误日志记录

启用错误日志记录

  • 将以下 Enabled 值设置为 1:

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

加载程序日志记录

启用加载程序日志记录

  • 将以下 Enabled 值设置为 1 可为加载程序启用日志记录,设置为 2 可为加载程序和全局程序集缓存启用日志记录:

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

网络日志记录

启用网络日志记录

  • 将以下 Enabled 值设置为 1:

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

    网络日志文件是二进制文件,如果没有 .NET Compact Framework 日志查看器 Logviewer.exe,将无法读取该文件。该查看器可将日志从二进制格式转换为人类可读的格式。在 .NET Compact Framework 3.5 及更高版本中,该日志查看器包含在 Power Toys for .NET Compact Framework 中。可以从 .NET Compact Framework Downloads page(.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 方法禁用所有日志记录。

  • WriteLoggingSettings 方法递归检查 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 的性能和诊断