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:
The file provides the following information:
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:
|
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
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. |