<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>Vista</title>
        <link>http://www.onteorasoftware.com/category/32.aspx</link>
        <description>Vista</description>
        <language>en-US</language>
        <copyright>Ken Tucker</copyright>
        <generator>Subtext Version 2.1.2.2</generator>
        <item>
            <title>Compact Framework DataGrid Alternating Color</title>
            <link>http://blog.onteorasoftware.net/archive/2007/10/19/compact-framework-datagrid-alternating-color.aspx</link>
            <description>&lt;p&gt;
One of the things I miss from the Windows Forms DataGrid is the ability to have the rows alternating in color.  For this example I created a custom DataGridTextBox column which will display each other row in an different color. Basically I override the paint method to call the existing paint method with a different back color brush for every other column.
&lt;/p&gt;
 
&lt;p&gt;
 
&lt;/p&gt;
 
&lt;p&gt;
Public Class AltColorColumn&lt;br /&gt;
    Inherits DataGridTextBoxColumn  
&lt;/p&gt;
&lt;p&gt;
    Private m_AltColor As Color&lt;br /&gt;
    Public Property AltColor() As Color&lt;br /&gt;
        Get&lt;br /&gt;
            Return m_AltColor&lt;br /&gt;
        End Get&lt;br /&gt;
        Set(ByVal value As Color)&lt;br /&gt;
            m_AltColor = value&lt;br /&gt;
        End Set&lt;br /&gt;
    End Property  
&lt;/p&gt;
&lt;p&gt;
    Protected Overrides Sub Paint(ByVal g As System.Drawing.Graphics, ByVal bounds As System.Drawing.Rectangle, ByVal source As System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer, ByVal backBrush As System.Drawing.Brush, ByVal foreBrush As System.Drawing.Brush, ByVal alignToRight As Boolean)&lt;br /&gt;
        If rowNum Mod 2 = 0 Then&lt;br /&gt;
            MyBase.Paint(g, bounds, source, rowNum, backBrush, foreBrush, alignToRight)&lt;br /&gt;
        Else&lt;br /&gt;
            Dim bb As New SolidBrush(m_AltColor)&lt;br /&gt;
            MyBase.Paint(g, bounds, source, rowNum, bb, foreBrush, alignToRight)&lt;br /&gt;
            bb.Dispose()&lt;br /&gt;
        End If&lt;br /&gt;
    End Sub  
&lt;/p&gt;
&lt;p&gt;
    Public Sub New()&lt;br /&gt;
        m_AltColor = Color.LightSkyBlue&lt;br /&gt;
    End Sub&lt;br /&gt;
End Class 
&lt;/p&gt;
&lt;p&gt;
  
&lt;/p&gt;
&lt;p&gt;
To test the column style I added the Northwind Sql Compact edition database and let it create a typed dataset for the products table for me.  While compiling the project I got a few errors in the designer generated code for the typed dataset. The compact framework does not support the dispose method for the memory stream.  You can comment out the few lines of code safely 
&lt;/p&gt;
&lt;p&gt;
  
&lt;/p&gt;
&lt;p&gt;
Finally&lt;br /&gt;
    If (Not (s1) Is Nothing) Then&lt;br /&gt;
        's1.Dispose&lt;br /&gt;
    End If&lt;br /&gt;
    If (Not (s2) Is Nothing) Then&lt;br /&gt;
        's2.Dispose&lt;br /&gt;
    End If&lt;br /&gt;
End Try  
&lt;/p&gt;
&lt;p&gt;
  
&lt;/p&gt;
&lt;p&gt;
Here is the code I used to generate a datagrid with alternating color columns. 
&lt;/p&gt;
&lt;p&gt;
Public Class Form1  
&lt;/p&gt;
&lt;p&gt;
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load&lt;br /&gt;
        Dim bs As New BindingSource&lt;br /&gt;
        Dim dt As New NorthwindDataSet.ProductsDataTable&lt;br /&gt;
        Dim ta As New NorthwindDataSetTableAdapters.ProductsTableAdapter  
&lt;/p&gt;
&lt;p&gt;
        ta.Fill(dt)  
&lt;/p&gt;
&lt;p&gt;
        bs.DataSource = dt  
&lt;/p&gt;
&lt;p&gt;
        Dim ts As New DataGridTableStyle&lt;br /&gt;
        ts.MappingName = dt.TableName  
