Send mail to the author(s)

October 28, 2004

Ultra-Simple Application Logging

This is a really cool technique that you can use to add simple logging/tracing functionality to your .NET Compact Framework apps. In Windows CE, there is a Win32 API which goes by the moniker of SetStdioPathW. By calling this API, you can redirect standard input, output and error output. The cool thing about this is that you can actually redirect the I/O to a text file! By redirecting standard output like this, you can scatter Console.WriteLine()'s all throughout your code and hey presto! Instant instrumentation.

So let's look at some VB code showing how to do this. As a best practice, it is always a good idea to revert the I/O redirection when you are done. To do this, we need to find out what the current standard I/O path is and this can be achieved by calling GetStdioPathW. The method signature for P/Invoking this is:

    <DllImport("coredll")> _

    Public Shared Function GetStdioPathW( _

        ByVal id As Integer, _

        ByVal originalPath As StringBuilder, _

        ByRef pathLength As Integer _

        ) As Integer

    End Function

And you call it like this:

    Dim STDOUT As Integer = 1

    Dim originalPath As New StringBuilder

    Dim pathLength As Integer = 256

    GetStdioPathW(STDOUT, originalPath, pathLength)

Now that you have retrieved the existing standard I/O configuration, you can set the I/O path. To do that, you need to P/Invoke SetStdioPathW. The signature for this is as follows:

    <DllImport("coredll")> _

    Public Shared Function SetStdioPathW( _

        ByVal id As Integer, _

        ByVal originalPath As String _

        ) As Integer

    End Function

And you call it like this:

    Dim myLogFile As String = "\My Documents\MyLogFile.txt"

    SetStdioPathW(STDOUT, myLogFile)

So, putting all this together in a simple VB Windows CE console app, we get something like this:

    Imports System.Runtime.InteropServices

    Imports System.Text

 

    Public Class MyConsoleApp

        <DllImport("coredll")> _

                Public Shared Function GetStdioPathW( _

                ByVal id As Integer, _

                ByVal originalPath As StringBuilder, _

                ByRef pathLength As Integer _

                ) As Integer

        End Function

 

        <DllImport("coredll")> _

        Public Shared Function SetStdioPathW( _

            ByVal id As Integer, _

            ByVal newPath As String _

            ) As Integer

        End Function

 

        Shared Sub Main()

            Dim STDOUT As Integer = 1

 

            ' Retrieve the existing path for standard output

            Dim originalPath As New StringBuilder

            Dim pathLength As Integer = 256

            GetStdioPathW(STDOUT, originalPath, pathLength)

 

            ' Set standard output to redirecto to a

            ' file in MyLogFile.txt

            Dim myLogFile As String = "\MyLogFile.txt"

            SetStdioPathW(STDOUT, myLogFile)

 

            ' Write to standard output

            Console.WriteLine("Hello World 1")

            Console.WriteLine("Hello World 2")

            Console.WriteLine("Hello World 3")

 

            ' Revert the settings to their original values

            SetStdioPathW(STDOUT, originalPath.ToString())

        End Sub

    End Class

 

Friday, October 29, 2004 2:42:36 PM (GMT Daylight Time, UTC+01:00)
Absolutely amazing. Wish I would have known that about nine months ago. Oh well.

Question: are the contents flushed to disk with every write operation? Is the file shared for reading? My point is, can a user open the log in another process while the main process is running and see the messages?

Tuesday, July 26, 2005 1:47:36 AM (GMT Daylight Time, UTC+01:00)
it is right
Thursday, June 08, 2006 7:49:53 AM (GMT Daylight Time, UTC+01:00)
Hie, excellent code!

I manage to translate this to C# and is working in Pocket PC 2003 emulator.

But when i run in the real device, it crashes at GetStdioPathW. Is it because the device don't have a console? or is it something else?
cutie
Comments are closed.