<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://community.bartdesmet.net/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>B# .NET Blog : Windows Vista</title><link>http://community.bartdesmet.net/blogs/bart/archive/tags/Windows+Vista/default.aspx</link><description>Tags: Windows Vista</description><dc:language>en</dc:language><generator>CommunityServer 2007 (Build: 20423.869)</generator><item><title>Calling the Task Scheduler in Windows Vista (and Windows Server 2008) from managed code</title><link>http://community.bartdesmet.net/blogs/bart/archive/2008/02/23/calling-the-task-scheduler-in-windows-vista-and-windows-server-2008-from-managed-code.aspx</link><pubDate>Sat, 23 Feb 2008 10:20:55 GMT</pubDate><guid isPermaLink="false">863c5522-913f-4a64-ac0a-bd5f05abad0f:13083</guid><dc:creator>bart</dc:creator><slash:comments>25</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://community.bartdesmet.net/blogs/bart/rsscomments.aspx?PostID=13083</wfw:commentRss><comments>http://community.bartdesmet.net/blogs/bart/archive/2008/02/23/calling-the-task-scheduler-in-windows-vista-and-windows-server-2008-from-managed-code.aspx#comments</comments><description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Today I received the following mail from one of my blog readers:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Hi Bart,&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;The task scheduler in Vista and Windows Server 2008 has improved dramatically.&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;Unfortunately, there are no classes in the .NET Framework that allow us VB.NET/C# developers to leverage its power.&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;Many .NET applications require some form of scheduling or alerting, and instead of trying to roll our own with timers and stuff, over and over again, it seems to me that it would be much nicer to use the stable and powerful foundation that the OS offers for this.&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;Therefore, I thought it would be a great idea for a future article on your blog, about how to access and use the Task Scheduler 2.0 from .NET, with possibly an easy-to-use .NET wrapper class?&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;It seems that a lot of developers don&amp;#39;t realize or think about what&amp;#39;s sitting there right under the hood, &amp;#39;cause I haven&amp;#39;t seen any blog posts about this new Task Scheduler and its many features from a .NET developer&amp;#39;s perspective yet. So here&amp;#39;s my thought... :)&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;Best regards,&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;************&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Obviously I completely agree with the statement on leveraging the power of the OS foundations whenever possible rather than reinventing the wheel once over again. Task Scheduler 2.0 is a great sample of such rich functionality offered by the OS and especially now we&amp;#39;re shipping Windows Server 2008 this becomes even more important for server applications. Nevertheless, for desktop uses the Task Scheduler provides a tremendous amount of functionality as well and Windows Vista is using its own dogfood as you can see when you execute &lt;strong&gt;schtasks&lt;/strong&gt; from the command-line (indicated a few well-known tasks in red):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_2.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="484" alt="image" src="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_thumb.png" width="278" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;In this post I&amp;#39;ll cover how to use this API in a fairly easy way from managed code though COM interop, and I&amp;#39;ll explain some of the richness the platform can give you.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Importing the library&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I assume you&amp;#39;ve already created a Console Application in C# (though all of this would work in e.g. VB.NET as well). The Task Scheduler 2.0 API lives in a file called Taskschd.dll under the System32 folder on your system. In order to reference it from your .NET project, simply go to Solution Explorer, right-click the project node and choose Add Reference:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_4.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="206" alt="image" src="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_thumb_1.png" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;This will create the COM interop assembly as shown in Solution Explorer:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_8.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="244" alt="image" src="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_thumb_3.png" width="115" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;A simple demo task&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Time to write our first task, or better to register it. Essentially tasks in Task Scheduler 2.0 are represented as XML fragments as you can see from schtasks:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_6.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="189" alt="image" src="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_thumb_2.png" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;I&amp;#39;d encourage readers to take a closer look at schtasks and the information one can obtain through it about the wide variety of tasks registered on the system. The API we&amp;#39;ll be talking to allows us to manage these tasks (create new ones for example) though code, which provides an object model to create the metadata that represents a task as displayed above under the format of XML.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Step 1 - Establish a connection with the service&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;In order to talk to the Task Scheduler service we need to create a proxy object to it and connect to the service, either on the local machine or remote machine. We&amp;#39;ll stick with the local machine for the scope of this post. Start by writing the following piece of code:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_10.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="281" alt="image" src="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_thumb_4.png" width="664" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;This will require to import the namespace TaskScheduler as revealed by the &amp;#39;SmartTag&amp;#39; in Visual Studio. Notice I&amp;#39;m using the C# 3.0 local variable type inference keyword &amp;quot;var&amp;quot; here, but one could well write:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;TaskSchedulerClass scheduler = new TaskSchedulerClass();&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;but not (using the TaskScheduler interface provided by the interop assembly)&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;TaskScheduler scheduler = new TaskSchedulerClass();&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;(little quiz - why?). Anyhow, we still need to connect to it using the Connect method:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_12.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="241" alt="image" src="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_thumb_5.png" width="438" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;We can simply supply four null arguments indicating we want to use the token of the user logged on currently (tip: run using administrative privileges to manage the service effectively). Needless to say, you can use other values for those parameters to connect to a particular machine (first parameter) and to specify a particular user (parameters 2-4 specify user name, password and domain) but we won&amp;#39;t go there in this post.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Step 2 - Create a new task&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The scheduler class provides a factory approach to create new tasks using the &lt;strong&gt;NewTask &lt;/strong&gt;method. It takes one parameter that&amp;#39;s reserved for future use (a typical COM API phenomenon) and should be set to 0 for the time being. Once the task has been created, we&amp;#39;ll set some properties on it; the most typical ones living under &lt;strong&gt;RegistrationInfo&lt;/strong&gt; and &lt;strong&gt;Settings&lt;/strong&gt; (others will be covered further on):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_14.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="586" alt="image" src="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_thumb_6.png" width="430" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Notice the amount of settings available to tweak the task, e.g. to control behavior with respect to the current power state of the machine, idle time, etc. For our purposes, the RegistrationInfo settings are enough as shown above.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Step 3 - Triggers&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;u&gt;When&lt;/u&gt; to run the task? Enter triggers. There are a bunch of different trigger types available as revealed when calling &lt;strong&gt;Triggers.Create&lt;/strong&gt;:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_16.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="299" alt="image" src="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_thumb_7.png" width="958" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Most of these are self-explanatory (in case of doubt more information can be found on MSDN). The more interesting part is how to create a trigger in managed code. The crux lies in the fact you need to cast the result of the Create call to the right interface, such as ITimeTrigger for the TASK_TRIGGER_TIME type. Let&amp;#39;s show a sample:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_18.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="290" alt="image" src="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_thumb_8.png" width="846" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Other similar interfaces for other types of triggers can be found in the TaskScheduler namespace. Time triggers are pretty simple to understand so let&amp;#39;s stick with those. In the sample above, we add an identifier to the trigger (tasks can have more than one trigger by the way) as well as some specific settings for this particular trigger. Besides of this we set the start and end time for the trigger; the settings in the sample specify a point in the past and the future so our current time falls nicely in between, triggering the demo task right away once we run it. If you want more powerful triggering, you can take a look at the Repetition property or use tasks such as &amp;#39;daily&amp;#39; or &amp;#39;monthly day-of-week (DOW)&amp;#39; or ...&lt;/p&gt;  &lt;p&gt;Notice the strange (ISO 8601) date/time format specified on MSDN as: YYYY-MM-DDTHH:MM:SS(+-)HH:MM. In here, the first part is self-explanatory; the part after the +- is used to specify a time zone since tasks are stored based on UTC time. &lt;u&gt;Tip:&lt;/u&gt; a string formatter will prove useful to generate this format.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Step 4 - Actions&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;After when comes &lt;u&gt;what&lt;/u&gt;. Again there&amp;#39;s some choice amongst the different types of actions to be taken:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_20.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="115" alt="image" src="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_thumb_9.png" width="864" border="0" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;The EXEC task is one of the most common ones though. The common pattern is the same again: Create, cast, configure. Here&amp;#39;s an example of a mail-task but this will require some server configuration in order to work:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_22.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="128" alt="image" src="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_thumb_10.png" width="798" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Here&amp;#39;s another one in the category EXEC:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_24.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="69" alt="image" src="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_thumb_11.png" width="726" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Feel free to choose either of those, I&amp;#39;ll go for yet another one that displays a message (by now the pattern should be captured I guess):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_28.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="72" alt="image" src="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_thumb_13.png" width="902" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Step 5 - Task registration&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;We&amp;#39;ve created all the data needed to hook up the task. Last step is to hook it really up by calling &lt;strong&gt;RegisterTaskDefinition&lt;/strong&gt; in some folder. Tasks are logically grouped in folders which you can managed through the ITaskFolder interface. One can obtain a specific folder using the &lt;strong&gt;GetFolder&lt;/strong&gt; call on the scheduler service object. For demo purposes (and because of lack of inspiration tonight :-)) we&amp;#39;ll drop the task in the root folder:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_30.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="174" alt="image" src="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_thumb_14.png" width="444" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Again there&amp;#39;s a bunch of flexibility available here but simplicity rules for blogging, so the stuff above is pretty much the easiest one can get. Basically we create (or update if it already exists) a named task &amp;quot;Demo&amp;quot; with the credentials of the logged-on used that can only be run when an interactive user is logged on to the machine and with no custom ACL to protect the task (which could be set using an SDDL descriptor).&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Step 6 - Running it&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;To run the task we could add a line of code (though you could use schtasks /Run too or obivously rely on your (complex) triggers you&amp;#39;ve put in place). Since the API is not only about creating tasks, this shows nicely how to control tasks. Here&amp;#39;s the whole program with the run line at the bottom:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_32.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="598" alt="image" src="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_thumb_15.png" width="969" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Run it and you should see the following dialog coming out of the blue:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_26.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="156" alt="image" src="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_thumb_12.png" width="239" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Victory at last :-). &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Step 7 - Geeks only&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Geeks can check where the message comes from e.g. using task manager (or a more advanced tool like Process Explorer):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_34.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="465" alt="image" src="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_thumb_16.png" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Also, you can take a look at the task metadata using schtasks.exe:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_38.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="484" alt="image" src="http://community.bartdesmet.net/blogs/bart/WindowsLiveWriter/CallingtheTaskSchedulerinWindowsVistaand_20ED/image_thumb_18.png" width="485" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;And finally, if you want to delete the experiment, use schtasks.exe with the /Delete flag:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;schtasks /delete /tn Demo&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;(or use the API to do so obviously :-)).&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Happy multi-tasking!&lt;/p&gt;&lt;img src="http://community.bartdesmet.net/aggbug.aspx?PostID=13083" width="1" height="1"&gt;</description><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/Windows+Vista/default.aspx">Windows Vista</category></item><item><title>Getting started with Windows PE 2.0 for Windows Vista: boot Windows from a USB flash drive</title><link>http://community.bartdesmet.net/blogs/bart/archive/2007/10/07/getting-started-with-windows-pe-2-0-for-windows-vista-boot-windows-from-a-usb-flash-drive.aspx</link><pubDate>Sun, 07 Oct 2007 17:42:54 GMT</pubDate><guid isPermaLink="false">863c5522-913f-4a64-ac0a-bd5f05abad0f:12810</guid><dc:creator>bart</dc:creator><slash:comments>21</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://community.bartdesmet.net/blogs/bart/rsscomments.aspx?PostID=12810</wfw:commentRss><comments>http://community.bartdesmet.net/blogs/bart/archive/2007/10/07/getting-started-with-windows-pe-2-0-for-windows-vista-boot-windows-from-a-usb-flash-drive.aspx#comments</comments><description>&lt;p&gt;This is going to be a somewhat unfamiliar post on my blog. The history for it goes back to 2003-2004 when I was involved in a local Microsoft Belux project called &amp;quot;SchoolServer&amp;quot;. At that time, we used a Windows PE (where PE stands for &amp;quot;Pre-Installation Environment&amp;quot; and not &lt;a href="http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx" target="_blank"&gt;&amp;quot;Portable Executable&amp;quot;&lt;/a&gt;) version extracted from the Windows Server 2003 branch (NT 5.2), which was available to volume licensing customers only. But what&amp;#39;s Windows PE?&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;Windows PE is a version of the Windows OS that runs without installation entirely in memory (no harddisk required) and boots from a cd-rom or the network (as we&amp;#39;ll see it goes further than that in v2.0).&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;The reason to use it is pretty straightforward: for &amp;quot;Pre-Installation&amp;quot; tasks, such as disk partitioning, or even to build a (scripted) system setup that runs in a familiar Windows environment right from the start (e.g. generating a winnt.sif unattended installation file using a nice graphical wizard, making the right partitions, copying setup sources to the harddrive&amp;nbsp;and invoking setup using winnt.exe or so). But also for day-to-day computer (disk) administration tasks, this proves very useful. Indeed, Microsoft&amp;#39;s Windows PE solution isn&amp;#39;t the only one out there but are others as well which have similar ideas like &lt;a href="http://www.nu2.nu/pebuilder/" target="_blank"&gt;BartPE&lt;/a&gt; (I&amp;#39;m not that Bart).&lt;/p&gt; &lt;p&gt;If you&amp;#39;ve installed Windows Vista or Windows Server 2008 already (I hope you did), you&amp;#39;ll have noticed that there&amp;#39;s no blue-background textual setup anymore, the system boots into Windows from the cd to have an end-to-end graphical setup which is based on the Windows PE technology. As a developer I loved to have such a Windows PE version myself &lt;strong&gt;bootable from USB Flash&lt;/strong&gt;&amp;nbsp;and &lt;strong&gt;for free&lt;/strong&gt;. In this post I explain how I did it from A to Z. I&amp;#39;ll also explain how to create an &lt;strong&gt;ISO image for Windows PE cd&amp;#39;s&lt;/strong&gt;.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h2&gt;&lt;strong&gt;Getting started: download and install the WAIK&lt;/strong&gt;&lt;/h2&gt; &lt;p&gt;WAIK stands for the Windows Automated Installation Kit and is available as a &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=C7D4BC6D-15F3-4284-9123-679830D629F2" target="_blank"&gt;download&lt;/a&gt;. It&amp;#39;s a big download, but it&amp;#39;s worth to put your connection under stress for :-). Burn it to a cd or mount it using some ISO/IMG mounting tool and install it.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h2&gt;&lt;strong&gt;The Windows PE Tools Command Prompt&lt;/strong&gt;&lt;/h2&gt; &lt;p&gt;Next, open up the Windows PE Tools Command Prompt from the Start Menu and make sure to &lt;strong&gt;Run as Administrator&lt;/strong&gt;:&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="240" alt="image" src="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_thumb.png" width="160" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Alternatively, you can change the shortcut&amp;#39;s properties, Advanced..., Run as Administrator to run it everytime elevated as an administrator:&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_6.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="181" alt="image" src="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_thumb_3.png" width="240" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;You should see something like this:&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_7.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="120" alt="image" src="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_thumb_4.png" width="240" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Notice the message points you at a few usable executables: peimg, oscdimg and imagex. We&amp;#39;re going to use these in a minute.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h2&gt;&lt;strong&gt;Building your Windows PE&lt;/strong&gt;&lt;/h2&gt; &lt;p&gt;In order to build your custom Windows PE, follow the next steps:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Run &lt;strong&gt;copype.cmd&lt;/strong&gt; as follows:&lt;br /&gt;&lt;br /&gt;&amp;gt; copype.cmd x86 c:\winpe_x86&lt;br /&gt;&lt;br /&gt;This makes a copy of the Windows PE files to the specified folder. Alternatively, you can specify amd64 for 64-bit machines. We&amp;#39;ll manipulate this folder in the next steps.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_8.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="148" alt="image" src="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_thumb_5.png" width="240" border="0" /&gt;&lt;/a&gt; &lt;br /&gt; &lt;li&gt;Next, you can customize the Windows PE image (using the Windows Imaging Format, aka WIM) using &lt;strong&gt;ImageX&lt;/strong&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_9.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="146" alt="image" src="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_thumb_6.png" width="240" border="0" /&gt;&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;You can mount a WIM file to a folder like this:&lt;br /&gt;&lt;br /&gt;&amp;gt; mkdir c:\winpe_x86\mount&lt;br /&gt;&amp;gt; imagex /mountrw c:\winpe_x86\winpe.wim 1 c:\winpe_x86\mount&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_10.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="86" alt="image" src="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_thumb_7.png" width="240" border="0" /&gt;&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_11.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="141" alt="image" src="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_thumb_8.png" width="240" border="0" /&gt;&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;For the curious, this works through a file system driver called WimFltr (see sc queryex WimFltr).&lt;br /&gt; &lt;li&gt;Add all apps you like to add to the image in the mounted folder. Windows PE is based on packages that can be added to the image at will. This is done through &lt;strong&gt;peimg&lt;/strong&gt;, like this:&lt;br /&gt;&lt;br /&gt;&amp;gt; peimg /list /image=c:\winpe_x86\mount\Windows&lt;br /&gt;&lt;br /&gt;to show a list of all images:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_12.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="218" alt="image" src="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_thumb_9.png" width="240" border="0" /&gt;&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;Next, you can add packages by calling:&lt;br /&gt;&lt;br /&gt;&amp;gt; peimg /install=&amp;lt;package&amp;gt; c:\winpe_x86\mount\Windows&lt;br /&gt;&lt;br /&gt;where package is either * (all packages) or one from the list shown by invoking peimg with the /list switch.&lt;br /&gt; &lt;li&gt;You could add drivers and language packs as well, but for that I refer kindly to the excellent help documentation that comes with the WAIK. When you&amp;#39;re done with the image customization, run &lt;strong&gt;peimg&lt;/strong&gt; with the &lt;strong&gt;prep&lt;/strong&gt; switch:&lt;br /&gt;&lt;br /&gt;&amp;gt; peimg /prep c:\winpe_x86\mount\Windows&lt;br /&gt;&lt;br /&gt;and unmount the image using &lt;strong&gt;ImageX&lt;/strong&gt;:&lt;br /&gt;&lt;br /&gt;&amp;gt; imagex /unmount c:\winpe_x86\mount /commit&lt;br /&gt;&lt;br /&gt;and copy the created .wim file to the ISO folder:&lt;br /&gt;&lt;br /&gt;&amp;gt; copy c:\winpe_x86\winpe.wim c:\winpe_x86\ISO\sources\boot.wim&lt;br /&gt; &lt;li&gt;Next you can create an &lt;strong&gt;ISO file&lt;/strong&gt; for the image using &lt;strong&gt;oscdimg&lt;/strong&gt;:&lt;br /&gt;&lt;br /&gt;&amp;gt; oscdimg -n -bc:\winpe_x86\etfsboot.com c:\winpe_x86\ISO c:\winpe_x86\winpe_x86.iso&lt;br /&gt;&lt;br /&gt;where the -b flag specifies the El Torito boot sector for the ISO to be created. It just takes a few seconds to complete:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_13.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="158" alt="image" src="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_thumb_10.png" width="240" border="0" /&gt;&lt;/a&gt; &lt;br /&gt; &lt;li&gt;To test your image, just create a new Virtual PC virtual machine (e.g. with 256 MB of RAM) and mount the ISO file. No harddisk or network adapters needed:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_14.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="170" alt="image" src="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_thumb_11.png" width="240" border="0" /&gt;&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;VPC should boot like this:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_15.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="175" alt="image" src="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_thumb_12.png" width="240" border="0" /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_16.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="203" alt="image" src="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_thumb_13.png" width="240" border="0" /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_17.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="199" alt="image" src="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_thumb_14.png" width="240" border="0" /&gt;&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;Feel free to start taskmgr and notepad or so to get familiar with your next big friend :-). Finally shut it down using &lt;strong&gt;wpeutil shutdown&lt;/strong&gt;.&lt;br /&gt; &lt;li&gt;You might have noticed the image has the QWERTY keyboard layout, but you can change that if you like to do so. Go back to step 2 to mount and do the following on the mounted image using &lt;strong&gt;intlcfg&lt;/strong&gt;:&lt;br /&gt;&lt;br /&gt;&amp;gt; intlcfg -inputlocale:&amp;lt;locale&amp;gt; -image:c:\winpe_x86\mount&lt;br /&gt;&amp;gt; intlcfg -syslocale:&amp;lt;locale&amp;gt; -image:c:\winpe_x86\mount&lt;br /&gt;&amp;gt; intlcfg -userlocale:&amp;lt;locale&amp;gt; -image:c:\winpe_x86\mount&lt;br /&gt;&lt;br /&gt;where &amp;lt;locale&amp;gt; is replaced by the locale you want (e.g. nl-be for Belgian Period keyboard).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_18.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="82" alt="image" src="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_thumb_15.png" width="240" border="0" /&gt;&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;Go back to step 4 to unmount, commit, prep and create the iso. Rerun VPC to test.&lt;br /&gt;&lt;br /&gt;For the curious, this changes some of the &amp;lt;mount&amp;gt;\Windows\System32\config\*.* registry hives:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_19.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="188" alt="image" src="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_thumb_16.png" width="240" border="0" /&gt;&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;In regedit.exe you can mount these hives to see what&amp;#39;s in. To do this, open regedit, select HKLM and choose File, Load Hive. Next select the file to load (e.g. DEFAULT) and specify a name for the loaded hive (e.g. Mount):&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_20.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="123" alt="image" src="http://www.bartdesmet.net/images/Get.0forWindowsVistakeyboardlocalization_14639/image_thumb_17.png" width="240" border="0" /&gt;&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;As you can see, intlcfg has changed the Keyboard Layout\Preload list. Of course, the hardcore ones of you might prefer to make changes to the registry hive directly this way. By the way, while you&amp;#39;re in the loaded hive, check out other settings like:&lt;br /&gt;&lt;br /&gt;- desktop wallpaper via Control Panel\Desktop\WallPaper&lt;br /&gt;- (from the SYSTEM hive) command line to invoke after starting Windows PE via Setup\Cmdline&lt;br /&gt;&lt;br /&gt;Tip: regedit.exe is also available in Windows PE itself, so you can check the outcome over there. However, changes mage while running Windows PE won&amp;#39;t take effect since the registry is loaded in memory.&lt;br /&gt; &lt;li&gt;Finally, it&amp;#39;s time to put the whole thing on a USB Flash key or to burn the ISO created in step 5 to a cd-rom. I&amp;#39;ll cover the former option. Open up diskpart and execute the following commands:&lt;br /&gt;&lt;br /&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;WARNING!&lt;/strong&gt; Make sure to select the &lt;u&gt;right&lt;/u&gt; disk in step 1; you can view all disks using the &amp;quot;list disk&amp;quot; command. In the steps below, all data from the USB Flash disk will be removed!&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&amp;gt; select disk 1&lt;br /&gt;&amp;gt; clean&lt;br /&gt;&amp;gt; create partition primary&lt;br /&gt;&amp;gt; select partition 1&lt;br /&gt;&amp;gt; active&lt;br /&gt;&amp;gt; format fs=fat32&lt;br /&gt;&amp;gt; assign&lt;br /&gt;&amp;gt; exit&lt;br /&gt;&lt;br /&gt;Now copy to the c:\winpe_x86\ISO folder contents to the&amp;nbsp;USB disk (which I assume has letter E: assigned):&lt;br /&gt;&lt;br /&gt;&amp;gt; xcopy c:\winpe_x86\ISO\*.* E: /E&lt;br /&gt; &lt;li&gt;Now you should be able to boot from the USB Flash disk. Make sure to select the right boot device during the boot cycle or to change the boot order in your computer&amp;#39;s BIOS.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://community.bartdesmet.net/aggbug.aspx?PostID=12810" width="1" height="1"&gt;</description><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/Windows+Vista/default.aspx">Windows Vista</category></item><item><title>Simple managed code UAC elevation tool</title><link>http://community.bartdesmet.net/blogs/bart/archive/2007/09/14/simple-managed-code-uac-elevation-tool.aspx</link><pubDate>Fri, 14 Sep 2007 23:34:20 GMT</pubDate><guid isPermaLink="false">863c5522-913f-4a64-ac0a-bd5f05abad0f:12772</guid><dc:creator>bart</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://community.bartdesmet.net/blogs/bart/rsscomments.aspx?PostID=12772</wfw:commentRss><comments>http://community.bartdesmet.net/blogs/bart/archive/2007/09/14/simple-managed-code-uac-elevation-tool.aspx#comments</comments><description>&lt;p&gt;Everyone knows UAC by now. One core element of Vista&amp;#39;s UAC vision is the elevation of processes, used to run something as an administrator. Typically, you open up a command line instance (cmd.exe) which has been elevated already prior to invoking commands that require elevation. But what if you&amp;#39;re already in a non-elevated command prompt window and need to start an executable that runs elevated? In a such a scenario a tool like the one shown below might be useful:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt; System;&lt;br /&gt;&lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt; &lt;/font&gt;System.Diagnostics;&lt;br /&gt;&lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt; &lt;/font&gt;System.Reflection; &lt;/font&gt; &lt;p&gt;&lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;class &lt;/font&gt;&lt;font color="#008080"&gt;Program&lt;/font&gt;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;static void &lt;/font&gt;Main(&lt;font color="#0000ff"&gt;string&lt;/font&gt;[] args)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;if &lt;/font&gt;(args.Length == 0)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#008080"&gt;Console&lt;/font&gt;.WriteLine(&lt;font color="#800000"&gt;&amp;quot;Usage: {0}.exe &amp;lt;command&amp;gt;&amp;quot;&lt;/font&gt;, Assembly.GetExecutingAssembly().GetName().Name);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;return&lt;/font&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/font&gt; &lt;p&gt;&lt;font face="courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;string&lt;/font&gt; @params = &lt;font color="#800000"&gt;&amp;quot;&amp;quot;&lt;/font&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (args.Length &amp;gt; 1)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @params = &lt;font color="#0000ff"&gt;string&lt;/font&gt;.Join(&lt;font color="#800000"&gt;&amp;quot; &amp;quot;&lt;/font&gt;, args, 1, args.Length - 1); &lt;/font&gt; &lt;p&gt;&lt;font face="courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#008080"&gt;ProcessStartInfo &lt;/font&gt;psi = &lt;font color="#0000ff"&gt;new &lt;/font&gt;&lt;font color="#008080"&gt;ProcessStartInfo&lt;/font&gt;(args[0], @params);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; psi.Verb = &lt;font color="#800000"&gt;&amp;quot;runas&amp;quot;&lt;/font&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#008080"&gt;Process&lt;/font&gt;.Start(psi);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;This tool uses the regular Process class from the .NET Framework but specifies a Verb on the ProcessStartInfo object. You can find more info on verbs in the Windows SDK under &amp;quot;Verbs and File Associations&amp;quot;. Enjoy!&lt;/p&gt;&lt;img src="http://community.bartdesmet.net/aggbug.aspx?PostID=12772" width="1" height="1"&gt;</description><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/Security/default.aspx">Security</category><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/Windows+Vista/default.aspx">Windows Vista</category></item><item><title>Windows Vista - WinSta0 isolation explained</title><link>http://community.bartdesmet.net/blogs/bart/archive/2007/03/05/windows-vista-winsta0-isolation-explained.aspx</link><pubDate>Tue, 06 Mar 2007 07:08:13 GMT</pubDate><guid isPermaLink="false">863c5522-913f-4a64-ac0a-bd5f05abad0f:12242</guid><dc:creator>bart</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://community.bartdesmet.net/blogs/bart/rsscomments.aspx?PostID=12242</wfw:commentRss><comments>http://community.bartdesmet.net/blogs/bart/archive/2007/03/05/windows-vista-winsta0-isolation-explained.aspx#comments</comments><description>&lt;p&gt;Time for another security feature in Windows Vista: WinSta0 isolation. The first question that might pop up in your head is "So, what exactly is WinSta0?". Keith Brown has the &lt;a href="http://www.pluralsight.com/wiki/default.aspx/Keith.GuideBook/WhatIsAWindowStation.html"&gt;answer&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;The problem with WinSta0 is the possibility for Windows Services to display a UI prompt in the window station. Pre-Vista, this prompt just appears on top of the desktop of the user logged on to the system. Because of this, the service is exceeding its boundary of isolation and the inware user is providing information across that "trust boundary".&lt;/p&gt; &lt;p&gt;Windows Vista reduces this risk by isolating WinSta0 from the active user's desktop; a user has to provide his/her consent to switch to the bare WinSta0 when that screams for attention (which is detected by an executable called UI0Detect.exe as displayed below):&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.bartdesmet.net/images/WindowsVistaWinSta0isolationexplained_1958/image05.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="209" src="http://www.bartdesmet.net/images/WindowsVistaWinSta0isolationexplained_1958/image04.png" width="240" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;When you see this kind of message, the app you're dealing with has "partial incompatibility with Windows Vista". The message to developers: &lt;strong&gt;fix it&lt;/strong&gt; - Windows doesn't like the old approach anymore! An example I've been faced with in practice&amp;nbsp;is the HP LaserJet 1020 software that uses WinSta0 to show out of paper messages and other printer maintenance messages.&lt;/p&gt; &lt;p&gt;In this post, I'm showing you the code for a demo of a WinSta0 isolation demo I gave some time ago, together with demonstration instructions.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h2&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Step&amp;nbsp;1 - Creating an interactive Windows Service&lt;/font&gt;&lt;/strong&gt;&lt;/h2&gt; &lt;p&gt;So, for sake of the demo, let's create something we really shouldn't have created: an interactive Windows Service. Open Visual Studio 2005&amp;nbsp;and create a new Windows Service project called "&lt;strong&gt;WinSta0Inspector&lt;/strong&gt;" in C#:&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.bartdesmet.net/images/WindowsVistaWinSta0isolationexplained_1958/image07.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="170" src="http://www.bartdesmet.net/images/WindowsVistaWinSta0isolationexplained_1958/image06.png" width="240" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Next, go to Service1.cs and change the service name to WinSta0Inspector:&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.bartdesmet.net/images/WindowsVistaWinSta0isolationexplained_1958/image09.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="240" src="http://www.bartdesmet.net/images/WindowsVistaWinSta0isolationexplained_1958/image08.png" width="238" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Right-click the designer surface and choose Add Installer. This will create a new file ProjectInstaller.cs that makes the executable installutil.exe-able. In there, select the serviceProcessInstaller1 "control" and set the Account property to Local System (to make things really bad):&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.bartdesmet.net/images/WindowsVistaWinSta0isolationexplained_1958/image011.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="240" src="http://www.bartdesmet.net/images/WindowsVistaWinSta0isolationexplained_1958/image010.png" width="236" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;In order to make the service interactive, we'll create a simple Windows Form. Right click the project in the Solution Explorer, choose Add New Item and add a Windows Form called ExecuteCommand.cs. Design it so that it looks like this:&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.bartdesmet.net/images/WindowsVistaWinSta0isolationexplained_1958/image013.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="179" src="http://www.bartdesmet.net/images/WindowsVistaWinSta0isolationexplained_1958/image012.png" width="240" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Hook up event handlers for both LinkLabels, with definitions like this:&lt;/p&gt; &lt;p&gt; &lt;div class="wlWriterSmartContent" id="F2210F5F-69EB-4d4c-AFF7-B8A050E9CC72:202fdf0e-efcc-4881-b2cb-a7074a99fbdd" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="width:100%;"&gt;&lt;div&gt;&lt;span style="color:#0000FF;"&gt;private&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; linkLabel1_LinkClicked(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt; sender, LinkLabelLinkClickedEventArgs e)
{
    Process.Start(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;cmd.exe&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;);
}