&lt;/p&gt;
&lt;p&gt;
        Dim colName As New AltColorColumn&lt;br /&gt;
        With colName&lt;br /&gt;
            .Width = 150&lt;br /&gt;
            .HeaderText = "Product Name"&lt;br /&gt;
            .MappingName = "Product Name"&lt;br /&gt;
        End With  
&lt;/p&gt;
&lt;p&gt;
        Dim colPrice As New AltColorColumn  
&lt;/p&gt;
&lt;p&gt;
        With colPrice&lt;br /&gt;
            .Width = 75&lt;br /&gt;
            .HeaderText = "Price"&lt;br /&gt;
            .MappingName = "Unit Price"&lt;br /&gt;
            .Format = "c"&lt;br /&gt;
        End With  
&lt;/p&gt;
&lt;p&gt;
        ts.GridColumnStyles.Add(colName)&lt;br /&gt;
        ts.GridColumnStyles.Add(colPrice)&lt;br /&gt;
        DataGrid1.TableStyles.Add(ts)&lt;br /&gt;
        DataGrid1.DataSource = bs&lt;br /&gt;
    End Sub&lt;br /&gt;
End Class 
&lt;/p&gt;
&lt;img src="http://blog.onteorasoftware.net/aggbug/48.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ken Tucker</dc:creator>
            <guid>http://blog.onteorasoftware.net/archive/2007/10/19/compact-framework-datagrid-alternating-color.aspx</guid>
            <pubDate>Fri, 19 Oct 2007 17:44:15 GMT</pubDate>
            <wfw:comment>http://blog.onteorasoftware.net/comments/48.aspx</wfw:comment>
            <comments>http://blog.onteorasoftware.net/archive/2007/10/19/compact-framework-datagrid-alternating-color.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blog.onteorasoftware.net/comments/commentRss/48.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Vista Task Dialog</title>
            <link>http://blog.onteorasoftware.net/archive/2007/09/16/vista-task-dialog.aspx</link>
            <description>&lt;h3 align="center"&gt;Vista Task Dialog&lt;/h3&gt;&lt;br /&gt;
&lt;p&gt;
Windows Vista has some cool looking new Dialog's. This example will show how to use the TaskDialog an improved message box with Visual Studio 2005. 
&lt;/p&gt;
&lt;p&gt;
 
&lt;/p&gt;
&lt;hr /&gt;
Public Class Form1 
&lt;p&gt;
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load&lt;br /&gt;
        Dim x As Integer&lt;br /&gt;
        TaskDialogHelper.TaskDialog(Me.Handle, IntPtr.Zero, "Title", "Are you sure?", "This is a test", TaskDialogHelper.TaskDialogButtons.Ok, TaskDialogHelper.TaskDialogIcon.Question, x)&lt;br /&gt;
    End Sub&lt;br /&gt;
End Class 
&lt;/p&gt;
&lt;p&gt;
Public Class TaskDialogHelper&lt;br /&gt;
    Public Enum TaskDialogButtons&lt;br /&gt;
        Ok = &amp;amp;H1&lt;br /&gt;
        Cancel = &amp;amp;H8&lt;br /&gt;
        Yes = &amp;amp;H2&lt;br /&gt;
        No = &amp;amp;H4&lt;br /&gt;
        Retry = &amp;amp;H10&lt;br /&gt;
        Close = &amp;amp;H20&lt;br /&gt;
    End Enum 
&lt;/p&gt;
&lt;p&gt;
    Public Enum TaskDialogIcon&lt;br /&gt;
        Information = UInt16.MaxValue - 2&lt;br /&gt;
        Warning = UInt16.MaxValue&lt;br /&gt;
        [Stop] = UInt16.MaxValue - 1&lt;br /&gt;
        Question = 0&lt;br /&gt;
        SecurityWarning = UInt16.MaxValue - 5&lt;br /&gt;
        SecurityError = UInt16.MaxValue - 6&lt;br /&gt;
        SecuritySuccess = UInt16.MaxValue - 7&lt;br /&gt;
        SecurityShield = UInt16.MaxValue - 3&lt;br /&gt;
        SecurityShieldBlue = UInt16.MaxValue - 4&lt;br /&gt;
        SecurityShieldGray = UInt16.MaxValue - 8&lt;br /&gt;
    End Enum 
