How to: Create Log Files

You can create log files that contain diagnostic information about interoperability, loading the program, and networking. You can enable logging by setting the registry keys. First, set a registry key to enable general logging, and then set the registry keys for the desired logging component and options.

You can use the following methods to set registry keys:

  • Use Remote Registry Editor in Visual Studio.

  • In the .NET Compact Framework 2.0 Service Pack 1, use the logging options in Remote Performance Monitor. For more information about Remote Performance Monitor, see How to: Monitor Performance at Run Time.

  • In the .NET Compact Framework 3.5, you can use the logging tool, NetCFLogging.exe, which provides a simple graphical user interface to enable and disable logging. This tool is included in the Power Toys for the .NET Compact Framework. For more information, see Power Toys for .NET Compact Framework.

  • Use the Registry and RegistryKey classes, which are supported in the .NET Compact Framework version 2.0 and later versions.

The following table summarizes the log files.

Logging component

Log file contents

Interop

Logs COM interop calls. Provides information about platform invoke calls and marshaling.

Error

Logs all unhandled and native exceptions. Errors are logged to a log file and to OutputDebugString. The log file is created for each assembly at the current path and applies to the current session. After the first occurrence of an unhandled or native exception, the log file is overwritten.

Loader

Logs information about loading the program. The file header contains the following information:

  • Application name.

  • Process ID (as provided by Windows Embedded CE).

  • Local date and time that the log file was created. The format is not global or culture-specific.

  • .NET Compact Framework version, such as 2.0.5021.00.

  • Platform-related information, such as Windows Embedded CE v5.0.1400 (CEPC) WinCE5x86 debug Dev i386 IJITv2.

The file provides the following information:

  • Coercion state (compatibility mode).

  • Trust level assigned to modules as they are loaded.

  • Failure to resolve method.

  • Failure to resolve type.

  • Failure to find or load assembly or module.

  • Success in assembly loading.

  • Invalid metadata version.

  • Failure to find platform invoke DLL.

  • Failure to find function within platform invoke DLL.

  • Name of the policy file or the fact of its absence.

  • Major errors during policy file processing.

  • Policy-based redirection of the managed assemblies.

You can also include information about the global assembly cache.

Networking

Logs network traffic. The networking log file is binary and cannot be accessed without the .NET Compact Framework log viewer, Logviewer.exe. In the .NET Compact Framework 3.5 and later, the log viewer is included in the Power Toys for the .NET Compact Framework. For more information, see Power Toys for .NET Compact Framework.

Because networking logging occurs at the Windows Sockets layer, the log file contains only network packet information. This includes the data sent over the network, which may be sensitive data if it is not encrypted.

Finalizer

Logs the class name of objects that are not disposed before they are discarded by the garbage collector. This log is supported in the .NET Compact Framework 3.5 and later versions.

The object names are not included in the log because the names are not available to the common language runtime (CLR). However, the class names for undisposed objects can help identify these objects. Undisposed objects can create performance issues in applications.

Note

In some cases, the .NET Compact Framework instead of the application code calls the finalizer.

This file includes the following information:

  • The time stamp that indicates when the finalizer ran the garbage collector on the the object.

  • The class of the object that was finalized.

Trace

Logs code exceptions for Windows Communication Foundation (WCF). On the desktop, .NET Framework supports three types of logging: trace, messaging, and event logging. WCF on the .NET Compact Framework supports only trace logging to track code exceptions, but it does not log warning and error messages.

This log is supported in the .NET Compact Framework 3.5 and later versions.

By default, log files are written to the directory that contains the application that is being diagnosed. However, you can specify a path and other options with registry keys as follows:

  • Use an alternate path to write the log files. This requires privileged access to the secure registry.

  • Include the application name in the log file name.

  • Include the process ID in the log file name.

A log file name has the following parts, where component can be "Interop", "Error", "Loader", "Network", "Finalizer", or "Trace":

netcf_application-name_component_processID.log