&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;private&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; linkLabel2_LinkClicked(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt; sender, LinkLabelLinkClickedEventArgs e)
{
    DialogResult &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; DialogResult.OK;
}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Don't forget to import System.Diagnostics in order to have access to the Process class. Now go back to Service1.cs and switch to the code view. Define the Service1 class as follows:&lt;/p&gt;
&lt;p&gt;
&lt;div class="wlWriterSmartContent" id="F2210F5F-69EB-4d4c-AFF7-B8A050E9CC72:eed015ad-7d34-403c-a06e-b1748eec48ea" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="width:100%;"&gt;&lt;div&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;partial&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; Service1 : ServiceBase
{
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;private&lt;/span&gt;&lt;span style="color:#000000;"&gt; ExecuteCommand dialog &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; ExecuteCommand();

    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; Service1()
    {
        InitializeComponent();
    }

    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;protected&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;override&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; OnStart(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt;[] args)
    {
    }

    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;protected&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;override&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; OnCustomCommand(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; command)
    {
        MessageBox.Show(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Welcome to WinSta0.&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;WinSta0 is calling you!&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        dialog.ShowDialog();
    }
}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;You'll need to import System.Windows.Forms to have access to MessageBox. This completes our interactive service.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Step 2 - Installing it&lt;/font&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Compile the solution and switch to a Visual Studio 2005 Command Prompt which runs elevated with administrator privileges. Install the service using &lt;em&gt;installutil -i WinSta0Inspector.exe&lt;/em&gt;. Then open the Services MMC snap-in (services.msc), locate the WinSta0Inspector service and change its properties to make it interactive:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.bartdesmet.net/images/WindowsVistaWinSta0isolationexplained_1958/image017.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="240" src="http://www.bartdesmet.net/images/WindowsVistaWinSta0isolationexplained_1958/image016.png" width="213" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Command-line freaks could also use the following command to install the service directly as an interactive service; no need to run installtutil then, just do this:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;sc create WinSta0Inspector binPath= WinSta0Inspector.exe type= interact DisplayName= "WinSta0 Inspector"&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;&lt;font color="#000080"&gt;&lt;strong&gt;Step 3 - Action!&lt;/strong&gt;&lt;/font&gt;&lt;/h2&gt;
&lt;p&gt;In order to see it in action, start the service and send it a custom command. You could write another app to send the custom command using the System.Service.ServiceController::ExecuteCommand method, but sc.exe has everything we need:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.bartdesmet.net/images/WindowsVistaWinSta0isolationexplained_1958/image019.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="120" src="http://www.bartdesmet.net/images/WindowsVistaWinSta0isolationexplained_1958/image018.png" width="240" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;First, we started the service using &lt;em&gt;net start WinSta0Inspector&lt;/em&gt;. Next, we sent a command to the service by using &lt;em&gt;sc control WinSta0Inspector 129&lt;/em&gt; (valid commands should be higher than 128, other values are system-reserved). Right away you'll see the Interactive services dialog detection dialog popping up in the background:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.bartdesmet.net/images/WindowsVistaWinSta0isolationexplained_1958/image021.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="130" src="http://www.bartdesmet.net/images/WindowsVistaWinSta0isolationexplained_1958/image020.png" width="240" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Click Show me the message and Vista will bring you to the raw WinSta0 environment which should look somewhat like this:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.bartdesmet.net/images/WindowsVistaWinSta0isolationexplained_1958/image023.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="150" src="http://www.bartdesmet.net/images/WindowsVistaWinSta0isolationexplained_1958/image022.png" width="240" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Press OK in our message box; the WinForms dialog will show up now:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.bartdesmet.net/images/WindowsVistaWinSta0isolationexplained_1958/image025.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="150" src="http://www.bartdesmet.net/images/WindowsVistaWinSta0isolationexplained_1958/image024.png" width="240" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Feel free to take a look around WinSta0 using the command-prompt link on the form. For example, run &lt;em&gt;whoami /all&lt;/em&gt; to find out about your SYSTEM power :-)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.bartdesmet.net/images/WindowsVistaWinSta0isolationexplained_1958/image027.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="240" src="http://www.bartdesmet.net/images/WindowsVistaWinSta0isolationexplained_1958/image026.png" width="143" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;If you have a hacker's mindset you might find HKLM\SECURITY\SAM an attractive place to visit while you're the Windows übermensch :o. Below you can see a few other screenshots of what it is like to be in WinSta0 (e.g. how did I create the screenshots?):&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.bartdesmet.net/images/WindowsVistaWinSta0isolationexplained_1958/image031.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="150" src="http://www.bartdesmet.net/images/WindowsVistaWinSta0isolationexplained_1958/image030.png" width="240" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.bartdesmet.net/images/WindowsVistaWinSta0isolationexplained_1958/image029.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="150" src="http://www.bartdesmet.net/images/WindowsVistaWinSta0isolationexplained_1958/image028.png" width="240" border="0"&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Have fun!&lt;/p&gt;&lt;img src="http://community.bartdesmet.net/aggbug.aspx?PostID=12242" width="1" height="1"&gt;</description><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/Security/default.aspx">Security</category><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/Windows+Vista/default.aspx">Windows Vista</category></item><item><title>New in Orcas - Embedding Vista UAC manifests in 30 seconds</title><link>http://community.bartdesmet.net/blogs/bart/archive/2007/03/04/new-in-orcas-embedding-vista-uac-manifests-in-30-seconds.aspx</link><pubDate>Mon, 05 Mar 2007 07:58:41 GMT</pubDate><guid isPermaLink="false">863c5522-913f-4a64-ac0a-bd5f05abad0f:12239</guid><dc:creator>bart</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://community.bartdesmet.net/blogs/bart/rsscomments.aspx?PostID=12239</wfw:commentRss><comments>http://community.bartdesmet.net/blogs/bart/archive/2007/03/04/new-in-orcas-embedding-vista-uac-manifests-in-30-seconds.aspx#comments</comments><description>&lt;p&gt;&lt;u&gt;Note:&lt;/u&gt; This article applies to the Visual Studio "Orcas" March 07 CTP build that can be downloaded from the &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=281FCB3D-5E79-4126-B4C0-8DB6332DE26E&amp;amp;displaylang=en"&gt;Microsoft website&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;In this post we'll talk about embedding UAC (User Account Control) manifests in managed code executables without having to rely on rather dirty tricks, as I explained in my older blog post entitled &lt;a href="http://community.bartdesmet.net/blogs/bart/archive/2006/10/28/Windows-Vista-_2D00_-Demand-UAC-elevation-for-an-application-by-adding-a-manifest-using-mt.exe.aspx"&gt;Windows Vista - Demand UAC elevation for an application by adding a manifest using mt.exe&lt;/a&gt;. Please read this&amp;nbsp;post prior to reading this post, in order to get a good idea about UAC&amp;nbsp;and manifests.&lt;/p&gt; &lt;p&gt;Essentially, this article performs a little word substitution on the title of the previous post: adding a manifest &lt;strike&gt;using mt.exe&lt;/strike&gt; &lt;strong&gt;using Visual Studio "Orcas"&lt;/strong&gt;.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h2&gt;&lt;strong&gt;&lt;font color="#000040"&gt;Step 1 - Creating the Windows Forms app&lt;/font&gt;&lt;/strong&gt;&lt;/h2&gt; &lt;p&gt;We'll start by creating the same app as we did in the previous post mentioned above. Open up VS "Orcas", create a new (C#) Windows Forms project called &lt;strong&gt;UacDemo &lt;/strong&gt;and add a label called "label1" to the designer surface. As a side-note, play around with the IDE designer for Windows Forms a bit, you'll see that the Layout toolbar has been revamped (for example, add another label, select both labels and observe the options in this toolbar):&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.bartdesmet.net/images/NewinOrcasEmbeddingVistaUACmanifestsin30_52E/image01.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="154" src="http://www.bartdesmet.net/images/NewinOrcasEmbeddingVistaUACmanifestsin30_52E/image0.png" width="240" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Next, go to the code and add an event handler for Form1_Load that does the following:&lt;/p&gt; &lt;p&gt; &lt;div class="wlWriterSmartContent" id="F2210F5F-69EB-4d4c-AFF7-B8A050E9CC72:652581ba-811a-4020-82c5-e570c6f37ae5" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="width:100%;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;label1.Text &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator) &lt;/span&gt;&lt;span style="color:#000000;"&gt;?&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Yup&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt; : &lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Nope&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;You'll need to bring the System.Security.Principal namespace in scope in order to compile the code above.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Step 2 - Add a manifest to the project&lt;/font&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Add a new item to the project and choose for an XML file. Call it &lt;strong&gt;UacDemo.exe.manifest&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.bartdesmet.net/images/NewinOrcasEmbeddingVistaUACmanifestsin30_52E/image03.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="145" src="http://www.bartdesmet.net/images/NewinOrcasEmbeddingVistaUACmanifestsin30_52E/image02.png" width="240" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Add the following contents to it:&lt;/p&gt;
&lt;p&gt;
&lt;div class="wlWriterSmartContent" id="F2210F5F-69EB-4d4c-AFF7-B8A050E9CC72:05231424-2cd1-4522-a52c-e96e79732f76" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="width:100%;"&gt;&lt;div&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;yes&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;?&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;assembly &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;xmlns&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;urn:schemas-microsoft-com:asm.v1&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; manifestVersion&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; 
   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;assemblyIdentity &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;version&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;1.0.0.0&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; processorArchitecture&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;X86&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;UacDemo&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; type&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;win32&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;trustInfo &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;xmlns&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;urn:schemas-microsoft-com:asm.v3&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;security&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
         &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;requestedPrivileges&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;requestedExecutionLevel &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;level&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;requireAdministrator&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; 
         &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;requestedPrivileges&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;security&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;trustInfo&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;assembly&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Notice that the &lt;strong&gt;name&lt;/strong&gt; attribute of the &lt;strong&gt;assemblyIdentity&lt;/strong&gt; element has to be set to the name of the executable (without .exe extension). Information about UAC manifests can be found by searching "requestedPrivileges" on the internet for instance.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Step 3 - Tell the build environment to include the manifest&lt;/font&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;This is where things got difficult in the past. A solution pre-Orcas was explained on my aforementioned previous blog entry on UAC using a post-build step calling the &lt;strong&gt;mt.exe&lt;/strong&gt; tool. Now, things have become much more simple. Just go to the properties of the project, tab Application and scroll down to the section "Resources" as shown below:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.bartdesmet.net/images/NewinOrcasEmbeddingVistaUACmanifestsin30_52E/image08.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="411" src="http://www.bartdesmet.net/images/NewinOrcasEmbeddingVistaUACmanifestsin30_52E/image0_thumb2.png" width="640" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;In the manifest dropdown box you can now point to the manifest we've created in the previous step.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Step 4 - Build, inspect, test&lt;/font&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;That's it; we're done now! To illustrate what has happened, take a look at the .csproj file of the project using an XML editor; below is a snippet from this file on my machine:&lt;/p&gt;
&lt;p&gt;
&lt;div class="wlWriterSmartContent" id="F2210F5F-69EB-4d4c-AFF7-B8A050E9CC72:b71a0506-b6a7-437f-83b4-cc2649b03cd9" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="width:100%;"&gt;&lt;div&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Project &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;ToolsVersion&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;3.5&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; DefaultTargets&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Build&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; xmlns&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;http://schemas.microsoft.com/developer/msbuild/2003&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;PropertyGroup&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Configuration &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Condition&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot; '$(Configuration)' == '' &amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Debug&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Configuration&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Platform &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Condition&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot; '$(Platform)' == '' &amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;AnyCPU&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Platform&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;ProductVersion&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;9.0.20209&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;ProductVersion&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;SchemaVersion&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;2.0&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;SchemaVersion&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;ProjectGuid&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;{8FB484D6-73DB-4AEE-8222-7FE5B0CBD622}&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;ProjectGuid&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;OutputType&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;WinExe&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;OutputType&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;AppDesignerFolder&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Properties&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;AppDesignerFolder&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;RootNamespace&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;UacDemo&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;RootNamespace&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;AssemblyName&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;UacDemo&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;AssemblyName&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;TargetFrameworkVersion&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;v3.5&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;TargetFrameworkVersion&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;FileAlignment&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;512&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;FileAlignment&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;ApplicationManifest&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;UacDemo.exe.manifest&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;ApplicationManifest&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;PropertyGroup&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;First, observe the presence of multi-targeting: the Project's ToolsVersion attribute tells the tools that use the .csproj file to use the 3.5 version of the framework; furthermore, &lt;strong&gt;TargetFrameworkVersion&lt;/strong&gt; tags appear in the file, as well as RequiredTargetFramework tags for dependencies (not illustrated in the snippet above). However, for us the &lt;strong&gt;ApplicationManifest&lt;/strong&gt; element is much more interesting since it points to our manifest file; this tells MSBuild to take mt.exe alike steps to include the manifest in the executable when compilation has been done successfully.&lt;/p&gt;
&lt;p&gt;To see that the manifest is included correctly, you can go to the Visual Studio Orcas Command Prompt, cd into the bin\Debug or bin\Release folder of the UacDemo project and call &lt;em&gt;mt -inputresource:uacdemo.exe -out:uacdemo.exe.manifest&lt;/em&gt; to extract the manifest from the file and to see what's in there:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.bartdesmet.net/images/NewinOrcasEmbeddingVistaUACmanifestsin30_52E/image011.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="317" src="http://www.bartdesmet.net/images/NewinOrcasEmbeddingVistaUACmanifestsin30_52E/image0_thumb3.png" width="640" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Finally, run the file on your Vista machine and you should see the UAC prompt popping up to elevate the privileges of the app:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.bartdesmet.net/images/NewinOrcasEmbeddingVistaUACmanifestsin30_52E/image013.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="53" src="http://www.bartdesmet.net/images/NewinOrcasEmbeddingVistaUACmanifestsin30_52E/image012.png" width="240" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Notice that creating screenshots from the UAC prompt isn't easy due to the presence of the "UAC Secure Desktop" where the UAC prompts are displayed. In order to make it possible, open up secpol.msc, go to Local Policies, Security Options and tweak the "User Account Control: Switch to the secure desktop when prompting for elevation" setting to Disabled (&lt;strong&gt;don't forget to revert it afterwards!&lt;/strong&gt;):&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.bartdesmet.net/images/NewinOrcasEmbeddingVistaUACmanifestsin30_52E/image019.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="192" src="http://www.bartdesmet.net/images/NewinOrcasEmbeddingVistaUACmanifestsin30_52E/image0_thumb5.png" width="240" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://community.bartdesmet.net/aggbug.aspx?PostID=12239" width="1" height="1"&gt;</description><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/Windows+Vista/default.aspx">Windows Vista</category><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/Orcas/default.aspx">Orcas</category></item><item><title>Windows Vista - Introducing TxF in C# (part 3) - CreateFileTransacted demo</title><link>http://community.bartdesmet.net/blogs/bart/archive/2007/02/21/windows-vista-introducing-txf-in-c-part-3-createfiletransacted-demo.aspx</link><pubDate>Thu, 22 Feb 2007 07:03:35 GMT</pubDate><guid isPermaLink="false">863c5522-913f-4a64-ac0a-bd5f05abad0f:12193</guid><dc:creator>bart</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://community.bartdesmet.net/blogs/bart/rsscomments.aspx?PostID=12193</wfw:commentRss><comments>http://community.bartdesmet.net/blogs/bart/archive/2007/02/21/windows-vista-introducing-txf-in-c-part-3-createfiletransacted-demo.aspx#comments</comments><description>&lt;p&gt;In November last year, I blogged about TxF:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href="http://community.bartdesmet.net/blogs/bart/archive/2006/11/05/Windows-Vista-_2D00_-Introducing-TxF-in-C_2300_-_2800_part-1_2900_-_2D00_-Transacted-file-delete.aspx"&gt;Windows Vista - Introducing TxF in C# (part 1) - Transacted file delete&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="http://community.bartdesmet.net/blogs/bart/archive/2006/11/19/Windows-Vista-_2D00_-Introducing-TxF-in-C_2300_-_2800_part-2_2900_-_2D00_-Using-System.Transactions-and-the-DTC.aspx"&gt;Windows Vista - Introducing TxF in C# (part 2) - Using System.Transactions and the DTC&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;A few days ago I received a mail from a reader of my blog who had an issue with a similar CreateFileTransacted code snippet which allows to manipulate file content in the scope of a transaction. In today's post, I show a little demo on how to do this.&lt;/p&gt; &lt;p&gt; &lt;div class="wlWriterSmartContent" id="F2210F5F-69EB-4d4c-AFF7-B8A050E9CC72:2d9cc627-07ba-4dbb-a667-b0d26da3108f" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="width:100%;"&gt;&lt;div&gt;&lt;span style="color:#999999;"&gt;  1&lt;/span&gt; &lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;  2&lt;/span&gt; &lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.IO;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;  3&lt;/span&gt; &lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; Microsoft.Win32.SafeHandles;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;  4&lt;/span&gt; &lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Runtime.InteropServices;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;  5&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;  6&lt;/span&gt; &lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; TxfDemo
&lt;/span&gt;&lt;span style="color:#999999;"&gt;  7&lt;/span&gt; &lt;span style="color:#000000;"&gt;{
&lt;/span&gt;&lt;span style="color:#999999;"&gt;  8&lt;/span&gt; &lt;span style="color:#000000;"&gt;   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;const&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;uint&lt;/span&gt;&lt;span style="color:#000000;"&gt; GENERIC_READ &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800080;"&gt;0x80000000&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;  9&lt;/span&gt; &lt;span style="color:#000000;"&gt;   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;const&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;uint&lt;/span&gt;&lt;span style="color:#000000;"&gt; GENERIC_WRITE &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800080;"&gt;0x40000000&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 10&lt;/span&gt; &lt;span style="color:#000000;"&gt;   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;const&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;uint&lt;/span&gt;&lt;span style="color:#000000;"&gt; CREATE_NEW &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800080;"&gt;1&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 11&lt;/span&gt; &lt;span style="color:#000000;"&gt;   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;const&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;uint&lt;/span&gt;&lt;span style="color:#000000;"&gt; CREATE_ALWAYS &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800080;"&gt;2&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 12&lt;/span&gt; &lt;span style="color:#000000;"&gt;   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;const&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;uint&lt;/span&gt;&lt;span style="color:#000000;"&gt; OPEN_EXISTING &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800080;"&gt;3&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 13&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 14&lt;/span&gt; &lt;span style="color:#000000;"&gt;   [DllImport(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;kernel32.dll&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, SetLastError &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;true&lt;/span&gt;&lt;span style="color:#000000;"&gt;)]
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 15&lt;/span&gt; &lt;span style="color:#000000;"&gt;   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;static&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;extern&lt;/span&gt;&lt;span style="color:#000000;"&gt; SafeFileHandle CreateFile(
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 16&lt;/span&gt; &lt;span style="color:#000000;"&gt;      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; lpFileName,
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 17&lt;/span&gt; &lt;span style="color:#000000;"&gt;      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;uint&lt;/span&gt;&lt;span style="color:#000000;"&gt; dwDesiredAccess,
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 18&lt;/span&gt; &lt;span style="color:#000000;"&gt;      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;uint&lt;/span&gt;&lt;span style="color:#000000;"&gt; dwShareMode,
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 19&lt;/span&gt; &lt;span style="color:#000000;"&gt;      IntPtr lpSecurityAttributes,
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 20&lt;/span&gt; &lt;span style="color:#000000;"&gt;      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;uint&lt;/span&gt;&lt;span style="color:#000000;"&gt; dwCreationDisposition,
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 21&lt;/span&gt; &lt;span style="color:#000000;"&gt;      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;uint&lt;/span&gt;&lt;span style="color:#000000;"&gt; dwFlagsAndAttributes,
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 22&lt;/span&gt; &lt;span style="color:#000000;"&gt;      IntPtr hTemplateFile);
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 23&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 24&lt;/span&gt; &lt;span style="color:#000000;"&gt;   [DllImport(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;kernel32.dll&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, SetLastError &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;true&lt;/span&gt;&lt;span style="color:#000000;"&gt;)]
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 25&lt;/span&gt; &lt;span style="color:#000000;"&gt;   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;static&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;extern&lt;/span&gt;&lt;span style="color:#000000;"&gt; SafeFileHandle CreateFileTransacted(
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 26&lt;/span&gt; &lt;span style="color:#000000;"&gt;      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; lpFileName,
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 27&lt;/span&gt; &lt;span style="color:#000000;"&gt;      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;uint&lt;/span&gt;&lt;span style="color:#000000;"&gt; dwDesiredAccess,
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 28&lt;/span&gt; &lt;span style="color:#000000;"&gt;      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;uint&lt;/span&gt;&lt;span style="color:#000000;"&gt; dwShareMode,
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 29&lt;/span&gt; &lt;span style="color:#000000;"&gt;      IntPtr lpSecurityAttributes,
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 30&lt;/span&gt; &lt;span style="color:#000000;"&gt;      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;uint&lt;/span&gt;&lt;span style="color:#000000;"&gt; dwCreationDisposition,
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 31&lt;/span&gt; &lt;span style="color:#000000;"&gt;      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;uint&lt;/span&gt;&lt;span style="color:#000000;"&gt; dwFlagsAndAttributes,
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 32&lt;/span&gt; &lt;span style="color:#000000;"&gt;      IntPtr hTemplateFile,
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 33&lt;/span&gt; &lt;span style="color:#000000;"&gt;      IntPtr hTransaction,
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 34&lt;/span&gt; &lt;span style="color:#000000;"&gt;      IntPtr pusMiniVersion,
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 35&lt;/span&gt; &lt;span style="color:#000000;"&gt;      IntPtr pExtendedParameter);
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 36&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 37&lt;/span&gt; &lt;span style="color:#000000;"&gt;   [DllImport(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;ktmw32.dll&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, SetLastError &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;true&lt;/span&gt;&lt;span style="color:#000000;"&gt;)]
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 38&lt;/span&gt; &lt;span style="color:#000000;"&gt;   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;static&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;extern&lt;/span&gt;&lt;span style="color:#000000;"&gt; IntPtr CreateTransaction(
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 39&lt;/span&gt; &lt;span style="color:#000000;"&gt;      IntPtr lpTransactionAttributes,
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 40&lt;/span&gt; &lt;span style="color:#000000;"&gt;      IntPtr uow,
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 41&lt;/span&gt; &lt;span style="color:#000000;"&gt;      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;uint&lt;/span&gt;&lt;span style="color:#000000;"&gt; createOptions,
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 42&lt;/span&gt; &lt;span style="color:#000000;"&gt;      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;uint&lt;/span&gt;&lt;span style="color:#000000;"&gt; isolationLevel,
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 43&lt;/span&gt; &lt;span style="color:#000000;"&gt;      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;uint&lt;/span&gt;&lt;span style="color:#000000;"&gt; isolationFlags,
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 44&lt;/span&gt; &lt;span style="color:#000000;"&gt;      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;uint&lt;/span&gt;&lt;span style="color:#000000;"&gt; timeout,
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 45&lt;/span&gt; &lt;span style="color:#000000;"&gt;      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; description);
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 46&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 47&lt;/span&gt; &lt;span style="color:#000000;"&gt;   [DllImport(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;ktmw32.dll&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, SetLastError &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;true&lt;/span&gt;&lt;span style="color:#000000;"&gt;)]
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 48&lt;/span&gt; &lt;span style="color:#000000;"&gt;   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;static&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;extern&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;bool&lt;/span&gt;&lt;span style="color:#000000;"&gt; CommitTransaction(
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 49&lt;/span&gt; &lt;span style="color:#000000;"&gt;      IntPtr transaction);
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 50&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 51&lt;/span&gt; &lt;span style="color:#000000;"&gt;   [DllImport(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;ktmw32.dll&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, SetLastError &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;true&lt;/span&gt;&lt;span style="color:#000000;"&gt;)]
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 52&lt;/span&gt; &lt;span style="color:#000000;"&gt;   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;static&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;extern&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;bool&lt;/span&gt;&lt;span style="color:#000000;"&gt; RollbackTransaction(
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 53&lt;/span&gt; &lt;span style="color:#000000;"&gt;      IntPtr transaction);
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 54&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 55&lt;/span&gt; &lt;span style="color:#000000;"&gt;   [DllImport(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Kernel32.dll&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;)]
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 56&lt;/span&gt; &lt;span style="color:#000000;"&gt;   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;static&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;extern&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;bool&lt;/span&gt;&lt;span style="color:#000000;"&gt; CloseHandle(IntPtr handle); 
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 57&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 58&lt;/span&gt; &lt;span style="color:#000000;"&gt;   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;static&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; Main()
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 59&lt;/span&gt; &lt;span style="color:#000000;"&gt;   {
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 60&lt;/span&gt; &lt;span style="color:#000000;"&gt;      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; file &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;txfdemo.txt&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 61&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 62&lt;/span&gt; &lt;span style="color:#000000;"&gt;      &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 63&lt;/span&gt; &lt;span style="color:#008000;"&gt;      &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; For demo purposes, delete the file first (if it already exists).
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 64&lt;/span&gt; &lt;span style="color:#008000;"&gt;      &lt;/span&gt;&lt;span style="color:#008000;"&gt;//
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 65&lt;/span&gt; &lt;span style="color:#008000;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; (File.Exists(file))
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 66&lt;/span&gt; &lt;span style="color:#000000;"&gt;        File.Delete(file);
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 67&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 68&lt;/span&gt; &lt;span style="color:#000000;"&gt;      &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 69&lt;/span&gt; &lt;span style="color:#008000;"&gt;      &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; Create KTM transaction.
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 70&lt;/span&gt; &lt;span style="color:#008000;"&gt;      &lt;/span&gt;&lt;span style="color:#008000;"&gt;//
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 71&lt;/span&gt; &lt;span style="color:#008000;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;      IntPtr transaction &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; CreateTransaction(IntPtr.Zero, IntPtr.Zero, &lt;/span&gt;&lt;span style="color:#800080;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#800080;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#800080;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#800080;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;null&lt;/span&gt;&lt;span style="color:#000000;"&gt;);
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 72&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 73&lt;/span&gt; &lt;span style="color:#000000;"&gt;      &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 74&lt;/span&gt; &lt;span style="color:#008000;"&gt;      &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; Check transaction handle.
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 75&lt;/span&gt; &lt;span style="color:#008000;"&gt;      &lt;/span&gt;&lt;span style="color:#008000;"&gt;//
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 76&lt;/span&gt; &lt;span style="color:#008000;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; (transaction &lt;/span&gt;&lt;span style="color:#000000;"&gt;==&lt;/span&gt;&lt;span style="color:#000000;"&gt; IntPtr.Zero)
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 77&lt;/span&gt; &lt;span style="color:#000000;"&gt;      {
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 78&lt;/span&gt; &lt;span style="color:#000000;"&gt;         Console.WriteLine(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Oops! KTM has taken a day off.&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;);
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 79&lt;/span&gt; &lt;span style="color:#000000;"&gt;         &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 80&lt;/span&gt; &lt;span style="color:#000000;"&gt;      }
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 81&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 82&lt;/span&gt; &lt;span style="color:#000000;"&gt;      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;try&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 83&lt;/span&gt; &lt;span style="color:#000000;"&gt;      {
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 84&lt;/span&gt; &lt;span style="color:#000000;"&gt;         &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 85&lt;/span&gt; &lt;span style="color:#008000;"&gt;         &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; Non-transacted.
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 86&lt;/span&gt; &lt;span style="color:#008000;"&gt;         &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 87&lt;/span&gt; &lt;span style="color:#008000;"&gt;         &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt;SafeFileHandle handle = CreateFile(file, GENERIC_READ | GENERIC_WRITE, 0, IntPtr.Zero, CREATE_NEW, 0, IntPtr.Zero);
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 88&lt;/span&gt; &lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 89&lt;/span&gt; &lt;span style="color:#008000;"&gt;         &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 90&lt;/span&gt; &lt;span style="color:#008000;"&gt;         &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; Transacted file creation (CREATE_NEW).
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 91&lt;/span&gt; &lt;span style="color:#008000;"&gt;         &lt;/span&gt;&lt;span style="color:#008000;"&gt;//
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 92&lt;/span&gt; &lt;span style="color:#008000;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;         SafeFileHandle handle &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; CreateFileTransacted(file, GENERIC_READ &lt;/span&gt;&lt;span style="color:#000000;"&gt;|&lt;/span&gt;&lt;span style="color:#000000;"&gt; GENERIC_WRITE, &lt;/span&gt;&lt;span style="color:#800080;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;, IntPtr.Zero, CREATE_NEW, &lt;/span&gt;&lt;span style="color:#800080;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;, IntPtr.Zero, transaction, IntPtr.Zero, IntPtr.Zero);
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 93&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 94&lt;/span&gt; &lt;span style="color:#000000;"&gt;         &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 95&lt;/span&gt; &lt;span style="color:#008000;"&gt;         &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; Check handle.
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 96&lt;/span&gt; &lt;span style="color:#008000;"&gt;         &lt;/span&gt;&lt;span style="color:#008000;"&gt;//
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 97&lt;/span&gt; &lt;span style="color:#008000;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;         &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; (handle.IsInvalid)
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 98&lt;/span&gt; &lt;span style="color:#000000;"&gt;            Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 99&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;100&lt;/span&gt; &lt;span style="color:#000000;"&gt;         &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;101&lt;/span&gt; &lt;span style="color:#008000;"&gt;         &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; Using pattern for stream operations.
&lt;/span&gt;&lt;span style="color:#999999;"&gt;102&lt;/span&gt; &lt;span style="color:#008000;"&gt;         &lt;/span&gt;&lt;span style="color:#008000;"&gt;//
&lt;/span&gt;&lt;span style="color:#999999;"&gt;103&lt;/span&gt; &lt;span style="color:#008000;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;         &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; (FileStream fs &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; FileStream(handle,FileAccess.ReadWrite))
&lt;/span&gt;&lt;span style="color:#999999;"&gt;104&lt;/span&gt; &lt;span style="color:#000000;"&gt;         {
&lt;/span&gt;&lt;span style="color:#999999;"&gt;105&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; (StreamWriter sw &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; StreamWriter(fs))
&lt;/span&gt;&lt;span style="color:#999999;"&gt;106&lt;/span&gt; &lt;span style="color:#000000;"&gt;            {
&lt;/span&gt;&lt;span style="color:#999999;"&gt;107&lt;/span&gt; &lt;span style="color:#000000;"&gt;               sw.WriteLine(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Hello&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;);
&lt;/span&gt;&lt;span style="color:#999999;"&gt;108&lt;/span&gt; &lt;span style="color:#000000;"&gt;            }
&lt;/span&gt;&lt;span style="color:#999999;"&gt;109&lt;/span&gt; &lt;span style="color:#000000;"&gt;         }
&lt;/span&gt;&lt;span style="color:#999999;"&gt;110&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;111&lt;/span&gt; &lt;span style="color:#000000;"&gt;         &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;112&lt;/span&gt; &lt;span style="color:#008000;"&gt;         &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; To commit or not to commit?
&lt;/span&gt;&lt;span style="color:#999999;"&gt;113&lt;/span&gt; &lt;span style="color:#008000;"&gt;         &lt;/span&gt;&lt;span style="color:#008000;"&gt;//
&lt;/span&gt;&lt;span style="color:#999999;"&gt;114&lt;/span&gt; &lt;span style="color:#008000;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;         Console.WriteLine(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Press Y to commit&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;);
&lt;/span&gt;&lt;span style="color:#999999;"&gt;115&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;116&lt;/span&gt; &lt;span style="color:#000000;"&gt;         &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;char&lt;/span&gt;&lt;span style="color:#000000;"&gt; c &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; Console.ReadKey().KeyChar;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;117&lt;/span&gt; &lt;span style="color:#000000;"&gt;         &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; (c &lt;/span&gt;&lt;span style="color:#000000;"&gt;==&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800000;"&gt;'&lt;/span&gt;&lt;span style="color:#800000;"&gt;y&lt;/span&gt;&lt;span style="color:#800000;"&gt;'&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;||&lt;/span&gt;&lt;span style="color:#000000;"&gt; c &lt;/span&gt;&lt;span style="color:#000000;"&gt;==&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800000;"&gt;'&lt;/span&gt;&lt;span style="color:#800000;"&gt;Y&lt;/span&gt;&lt;span style="color:#800000;"&gt;'&lt;/span&gt;&lt;span style="color:#000000;"&gt;)
&lt;/span&gt;&lt;span style="color:#999999;"&gt;118&lt;/span&gt; &lt;span style="color:#000000;"&gt;            CommitTransaction(transaction);
&lt;/span&gt;&lt;span style="color:#999999;"&gt;119&lt;/span&gt; &lt;span style="color:#000000;"&gt;         &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;else&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;120&lt;/span&gt; &lt;span style="color:#000000;"&gt;            RollbackTransaction(transaction);
&lt;/span&gt;&lt;span style="color:#999999;"&gt;121&lt;/span&gt; &lt;span style="color:#000000;"&gt;      }
&lt;/span&gt;&lt;span style="color:#999999;"&gt;122&lt;/span&gt; &lt;span style="color:#000000;"&gt;      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;catch&lt;/span&gt;&lt;span style="color:#000000;"&gt; (Exception ex)
&lt;/span&gt;&lt;span style="color:#999999;"&gt;123&lt;/span&gt; &lt;span style="color:#000000;"&gt;      {
&lt;/span&gt;&lt;span style="color:#999999;"&gt;124&lt;/span&gt; &lt;span style="color:#000000;"&gt;         Console.WriteLine(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Oops! {0}&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, ex.Message);
&lt;/span&gt;&lt;span style="color:#999999;"&gt;125&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;126&lt;/span&gt; &lt;span style="color:#000000;"&gt;         &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;127&lt;/span&gt; &lt;span style="color:#008000;"&gt;         &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; Rollback.
&lt;/span&gt;&lt;span style="color:#999999;"&gt;128&lt;/span&gt; &lt;span style="color:#008000;"&gt;         &lt;/span&gt;&lt;span style="color:#008000;"&gt;//
&lt;/span&gt;&lt;span style="color:#999999;"&gt;129&lt;/span&gt; &lt;span style="color:#008000;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;         RollbackTransaction(transaction);
&lt;/span&gt;&lt;span style="color:#999999;"&gt;130&lt;/span&gt; &lt;span style="color:#000000;"&gt;      }
&lt;/span&gt;&lt;span style="color:#999999;"&gt;131&lt;/span&gt; &lt;span style="color:#000000;"&gt;      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;finally&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;132&lt;/span&gt; &lt;span style="color:#000000;"&gt;      {
&lt;/span&gt;&lt;span style="color:#999999;"&gt;133&lt;/span&gt; &lt;span style="color:#000000;"&gt;         &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;134&lt;/span&gt; &lt;span style="color:#008000;"&gt;         &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; Close kernel mode transaction handle.
&lt;/span&gt;&lt;span style="color:#999999;"&gt;135&lt;/span&gt; &lt;span style="color:#008000;"&gt;         &lt;/span&gt;&lt;span style="color:#008000;"&gt;//
&lt;/span&gt;&lt;span style="color:#999999;"&gt;136&lt;/span&gt; &lt;span style="color:#008000;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;         CloseHandle(tx); 
&lt;/span&gt;&lt;span style="color:#999999;"&gt;137&lt;/span&gt; &lt;span style="color:#000000;"&gt;      }
&lt;/span&gt;&lt;span style="color:#999999;"&gt;138&lt;/span&gt; &lt;span style="color:#000000;"&gt;   }
&lt;/span&gt;&lt;span style="color:#999999;"&gt;139&lt;/span&gt; &lt;span style="color:#000000;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;The sample shows how to create a file (change CREATE_NEW on line 89 if you want to open an existing file for instance) and how to hand over the SafeFileHandle to the FileStream class for further usage. &lt;font color="#ff0000"&gt;Notice that the code above has some fundamental &lt;strong&gt;security&lt;/strong&gt; problems concerning path sanitation&lt;/font&gt; of the variable "file". You might want to take a look at the SSCLI code (\clr\src\bcl\system\io\filestream.cs - FileStream::Init(...) method) for details on how to implement a much safer library that calls CreateFile(Transacted). Especially, you have to pay attention to path normalization (do you really want ".." sequences in your path?), the infamous \\.\ sequence that allows to talk to ports (e.g. COM1), the \\?\ prefix for long path names&amp;nbsp;(cf. MAX_PATH), code access security (cf. FileIOPermission demand), etc.&lt;/p&gt;
&lt;p&gt;Ignoring the warnings above (which - one day - I might resolve using a TxF aware set of classes that incorporates the required security checks), the sample will create a file called "txfdemo.txt" in the current folder, write "Hello" to it (line 104) and wait for the end-user to press Y to commit. Before you press a key (line 113), open up an instance of Windows Explorer or another command prompt and observe that (due to the isolation property of AC&lt;strong&gt;&lt;u&gt;I&lt;/u&gt;&lt;/strong&gt;D transactions) the file isn't present yet. If you press Y, the file will appear out of the blue because of the transaction commit. Any other key (other than 'y' and 'Y') will rollback the transaction, which also happens in case of an exception.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;u&gt;Exercise:&lt;/u&gt;&lt;/strong&gt; (re)read &lt;a href="http://community.bartdesmet.net/blogs/bart/archive/2006/11/19/Windows-Vista-_2D00_-Introducing-TxF-in-C_2300_-_2800_part-2_2900_-_2D00_-Using-System.Transactions-and-the-DTC.aspx"&gt;Windows Vista - Introducing TxF in C# (part 2) - Using System.Transactions and the DTC&lt;/a&gt;&amp;nbsp;and make the code above System.Transactions aware (also adding more flexibility concerning various parameters&amp;nbsp;- line 89 - see &lt;a href="http://msdn2.microsoft.com/en-us/library/aa363859.aspx"&gt;Windows SDK CreateFileTransacted documentation&lt;/a&gt; for more info, as well as the .h header file that come with the SDK for symbolic constant values).&lt;/p&gt;
&lt;p&gt;Brain.Commit();&lt;/p&gt;&lt;img src="http://community.bartdesmet.net/aggbug.aspx?PostID=12193" width="1" height="1"&gt;</description><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/.NET+Framework+v2.0/default.aspx">.NET Framework v2.0</category><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/Windows+Vista/default.aspx">Windows Vista</category><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/C_2300_+2.0/default.aspx">C# 2.0</category></item><item><title>Windows Vista Application Recovery on MSDN (woohoo)</title><link>http://community.bartdesmet.net/blogs/bart/archive/2006/12/28/Windows-Vista-Application-Recovery-on-MSDN-_2800_woohoo_2900_.aspx</link><pubDate>Thu, 28 Dec 2006 14:03:07 GMT</pubDate><guid isPermaLink="false">863c5522-913f-4a64-ac0a-bd5f05abad0f:12122</guid><dc:creator>bart</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://community.bartdesmet.net/blogs/bart/rsscomments.aspx?PostID=12122</wfw:commentRss><comments>http://community.bartdesmet.net/blogs/bart/archive/2006/12/28/Windows-Vista-Application-Recovery-on-MSDN-_2800_woohoo_2900_.aspx#comments</comments><description>&lt;p&gt;I couldn't believe my own eyes when reviewing the blog stats of yesterday: a 90% overall increase in the number of requests. Impossible at first sight, but here's the explanation: a link on &lt;a href="http://msdn2.microsoft.com/en-us/windowsvista/default.aspx"&gt;MSDN's Windows Vista homepage&lt;/a&gt;&amp;nbsp;to &lt;a href="http://community.bartdesmet.net/blogs/bart/archive/2006/11/11/Windows-Vista-Application-Recovery-with-C_2300_.aspx"&gt;my article&lt;/a&gt; on &lt;strong&gt;Application Recovery&lt;/strong&gt;&amp;nbsp;:o.&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.bartdesmet.net/images/WindowsVistaApplicationRecoveryonMSDNwoo_D39C/image01.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="225" src="http://www.bartdesmet.net/images/WindowsVistaApplicationRecoveryonMSDNwoo_D39C/image0.png" width="240" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;Update:&lt;/strong&gt; December 28, 2006 finished with a total number of 150,979 page requests. Compared to an average of 20,192 page requests per day this is too good to be true (647% increase). For the overall month score, there's already a growth of 50% compared to November. Seems like my New Year's gift will be additional bandwidth at my hosting company...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;Apparently the &lt;a href="http://linuxfr.org/~grognon/23392.html"&gt;"other side"&lt;/a&gt; was reading this page too, quoting the following phrase:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Although it's always better to fix the bugs, a smooth "crashing experience" [...] also helps to improve the end-user experience.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;What I want to stress on&amp;nbsp;is that the Application Recovery API is a &lt;strong&gt;generic OS-level API&lt;/strong&gt; that controls how Windows responds to the event of an application that crashes. In the past, error reporting and immediate process termination was the only possible outcome. Now developers have the tools at hand to control what happens: application restart and a recovery opportunity before process termination.&lt;/p&gt; &lt;p&gt;In the end, who wants to bet his or her software to be 100% bug free? Think of the number of dependencies software rely on nowadays ... lots of places where something might go wrong you didn't account for.&lt;/p&gt; &lt;p&gt;&lt;u&gt;Note:&lt;/u&gt; Others mention that lots of software packages in the past had the same functionality, allowing for document recovery etc. That's true of course, but with the Application Recovery API this kind of functionality becomes more available for all sorts of developers and all sorts of applications. The whole point is that existing software packages with recovery functionality have to employ some strategy in the code to make this possible, e.g. by working on temporary files (cf. Word) that can be recovered when the app is restarted. Or by some kind of auto-save functionality (I recall what I read in some manual 10 years or so ago: &lt;em&gt;"auto-save prevents loosing information when the computer's power supply fails or electricity outage occurs"&lt;/em&gt;). When programming with the Application Recovery API, action is taken right after the moment the software crashed, allowing you to do recovery from the inside before the process is terminated. In lots of cases, you'll just grab some internal data structure and persist it to disk. It all depends on the kind of app.&lt;/p&gt; &lt;p&gt;Last but not least, it's a &lt;strong&gt;tradeoff&lt;/strong&gt; once more. Do you want to go through the burden of writing possible complex &lt;strong&gt;recovery mechanisms&lt;/strong&gt;, allowing to "clean up" the "normal" code paths (i.e. eliminating the "aspect" of recovery allowance thoughout the code), or do you trust the software to be bug-free enough, or maybe you just don't care about crashes (but you still might to want to use the Application Recovery API &lt;strong&gt;just to restart&lt;/strong&gt; the app automatically after a possible crash, just like Windows Services can be restarted automatically by the SCM after unexpected termination).&lt;/p&gt; &lt;p&gt;&lt;em&gt;After all, it's about fighting &lt;a href="http://en.wikipedia.org/wiki/Finagle%27s_law"&gt;Finagle's law&lt;/a&gt;&lt;/em&gt; (wouldn't that be even nicer to quote me on?). And under &lt;u&gt;any&lt;/u&gt; circumstance, including the recovery itself, something &lt;u&gt;might&lt;/u&gt; go wrong.&lt;/p&gt; &lt;p&gt;Just my .314 cents.&lt;/p&gt;&lt;img src="http://community.bartdesmet.net/aggbug.aspx?PostID=12122" width="1" height="1"&gt;</description><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/Windows+Vista/default.aspx">Windows Vista</category></item><item><title>Windows Vista - Introducing TxR in C# (Part 2)</title><link>http://community.bartdesmet.net/blogs/bart/archive/2006/12/15/Windows-Vista-_2D00_-Introducing-TxR-in-C_2300_-_2800_Part-2_2900_.aspx</link><pubDate>Fri, 15 Dec 2006 16:15:35 GMT</pubDate><guid isPermaLink="false">863c5522-913f-4a64-ac0a-bd5f05abad0f:12113</guid><dc:creator>bart</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://community.bartdesmet.net/blogs/bart/rsscomments.aspx?PostID=12113</wfw:commentRss><comments>http://community.bartdesmet.net/blogs/bart/archive/2006/12/15/Windows-Vista-_2D00_-Introducing-TxR-in-C_2300_-_2800_Part-2_2900_.aspx#comments</comments><description>&lt;p&gt;&lt;/p&gt; &lt;h2&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Introduction&lt;/font&gt;&lt;/strong&gt;&lt;/h2&gt; &lt;p&gt;In the &lt;a href="http://community.bartdesmet.net/blogs/bart/archive/2006/12/14/Windows-Vista-_2D00_-Introducing-TxR-in-C_2300_-_2800_Part-1_2900_.aspx"&gt;previous post about TxR&lt;/a&gt;, we covered how to interact with the KTM (Kernel Transaction Manager) directly from managed code and how to perform transactional registry operations, illustrated by using &lt;strong&gt;RegDeleteKeyTransacted&lt;/strong&gt;. In today's post, we'll bring the DTC (Distributed Transaction Coordinator) and &lt;strong&gt;System.Transactions&lt;/strong&gt; into play, which will allow us to do things like this:&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="F2210F5F-69EB-4d4c-AFF7-B8A050E9CC72:6b5fe3f9-da4a-47ae-8250-d68edb3d987c" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="width:100%;"&gt;&lt;div&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; (TransactionScope tx &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; TransactionScope())
{
    DeleteKey(HKey.HKEY_CURRENT_USER, key1);
    DeleteKey(HKey.HKEY_CURRENT_USER, key2);
}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Needless to say, because of the role of the DTC, we can perform other transactional operations in the same scope and make all of these either complete together or not. Examples include the use of TxF in the same transaction scope, or database operations on SQL Server, or MSMQ stuff, or ... well whatever you might think of.&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;&lt;font color="#000080"&gt;The code&lt;/font&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Below, you can find a piece of sample code on how you might go ahead and create a very basic TxR library. The focus of this post will be on the System.Transactions stuff you have to take care of and the low-level plumbing to involve the DTC:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="F2210F5F-69EB-4d4c-AFF7-B8A050E9CC72:9b22d8b1-adf5-4047-ba0b-ed27d898a14f" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="width:100%;"&gt;&lt;div&gt;&lt;span style="color:#999999;"&gt;  1&lt;/span&gt; &lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;  2&lt;/span&gt; &lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Runtime.InteropServices;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;  3&lt;/span&gt; &lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.IO;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;  4&lt;/span&gt; &lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; Microsoft.Win32;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;  5&lt;/span&gt; &lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Transactions;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;  6&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;  7&lt;/span&gt; &lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;namespace&lt;/span&gt;&lt;span style="color:#000000;"&gt; TxR
&lt;/span&gt;&lt;span style="color:#999999;"&gt;  8&lt;/span&gt; &lt;span style="color:#000000;"&gt;{
&lt;/span&gt;&lt;span style="color:#999999;"&gt;  9&lt;/span&gt; &lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; Program
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 10&lt;/span&gt; &lt;span style="color:#000000;"&gt;    {
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 11&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;#region&lt;/span&gt;&lt;span style="color:#000000;"&gt; Transactional Registry operations&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 12&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 13&lt;/span&gt; &lt;span style="color:#000000;"&gt;        [DllImport(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;advapi32.dll&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, EntryPoint&lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;RegDeleteKeyTransactedW&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;)]
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 14&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;static&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;extern&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;long&lt;/span&gt;&lt;span style="color:#000000;"&gt; RegDeleteKeyTransacted(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;uint&lt;/span&gt;&lt;span style="color:#000000;"&gt; hkey, [MarshalAs(UnmanagedType.LPWStr)]&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; subkey, RegSam sam, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;uint&lt;/span&gt;&lt;span style="color:#000000;"&gt; reserved, IntPtr transaction, IntPtr reserved2);
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 15&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 16&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;enum&lt;/span&gt;&lt;span style="color:#000000;"&gt; HKey : &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;uint&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 17&lt;/span&gt; &lt;span style="color:#000000;"&gt;        {
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 18&lt;/span&gt; &lt;span style="color:#000000;"&gt;            HKEY_CURRENT_USER &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800080;"&gt;0x80000001&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 19&lt;/span&gt; &lt;span style="color:#000000;"&gt;        }
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 20&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 21&lt;/span&gt; &lt;span style="color:#000000;"&gt;        [DllImport(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Kernel32.dll&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;)]
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 22&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;static&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;extern&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;bool&lt;/span&gt;&lt;span style="color:#000000;"&gt; CloseHandle(IntPtr handle);
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 23&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 24&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;enum&lt;/span&gt;&lt;span style="color:#000000;"&gt; RegSam : &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;uint&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 25&lt;/span&gt; &lt;span style="color:#000000;"&gt;        {
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 26&lt;/span&gt; &lt;span style="color:#000000;"&gt;            KEY_WOW64_32KEY &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800080;"&gt;0x0200&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 27&lt;/span&gt; &lt;span style="color:#000000;"&gt;            KEY_WOW64_64KEY &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800080;"&gt;0x0100&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 28&lt;/span&gt; &lt;span style="color:#000000;"&gt;        }
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 29&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 30&lt;/span&gt; &lt;span style="color:#000000;"&gt;        [ComImport]
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 31&lt;/span&gt; &lt;span style="color:#000000;"&gt;        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 32&lt;/span&gt; &lt;span style="color:#000000;"&gt;        [Guid(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;79427A2B-F895-40e0-BE79-B57DC82ED231&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;)]
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 33&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;internal&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;interface&lt;/span&gt;&lt;span style="color:#000000;"&gt; IKernelTransaction
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 34&lt;/span&gt; &lt;span style="color:#000000;"&gt;        {
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 35&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; GetHandle([Out] &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;out&lt;/span&gt;&lt;span style="color:#000000;"&gt; IntPtr handle);
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 36&lt;/span&gt; &lt;span style="color:#000000;"&gt;        }
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 37&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 38&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;static&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; DeleteKey(HKey hkey, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; subkey)
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 39&lt;/span&gt; &lt;span style="color:#000000;"&gt;        {
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 40&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; (Transaction.Current &lt;/span&gt;&lt;span style="color:#000000;"&gt;!=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;null&lt;/span&gt;&lt;span style="color:#000000;"&gt;)
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 41&lt;/span&gt; &lt;span style="color:#000000;"&gt;            {
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 42&lt;/span&gt; &lt;span style="color:#000000;"&gt;                IKernelTransaction tx &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; (IKernelTransaction)TransactionInterop.GetDtcTransaction(Transaction.Current);
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 43&lt;/span&gt; &lt;span style="color:#000000;"&gt;                IntPtr txh;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 44&lt;/span&gt; &lt;span style="color:#000000;"&gt;                tx.GetHandle(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;out&lt;/span&gt;&lt;span style="color:#000000;"&gt; txh);
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 45&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 46&lt;/span&gt; &lt;span style="color:#000000;"&gt;                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; (txh &lt;/span&gt;&lt;span style="color:#000000;"&gt;==&lt;/span&gt;&lt;span style="color:#000000;"&gt; IntPtr.Zero)
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 47&lt;/span&gt; &lt;span style="color:#000000;"&gt;                    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;throw&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; Exception(); &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt;Q-n-D&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 48&lt;/span&gt; &lt;span style="color:#008000;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 49&lt;/span&gt; &lt;span style="color:#000000;"&gt;                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; (RegDeleteKeyTransacted((&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;uint&lt;/span&gt;&lt;span style="color:#000000;"&gt;)hkey, subkey, RegSam.KEY_WOW64_32KEY, &lt;/span&gt;&lt;span style="color:#800080;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;, txh, IntPtr.Zero) &lt;/span&gt;&lt;span style="color:#000000;"&gt;!=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800080;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;)
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 50&lt;/span&gt; &lt;span style="color:#000000;"&gt;                    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;throw&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; Exception(); &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt;Q-n-D&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 51&lt;/span&gt; &lt;span style="color:#008000;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 52&lt;/span&gt; &lt;span style="color:#000000;"&gt;                CloseHandle(txh);
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 53&lt;/span&gt; &lt;span style="color:#000000;"&gt;            }
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 54&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;else&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 55&lt;/span&gt; &lt;span style="color:#000000;"&gt;            {
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 56&lt;/span&gt; &lt;span style="color:#000000;"&gt;                &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 57&lt;/span&gt; &lt;span style="color:#008000;"&gt;                &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; Perform non-transacted delete using Microsoft.Win32 APIs.
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 58&lt;/span&gt; &lt;span style="color:#008000;"&gt;                &lt;/span&gt;&lt;span style="color:#008000;"&gt;//
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 59&lt;/span&gt; &lt;span style="color:#008000;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;            }
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 60&lt;/span&gt; &lt;span style="color:#000000;"&gt;        }
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 61&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 62&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;#endregion&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 63&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 64&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;static&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; Main(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt;[] args)
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 65&lt;/span&gt; &lt;span style="color:#000000;"&gt;        {
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 66&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 67&lt;/span&gt; &lt;span style="color:#008000;"&gt;            &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; Demo setup.
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 68&lt;/span&gt; &lt;span style="color:#008000;"&gt;            &lt;/span&gt;&lt;span style="color:#008000;"&gt;//
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 69&lt;/span&gt; &lt;span style="color:#008000;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; key1 &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;RegDeleteKeyTransactedDemo_01&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 70&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; key2 &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;RegDeleteKeyTransactedDemo_02&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 71&lt;/span&gt; &lt;span style="color:#000000;"&gt;            Registry.CurrentUser.CreateSubKey(key1);
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 72&lt;/span&gt; &lt;span style="color:#000000;"&gt;            Registry.CurrentUser.CreateSubKey(key2);
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 73&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 74&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 75&lt;/span&gt; &lt;span style="color:#008000;"&gt;            &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; Start the demo.
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 76&lt;/span&gt; &lt;span style="color:#008000;"&gt;            &lt;/span&gt;&lt;span style="color:#008000;"&gt;//
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 77&lt;/span&gt; &lt;span style="color:#008000;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;            Console.WriteLine(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Press &amp;lt;ENTER&amp;gt; to start the transaction.&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;);
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 78&lt;/span&gt; &lt;span style="color:#000000;"&gt;            Console.ReadLine();
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 79&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 80&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 81&lt;/span&gt; &lt;span style="color:#008000;"&gt;            &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; Make it transacted.
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 82&lt;/span&gt; &lt;span style="color:#008000;"&gt;            &lt;/span&gt;&lt;span style="color:#008000;"&gt;//
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 83&lt;/span&gt; &lt;span style="color:#008000;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; (TransactionScope tx &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; TransactionScope())
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 84&lt;/span&gt; &lt;span style="color:#000000;"&gt;            {
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 85&lt;/span&gt; &lt;span style="color:#000000;"&gt;                &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 86&lt;/span&gt; &lt;span style="color:#008000;"&gt;                &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; Delete the keys (transacted).
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 87&lt;/span&gt; &lt;span style="color:#008000;"&gt;                &lt;/span&gt;&lt;span style="color:#008000;"&gt;//
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 88&lt;/span&gt; &lt;span style="color:#008000;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;                DeleteKey(HKey.HKEY_CURRENT_USER, key1);
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 89&lt;/span&gt; &lt;span style="color:#000000;"&gt;                DeleteKey(HKey.HKEY_CURRENT_USER, key2);
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 90&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 91&lt;/span&gt; &lt;span style="color:#000000;"&gt;                &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 92&lt;/span&gt; &lt;span style="color:#008000;"&gt;                &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; Commit or rollback?
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 93&lt;/span&gt; &lt;span style="color:#008000;"&gt;                &lt;/span&gt;&lt;span style="color:#008000;"&gt;//
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 94&lt;/span&gt; &lt;span style="color:#008000;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;char&lt;/span&gt;&lt;span style="color:#000000;"&gt; c;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 95&lt;/span&gt; &lt;span style="color:#000000;"&gt;                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;do&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 96&lt;/span&gt; &lt;span style="color:#000000;"&gt;                {
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 97&lt;/span&gt; &lt;span style="color:#000000;"&gt;                    Console.WriteLine(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;{0} {1}.&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, key1, Registry.CurrentUser.OpenSubKey(key1) &lt;/span&gt;&lt;span style="color:#000000;"&gt;!=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;null&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;?&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;still exists&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt; : &lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;has vanished&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;);
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 98&lt;/span&gt; &lt;span style="color:#000000;"&gt;                    Console.WriteLine(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;{0} {1}.&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, key2, Registry.CurrentUser.OpenSubKey(key2) &lt;/span&gt;&lt;span style="color:#000000;"&gt;!=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;null&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;?&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;still exists&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt; : &lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;has vanished&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;);
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 99&lt;/span&gt; &lt;span style="color:#000000;"&gt;                    Console.Write(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Commit transaction (Y/N)? &lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;);
&lt;/span&gt;&lt;span style="color:#999999;"&gt;100&lt;/span&gt; &lt;span style="color:#000000;"&gt;                    c &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; (&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;char&lt;/span&gt;&lt;span style="color:#000000;"&gt;)Console.Read();
&lt;/span&gt;&lt;span style="color:#999999;"&gt;101&lt;/span&gt; &lt;span style="color:#000000;"&gt;                }
&lt;/span&gt;&lt;span style="color:#999999;"&gt;102&lt;/span&gt; &lt;span style="color:#000000;"&gt;                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;while&lt;/span&gt;&lt;span style="color:#000000;"&gt; (c &lt;/span&gt;&lt;span style="color:#000000;"&gt;!=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800000;"&gt;'&lt;/span&gt;&lt;span style="color:#800000;"&gt;Y&lt;/span&gt;&lt;span style="color:#800000;"&gt;'&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color:#000000;"&gt; c &lt;/span&gt;&lt;span style="color:#000000;"&gt;!=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800000;"&gt;'&lt;/span&gt;&lt;span style="color:#800000;"&gt;y&lt;/span&gt;&lt;span style="color:#800000;"&gt;'&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color:#000000;"&gt; c &lt;/span&gt;&lt;span style="color:#000000;"&gt;!=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800000;"&gt;'&lt;/span&gt;&lt;span style="color:#800000;"&gt;N&lt;/span&gt;&lt;span style="color:#800000;"&gt;'&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color:#000000;"&gt; c &lt;/span&gt;&lt;span style="color:#000000;"&gt;!=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800000;"&gt;'&lt;/span&gt;&lt;span style="color:#800000;"&gt;n&lt;/span&gt;&lt;span style="color:#800000;"&gt;'&lt;/span&gt;&lt;span style="color:#000000;"&gt;);
&lt;/span&gt;&lt;span style="color:#999999;"&gt;103&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;104&lt;/span&gt; &lt;span style="color:#000000;"&gt;                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; (c &lt;/span&gt;&lt;span style="color:#000000;"&gt;==&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800000;"&gt;'&lt;/span&gt;&lt;span style="color:#800000;"&gt;Y&lt;/span&gt;&lt;span style="color:#800000;"&gt;'&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;||&lt;/span&gt;&lt;span style="color:#000000;"&gt; c &lt;/span&gt;&lt;span style="color:#000000;"&gt;==&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800000;"&gt;'&lt;/span&gt;&lt;span style="color:#800000;"&gt;y&lt;/span&gt;&lt;span style="color:#800000;"&gt;'&lt;/span&gt;&lt;span style="color:#000000;"&gt;)
&lt;/span&gt;&lt;span style="color:#999999;"&gt;105&lt;/span&gt; &lt;span style="color:#000000;"&gt;                    tx.Complete();
&lt;/span&gt;&lt;span style="color:#999999;"&gt;106&lt;/span&gt; &lt;span style="color:#000000;"&gt;            }
&lt;/span&gt;&lt;span style="color:#999999;"&gt;107&lt;/span&gt; &lt;span style="color:#000000;"&gt;       }
&lt;/span&gt;&lt;span style="color:#999999;"&gt;108&lt;/span&gt; &lt;span style="color:#000000;"&gt;   }
&lt;/span&gt;&lt;span style="color:#999999;"&gt;109&lt;/span&gt; &lt;span style="color:#000000;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The "library" is implemented in lines 11 to 62. First of all, compared to the code in the &lt;a href="http://community.bartdesmet.net/blogs/bart/archive/2006/12/14/Windows-Vista-_2D00_-Introducing-TxR-in-C_2300_-_2800_Part-1_2900_.aspx"&gt;previous post&lt;/a&gt;, observe the omission of the KTM-related functions. Instead, we'll rely on the DTC to do the plubming behind the scenes to create the transaction. We only need to obtain a handle to the transaction to get ahead and call the RegDeleteKeyTransacted function in line 49.&lt;/p&gt;
&lt;p&gt;A few remarks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Line 14 has remained unchanged compared to the original version. It just declares our much desired demo function&lt;strong&gt; RegDeleteKeyTransacted&lt;/strong&gt;. 
&lt;li&gt;Lines 16 to 19 define a simple enum which of course needs to be extended to be really useful. Basically, I just wanted to encapsulate &lt;strong&gt;HKEY_CURRENT_USER&lt;/strong&gt; in a an enum that will be used further on as a parameter to indicate the root hive when calling our DeleteKey function. 
&lt;li&gt;Lines 30 to 36 are used to obtain a handle to the KTM transaction through DTC. This &lt;strong&gt;IKernelTransaction&lt;/strong&gt; interface is new in Windows Vista and is used to build the bridge between DTC and the KTM for transactional Windows API. It has only one method called &lt;strong&gt;GetHandle&lt;/strong&gt; described as follows in the SDK: &lt;em&gt;Returns a handle that represents the transaction and can be passed as a parameter to transacted Windows APIs&lt;/em&gt;. 
&lt;li&gt;One line 40, we investigate whether or not we're already involved in a System.Transactions transaction (by means of a TransactionScope that is): 
&lt;ul&gt;
&lt;li&gt;If not, we'll just perform the operation without using a transaction (line 56-59) using &lt;strong&gt;Microsoft.Win32 &lt;/strong&gt;(you can supply this code yourself; I didn't want to do it here because it'd need a switch over different HKey values, which still needs to be extended). 
&lt;li&gt;Otherwise, in line 42, the &lt;strong&gt;IKernelTransaction::GetHandle&lt;/strong&gt; function gets called. Luckily, the System.Transactions.&lt;strong&gt;TransactionInterop&lt;/strong&gt; class has a static method&amp;nbsp;&lt;strong&gt;GetDtcTransaction&lt;/strong&gt; defined that can obtain the low-level DTC transaction corresponding to a System.Transactions transaction. The handle is obtained in lines 43 and 44. 
&lt;ul&gt;
&lt;li&gt;If no valid handle is retrieved, we throw an exception, which on the caller side of our function will terminate the transaction in flight (when exceptions are thrown through the course of a TransactionScope, it rolls back). 
&lt;li&gt;Otherwise, the &lt;strong&gt;RegDeleteKeyTransacted&lt;/strong&gt; function is called on line 49. Again, if something goes wrong, we throw an exception (which is done in a quick-n-dirty way for demo purposes; you'll need to provide more information through a self-written exception to do it the right way).&lt;/li&gt;&lt;/ul&gt;
&lt;li&gt;On line 52, the transaction's handle is closed using &lt;strong&gt;CloseHandle&lt;/strong&gt;. Again, code needs to be polished to be ready for production and to make sure this handle is closed under all circumstances. &lt;strong&gt;SafeHandle&lt;/strong&gt;s might be your friends to do this (which I'll blog about later).&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;On the consumer side, not much has changed. Again we do create two keys for demo purposes (on lines 69 to 72). Next, in the &lt;strong&gt;System.Transactions.TransactionScope&lt;/strong&gt; transaction scope (lines 83 to 106), the keys are deleted. If one of the deletions fails, an exception is thrown by our &lt;strong&gt;DeleteKey&lt;/strong&gt; function and the transaction will roll back. Otherwise, execution reaches line 94, triggering the end-user decision logic, which ultimately calls &lt;strong&gt;Complete&lt;/strong&gt; for commit the transaction scope if the user decides to do so.&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Conclusion&lt;/font&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;All of the magic done in &lt;strong&gt;DeleteKey&lt;/strong&gt; makes the use of the KTM and transactional APIs completely invisible&amp;nbsp;for the managed code programmers that can rely on the comfortable System.Transactions namespace. Just what we needed.&lt;/p&gt;&lt;img src="http://community.bartdesmet.net/aggbug.aspx?PostID=12113" width="1" height="1"&gt;</description><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/Windows+Vista/default.aspx">Windows Vista</category><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/C_2300_+2.0/default.aspx">C# 2.0</category></item><item><title>Windows Vista - Introducing TxR in C# (Part 1)</title><link>http://community.bartdesmet.net/blogs/bart/archive/2006/12/14/Windows-Vista-_2D00_-Introducing-TxR-in-C_2300_-_2800_Part-1_2900_.aspx</link><pubDate>Thu, 14 Dec 2006 21:12:48 GMT</pubDate><guid isPermaLink="false">863c5522-913f-4a64-ac0a-bd5f05abad0f:12112</guid><dc:creator>bart</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://community.bartdesmet.net/blogs/bart/rsscomments.aspx?PostID=12112</wfw:commentRss><comments>http://community.bartdesmet.net/blogs/bart/archive/2006/12/14/Windows-Vista-_2D00_-Introducing-TxR-in-C_2300_-_2800_Part-1_2900_.aspx#comments</comments><description>&lt;h2&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Introduction&lt;/font&gt;&lt;/strong&gt;&lt;/h2&gt; &lt;p&gt;Last month I blogged about TxF in Windows Vista and how to use it from your own application to perform transactional file operations. You can find both posts over here:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href="http://community.bartdesmet.net/blogs/bart/archive/2006/11/05/Windows-Vista-_2D00_-Introducing-TxF-in-C_2300_-_2800_part-1_2900_-_2D00_-Transacted-file-delete.aspx"&gt;Windows Vista - Introducing TxF in C# (part 1) - Transacted file delete&lt;/a&gt;  &lt;li&gt;&lt;a href="http://community.bartdesmet.net/blogs/bart/archive/2006/11/05/Windows-Vista-_2D00_-Introducing-TxF-in-C_2300_-_2800_part-1_2900_-_2D00_-Transacted-file-delete.aspx"&gt;Windows Vista - Introducing TxF in C# (part 2) - Using System.Transactions and the DTC&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Today we'll take a look at TxR brother, TxR which stands for Transactional Registry, a brand new feature in Windows Vista (and Longhorn Server) that makes it possible to perform registry operations in a transactional manner. A typical usage scenario might be a setup application that's performing a bunch of file operations (using TxF) and registry operations (using TxR) which can either be committed all together or rolled back in case something went wrong (or the user cancelled the installer).&lt;/p&gt; &lt;p&gt;The next two paragraphs are borrowed from my orginal TxF posts, but adapted for TxR and to reflect the situation in Windows Vista RTM.&lt;/p&gt; &lt;h2&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Your new friends are *Transacted&lt;/font&gt;&lt;/strong&gt;&lt;/h2&gt; &lt;p&gt;Probably you know about the Reg* functions in the Windows API, like &lt;strong&gt;RegDeleteKey&lt;/strong&gt;, RegDeleteKeyEx, RegCreateKeyEx, amongst many others (take a look at the &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/registry_functions.asp"&gt;MSDN documentation&lt;/a&gt; for a full list). All these functions remain unchanged in Windows Vista, with the same semantics.  &lt;p&gt;However, if you want to perform transactional registry operations, a new set of functions is in place to help you out: Reg*Transacted, for example &lt;strong&gt;RegDeleteKeyTransacted&lt;/strong&gt; and RegOpenKeyTransacted (which makes all subsequent operations performed against that key - with classic functions to set values and stuff). All of the transactional functions rely on the Kernel Transaction Manager (KTM) which manages transactions in the operating system. As an example, consider the following RegDeleteKeyTransacted function which has a pretty simple signature:  &lt;p&gt;&lt;strong&gt;LONG&amp;nbsp;RegDeleteKeyTransacted( HKEY &lt;/strong&gt;&lt;em&gt;hKey&lt;/em&gt;&lt;strong&gt;, LPCTSTR&lt;/strong&gt; &lt;em&gt;lpSubKey&lt;/em&gt;&lt;strong&gt;, REGSAM&lt;/strong&gt; &lt;em&gt;samDesired&lt;/em&gt;&lt;strong&gt;, DWORD&lt;/strong&gt; &lt;em&gt;Reserved&lt;/em&gt;&lt;strong&gt;, HANDLE&lt;/strong&gt; &lt;em&gt;hTransaction&lt;/em&gt;&lt;strong&gt;, PVOID&lt;/strong&gt; &lt;em&gt;pExtendedParameter&lt;/em&gt; &lt;strong&gt;);&lt;/strong&gt;  &lt;p&gt;The last two parameters are the ones used to make the operation transactional: &lt;em&gt;hTransaction&lt;/em&gt; passes a handle to the KTM transaction, the &lt;em&gt;pExtendedParameter&lt;/em&gt; is currently reserved and has to be set to NULL.  &lt;h2&gt;&lt;strong&gt;&lt;font color="#000080"&gt;The KTM in a few words&lt;/font&gt;&lt;/strong&gt;&lt;/h2&gt; &lt;p&gt;On to the KTM stuff right now. As mentioned earlier, KTM stands for Kernel Transaction Manager. Don't get confused by the word kernel, it only refers to the fact the KTM's transaction engine is in the kernel. This doesn't imply the transaction can only run in kernel mode (i.e. KTM-transactions can be used in kernel &lt;u&gt;and&lt;/u&gt; user mode)&amp;nbsp;nor does it mean the transaction would be machine-local (i.e. the transaction &lt;u&gt;is&lt;/u&gt; DTC-able). On Vista and Longhorn Server, the KTM is in charge of TxF (Transactional NTFS) and TxR (Transactional Registry).  &lt;p&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;Important remark: &lt;/strong&gt;Today we walk the low-level path, interacting directly with the KTM. This is not the ideal way but just a mind-setter for follow-up posts. Later on, we'll bring System.Transactions on stage to interact with the KTM transaction.&lt;/font&gt;  &lt;p&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;Warning: &lt;/strong&gt;Do read the Windows SDK documentation carefully before working with TxR operations, especially the RegOpenKeyTransacted function information concerning the pick-up of the active transaction by other functions subsequently.&lt;/font&gt;  &lt;h2&gt;&lt;font color="#000080"&gt;&lt;strong&gt;A demo&lt;/strong&gt;&lt;/font&gt;&lt;/h2&gt; &lt;p&gt;Let's start by showing you the code right away:&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="F2210F5F-69EB-4d4c-AFF7-B8A050E9CC72:c5ee0ba5-2c3c-4fff-a156-d97d31ba230f" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="width:100%;"&gt;&lt;div&gt;&lt;span style="color:#999999;"&gt; 1&lt;/span&gt; &lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 2&lt;/span&gt; &lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Runtime.InteropServices;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 3&lt;/span&gt; &lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.IO;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 4&lt;/span&gt; &lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; Microsoft.Win32;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 5&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 6&lt;/span&gt; &lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;namespace&lt;/span&gt;&lt;span style="color:#000000;"&gt; TxR
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 7&lt;/span&gt; &lt;span style="color:#000000;"&gt;{
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 8&lt;/span&gt; &lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; Program
&lt;/span&gt;&lt;span style="color:#999999;"&gt; 9&lt;/span&gt; &lt;span style="color:#000000;"&gt;    {
&lt;/span&gt;&lt;span style="color:#999999;"&gt;10&lt;/span&gt; &lt;span style="color:#000000;"&gt;        [DllImport(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;advapi32.dll&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, EntryPoint&lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;RegDeleteKeyTransactedW&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;)]
&lt;/span&gt;&lt;span style="color:#999999;"&gt;11&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;static&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;extern&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;long&lt;/span&gt;&lt;span style="color:#000000;"&gt; RegDeleteKeyTransactedW(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;uint&lt;/span&gt;&lt;span style="color:#000000;"&gt; hkey, [MarshalAs(UnmanagedType.LPWStr)]&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; subkey, RegSam sam, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;uint&lt;/span&gt;&lt;span style="color:#000000;"&gt; reserved, IntPtr transaction, IntPtr reserved2);
&lt;/span&gt;&lt;span style="color:#999999;"&gt;12&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;13&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;static&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;uint&lt;/span&gt;&lt;span style="color:#000000;"&gt; HKEY_CURRENT_USER &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800080;"&gt;0x80000001&lt;/span&gt;&lt;span style="color:#000000;"&gt;; 
&lt;/span&gt;&lt;span style="color:#999999;"&gt;14&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;15&lt;/span&gt; &lt;span style="color:#000000;"&gt;        [DllImport(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Kernel32.dll&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;)]
&lt;/span&gt;&lt;span style="color:#999999;"&gt;16&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;static&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;extern&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;bool&lt;/span&gt;&lt;span style="color:#000000;"&gt; CloseHandle(IntPtr handle);
&lt;/span&gt;&lt;span style="color:#999999;"&gt;17&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;18&lt;/span&gt; &lt;span style="color:#000000;"&gt;        [DllImport(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Ktmw32.dll&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;)]
&lt;/span&gt;&lt;span style="color:#999999;"&gt;19&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;static&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;extern&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;bool&lt;/span&gt;&lt;span style="color:#000000;"&gt; CommitTransaction(IntPtr transaction);
&lt;/span&gt;&lt;span style="color:#999999;"&gt;20&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;21&lt;/span&gt; &lt;span style="color:#000000;"&gt;        [DllImport(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Ktmw32.dll&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;)]
&lt;/span&gt;&lt;span style="color:#999999;"&gt;22&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;static&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;extern&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;bool&lt;/span&gt;&lt;span style="color:#000000;"&gt; RollbackTransaction(IntPtr transaction);
&lt;/span&gt;&lt;span style="color:#999999;"&gt;23&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;24&lt;/span&gt; &lt;span style="color:#000000;"&gt;        [DllImport(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Ktmw32.dll&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;)]
&lt;/span&gt;&lt;span style="color:#999999;"&gt;25&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;static&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;extern&lt;/span&gt;&lt;span style="color:#000000;"&gt; IntPtr CreateTransaction(IntPtr securityAttributes, IntPtr guid, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; options, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; isolationLevel, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; isolationFlags, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; milliSeconds, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; description);
&lt;/span&gt;&lt;span style="color:#999999;"&gt;26&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;27&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;static&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; Main(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt;[] args)
&lt;/span&gt;&lt;span style="color:#999999;"&gt;28&lt;/span&gt; &lt;span style="color:#000000;"&gt;        {
&lt;/span&gt;&lt;span style="color:#999999;"&gt;29&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;30&lt;/span&gt; &lt;span style="color:#008000;"&gt;            &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; Demo setup.
&lt;/span&gt;&lt;span style="color:#999999;"&gt;31&lt;/span&gt; &lt;span style="color:#008000;"&gt;            &lt;/span&gt;&lt;span style="color:#008000;"&gt;//
&lt;/span&gt;&lt;span style="color:#999999;"&gt;32&lt;/span&gt; &lt;span style="color:#008000;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; key1 &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;RegDeleteKeyTransactedDemo_01&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;33&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; key2 &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;RegDeleteKeyTransactedDemo_02&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;34&lt;/span&gt; &lt;span style="color:#000000;"&gt;            Registry.CurrentUser.CreateSubKey(key1);
&lt;/span&gt;&lt;span style="color:#999999;"&gt;35&lt;/span&gt; &lt;span style="color:#000000;"&gt;            Registry.CurrentUser.CreateSubKey(key2);
&lt;/span&gt;&lt;span style="color:#999999;"&gt;36&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;37&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;38&lt;/span&gt; &lt;span style="color:#008000;"&gt;            &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; Start the demo.
&lt;/span&gt;&lt;span style="color:#999999;"&gt;39&lt;/span&gt; &lt;span style="color:#008000;"&gt;            &lt;/span&gt;&lt;span style="color:#008000;"&gt;//
&lt;/span&gt;&lt;span style="color:#999999;"&gt;40&lt;/span&gt; &lt;span style="color:#008000;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;            Console.WriteLine(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Press &amp;lt;ENTER&amp;gt; to start the transaction.&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;);
&lt;/span&gt;&lt;span style="color:#999999;"&gt;41&lt;/span&gt; &lt;span style="color:#000000;"&gt;            Console.ReadLine();
&lt;/span&gt;&lt;span style="color:#999999;"&gt;42&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;43&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;44&lt;/span&gt; &lt;span style="color:#008000;"&gt;            &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; Create a kernel transaction.
&lt;/span&gt;&lt;span style="color:#999999;"&gt;45&lt;/span&gt; &lt;span style="color:#008000;"&gt;            &lt;/span&gt;&lt;span style="color:#008000;"&gt;//
&lt;/span&gt;&lt;span style="color:#999999;"&gt;46&lt;/span&gt; &lt;span style="color:#008000;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;            IntPtr tx &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; CreateTransaction(IntPtr.Zero, IntPtr.Zero, &lt;/span&gt;&lt;span style="color:#800080;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#800080;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#800080;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#800080;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;null&lt;/span&gt;&lt;span style="color:#000000;"&gt;);
&lt;/span&gt;&lt;span style="color:#999999;"&gt;47&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;48&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;49&lt;/span&gt; &lt;span style="color:#008000;"&gt;            &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; Delete the keys (transacted).
&lt;/span&gt;&lt;span style="color:#999999;"&gt;50&lt;/span&gt; &lt;span style="color:#008000;"&gt;            &lt;/span&gt;&lt;span style="color:#008000;"&gt;//
&lt;/span&gt;&lt;span style="color:#999999;"&gt;51&lt;/span&gt; &lt;span style="color:#008000;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;bool&lt;/span&gt;&lt;span style="color:#000000;"&gt; rollback &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;false&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;52&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; (RegDeleteKeyTransacted(HKEY_CURRENT_USER, key1, RegSam.KEY_WOW64_32KEY, &lt;/span&gt;&lt;span style="color:#800080;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;, tx, IntPtr.Zero) &lt;/span&gt;&lt;span style="color:#000000;"&gt;!=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800080;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;)
&lt;/span&gt;&lt;span style="color:#999999;"&gt;53&lt;/span&gt; &lt;span style="color:#000000;"&gt;                rollback &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;true&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;54&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; (RegDeleteKeyTransacted(HKEY_CURRENT_USER, key2, RegSam.KEY_WOW64_32KEY, &lt;/span&gt;&lt;span style="color:#800080;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;, tx, IntPtr.Zero) &lt;/span&gt;&lt;span style="color:#000000;"&gt;!=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800080;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;)
&lt;/span&gt;&lt;span style="color:#999999;"&gt;55&lt;/span&gt; &lt;span style="color:#000000;"&gt;                rollback &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;true&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;56&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;57&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;58&lt;/span&gt; &lt;span style="color:#008000;"&gt;            &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; Commit or rollback?
&lt;/span&gt;&lt;span style="color:#999999;"&gt;59&lt;/span&gt; &lt;span style="color:#008000;"&gt;            &lt;/span&gt;&lt;span style="color:#008000;"&gt;//
&lt;/span&gt;&lt;span style="color:#999999;"&gt;60&lt;/span&gt; &lt;span style="color:#008000;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; (&lt;/span&gt;&lt;span style="color:#000000;"&gt;!&lt;/span&gt;&lt;span style="color:#000000;"&gt;rollback)
&lt;/span&gt;&lt;span style="color:#999999;"&gt;61&lt;/span&gt; &lt;span style="color:#000000;"&gt;            {
&lt;/span&gt;&lt;span style="color:#999999;"&gt;62&lt;/span&gt; &lt;span style="color:#000000;"&gt;                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;char&lt;/span&gt;&lt;span style="color:#000000;"&gt; c;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;63&lt;/span&gt; &lt;span style="color:#000000;"&gt;                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;do&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;64&lt;/span&gt; &lt;span style="color:#000000;"&gt;                {
&lt;/span&gt;&lt;span style="color:#999999;"&gt;65&lt;/span&gt; &lt;span style="color:#000000;"&gt;                    Console.WriteLine(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;{0} {1}.&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, key1, Registry.CurrentUser.OpenSubKey(key1) &lt;/span&gt;&lt;span style="color:#000000;"&gt;!=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;null&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;?&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;still exists&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt; : &lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;has vanished&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;);
&lt;/span&gt;&lt;span style="color:#999999;"&gt;66&lt;/span&gt; &lt;span style="color:#000000;"&gt;                    Console.WriteLine(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;{0} {1}.&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, key2, Registry.CurrentUser.OpenSubKey(key2) &lt;/span&gt;&lt;span style="color:#000000;"&gt;!=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;null&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;?&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;still exists&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt; : &lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;has vanished&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;);
&lt;/span&gt;&lt;span style="color:#999999;"&gt;67&lt;/span&gt; &lt;span style="color:#000000;"&gt;                    Console.Write(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Commit transaction (Y/N)? &lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;);
&lt;/span&gt;&lt;span style="color:#999999;"&gt;68&lt;/span&gt; &lt;span style="color:#000000;"&gt;                    c &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; (&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;char&lt;/span&gt;&lt;span style="color:#000000;"&gt;)Console.Read();
&lt;/span&gt;&lt;span style="color:#999999;"&gt;69&lt;/span&gt; &lt;span style="color:#000000;"&gt;                }
&lt;/span&gt;&lt;span style="color:#999999;"&gt;70&lt;/span&gt; &lt;span style="color:#000000;"&gt;                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;while&lt;/span&gt;&lt;span style="color:#000000;"&gt; (c &lt;/span&gt;&lt;span style="color:#000000;"&gt;!=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800000;"&gt;'&lt;/span&gt;&lt;span style="color:#800000;"&gt;Y&lt;/span&gt;&lt;span style="color:#800000;"&gt;'&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color:#000000;"&gt; c &lt;/span&gt;&lt;span style="color:#000000;"&gt;!=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800000;"&gt;'&lt;/span&gt;&lt;span style="color:#800000;"&gt;y&lt;/span&gt;&lt;span style="color:#800000;"&gt;'&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color:#000000;"&gt; c &lt;/span&gt;&lt;span style="color:#000000;"&gt;!=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800000;"&gt;'&lt;/span&gt;&lt;span style="color:#800000;"&gt;N&lt;/span&gt;&lt;span style="color:#800000;"&gt;'&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color:#000000;"&gt; c &lt;/span&gt;&lt;span style="color:#000000;"&gt;!=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800000;"&gt;'&lt;/span&gt;&lt;span style="color:#800000;"&gt;n&lt;/span&gt;&lt;span style="color:#800000;"&gt;'&lt;/span&gt;&lt;span style="color:#000000;"&gt;);
&lt;/span&gt;&lt;span style="color:#999999;"&gt;71&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;72&lt;/span&gt; &lt;span style="color:#000000;"&gt;                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; (c &lt;/span&gt;&lt;span style="color:#000000;"&gt;==&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800000;"&gt;'&lt;/span&gt;&lt;span style="color:#800000;"&gt;Y&lt;/span&gt;&lt;span style="color:#800000;"&gt;'&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;||&lt;/span&gt;&lt;span style="color:#000000;"&gt; c &lt;/span&gt;&lt;span style="color:#000000;"&gt;==&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800000;"&gt;'&lt;/span&gt;&lt;span style="color:#800000;"&gt;y&lt;/span&gt;&lt;span style="color:#800000;"&gt;'&lt;/span&gt;&lt;span style="color:#000000;"&gt;)
&lt;/span&gt;&lt;span style="color:#999999;"&gt;73&lt;/span&gt; &lt;span style="color:#000000;"&gt;                    CommitTransaction(tx);
&lt;/span&gt;&lt;span style="color:#999999;"&gt;74&lt;/span&gt; &lt;span style="color:#000000;"&gt;                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;else&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;75&lt;/span&gt; &lt;span style="color:#000000;"&gt;                    RollbackTransaction(tx);
&lt;/span&gt;&lt;span style="color:#999999;"&gt;76&lt;/span&gt; &lt;span style="color:#000000;"&gt;            }
&lt;/span&gt;&lt;span style="color:#999999;"&gt;77&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;else&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;78&lt;/span&gt; &lt;span style="color:#000000;"&gt;            {
&lt;/span&gt;&lt;span style="color:#999999;"&gt;79&lt;/span&gt; &lt;span style="color:#000000;"&gt;                Console.WriteLine(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Forced rollback!&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;);
&lt;/span&gt;&lt;span style="color:#999999;"&gt;80&lt;/span&gt; &lt;span style="color:#000000;"&gt;                RollbackTransaction(tx);
&lt;/span&gt;&lt;span style="color:#999999;"&gt;81&lt;/span&gt; &lt;span style="color:#000000;"&gt;            }
&lt;/span&gt;&lt;span style="color:#999999;"&gt;82&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;83&lt;/span&gt; &lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;84&lt;/span&gt; &lt;span style="color:#008000;"&gt;            &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; Close kernel mode transaction handle.
&lt;/span&gt;&lt;span style="color:#999999;"&gt;85&lt;/span&gt; &lt;span style="color:#008000;"&gt;            &lt;/span&gt;&lt;span style="color:#008000;"&gt;//
&lt;/span&gt;&lt;span style="color:#999999;"&gt;86&lt;/span&gt; &lt;span style="color:#008000;"&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;            CloseHandle(tx);
&lt;/span&gt;&lt;span style="color:#999999;"&gt;87&lt;/span&gt; &lt;span style="color:#000000;"&gt;        }
&lt;/span&gt;&lt;span style="color:#999999;"&gt;88&lt;/span&gt; &lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;89&lt;/span&gt; &lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;enum&lt;/span&gt;&lt;span style="color:#000000;"&gt; RegSam : &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;uint&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;90&lt;/span&gt; &lt;span style="color:#000000;"&gt;        {
&lt;/span&gt;&lt;span style="color:#999999;"&gt;91&lt;/span&gt; &lt;span style="color:#000000;"&gt;            KEY_WOW64_32KEY &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800080;"&gt;0x0200&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
&lt;/span&gt;&lt;span style="color:#999999;"&gt;92&lt;/span&gt; &lt;span style="color:#000000;"&gt;            KEY_WOW64_64KEY &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800080;"&gt;0x0100&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#999999;"&gt;93&lt;/span&gt; &lt;span style="color:#000000;"&gt;        }
&lt;/span&gt;&lt;span style="color:#999999;"&gt;94&lt;/span&gt; &lt;span style="color:#000000;"&gt;    }
&lt;/span&gt;&lt;span style="color:#999999;"&gt;95&lt;/span&gt; &lt;span style="color:#000000;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;So, what's going on in here? Some explanation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Lines 19, 22 and 25 contain the KTM functions to create&amp;nbsp;a transaction (&lt;strong&gt;CreateTransaction&lt;/strong&gt;), commit a transaction (&lt;strong&gt;CommitTransaction&lt;/strong&gt;) and rollback a transaction (&lt;strong&gt;RollbackTransaction&lt;/strong&gt;). More information can be found in the Windows SDK. 
&lt;li&gt;On line 11, the &lt;strong&gt;RegDeleteKeyTransacted&lt;/strong&gt; function is declared with the parameters aforementioned in this post. The handle retrieved from CreateTransaction has to be past as the 5th parameter. Notice the EntryPoint property of the DllImport attribute to choose the Unicode version of the function, as well as the LPWStr marshal type for the second parameter. (All of this is done for clarity and explicitness to see the relation between the Windows API and the interop code.) 
&lt;li&gt;To use the HKCU hive of the registry, we're declaring the symbolic constant &lt;strong&gt;HKEY_CURRENT_USER&lt;/strong&gt; on line 13. This will be the first parameter to our RegDeleteKeyTransacted call subsequently. 
&lt;li&gt;Next, lines 32 to 35 create two registry keys under HKCU for further demonstration purposes. These are using the non-transactional APIs which have been wrapped in the Microsoft.Win32 managed code namespace's RegistryKey class. 
&lt;li&gt;One line 46, the real work starts by creating a KTM transaction using a call to &lt;strong&gt;CreateTransaction&lt;/strong&gt;. We keep things simple by passing a lot of default values. For more information, take a look at the SDK. 
&lt;li&gt;Lines 52 and 54 perform the &lt;strong&gt;RegDeleteKeyTransacted&lt;/strong&gt; calls. If those return an error code (non-zero), we set the rollback boolean value to true, to indicate that not all operations succeeded and the transaction has to be rolled back (if that's the behavior you want if any of the operations fails, you might want to do more error code analysis to make this decision too of course). 
&lt;ul&gt;
&lt;li&gt;If the transaction has to be rolled back, line 80 does that work by calling &lt;strong&gt;RollbackTransaction&lt;/strong&gt;. 
&lt;li&gt;Otherwise, we leave the decision to the user to either commit (&lt;strong&gt;CommitTransaction&lt;/strong&gt;) or rollback.&lt;/li&gt;&lt;/ul&gt;
&lt;li&gt;Finally, let's clean up things an close the handle used for the KTM transaction on line 86 by calling &lt;strong&gt;CloseHandle&lt;/strong&gt;.&lt;/li&gt;&lt;/ul&gt;
&lt;h2&gt;&lt;font color="#000080"&gt;&lt;strong&gt;In action&lt;/strong&gt;&lt;/font&gt;&lt;/h2&gt;
&lt;p&gt;Let's show a few pictures on a "breakpoint" basis. If the code reaches the specified line, the displayed screenshot (click to enlarge) will reflect the actual situation in the registry:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Line 28 - the demo keys haven't been created yet:&lt;br&gt;&lt;br&gt;&lt;a href="http://www.bartdesmet.net/images/WindowsVistaIntroducingTxRinCPart1_F2B0/txr011.jpg"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="152" src="http://www.bartdesmet.net/images/WindowsVistaIntroducingTxRinCPart1_F2B0/txr01.jpg" width="240" border="0"&gt;&lt;/a&gt; &lt;br&gt;
&lt;li&gt;Line 40 - the demo keys are there:&lt;br&gt;&lt;br&gt;&lt;a href="http://www.bartdesmet.net/images/WindowsVistaIntroducingTxRinCPart1_F2B0/txr021.jpg"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="152" src="http://www.bartdesmet.net/images/WindowsVistaIntroducingTxRinCPart1_F2B0/txr02.jpg" width="240" border="0"&gt;&lt;/a&gt; &lt;br&gt;
&lt;li&gt;Line 67 - the transactional delete operations have been executed but because of the AC&lt;strong&gt;I&lt;/strong&gt;D &lt;strong&gt;Isolation&lt;/strong&gt; property, nothing is visible yet for the outside world:&lt;br&gt;&lt;br&gt;&lt;a href="http://www.bartdesmet.net/images/WindowsVistaIntroducingTxRinCPart1_F2B0/txr031.jpg"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="120" src="http://www.bartdesmet.net/images/WindowsVistaIntroducingTxRinCPart1_F2B0/txr03.jpg" width="240" border="0"&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href="http://www.bartdesmet.net/images/WindowsVistaIntroducingTxRinCPart1_F2B0/txr023.jpg"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="152" src="http://www.bartdesmet.net/images/WindowsVistaIntroducingTxRinCPart1_F2B0/txr022.jpg" width="240" border="0"&gt;&lt;/a&gt; &lt;br&gt;
&lt;li&gt;Line 73 - the user decided to commit the transaction, now the keys are gone:&lt;br&gt;&lt;br&gt;&lt;a href="http://www.bartdesmet.net/images/WindowsVistaIntroducingTxRinCPart1_F2B0/txr013.jpg"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="152" src="http://www.bartdesmet.net/images/WindowsVistaIntroducingTxRinCPart1_F2B0/txr012.jpg" width="240" border="0"&gt;&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;
&lt;h2&gt;&lt;font color="#000080"&gt;&lt;strong&gt;What's next?&lt;/strong&gt;&lt;/font&gt;&lt;/h2&gt;
&lt;p&gt;In &lt;a href="http://community.bartdesmet.net/blogs/bart/archive/2006/12/15/Windows-Vista-_2D00_-Introducing-TxR-in-C_2300_-_2800_Part-2_2900_.aspx"&gt;part 2&lt;/a&gt;&amp;nbsp;we'll take a look at how we can use the &lt;strong&gt;DTC&lt;/strong&gt; and the &lt;strong&gt;System.Transactions&lt;/strong&gt; namespace to enroll the KTM transaction in a distributed transaction and how to encapsulate the low level plumbing in a little library. Again, we'll focus on the RegDeleteKeyTransacted stuff because of its simplicity. In a later post, we might take a look at other registry operations too, which - however - need a bit more work regarding various parameters and would take the focus off the transactional stuff we're covering. The ultimate solution would be a change to &lt;strong&gt;Microsoft.Win32&lt;/strong&gt; to incorporate transactional support in Windows Vista and higher.&lt;/p&gt;&lt;img src="http://community.bartdesmet.net/aggbug.aspx?PostID=12112" width="1" height="1"&gt;</description><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/Windows+Vista/default.aspx">Windows Vista</category><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/C_2300_+2.0/default.aspx">C# 2.0</category></item><item><title>Windows Vista - Exploring the Windows System Assessment Tool (WinSAT) API in C# (some reactions)</title><link>http://community.bartdesmet.net/blogs/bart/archive/2006/12/13/Windows-Vista-_2D00_-Exploring-the-Windows-System-Assessment-Tool-_2800_WinSAT_2900_-API-in-C_2300_-_2800_some-reactions_2900_.aspx</link><pubDate>Wed, 13 Dec 2006 22:59:41 GMT</pubDate><guid isPermaLink="false">863c5522-913f-4a64-ac0a-bd5f05abad0f:12107</guid><dc:creator>bart</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://community.bartdesmet.net/blogs/bart/rsscomments.aspx?PostID=12107</wfw:commentRss><comments>http://community.bartdesmet.net/blogs/bart/archive/2006/12/13/Windows-Vista-_2D00_-Exploring-the-Windows-System-Assessment-Tool-_2800_WinSAT_2900_-API-in-C_2300_-_2800_some-reactions_2900_.aspx#comments</comments><description>&lt;p&gt;Yesterday I published a &lt;a href="http://community.bartdesmet.net/blogs/bart/archive/2006/12/12/Windows-Vista-_2D00_-Exploring-the-Windows-System-Assessment-Tool-_2800_WinSAT_2900_-API-in-C_2300_.aspx"&gt;&lt;strong&gt;blog post about the WinSAT API in Windows Vista&lt;/strong&gt;&lt;/a&gt;. It's always great to see others referring to posts and providing comments and suggestions, as this was the case with &lt;a href="http://addressof.com/blog/archive/2006/12/13/Exploring-WinSAT-Announcement.aspx"&gt;AddressOf.com&lt;/a&gt;. However, a few reactions on the reactions:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;&lt;strong&gt;&lt;font color="#008000"&gt;I really distaste the idea of "unsafe" code unless there is absolutely no way around using it... and even then I'd probably choose to implement a solution using C/C++ if that was the case.&lt;/font&gt;&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;What &lt;strong&gt;unsafe code &lt;/strong&gt;is concerned, if you know what you're doing there's no real problem but I agree it's better to avoid it whenever you can. I didn't want to go through the whole burden of explaining GCHandle, pinning, etc and for sake of the demo I just took advantage of some simple pointer stuff. So, I certainly wouldn't exchange one line of unsafe code for a complete makeover in C/C++ unmanaged code. In that case I wouldn't have written the article at all since the Windows SDK has all the info C/C++ devs need. Nevertheless, thanks for pointing to the alternative using &lt;strong&gt;GCHandle.Alloc&lt;/strong&gt;. I won't ever pronounce the word unsafe code anymore :p.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;&lt;strong&gt;&lt;font color="#008000"&gt;I also didn't like the fact that he was using GetEnumerator instead of using the much more friendly foreach functionality and because he was using GetEnumerator, he was having to do some unnecessary casting in the process.&lt;/font&gt;&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Then tell me how to &lt;strong&gt;foreach&lt;/strong&gt; over an enumeration without casting. Okay, I could just have duplicated the code five times, like this, which would be more explicit:&lt;/p&gt; &lt;p&gt; &lt;div class="wlWriterSmartContent" id="F2210F5F-69EB-4d4c-AFF7-B8A050E9CC72:a9598016-e87f-44eb-9459-51351304dd8d" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="width:100%;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;IProvideWinSATAssessmentInfo i;
i &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; q.Info.GetAssessmentInfo(WINSAT_ASSESSMENT_TYPE.WINSAT_ASSESSMENT_CPU);
Console.WriteLine(format, i.Title, i.Description, i.Score);
i &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; q.Info.GetAssessmentInfo(WINSAT_ASSESSMENT_TYPE.WINSAT_ASSESSMENT_D3D);
Console.WriteLine(format, i.Title, i.Description, i.Score);
i &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; q.Info.GetAssessmentInfo(WINSAT_ASSESSMENT_TYPE.WINSAT_ASSESSMENT_DISK);
Console.WriteLine(format, i.Title, i.Description, i.Score);
i &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; q.Info.GetAssessmentInfo(WINSAT_ASSESSMENT_TYPE.WINSAT_ASSESSMENT_GRAPHICS);
Console.WriteLine(format, i.Title, i.Description, i.Score);
i &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; q.Info.GetAssessmentInfo(WINSAT_ASSESSMENT_TYPE.WINSAT_ASSESSMENT_MEMORY);
Console.WriteLine(format, i.Title, i.Description, i.Score);&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;In the end we're talking about 5 casts; no big deal for a demo app. Difference in perf? Maybe 5 to 10 ms I guess; the relatively slow API calls overshadow the whole thing. Or maybe the source of the confusion is the &lt;strong&gt;classic misconception&lt;/strong&gt; that the method A1 in the following piece of code would be more efficient than method A2:&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="F2210F5F-69EB-4d4c-AFF7-B8A050E9CC72:501f7679-e495-4dbf-b2f6-37fcfd310ff8" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="width:100%;"&gt;&lt;div&gt;&lt;span style="color:#0000FF;"&gt;private&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;static&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; A1(CQueryWinSATClass q, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; format)
{
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;foreach&lt;/span&gt;&lt;span style="color:#000000;"&gt; (WINSAT_ASSESSMENT_TYPE wat &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;in&lt;/span&gt;&lt;span style="color:#000000;"&gt; Enum.GetValues(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;typeof&lt;/span&gt;&lt;span style="color:#000000;"&gt;(WINSAT_ASSESSMENT_TYPE)))
    {
        IProvideWinSATAssessmentInfo i &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; q.Info.GetAssessmentInfo(wat);
        Console.WriteLine(format, i.Title, i.Description, i.Score);
    }
}

&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;private&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;static&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; A2(CQueryWinSATClass q, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; format)
{
    IEnumerator e &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; Enum.GetValues(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;typeof&lt;/span&gt;&lt;span style="color:#000000;"&gt;(WINSAT_ASSESSMENT_TYPE)).GetEnumerator();
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;while&lt;/span&gt;&lt;span style="color:#000000;"&gt; (e.MoveNext())
    {
        IProvideWinSATAssessmentInfo i &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; q.Info.GetAssessmentInfo((WINSAT_ASSESSMENT_TYPE)e.Current);
        Console.WriteLine(format, i.Title, i.Description, i.Score);
    }
}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The point is that GetValues returns an Array, which contains elements of type System.Object, which in case of enums introduces boxing to occur. What happens in A1 is that the foreach loop is translated in similar logic as in A2, which is iterating over the (non-generic) IEnumerator returned by calling System.Array::GetEnumerator. Inside the loop, the IEnumerator's Current property will be retrieved and unboxed to the enum type. Because my blog readers like IL, I've included this analysis below. For A1 take a look at lines IL_001a and IL_001f, for A2 look at IL_0020 and IL_0025.&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="F2210F5F-69EB-4d4c-AFF7-B8A050E9CC72:279a4419-2109-4307-8275-6c12864d1370" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="width:100%;"&gt;&lt;div&gt;&lt;span style="color:#0000FF;"&gt;.method&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;private&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;hidebysig&lt;/span&gt;&lt;span style="color:#000000;"&gt; static &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt;  A1(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; [Interop.WINSATLib]WINSATLib.CQueryWinSATClass q,
                                          &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; format) &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;cil&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;managed&lt;/span&gt;&lt;span style="color:#000000;"&gt;
{
  &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; Code size       122 (0x7a)&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;.maxstack&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#800080;"&gt;4&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;.locals&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;init&lt;/span&gt;&lt;span style="color:#000000;"&gt; ([&lt;/span&gt;&lt;span style="color:#800080;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;] valuetype [Interop.WINSATLib]WINSATLib.WINSAT_ASSESSMENT_TYPE wat,
           [&lt;/span&gt;&lt;span style="color:#800080;"&gt;1&lt;/span&gt;&lt;span style="color:#000000;"&gt;] &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; [Interop.WINSATLib]WINSATLib.IProvideWinSATAssessmentInfo i,
           [&lt;/span&gt;&lt;span style="color:#800080;"&gt;2&lt;/span&gt;&lt;span style="color:#000000;"&gt;] &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; [mscorlib]System.Collections.IEnumerator CS$&lt;/span&gt;&lt;span style="color:#800080;"&gt;5&lt;/span&gt;&lt;span style="color:#000000;"&gt;$&lt;/span&gt;&lt;span style="color:#800080;"&gt;0000&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
           [&lt;/span&gt;&lt;span style="color:#800080;"&gt;3&lt;/span&gt;&lt;span style="color:#000000;"&gt;] &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;bool&lt;/span&gt;&lt;span style="color:#000000;"&gt; CS$&lt;/span&gt;&lt;span style="color:#800080;"&gt;4&lt;/span&gt;&lt;span style="color:#000000;"&gt;$&lt;/span&gt;&lt;span style="color:#800080;"&gt;0001&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
           [&lt;/span&gt;&lt;span style="color:#800080;"&gt;4&lt;/span&gt;&lt;span style="color:#000000;"&gt;] &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; [mscorlib]System.IDisposable CS$&lt;/span&gt;&lt;span style="color:#800080;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;$&lt;/span&gt;&lt;span style="color:#800080;"&gt;0002&lt;/span&gt;&lt;span style="color:#000000;"&gt;)
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0000:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;nop&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0001:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;nop&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0002:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;ldtoken&lt;/span&gt;&lt;span style="color:#000000;"&gt;    [Interop.WINSATLib]WINSATLib.WINSAT_ASSESSMENT_TYPE
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0007:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;call&lt;/span&gt;&lt;span style="color:#000000;"&gt;       &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_000c:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;call&lt;/span&gt;&lt;span style="color:#000000;"&gt;       &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; [mscorlib]System.Array [mscorlib]System.Enum::GetValues(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; [mscorlib]System.Type)
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0011:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;callvirt&lt;/span&gt;&lt;span style="color:#000000;"&gt;   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;instance&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; [mscorlib]System.Collections.IEnumerator [mscorlib]System.Array::GetEnumerator()
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0016:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;stloc.2&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  .try
  {
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0017:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;br.s&lt;/span&gt;&lt;span style="color:#000000;"&gt;       IL_0052
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0019:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;ldloc.2&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_001a:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;callvirt&lt;/span&gt;&lt;span style="color:#000000;"&gt;   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;instance&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt; [mscorlib]System.Collections.IEnumerator::get_Current()
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_001f:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;unbox&lt;/span&gt;&lt;span style="color:#000000;"&gt;.any  [Interop.WINSATLib]WINSATLib.WINSAT_ASSESSMENT_TYPE
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0024:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;stloc.0&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0025:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;nop&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0026:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;ldarg.0&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0027:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;callvirt&lt;/span&gt;&lt;span style="color:#000000;"&gt;   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;instance&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; [Interop.WINSATLib]WINSATLib.IProvideWinSATResultsInfo [Interop.WINSATLib]WINSATLib.CQueryWinSATClass::get_Info()
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_002c:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;ldloc.0&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_002d:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;callvirt&lt;/span&gt;&lt;span style="color:#000000;"&gt;   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;instance&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; [Interop.WINSATLib]WINSATLib.IProvideWinSATAssessmentInfo [Interop.WINSATLib]WINSATLib.IProvideWinSATResultsInfo::GetAssessmentInfo(valuetype [Interop.WINSATLib]WINSATLib.WINSAT_ASSESSMENT_TYPE)
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0032:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;stloc.1&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0033:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;ldarg.1&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0034:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;ldloc.1&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0035:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;callvirt&lt;/span&gt;&lt;span style="color:#000000;"&gt;   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;instance&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; [Interop.WINSATLib]WINSATLib.IProvideWinSATAssessmentInfo::get_Title()
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_003a:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;ldloc.1&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_003b:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;callvirt&lt;/span&gt;&lt;span style="color:#000000;"&gt;   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;instance&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; [Interop.WINSATLib]WINSATLib.IProvideWinSATAssessmentInfo::get_Description()
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0040:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;ldloc.1&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0041:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;callvirt&lt;/span&gt;&lt;span style="color:#000000;"&gt;   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;instance&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;float32&lt;/span&gt;&lt;span style="color:#000000;"&gt; [Interop.WINSATLib]WINSATLib.IProvideWinSATAssessmentInfo::get_Score()
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0046:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;box&lt;/span&gt;&lt;span style="color:#000000;"&gt;        [mscorlib]System.Single
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_004b:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;call&lt;/span&gt;&lt;span style="color:#000000;"&gt;       &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; [mscorlib]System.Console::WriteLine(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
                                                                  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
                                                                  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
                                                                  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt;)
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0050:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;nop&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0051:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;nop&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0052:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;ldloc.2&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0053:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;callvirt&lt;/span&gt;&lt;span style="color:#000000;"&gt;   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;instance&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;bool&lt;/span&gt;&lt;span style="color:#000000;"&gt; [mscorlib]System.Collections.IEnumerator::MoveNext()
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0058:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;stloc.3&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0059:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;ldloc.3&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_005a:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;brtrue.s&lt;/span&gt;&lt;span style="color:#000000;"&gt;   IL_0019
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_005c:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;leave&lt;/span&gt;&lt;span style="color:#000000;"&gt;.s    IL_0078
  }  &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; end .try&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#000000;"&gt;  finally
  {
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_005e:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;ldloc.2&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_005f:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;isinst&lt;/span&gt;&lt;span style="color:#000000;"&gt;     [mscorlib]System.IDisposable
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0064:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;stloc.s&lt;/span&gt;&lt;span style="color:#000000;"&gt;    CS$&lt;/span&gt;&lt;span style="color:#800080;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;$&lt;/span&gt;&lt;span style="color:#800080;"&gt;0002&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0066:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;ldloc.s&lt;/span&gt;&lt;span style="color:#000000;"&gt;    CS$&lt;/span&gt;&lt;span style="color:#800080;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;$&lt;/span&gt;&lt;span style="color:#800080;"&gt;0002&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0068:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;ldnull&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0069:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  ceq
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_006b:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;stloc.3&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_006c:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;ldloc.3&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_006d:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;brtrue.s&lt;/span&gt;&lt;span style="color:#000000;"&gt;   IL_0077
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_006f:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;ldloc.s&lt;/span&gt;&lt;span style="color:#000000;"&gt;    CS$&lt;/span&gt;&lt;span style="color:#800080;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;$&lt;/span&gt;&lt;span style="color:#800080;"&gt;0002&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0071:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;callvirt&lt;/span&gt;&lt;span style="color:#000000;"&gt;   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;instance&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; [mscorlib]System.IDisposable::Dispose()
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0076:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;nop&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0077:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;endfinally&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  }  &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; end handler&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0078:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;nop&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0079:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;ret&lt;/span&gt;&lt;span style="color:#000000;"&gt;
} &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; end of method Program::A1&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="wlWriterSmartContent" id="F2210F5F-69EB-4d4c-AFF7-B8A050E9CC72:efe0e198-b0c0-4565-bcee-c5d4a72c5395" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="width:100%;"&gt;&lt;div&gt;&lt;span style="color:#0000FF;"&gt;.method&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;private&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;hidebysig&lt;/span&gt;&lt;span style="color:#000000;"&gt; static &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt;  A2(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; [Interop.WINSATLib]WINSATLib.CQueryWinSATClass q,
                                          &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; format) &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;cil&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;managed&lt;/span&gt;&lt;span style="color:#000000;"&gt;
{
  &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; Code size       90 (0x5a)&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;.maxstack&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#800080;"&gt;4&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;.locals&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;init&lt;/span&gt;&lt;span style="color:#000000;"&gt; ([&lt;/span&gt;&lt;span style="color:#800080;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;] &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; [mscorlib]System.Collections.IEnumerator e,
           [&lt;/span&gt;&lt;span style="color:#800080;"&gt;1&lt;/span&gt;&lt;span style="color:#000000;"&gt;] &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; [Interop.WINSATLib]WINSATLib.IProvideWinSATAssessmentInfo i,
           [&lt;/span&gt;&lt;span style="color:#800080;"&gt;2&lt;/span&gt;&lt;span style="color:#000000;"&gt;] &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;bool&lt;/span&gt;&lt;span style="color:#000000;"&gt; CS$&lt;/span&gt;&lt;span style="color:#800080;"&gt;4&lt;/span&gt;&lt;span style="color:#000000;"&gt;$&lt;/span&gt;&lt;span style="color:#800080;"&gt;0000&lt;/span&gt;&lt;span style="color:#000000;"&gt;)
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0000:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;nop&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0001:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;ldtoken&lt;/span&gt;&lt;span style="color:#000000;"&gt;    [Interop.WINSATLib]WINSATLib.WINSAT_ASSESSMENT_TYPE
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0006:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;call&lt;/span&gt;&lt;span style="color:#000000;"&gt;       &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_000b:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;call&lt;/span&gt;&lt;span style="color:#000000;"&gt;       &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; [mscorlib]System.Array [mscorlib]System.Enum::GetValues(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; [mscorlib]System.Type)
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0010:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;callvirt&lt;/span&gt;&lt;span style="color:#000000;"&gt;   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;instance&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; [mscorlib]System.Collections.IEnumerator [mscorlib]System.Array::GetEnumerator()
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0015:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;stloc.0&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0016:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;br.s&lt;/span&gt;&lt;span style="color:#000000;"&gt;       IL_004f
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0018:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;nop&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0019:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;ldarg.0&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_001a:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;callvirt&lt;/span&gt;&lt;span style="color:#000000;"&gt;   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;instance&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; [Interop.WINSATLib]WINSATLib.IProvideWinSATResultsInfo [Interop.WINSATLib]WINSATLib.CQueryWinSATClass::get_Info()
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_001f:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;ldloc.0&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0020:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;callvirt&lt;/span&gt;&lt;span style="color:#000000;"&gt;   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;instance&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt; [mscorlib]System.Collections.IEnumerator::get_Current()
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0025:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;unbox&lt;/span&gt;&lt;span style="color:#000000;"&gt;.any  [Interop.WINSATLib]WINSATLib.WINSAT_ASSESSMENT_TYPE
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_002a:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;callvirt&lt;/span&gt;&lt;span style="color:#000000;"&gt;   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;instance&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; [Interop.WINSATLib]WINSATLib.IProvideWinSATAssessmentInfo [Interop.WINSATLib]WINSATLib.IProvideWinSATResultsInfo::GetAssessmentInfo(valuetype [Interop.WINSATLib]WINSATLib.WINSAT_ASSESSMENT_TYPE)
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_002f:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;stloc.1&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0030:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;ldarg.1&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0031:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;ldloc.1&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0032:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;callvirt&lt;/span&gt;&lt;span style="color:#000000;"&gt;   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;instance&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; [Interop.WINSATLib]WINSATLib.IProvideWinSATAssessmentInfo::get_Title()
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0037:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;ldloc.1&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0038:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;callvirt&lt;/span&gt;&lt;span style="color:#000000;"&gt;   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;instance&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; [Interop.WINSATLib]WINSATLib.IProvideWinSATAssessmentInfo::get_Description()
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_003d:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;ldloc.1&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_003e:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;callvirt&lt;/span&gt;&lt;span style="color:#000000;"&gt;   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;instance&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;float32&lt;/span&gt;&lt;span style="color:#000000;"&gt; [Interop.WINSATLib]WINSATLib.IProvideWinSATAssessmentInfo::get_Score()
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0043:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;box&lt;/span&gt;&lt;span style="color:#000000;"&gt;        [mscorlib]System.Single
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0048:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;call&lt;/span&gt;&lt;span style="color:#000000;"&gt;       &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; [mscorlib]System.Console::WriteLine(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
                                                                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
                                                                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
                                                                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt;)
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_004d:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;nop&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_004e:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;nop&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_004f:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;ldloc.0&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0050:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;callvirt&lt;/span&gt;&lt;span style="color:#000000;"&gt;   &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;instance&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;bool&lt;/span&gt;&lt;span style="color:#000000;"&gt; [mscorlib]System.Collections.IEnumerator::MoveNext()
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0055:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;stloc.2&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0056:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;ldloc.2&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0057:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;brtrue.s&lt;/span&gt;&lt;span style="color:#000000;"&gt;   IL_0018
  &lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;IL_0059:&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;ret&lt;/span&gt;&lt;span style="color:#000000;"&gt;
} &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; end of method Program::A2&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As the matter in fact, the explicit enumeration logic using a while-loop might look less elegant, but it makes the casting explicit which is otherwise introduced by compiler magic. By the way, don't worry about the try-finally block in A1 which doesn't provide us with more value, since System.Array isn't IDisposable. (Btw, if you really want to optimize somewhat, take q.Info out of the loop.)
&lt;blockquote&gt;
&lt;p&gt;&lt;font color="#008000"&gt;&lt;em&gt;&lt;strong&gt;Finally, implementing this as a console application just seemed wrong somehow; especially since he was still showing a windows form from the console app to demonstrate the ability to garner the Windows Vista generated image representing the base score.&lt;/strong&gt;&lt;/em&gt;&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;I always intend to make things &lt;strong&gt;as simple as possible&lt;/strong&gt; (cf. Einstein's famous quote mentioned in &lt;a href="http://community.bartdesmet.net/blogs/bart/archive/2006/12/10/C_2300_-3.0-Extension-Method-Versioning-Troubles-_2D00_-Some-thoughts-and-random-ideas.aspx"&gt;this post&lt;/a&gt;), in this case the console app just does the trick; everyone knows you can put the whole stuff in a WinForms app too in a completely similar manner. The score display was the only aspect that required WinForms and the orginal implementation just invoked the Save method on the bitmap to store it as a .bmp file, like this:&lt;/p&gt;
&lt;p&gt;
&lt;div class="wlWriterSmartContent" id="F2210F5F-69EB-4d4c-AFF7-B8A050E9CC72:0b359aa0-dadb-42e1-a0ba-6325e6634a99" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="width:100%;"&gt;&lt;div&gt;&lt;span style="color:#0000FF;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; (t &lt;/span&gt;&lt;span style="color:#000000;"&gt;!=&lt;/span&gt;&lt;span style="color:#000000;"&gt; IntPtr.Zero)
   Bitmap.FromHbitmap(t).Save(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;WinSATDemo.bmp&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;It would have been even shorter, I agree.&amp;nbsp;Ultimately, I decided to use WinForms instead to display the picture. For me, &lt;strong&gt;the focus is on retrieving the numbers, not cloning what's already available in Windows to display the scores&lt;/strong&gt;. Lots of WinForms code hide the real intention of the app in quite some cases. Anyway, just my .314 cents.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(PS: Sorry I had to delay the real technical post of today, but I felt I had to put a reaction online.)&lt;/em&gt;&lt;/p&gt;&lt;img src="http://community.bartdesmet.net/aggbug.aspx?PostID=12107" width="1" height="1"&gt;</description><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/Windows+Vista/default.aspx">Windows Vista</category></item></channel></rss>