&lt;/p&gt;
&lt;p&gt;
    Public Enum TaskDialogResult&lt;br /&gt;
        None&lt;br /&gt;
        OK&lt;br /&gt;
        Cancel&lt;br /&gt;
        Yes = 6&lt;br /&gt;
        No = 7&lt;br /&gt;
        Retry = 4&lt;br /&gt;
        Close = 8&lt;br /&gt;
    End Enum 
&lt;/p&gt;
&lt;p&gt;
    Public Declare Auto Function TaskDialog Lib "comctl32.dll" (ByVal hWnd As IntPtr, ByVal hInstance As IntPtr, _&lt;br /&gt;
        ByVal WindowTitle As String, ByVal MainInstruction As String, ByVal Content As String, _&lt;br /&gt;
        ByVal CommonButton As Integer, ByVal DialogIcon As Integer, ByRef PushedButton As Integer) As Integer 
&lt;/p&gt;
&lt;p&gt;
End Class 
&lt;/p&gt;
&lt;img src="/BlogEngine.NET/image.axd?picture=TaskDialog.PNG" alt="" width="369" height="146" /&gt; 
&lt;img src="http://blog.onteorasoftware.net/aggbug/92.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ken Tucker</dc:creator>
            <guid>http://blog.onteorasoftware.net/archive/2007/09/16/vista-task-dialog.aspx</guid>
            <pubDate>Sun, 16 Sep 2007 22:17:16 GMT</pubDate>
            <wfw:comment>http://blog.onteorasoftware.net/comments/92.aspx</wfw:comment>
            <comments>http://blog.onteorasoftware.net/archive/2007/09/16/vista-task-dialog.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blog.onteorasoftware.net/comments/commentRss/92.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Vista: Get WinSat Info</title>
            <link>http://blog.onteorasoftware.net/archive/2007/09/16/vista-get-winsat-info.aspx</link>
            <description>&lt;h3 align="center"&gt;Vista: Get WinSat Info&lt;/h3&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;
Windows Vista has a performance index for your hardware.  The scores range from 1(worst) to 5.9(best).  If your application uses a lot of graphics you might get poor performance on a computer with a graphics score of 1.  You can use this number to scale back on the graphics to improve your apps performance.  This example gets displays the scores in the forms paint event.  For this example add a reference to the WinSat 1.0 type library in the com tab. 
&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;
Imports WINSATLib&lt;br /&gt;
Imports System.Text 
&lt;/p&gt;
&lt;p&gt;
Public Class Form1 
&lt;/p&gt;
&lt;p&gt;
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
&lt;/p&gt;
&lt;p&gt;
    End Sub 
&lt;/p&gt;
&lt;p&gt;
    Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint&lt;br /&gt;
        Dim ws As New CQueryWinSAT&lt;br /&gt;
        Dim sbInfo As New StringBuilder 
&lt;/p&gt;
&lt;p&gt;
        For x As Integer = 0 To 4&lt;br /&gt;
            Dim info As IProvideWinSATAssessmentInfo = ws.Info.GetAssessmentInfo(x)&lt;br /&gt;
            sbInfo.Append(info.Title &amp;amp; vbCrLf)&lt;br /&gt;
            sbInfo.Append(info.Description &amp;amp; vbCrLf)&lt;br /&gt;
            sbInfo.Append(info.Score &amp;amp; vbCrLf &amp;amp; vbCrLf)&lt;br /&gt;
        Next 
&lt;/p&gt;
&lt;p&gt;
        e.Graphics.DrawString(sbInfo.ToString, Me.Font, Brushes.Black, 0, 0)&lt;br /&gt;
    End Sub&lt;br /&gt;
End Class 
&lt;/p&gt;
&lt;img src="http://blog.onteorasoftware.net/aggbug/72.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ken Tucker</dc:creator>
            <guid>http://blog.onteorasoftware.net/archive/2007/09/16/vista-get-winsat-info.aspx</guid>
            <pubDate>Sun, 16 Sep 2007 19:41:24 GMT</pubDate>
            <wfw:comment>http://blog.onteorasoftware.net/comments/72.aspx</wfw:comment>
            <comments>http://blog.onteorasoftware.net/archive/2007/09/16/vista-get-winsat-info.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blog.onteorasoftware.net/comments/commentRss/72.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Vista Updates and Tools</title>
            <link>http://blog.onteorasoftware.net/archive/2007/09/16/vista-updates-and-tools.aspx</link>
            <description>&lt;h3 align="center"&gt;Vista Updates and Tools&lt;/h3&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;