The application name and process ID are optional and are based on registry settings.

For example, a loader log file for an application named MyApp.exe might be named as follows:

netcf_MyApp_Loader_2066923010.log

For information about how to examine log files such as the interop and loader log file, see Log File Information.

To enable logging

  • Set the following Enabled key value to 1:

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

    This key value must be set to enable the six types of logging: interop, loader, error, networking, finalizer, and trace. Note that the subkeys under Logging do not exist by default.

    You can turn off all logging by setting this value to 0 (zero).

To specify a path for the log file (optional)

  • Set the following Path key value to a string that represents the location for the log files:

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

    This key can be accessed only by applications that can write to the secure registry. If a path is not specified, the log file is written to the directory that contains the application.

To include the application in the name (optional)

  • Set the following UseApp key value to 1:

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

    This key is useful if you want to run multiple applications and obtain separate log files for each application. If two applications are writing log files to the same directory, the older log file will always be overwritten by the newer log file when the second application runs. The UseApp key can be used as a differentiator for the log file.

To include the process ID in the name (optional)

  • Set the following UsePid key value to 1:

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

    This key is useful if you want to run one application multiple times and create separate logs for each instance. This setting adds the process ID to the log file name so that each instance of the application creates a new log file with a different name.

To log events as they occur (optional)

  • Set the following Flush key value to 1:

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

    This value causes the common language runtime (CLR) to write log events to the log file as they occur instead of keeping them in the buffer and writing them when the buffer is full. This setting adversely affects the performance of the application and might modify the timing of the application slightly. However, it can be useful for diagnosing problems related to application failures or other errors where you might want to see the last few events that resulted in the error. If this key is not present or not set, data is not written to the log files until the buffer is full.

Interop Logging

To enable interop logging

  • Set the following Enabled key value to 1:

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

Error Logging

To enable error logging

  • Set the following Enabled value to 1:

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

Loader Logging

To enable loader logging

  • Set the following Enabled value to 1 to enable logging for the loader, or set it to 2 to enable logging for the loader and the global assembly cache:

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

Networking Logging

To enable networking logging

  • Set the following Enabled value to 1:

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

    The networking log file is binary and cannot be read without the .NET Compact Framework log viewer, Logviewer.exe, which translates the log from binary format to human-readable format. In the .NET Compact Framework 3.5 and later, the log viewer is included in the Power Toys for the .NET Compact Framework. You can download this tool from the .NET Compact Framework Downloads page.

Finalizer Logging

To enable finalizer logging

  • Set the following Enabled value to 1:

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

Trace Logging

To enable WCF trace logging

  • Set the following Enabled value to 1:

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

Example

You can write an application that will set the registry values. The example in this section contains the following methods that handle the necessary registry tasks:

  • The EnableLogging method enables general logging and contains parameters to specify an alternate path for the log file, to specify whether the application name and process ID will be added to the log file name, and to specify whether events will be logged as they occur.

  • The SetInteropLogging, SetLoaderLogging, and SetNetworkLogging methods set the corresponding Enabled key value to 1 so that logging for that component is enabled.

  • The DisableLogging method disables all logging.

  • The WriteLoggingSettings method recursively examines the keys under the Logging subkey and writes their names and values to a log file. The log file is named logsettings.txt and is located in the directory that contains this example application.

' 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\Network" 
    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\Network")
    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\\Network";
    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\\Network");
    string[] netNames = rkNetworking.GetValueNames();
    for (int x = 0; x < netNames.Length; x+)
    {
        sw.WriteLine(netNames[x].ToString() + ": " + rkNetworking.GetValue(netNames[x]).ToString());
    }
   sw.Close();
}

Compiling the Code

This example requires references to the following namespaces:

See Also

Concepts

Log File Information

Other Resources

Performance and Diagnostics in the .NET Compact Framework

Change History

Date

History

Reason

February 2009

Corrected name of Networking registry key

Customer feedback.