First the &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=90E2942D-3AD1-4873-A2EE-4ACC0AACE5B6&amp;amp;displaylang=en"&gt;Visual Studio 2005 SP1 update for Vista&lt;/a&gt; has been released. 
&lt;/p&gt;
&lt;br /&gt;
&lt;p&gt;
&lt;a href="http://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/servicepacks/sp2.mspx"&gt;Service Pack 2 for SQL Server 2005&lt;/a&gt; is out. This is the only version of SQL Server 2005 that is supported on Vista.
&lt;/p&gt;
&lt;br /&gt;
&lt;p&gt;
Finally the free &lt;a href="http://www.microsoft.com/windows/products/winfamily/virtualpc/default.mspx"&gt;Virtual PC 2007&lt;/a&gt; is available
&lt;/p&gt;
&lt;img src="http://blog.onteorasoftware.net/aggbug/79.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ken Tucker</dc:creator>
            <guid>http://blog.onteorasoftware.net/archive/2007/09/16/vista-updates-and-tools.aspx</guid>
            <pubDate>Sun, 16 Sep 2007 19:30:30 GMT</pubDate>
            <wfw:comment>http://blog.onteorasoftware.net/comments/79.aspx</wfw:comment>
            <comments>http://blog.onteorasoftware.net/archive/2007/09/16/vista-updates-and-tools.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blog.onteorasoftware.net/comments/commentRss/79.aspx</wfw:commentRss>
        </item>
        <item>
            <title>List Vista RSS feeds</title>
            <link>http://blog.onteorasoftware.net/archive/2007/09/16/list-vista-rss-feeds.aspx</link>
            <description>&lt;h3 align="center"&gt;List Vista RSS feeds&lt;/h3&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;
To list the RSS feeds added to IE7 in windows Vista add a reference to Microsoft.Feeds 1.0. You will find it in the com tab.  
&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;
Imports Microsoft.Feeds.Interop 
&lt;/p&gt;
&lt;p&gt;
Public Class Form1&lt;br /&gt;
    Dim mgr As New FeedsManager&lt;br /&gt;
    Dim fldr As IFeedFolder 
&lt;/p&gt;
&lt;p&gt;
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load&lt;br /&gt;
        fldr = mgr.RootFolder 
&lt;/p&gt;
&lt;p&gt;
        ListFeeds(fldr) 
&lt;/p&gt;
&lt;p&gt;
    End Sub 
&lt;/p&gt;
&lt;p&gt;
    Private Sub ListFeeds(ByVal fldr As IFeedFolder)&lt;br /&gt;
        For Each feed As IFeed In fldr.Feeds&lt;br /&gt;
            Trace.WriteLine(feed.Name)&lt;br /&gt;
            ListItems(feed)&lt;br /&gt;
        Next&lt;br /&gt;
        For Each f As IFeedFolder In fldr.Subfolders&lt;br /&gt;
            Trace.WriteLine(f.Name)&lt;br /&gt;
            ListItems(f)&lt;br /&gt;
        Next&lt;br /&gt;
    End Sub 
&lt;/p&gt;
&lt;p&gt;
    Private Sub ListItems(ByVal feed As IFeed)&lt;br /&gt;
        Trace.Indent()&lt;br /&gt;
        For Each item As IFeedItem In feed.Items&lt;br /&gt;
            Trace.WriteLine(item.Title)&lt;br /&gt;
        Next&lt;br /&gt;
        Trace.Unindent()&lt;br /&gt;
    End Sub&lt;br /&gt;
End Class 
&lt;/p&gt;
&lt;img src="http://blog.onteorasoftware.net/aggbug/74.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ken Tucker</dc:creator>
            <guid>http://blog.onteorasoftware.net/archive/2007/09/16/list-vista-rss-feeds.aspx</guid>
            <pubDate>Sun, 16 Sep 2007 19:27:16 GMT</pubDate>
            <wfw:comment>http://blog.onteorasoftware.net/comments/74.aspx</wfw:comment>
            <comments>http://blog.onteorasoftware.net/archive/2007/09/16/list-vista-rss-feeds.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blog.onteorasoftware.net/comments/commentRss/74.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Vista: File System Transactions</title>
            <link>http://blog.onteorasoftware.net/archive/2007/09/16/vista-file-system-transactions.aspx</link>
            <description>&lt;h3 align="center"&gt;Vista: File System Transactions&lt;/h3&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;
Windows Vista has several new functions for using transactions when working with files.  Here is an example on how to create a transaction, work with some files, and commit it.
&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;
Imports System.Runtime.InteropServices&lt;br /&gt;
Imports Microsoft.Win32.SafeHandles&lt;br /&gt;
Imports System.IO
&lt;/p&gt;
&lt;p&gt;
&lt;br /&gt;
Module Module1
&lt;/p&gt;
&lt;p&gt;
    Public Declare Auto Function CreateTransaction Lib "Ktmw32.dll" (ByVal Attributes As IntPtr, _&lt;br /&gt;
        ByVal guid As IntPtr, ByVal options As Integer, ByVal isolationlevel As Integer, _&lt;br /&gt;
        ByVal isolationflags As Integer, ByVal milliseconds As Integer, ByVal description As String) As IntPtr
&lt;/p&gt;
&lt;p&gt;
    Public Declare Auto Function RollbackTransaction Lib "Ktmw32.dll" (ByVal handle As IntPtr) As Boolean
&lt;/p&gt;
&lt;p&gt;
    Public Declare Auto Function CommitTransaction Lib "Ktmw32.dll" (ByVal handle As IntPtr) As Boolean
&lt;/p&gt;
&lt;p&gt;
    Public Declare Auto Function CloseHandle Lib "Kernel32.dll" (ByVal handle As IntPtr) As Boolean
&lt;/p&gt;
&lt;p&gt;
    Public Declare Auto Function CreateFileTransacted Lib "Kernel32.dll" (ByVal fileName As String, _&lt;br /&gt;
        ByVal desiredAccess As Integer, ByVal ShareMode As Integer, ByVal SecurityAttributes As IntPtr, _&lt;br /&gt;
        ByVal CreationDisposition As Integer, ByVal FlagsAndAttributes As Integer, _&lt;br /&gt;
        ByVal hTemplateFile As IntPtr, ByVal transaction As IntPtr, _&lt;br /&gt;
        ByVal miniversion As IntPtr, ByVal extendedOpenInfo As IntPtr) As SafeFileHandle
&lt;/p&gt;
&lt;p&gt;
    Public Declare Auto Function DeleteFileTransacted Lib "Kernel32.dll" (ByVal fileName As String, _&lt;br /&gt;
        ByVal transaction As IntPtr) As Boolean
&lt;/p&gt;
&lt;p&gt;
    Private Const GENERIC_READ As Integer = &amp;amp;H80000000&lt;br /&gt;
    Private Const GENERIC_WRITE As Integer = &amp;amp;H40000000&lt;br /&gt;
    Private Const CREATE_NEW As Integer = 1&lt;br /&gt;
    Private Const CREATE_ALWAYS As Integer = 2&lt;br /&gt;
    Private Const OPEN_EXISTING As Integer = 3
&lt;/p&gt;
&lt;p&gt;
    Sub Main()&lt;br /&gt;
        Using sw As StreamWriter = File.CreateText("test1.txt")&lt;br /&gt;
            sw.WriteLine("This is the first file")&lt;br /&gt;
        End Using
&lt;/p&gt;
&lt;p&gt;
        Using sw2 As StreamWriter = File.CreateText("test2.txt")&lt;br /&gt;
            sw2.WriteLine("The other file")&lt;br /&gt;
        End Using
&lt;/p&gt;
&lt;p&gt;
        Console.WriteLine("Before delete")&lt;br /&gt;
        Console.WriteLine("------------------")&lt;br /&gt;
        Dim diBefore As New DirectoryInfo(My.Application.Info.DirectoryPath)&lt;br /&gt;
        For Each fi As FileInfo In diBefore.GetFiles&lt;br /&gt;
            Console.WriteLine(fi.Name)&lt;br /&gt;
        Next&lt;br /&gt;
        Console.WriteLine("------------------")&lt;br /&gt;
        Console.WriteLine("After transaction delete")&lt;br /&gt;
        Dim tx As IntPtr = CreateTransaction(IntPtr.Zero, IntPtr.Zero, 0, 0, 0, 0, Nothing)&lt;br /&gt;
        Dim b As Boolean = DeleteFileTransacted("test1.txt", tx)&lt;br /&gt;
        Dim sh As SafeFileHandle&lt;br /&gt;
        sh = CreateFileTransacted("SafeTest.txt", GENERIC_READ Or GENERIC_WRITE, 0, IntPtr.Zero, CREATE_NEW, 0, IntPtr.Zero, tx, IntPtr.Zero, IntPtr.Zero)
&lt;/p&gt;
&lt;p&gt;
        Dim fst As New FileStream(sh, FileAccess.Write)&lt;br /&gt;
        Dim swt As New StreamWriter(fst)&lt;br /&gt;
        swt.WriteLine("Hello World")&lt;br /&gt;
        swt.Close()
&lt;/p&gt;
&lt;p&gt;
        For Each fi As FileInfo In diBefore.GetFiles&lt;br /&gt;
            Console.WriteLine(fi.Name)&lt;br /&gt;
        Next&lt;br /&gt;
        Console.WriteLine("------------------")&lt;br /&gt;
        Console.WriteLine("After commit delete")&lt;br /&gt;
        CommitTransaction(tx)
&lt;/p&gt;
&lt;p&gt;
        For Each fi As FileInfo In diBefore.GetFiles&lt;br /&gt;
            Console.WriteLine(fi.Name)&lt;br /&gt;
        Next&lt;br /&gt;
        CloseHandle(tx)
&lt;/p&gt;
&lt;p&gt;
&lt;br /&gt;
    End Sub
&lt;/p&gt;
&lt;p&gt;
End Module
&lt;/p&gt;
&lt;img src="http://blog.onteorasoftware.net/aggbug/73.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ken Tucker</dc:creator>
            <guid>http://blog.onteorasoftware.net/archive/2007/09/16/vista-file-system-transactions.aspx</guid>
            <pubDate>Sun, 16 Sep 2007 19:25:52 GMT</pubDate>
            <wfw:comment>http://blog.onteorasoftware.net/comments/73.aspx</wfw:comment>
            <comments>http://blog.onteorasoftware.net/archive/2007/09/16/vista-file-system-transactions.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blog.onteorasoftware.net/comments/commentRss/73.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Vista Application Recovery</title>
            <link>http://blog.onteorasoftware.net/archive/2007/09/16/vista-application-recovery.aspx</link>
            <description>&lt;h3 align="center"&gt;Vista Application Recovery&lt;/h3&gt;&lt;br /&gt;
&lt;p&gt;
Ever want to add the ability to recover the user data if your application has crashed. Windows Vista has some nice apis to make this easy. 
&lt;/p&gt;
&lt;br /&gt;
&lt;p&gt;
The RegisterApplicationRestart api tells Vista we would like the app to restart if it crashes or hangs. This api takes two arguments a string which will be the command line argument when the application restarts and RestartFlags. For this example we will tell the app to always restart. Note the app must run 60 seconds before it will restart. 
&lt;/p&gt;
&lt;p&gt;
&lt;br /&gt;
&lt;br /&gt;
    Enum RestartFlags&lt;br /&gt;
        Always = 0&lt;br /&gt;
        Cyclical = 1&lt;br /&gt;
        NotifySolution = 2&lt;br /&gt;
        NotifyFault = 4&lt;br /&gt;
        DoNotRestartOnCrash = 8&lt;br /&gt;
        DoNotRestartOnHang = 16&lt;br /&gt;
        DoNotRestartOnUpdate = 32&lt;br /&gt;
    End Enum
&lt;/p&gt;
&lt;p&gt;
    Declare Auto Function RegisterApplicationRestart Lib "kernel32.dll" (ByVal strMessage As String, ByVal RestartOption As RestartFlags) As Integer
&lt;/p&gt;
&lt;p&gt;
RegisterApplicationRestart("Restarted", RestartFlags.Always)
&lt;/p&gt;
&lt;p&gt;
&lt;br /&gt;
&lt;br /&gt;
 
&lt;/p&gt;
&lt;p&gt;
The RegisterApplicationRecoveryCallback will allow us to register a function to run if our application crashes or hangs. This will allow us to save the users work before the app terminates. Note that you will not have access to the forms controls but you will have access to the variables. If you want to be able to recover the text in a textbox I would use a variable which is updated in the textboxes textchanged event. Inside the callback function you must tell Vista you are working with the ApplicationRecoveryInProgress function. When the recovery is complete tell Vista with the ApplicationRecoveryFinished function. 
&lt;/p&gt;
&lt;p&gt;
&lt;br /&gt;
&lt;br /&gt;
    Declare Auto Function RegisterApplicationRecoveryCallback Lib "kernel32.dll" (ByVal cb As App_Recovery_Callback, ByVal Param As String, ByVal PintInterval As Integer, ByVal flags As RestartFlags) As Integer&lt;br /&gt;
    Declare Auto Function ApplicationRecoveryInProgress Lib "kernel32.dll" (ByRef Canceled As Boolean) As Integer&lt;br /&gt;
    Declare Auto Function ApplicationRecoveryFinished Lib "kernel32.dll" (ByRef Success As Boolean) As Integer
&lt;/p&gt;
&lt;p&gt;
    Delegate Function App_Recovery_Callback(ByVal Param As String) As Integer
&lt;/p&gt;
&lt;p&gt;
&lt;br /&gt;
    Private Function Recover(ByVal Param As String) As Integer&lt;br /&gt;
        Dim b As Boolean&lt;br /&gt;
        Using sw As New StreamWriter("Recovered.txt", False)&lt;br /&gt;
            ApplicationRecoveryInProgress(b)&lt;br /&gt;
            sw.WriteLine(strTextbox)&lt;br /&gt;
            ApplicationRecoveryInProgress(b)&lt;br /&gt;
            sw.Flush()&lt;br /&gt;
            sw.Close()&lt;br /&gt;
        End Using&lt;br /&gt;
        ApplicationRecoveryFinished(True)
&lt;/p&gt;
&lt;p&gt;
        Return 0&lt;br /&gt;
    End Function&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;
One last thing. The .Net framework will catch the error and prevent our recovery callback function from being called. So we need to uncheck the enable application framework box in my projects so we can make the application start with Sub Main. In Sub Main we can Set the UnHandledException Mode to throw exception so Vista will know about the crash 
&lt;/p&gt;
&lt;br /&gt;
    Public Shared Sub Main()&lt;br /&gt;
        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException)&lt;br /&gt;
        Application.Run(New Form1)&lt;br /&gt;
    End Sub&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;
For the sample Application I have a form with a label (label1), textbox (textbox1), 2 buttons (btnCrash an btnHang), and a timer. The timer is used to update the label with how long the app ran. The 2 buttons will hang or crash the app. Here is the code for the sample app. For the app recovery to work run the program without debugging (ctrl+F5). 
&lt;/p&gt;
&lt;p&gt;
&lt;br /&gt;
&lt;br /&gt;
Imports System.IO
&lt;/p&gt;
&lt;p&gt;
Public Class Form1&lt;br /&gt;
    Enum RestartFlags&lt;br /&gt;
        Always = 0&lt;br /&gt;
        Cyclical = 1&lt;br /&gt;
        NotifySolution = 2&lt;br /&gt;
        NotifyFault = 4&lt;br /&gt;
        DoNotRestartOnCrash = 8&lt;br /&gt;
        DoNotRestartOnHang = 16&lt;br /&gt;
        DoNotRestartOnUpdate = 32&lt;br /&gt;
    End Enum
&lt;/p&gt;
&lt;p&gt;
    Dim strTextbox As String
&lt;/p&gt;
&lt;p&gt;
    Declare Auto Function RegisterApplicationRestart Lib "kernel32.dll" (ByVal strMessage As String, ByVal RestartOption As RestartFlags) As Integer&lt;br /&gt;
    Declare Auto Function RegisterApplicationRecoveryCallback Lib "kernel32.dll" (ByVal cb As App_Recovery_Callback, ByVal Param As String, ByVal PintInterval As Integer, ByVal flags As RestartFlags) As Integer&lt;br /&gt;
    Declare Auto Function ApplicationRecoveryInProgress Lib "kernel32.dll" (ByRef Canceled As Boolean) As Integer&lt;br /&gt;
    Declare Auto Function ApplicationRecoveryFinished Lib "kernel32.dll" (ByRef Success As Boolean) As Integer
&lt;/p&gt;
&lt;p&gt;
    Delegate Function App_Recovery_Callback(ByVal Param As String) As Integer
&lt;/p&gt;
&lt;p&gt;
    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick&lt;br /&gt;
        Static x As Integer = 0&lt;br /&gt;
        Label1.Text = String.Format("App running {0} seconds", x)&lt;br /&gt;
        x += 1&lt;br /&gt;
    End Sub
&lt;/p&gt;
&lt;p&gt;
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load&lt;br /&gt;
        If My.Application.CommandLineArgs.Count &amp;gt; 0 Then&lt;br /&gt;
            TextBox1.Text = My.Computer.FileSystem.ReadAllText("Recovered.txt")&lt;br /&gt;
            ApplicationRecoveryFinished(True)&lt;br /&gt;
        End If
&lt;/p&gt;
&lt;p&gt;
        'register app to restart&lt;br /&gt;
        RegisterApplicationRestart("Restarted", RestartFlags.Always)
&lt;/p&gt;
&lt;p&gt;
        'setup the Recovery Callback&lt;br /&gt;
        RegisterApplicationRecoveryCallback(AddressOf Recover, "Recover Data", 50000, RestartFlags.Always)&lt;br /&gt;
        'start a timer to show how long the app has run&lt;br /&gt;
        Timer1.Interval = 1000&lt;br /&gt;
        Timer1.Enabled = True
&lt;/p&gt;
&lt;p&gt;
    End Sub
&lt;/p&gt;
&lt;p&gt;
    Private Function Recover(ByVal Param As String) As Integer&lt;br /&gt;
        Dim b As Boolean&lt;br /&gt;
        Using sw As New StreamWriter("Recovered.txt", False)&lt;br /&gt;
            ApplicationRecoveryInProgress(b)&lt;br /&gt;
            sw.WriteLine(strTextbox)&lt;br /&gt;
            ApplicationRecoveryInProgress(b)&lt;br /&gt;
            sw.Flush()&lt;br /&gt;
            sw.Close()&lt;br /&gt;
        End Using&lt;br /&gt;
        ApplicationRecoveryFinished(True)
&lt;/p&gt;
&lt;p&gt;
        Return 0&lt;br /&gt;
    End Function
&lt;/p&gt;
&lt;p&gt;
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCrash.Click&lt;br /&gt;
        Throw New Exception("Crash Me!!!")&lt;br /&gt;
    End Sub
&lt;/p&gt;
&lt;p&gt;
    Public Shared Sub Main()&lt;br /&gt;
        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException)&lt;br /&gt;
        Application.Run(New Form1)&lt;br /&gt;
    End Sub
&lt;/p&gt;
&lt;p&gt;
    Private Sub TextBox1_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged&lt;br /&gt;
        strTextbox = TextBox1.Text&lt;br /&gt;
    End Sub
&lt;/p&gt;
&lt;p&gt;
 
&lt;/p&gt;
&lt;p&gt;
    Private Sub btnHang_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnHang.Click&lt;br /&gt;
        Do While True&lt;br /&gt;
            ' lock me up&lt;br /&gt;
        Loop&lt;br /&gt;
    End Sub&lt;br /&gt;
End Class
&lt;/p&gt;
&lt;p&gt;
 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://channel9.msdn.com/ShowPost.aspx?PostID=256582"&gt;Daniel Moth&lt;/a&gt; and &lt;a href="http://community.bartdesmet.net/blogs/bart/archive/2006/11/11/Windows-Vista-Application-Recovery-with-C_2300_.aspx"&gt;Bart De Smet's&lt;/a&gt; have some nice blog entries about using app recovery with c# console apps. You can register your application (a digital signature is required) at the &lt;a href="https://winqual.microsoft.com/default.aspx"&gt;Windows Quality Online Services&lt;/a&gt; site to be able to see any error reports sent by your app. 
&lt;/p&gt;
&lt;img src="http://blog.onteorasoftware.net/aggbug/91.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ken Tucker</dc:creator>
            <guid>http://blog.onteorasoftware.net/archive/2007/09/16/vista-application-recovery.aspx</guid>
            <pubDate>Sun, 16 Sep 2007 19:22:11 GMT</pubDate>
            <wfw:comment>http://blog.onteorasoftware.net/comments/91.aspx</wfw:comment>
            <comments>http://blog.onteorasoftware.net/archive/2007/09/16/vista-application-recovery.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blog.onteorasoftware.net/comments/commentRss/91.aspx</wfw:commentRss>
        </item>
    </channel>
</rss>