<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>dougzuck.com &#187; Technology</title>
	<atom:link href="http://dougzuck.com/category/technology/feed" rel="self" type="application/rss+xml" />
	<link>http://dougzuck.com</link>
	<description>A place to put some stuff...</description>
	<lastBuildDate>Sun, 25 Jul 2010 19:48:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=abc</generator>
		<item>
		<title>My frustrating experience trying to purchase a new iPhone 4</title>
		<link>http://dougzuck.com/my-frustrating-experience-trying-to-purchase-a-new-iphone-4</link>
		<comments>http://dougzuck.com/my-frustrating-experience-trying-to-purchase-a-new-iphone-4#comments</comments>
		<pubDate>Sun, 25 Jul 2010 19:48:42 +0000</pubDate>
		<dc:creator>doug</dc:creator>
				<category><![CDATA[Current Events]]></category>
		<category><![CDATA[Pop]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://dougzuck.com/?p=806</guid>
		<description><![CDATA[I need to vent&#8230;  First off, let me say that I&#8217;m an Apple hater.  I&#8217;m an Apple hater, but I&#8217;m also an iPhone lover.  I know it sounds stupid.  Honestly, I&#8217;ve tried to like Apple many times over the years, and this even includes purchasing a Mac Mini at one point a couple years ago, [...]]]></description>
			<content:encoded><![CDATA[<p>I need to vent&#8230;  First off, let me say that I&#8217;m an Apple hater.  I&#8217;m an Apple hater, but I&#8217;m also an iPhone lover.  I know it sounds stupid.  Honestly, I&#8217;ve tried to like Apple many times over the years, and this even includes purchasing a Mac Mini at one point a couple years ago, but I ended up selling it soon after because I was so frustrated with it.  What can I say&#8211;  I&#8217;m a PC guy at heart.  Moreover, walking into the Apple store makes my skin crawl.  I hate the vibe.  I hate the people who work there and their Apple-loving attitudes.  It just drives me crazy.  But here I am trying to buy a new iPhone because I think it&#8217;s the coolest piece of technology out right now, so this also seemed like a good time for me to give Apple another chance at not frustrating me or pissing me off.  Well, it didn&#8217;t work.</p>
<p>The company I work for has generously offered to reimburse me for the cost of a new iPhone 4.  I currently own the iPhone 3GS, which my company also paid for.  When the iPhone 4 first came out, I wanted to buy it from the Apple website because that seemed like the easiest and fastest way to get it.  However, while I was attempting to purchase it online, I learned that Apple requires you to ship it to the address where your AT&amp;T account is registered, and that it will require a signature at the time of delivery.  Seems reasonable enough, but unfortunately I live in an apartment, and I don&#8217;t have anyone to sign for my packages, so I can&#8217;t have it shipped to me unless I want to deal with picking it up at the carrier&#8217;s facility after a failed delivery attempt.  However, that&#8217;s a pain because like most of the rest of the people in this country, I have a job that makes it difficult for me to get to a carrier&#8217;s facility during their business hours.  It&#8217;s not that I absolutely can&#8217;t do it, it&#8217;s that I&#8217;d prefer not to if I don&#8217;t have to.  It would be really nice if I could just have the phone shipped to my office, but of course that&#8217;s not allowed as I mentioned a moment ago.</p>
<p>The truth is that I&#8217;m not in a huge rush to get the new phone.  Sure I&#8217;d like to get it sooner rather than later, but I&#8217;m certainly not losing any sleep over it.  At this time you still can&#8217;t just walk into an Apple store to buy the phone.  You have to get put on a waiting list, and then they email you when it&#8217;s your time to come to the store, at which point you have 24 hours to buy the phone before they remove you from the list.  Seems simple enough, so I got put on the list.  Today I received my notification that I can go to the store and buy the phone, but when I got to the store they told me that I have to work with one of their specialists to activate the new phone before I leave the store.  This sounds like a pretty normal situation, but the thing is I actually don&#8217;t want to activate the phone right away.  I&#8217;m hoping to get a case for the phone that I like before I actually start using the phone on a daily basis, but there aren&#8217;t that many cases out there for the new iPhone yet, and admittedly I&#8217;m pretty particular about cases, so I&#8217;d like to take my time and find one that works best for me.  Additionally, they don&#8217;t sell any iPhone 4 cases in my local Apple store, so it&#8217;s not like I can even buy a temporary one while I&#8217;m there buying the phone.</p>
<p>I don&#8217;t understand why Apple is willing and able to ship a phone to you and let you activate yourself through iTunes at your leisure, but if you go to the store they require that you activate it on the spot, thereby deactivating your old iPhone (Note that this just applies to upgrading your phone at the subsidized price.  It does not apply to new phone purchases where you pay the full cost of the phone).  I would have allowed them to activate my phone on the spot if I could have at least purchased a temporary case for it until I find a more permanent case, but they don&#8217;t sell iPhone 4 cases for completely unknown reasons (yes, the do sell iPhone 3GS cases).  So, I left the store, and I still do not own a new iPhone.</p>
<p>I friggin hate Apple.  I hate going in that store.  I hate those stupid blue shirts their employees wear.  But I love the iPhone.  And for this, apparently I&#8217;m willing to overlook my disgust and distaste for everything else about Apple.</p>
]]></content:encoded>
			<wfw:commentRss>http://dougzuck.com/my-frustrating-experience-trying-to-purchase-a-new-iphone-4/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Remote Reboot X &#8211; The Ultimate WSUS Companion Tool &#8211; Version 1.5 Available Now</title>
		<link>http://dougzuck.com/remote-reboot-x-the-ultimate-wsus-companion-tool-version-1-5-available-now</link>
		<comments>http://dougzuck.com/remote-reboot-x-the-ultimate-wsus-companion-tool-version-1-5-available-now#comments</comments>
		<pubDate>Fri, 02 Oct 2009 23:22:57 +0000</pubDate>
		<dc:creator>doug</dc:creator>
				<category><![CDATA[C#.NET]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[C sharp]]></category>
		<category><![CDATA[Remote Reboot]]></category>
		<category><![CDATA[Windows updates]]></category>
		<category><![CDATA[WSUS]]></category>

		<guid isPermaLink="false">http://dougzuck.com/?p=707</guid>
		<description><![CDATA[Download it here:  http://dougzuck.com/remoterebootx Along with bug fixes and cosmetic changes, here are some of the features that have been added: Automatically reboot if required after installing WSUS updates Automatically force reboot if normal reboot fails Automatically stop pinging after reboot In addition to installing downloaded updates you can now specify to search for available [...]]]></description>
			<content:encoded><![CDATA[<p>Download it here:  <a href="http://dougzuck.com/remoterebootx" target="_self">http://dougzuck.com/remoterebootx</a></p>
<p>Along with bug fixes and cosmetic changes, here are some of the features that have been added:</p>
<ul>
<li>Automatically reboot if required after installing WSUS updates</li>
<li>Automatically force reboot if normal reboot fails</li>
<li>Automatically stop pinging after reboot</li>
<li>In addition to installing downloaded updates you can now specify to search for available updates, then download and install them all with a single click</li>
<li>Save and load state (XML import/export)</li>
<li>Wake On LAN</li>
</ul>
<p style="text-align: center;"><a href="http://dougzuck.com/wp-content/uploads/2009/05/rrx20091013.png"><img class="aligncenter size-full wp-image-743" title="rrx20091013" src="http://dougzuck.com/wp-content/uploads/2009/05/rrx20091013.png" alt="rrx20091013" width="540" height="315" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://dougzuck.com/remote-reboot-x-the-ultimate-wsus-companion-tool-version-1-5-available-now/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML Application &#8211; SQL Differential Backup Size Prediction</title>
		<link>http://dougzuck.com/html-application-sql-differential-backup-size-prediction</link>
		<comments>http://dougzuck.com/html-application-sql-differential-backup-size-prediction#comments</comments>
		<pubDate>Sun, 02 Aug 2009 20:50:01 +0000</pubDate>
		<dc:creator>doug</dc:creator>
				<category><![CDATA[HTML Applications]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[VBScript]]></category>
		<category><![CDATA[HTA]]></category>

		<guid isPermaLink="false">http://dougzuck.com/?p=645</guid>
		<description><![CDATA[You can find the full post here: http://dougzuck.com/hta]]></description>
			<content:encoded><![CDATA[<p>You can find the full post here: <a href="http://dougzuck.com/hta">http://dougzuck.com/hta</a></p>
<p style="text-align: center;"><a href="http://dougzuck.com/wp-content/uploads/2009/05/diffBackupPredictionHTA.png"><img class="aligncenter size-full wp-image-640" title="diffBackupPredictionHTA" src="http://dougzuck.com/wp-content/uploads/2009/05/diffBackupPredictionHTA.png" alt="diffBackupPredictionHTA" width="597" height="221" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://dougzuck.com/html-application-sql-differential-backup-size-prediction/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQL &#8211; Differential Backup Size Prediction</title>
		<link>http://dougzuck.com/sql-differential-backup-size-prediction</link>
		<comments>http://dougzuck.com/sql-differential-backup-size-prediction#comments</comments>
		<pubDate>Sun, 02 Aug 2009 20:22:32 +0000</pubDate>
		<dc:creator>doug</dc:creator>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://dougzuck.com/?p=625</guid>
		<description><![CDATA[SQL Differential Backup Size Prediction]]></description>
			<content:encoded><![CDATA[<p>One of the tasks I regularly have to perform at my job involves moving multi-terabyte databases from one server to another.  The goal is to make these database moves happen with as little downtime as possible, so I always make use of differential backups and restores to keep the move times to a minimum.  I&#8217;ll do a full backup of the source database, then I&#8217;ll perform a restore of that database to the new server, specifying &#8216;with norecovery&#8217; in the restore command.  For a 2 terabyte database, this process will take many hours, but that&#8217;s ok because I&#8217;ll make sure it&#8217;s complete prior to the actual maintenance window.  Then when the maintenance window begins, I&#8217;ll disable access to the database and perform a differential backup of the database on the source server.  Then I restore the differential backup &#8216;with recovery&#8217; to the new server.  The process of doing a differential backup and restore is <em>much</em> less time consuming than the full backup and restore, and this allows the actual maintenance window to be much smaller since the full backup and restore is completed at an earlier time.  However, when I&#8217;m dealing with such large databases, it becomes extremely helpful to know how big the differential backup is going to be before I actually execute it.  This way I&#8217;m able to estimate how long the whole process will take.  When you have a 2 terabyte database, it&#8217;s not uncommon to have a several hundred gigabyte differential backup.  You could see why it might help to know in advance whether the differential is going to be 10GB or 200GB.</p>
<p>Darwin Hatheway wrote a <a href="http://www.sqlservercentral.com/articles/Administration/differentialbackupprediction/2306/">really nice article</a> explaining how the differential backup size can be estimated.  He gets all the credit for teaching me how to do this.  I have two implementations below.  One is a straight T-SQL script, and the other is a HTML Application (HTA) that utilizes the T-SQL script with a bit of vbscript.  On a 2TB database it generally only takes a handful of seconds for the script to complete.</p>
<p>T-SQL Version: <a href="http://dougzuck.com/downloads/SQL-Differential-Backup-Size-Prediction-dz.sql">SQL Differential Backup Size Prediction</a><br />
HTML Application: <a href="http://dougzuck.com/hta">http://dougzuck.com/hta</a></p>
<p><a href="http://dougzuck.com/wp-content/uploads/2009/08/diffPredictionResults.png"><img class="aligncenter size-full wp-image-631" title="diffPredictionResults" src="http://dougzuck.com/wp-content/uploads/2009/08/diffPredictionResults.png" alt="diffPredictionResults" width="349" height="36" /></a></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
</pre></td><td class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">/*SQL Differential Backup Size Prediction - Doug Zuckerman, 2009 - http://dougzuck.com */</span>
&nbsp;
<span style="color: #993333; font-weight: bold;">IF</span> isNULL<span style="color: #66cc66;">&#40;</span>object_id<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'tempdb.dbo.##showFileStats'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&lt;&gt;</span> <span style="color: #cc66cc;">1</span>
	<span style="color: #993333; font-weight: bold;">DROP</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #808080; font-style: italic;">##showFileStats</span>
&nbsp;
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #808080; font-style: italic;">##showFileStats (</span>
	fileID INT<span style="color: #66cc66;">,</span>
	fileGroup INT<span style="color: #66cc66;">,</span>
	totalExtents BIGINT<span style="color: #66cc66;">,</span>
	usedExtents BIGINT<span style="color: #66cc66;">,</span>
	logicalFileName VARCHAR <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">500</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>	
	filePath VARCHAR <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1000</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #993333; font-weight: bold;">IF</span> isNULL<span style="color: #66cc66;">&#40;</span>object_id<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'tempdb.dbo.##DCM'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&lt;&gt;</span> <span style="color: #cc66cc;">1</span>
	<span style="color: #993333; font-weight: bold;">DROP</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #808080; font-style: italic;">##DCM</span>
&nbsp;
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #808080; font-style: italic;">##DCM (</span>
	parentObject VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">5000</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
	<span style="color: #66cc66;">&#91;</span>object<span style="color: #66cc66;">&#93;</span> VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">5000</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
	<span style="color: #993333; font-weight: bold;">FIELD</span> VARCHAR <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">5000</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
	value VARCHAR <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">5000</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/*we need to get a list of all the files in the database.  each file needs to be looked at*/</span>	
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> <span style="color: #808080; font-style: italic;">##showFileStats EXEC('DBCC SHOWFILESTATS with tableresults')</span>
&nbsp;
DECLARE @currentFileID INT<span style="color: #66cc66;">,</span>
	@totalExtentsOfFile BIGINT<span style="color: #66cc66;">,</span>
	@dbname VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">100</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
	@SQL VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">200</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
	@currentDCM BIGINT<span style="color: #66cc66;">,</span>
	@step INT
&nbsp;
<span style="color: #993333; font-weight: bold;">SET</span> @dbname <span style="color: #66cc66;">=</span> db_name<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">SET</span> @step <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">511232</span>
&nbsp;
DECLARE myCursor SCROLL CURSOR <span style="color: #993333; font-weight: bold;">FOR</span>
<span style="color: #993333; font-weight: bold;">SELECT</span> fileID<span style="color: #66cc66;">,</span> totalExtents 
<span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #808080; font-style: italic;">##showFileStats</span>
&nbsp;
OPEN myCursor
FETCH NEXT <span style="color: #993333; font-weight: bold;">FROM</span> myCursor <span style="color: #993333; font-weight: bold;">INTO</span> @currentFileID<span style="color: #66cc66;">,</span> @totalExtentsOfFile
&nbsp;
<span style="color: #808080; font-style: italic;">/*look at each differential change map page in each data file of the database and put the output into ##DCM*/</span>
WHILE @@FETCH_STATUS <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span> 
BEGIN
&nbsp;
	<span style="color: #993333; font-weight: bold;">SET</span> @currentDCM <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">6</span>
	WHILE @currentDCM <span style="color: #66cc66;">&lt;=</span> @totalExtentsOfFile<span style="color: #66cc66;">*</span><span style="color: #cc66cc;">8</span>
	BEGIN	
		<span style="color: #993333; font-weight: bold;">SET</span> @SQL <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'dbcc page('</span><span style="color: #66cc66;">+</span> @dbname <span style="color: #66cc66;">+</span> <span style="color: #ff0000;">', '</span> <span style="color: #66cc66;">+</span> CAST<span style="color: #66cc66;">&#40;</span>@currentFileID <span style="color: #993333; font-weight: bold;">AS</span> VARCHAR<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #ff0000;">', '</span> <span style="color: #66cc66;">+</span> CAST<span style="color: #66cc66;">&#40;</span>@currentDCM <span style="color: #993333; font-weight: bold;">AS</span> VARCHAR<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #ff0000;">', 3) WITH TABLERESULTS'</span>
		<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> <span style="color: #808080; font-style: italic;">##DCM EXEC (@SQL)</span>
		<span style="color: #993333; font-weight: bold;">SET</span> @currentDCM <span style="color: #66cc66;">=</span> @currentDCM <span style="color: #66cc66;">+</span> @step
	END
&nbsp;
	FETCH NEXT <span style="color: #993333; font-weight: bold;">FROM</span> myCursor <span style="color: #993333; font-weight: bold;">INTO</span> @currentFileID<span style="color: #66cc66;">,</span> @totalExtentsOfFile
END
CLOSE myCursor
DEALLOCATE myCursor
&nbsp;
<span style="color: #808080; font-style: italic;">/*remove all unneeded rows from our results table*/</span>
<span style="color: #993333; font-weight: bold;">DELETE</span> <span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #808080; font-style: italic;">##DCM WHERE value = 'NOT CHANGED' OR parentObject NOT LIKE 'DIFF_MAP%'</span>
<span style="color: #808080; font-style: italic;">--SELECT * FROM ##DCM</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/*sum the extentTally column*/</span>
<span style="color: #993333; font-weight: bold;">SELECT</span> SUM <span style="color: #66cc66;">&#40;</span>extentTally<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> totalChangedExtents<span style="color: #66cc66;">,</span> SUM<span style="color: #66cc66;">&#40;</span>extentTally<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">/</span><span style="color: #cc66cc;">16</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">'diffPrediction(MB)'</span><span style="color: #66cc66;">,</span> SUM<span style="color: #66cc66;">&#40;</span>extentTally<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">/</span><span style="color: #cc66cc;">16</span><span style="color: #66cc66;">/</span><span style="color: #cc66cc;">1024</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">'diffPrediction(GB)'</span> 
<span style="color: #993333; font-weight: bold;">FROM</span>
	<span style="color: #808080; font-style: italic;">/*create extentTally column*/</span>
	<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> extentTally <span style="color: #66cc66;">=</span>
	CASE
		WHEN secondChangedExtent <span style="color: #66cc66;">&gt;</span> <span style="color: #cc66cc;">0</span> THEN CAST<span style="color: #66cc66;">&#40;</span>secondChangedExtent <span style="color: #993333; font-weight: bold;">AS</span> BIGINT<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span> CAST<span style="color: #66cc66;">&#40;</span>firstChangedExtent <span style="color: #993333; font-weight: bold;">AS</span> BIGINT<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">1</span>
		ELSE <span style="color: #cc66cc;">1</span>
	END
	<span style="color: #993333; font-weight: bold;">FROM</span>
		<span style="color: #808080; font-style: italic;">/*parse the 'field' column to give us the first and last extents of the range*/</span>
		<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">&#40;</span>SUBSTRING<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">FIELD</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> CHARINDEX<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">':'</span><span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">FIELD</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">+</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#40;</span>CHARINDEX<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">')'</span><span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">FIELD</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">-</span><span style="color: #66cc66;">&#40;</span>CHARINDEX<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">':'</span><span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">FIELD</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">-</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">/</span><span style="color: #cc66cc;">8</span> <span style="color: #993333; font-weight: bold;">AS</span> firstChangedExtent<span style="color: #66cc66;">,</span>
		secondChangedExtent <span style="color: #66cc66;">=</span> 
		CASE	
			WHEN CHARINDEX<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">':'</span><span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">FIELD</span><span style="color: #66cc66;">,</span> CHARINDEX<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">':'</span><span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">FIELD</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">+</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&gt;</span> <span style="color: #cc66cc;">0</span> THEN <span style="color: #66cc66;">&#40;</span>SUBSTRING<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">FIELD</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#40;</span>CHARINDEX<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">':'</span><span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">FIELD</span><span style="color: #66cc66;">,</span> CHARINDEX<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">':'</span><span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">FIELD</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">+</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">+</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#40;</span>CHARINDEX<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">')'</span><span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">FIELD</span><span style="color: #66cc66;">,</span>CHARINDEX<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">')'</span><span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">FIELD</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">+</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">-</span><span style="color: #66cc66;">&#40;</span>CHARINDEX<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">':'</span><span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">FIELD</span><span style="color: #66cc66;">,</span> CHARINDEX<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">':'</span><span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">FIELD</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">+</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">-</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">/</span><span style="color: #cc66cc;">8</span>
			ELSE <span style="color: #ff0000;">''</span>
		END 
		<span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #808080; font-style: italic;">##DCM)parsedFieldColumn)extentTallyColumn</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://dougzuck.com/sql-differential-backup-size-prediction/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML Application &#8211; Retrieve SP_WHO2 and the Input Buffer from a SQL Server</title>
		<link>http://dougzuck.com/html-application-retrieve-sp_who2-and-the-input-buffer-from-a-sql-server</link>
		<comments>http://dougzuck.com/html-application-retrieve-sp_who2-and-the-input-buffer-from-a-sql-server#comments</comments>
		<pubDate>Sun, 05 Jul 2009 01:56:56 +0000</pubDate>
		<dc:creator>doug</dc:creator>
				<category><![CDATA[HTML Applications]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[VBScript]]></category>
		<category><![CDATA[HTA]]></category>

		<guid isPermaLink="false">http://dougzuck.com/?p=600</guid>
		<description><![CDATA[You can find the full post here: http://www.dougzuck.com/hta]]></description>
			<content:encoded><![CDATA[<p>You can find the full post here: <a href="http://www.dougzuck.com/hta" target="_self">http://www.dougzuck.com/hta</a></p>
<p style="text-align: center;"><a href="http://dougzuck.com/wp-content/uploads/2009/05/get_sql_spwho2_and_inputbuffer.png"><img class="aligncenter size-large wp-image-520" title="get_sql_spwho2_and_inputbuffer" src="http://dougzuck.com/wp-content/uploads/2009/05/get_sql_spwho2_and_inputbuffer-1024x676.png" alt="get_sql_spwho2_and_inputbuffer" width="614" height="406" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://dougzuck.com/html-application-retrieve-sp_who2-and-the-input-buffer-from-a-sql-server/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Decrease Malware Infections Using Software Restriction Policies (SRP) to Strip Administrative Privileges from Internet-Facing Applications</title>
		<link>http://dougzuck.com/decrease-malware-infections-using-software-restriction-policies</link>
		<comments>http://dougzuck.com/decrease-malware-infections-using-software-restriction-policies#comments</comments>
		<pubDate>Fri, 03 Jul 2009 04:27:51 +0000</pubDate>
		<dc:creator>doug</dc:creator>
				<category><![CDATA[Security]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Security Restriction Policies]]></category>
		<category><![CDATA[Systems Administration]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://dougzuck.com/?p=541</guid>
		<description><![CDATA[I know that many organizations do not put restrictions on their users&#8217; computers.  The users are often given full administrative privileges on their workstations, which means that they can not only mess around with all the settings on their computers, but they can also install and uninstall applications.  This includes accidental virus and malware installations.  [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;">I know that many organizations do not put restrictions on their users&#8217; computers.  The users are often given full administrative privileges on their workstations, which means that they can not only mess around with all the settings on their computers, but they can also install and uninstall applications.  This includes accidental virus and malware installations.  While many <a href="http://en.wikipedia.org/wiki/System_administrator" target="_blank">Systems and Network Admins</a> consider this unacceptable, it&#8217;s still a reality in many working environments.  So rather than complain about how it&#8217;s not the ideal way to run a windows network, let&#8217;s focus on cool ways to mitigate the risks of this approach.  This is one VERY simple but effective method to limit malware infections on your network computers while still allowing users to be local administrators.  This approach can be used across an entire network with a group policy object, or it can simply be applied to a single computer by modifying the computer&#8217;s local security policy.</p>
<h3 style="text-align: left;">Overview&#8230;</h3>
<p style="text-align: left;">The idea here is that you apply a group policy object to the users or computers in your organization.   It prevents whatever applications you choose from launching with full admin privileges on the users&#8217; computers.  The users are still local administrators, but the particular applications that you pre-select get launched <em>without </em>administrative permissions.  If you apply this restriction to all of the applications that deal with typically untrusted, unsafe, or unknown content, then you dramatically decrease the likelihood that a virus or other malware can be installed because non-admin users are not able to install software on the computer.  Windows doesn&#8217;t let them.  I recommend applying it to all web browsers, all email clients, and all media players because these are the primary apps that deal with internet content.  You could alternatively apply it to the entire C:\Program Files folder, but if you do so you should be mindful of the fact that some apps might break as a result.</p>
<p style="text-align: left;">You can produce functionality that is similar to <a href="http://blogs.msdn.com/michael_howard/archive/2007/08/13/update-on-dropmyrights.aspx" target="_blank">DropMyRights</a> but <em>without </em>the annoyances that come along with it.  In my opinion this method is by far the easiest to deploy to a lot of users or computers, something which <a href="http://blogs.msdn.com/michael_howard/archive/2007/08/13/update-on-dropmyrights.aspx" target="_blank">DropMyRights </a>isn&#8217;t suited for (since any time an application is updated or a new one installed, the <a href="http://blogs.msdn.com/michael_howard/archive/2007/08/13/update-on-dropmyrights.aspx" target="_blank">DropMyRights </a>configuration has to be re-applied).  Using <a href="http://technet.microsoft.com/en-us/library/bb457006.aspx" target="_blank">Software Restriction Policies</a>, you can apply this functionality in a way that is virtually transparent to users.  However, Microsoft doesn&#8217;t publicize this particular usage of SRP for whatever reason (the functionality is actually hidden in XP by default &#8211; you need to add a registry DWORD to make it available), which is why I&#8217;m taking the time to mention it here.  When I embarked on setting this up today at my job I spent hours researching something that took only minutes to implement.  Hopefully I&#8217;m now saving you the hours of research.</p>
<h3 style="text-align: left;">Caveat&#8230;</h3>
<p style="text-align: left;">The only real caveat is that when an application is launched without admin privileges, if that application then launches another process or program, the program that it launches will also not have admin privileges.  This means that if a user wants to install software that he/she downloads from the web, he/she needs to be aware that launching the setup.exe file directly from browser&#8217;s &#8216;Downloads&#8217; window will generate an error and abort the installation.  In some cases it might not throw an error and instead will appear to install successfully, but when the app is launched it isn&#8217;t able to run because the installation was actually not successful.  Users have to be trained to save the application setup files to their desktops (or wherever) and then launch them from the desktops or through Windows Explorer.</p>
<p style="text-align: left;">Additionally, it is up to you test out any applications that you restrict.  While most of the time this is a transparent deployment, there is always the possibility that this restriction could hinder a custom application from working in the way that it was designed.  However, for most applications in most situations it works great and causes no issues.</p>
<h3 style="text-align: left;">Here&#8217;s the step by step:</h3>
<p style="text-align: left;">1. Expose the hidden &#8216;Basic User&#8217; option by opening the registry editor and adding a DWORD called &#8220;Levels&#8221; with a value of 20000 (hexadecimal) to</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">HKLM\Software\Policies\Microsoft\Windows\Safer\CodeIdentifiers</pre></div></div>

<p style="text-align: center;"><a href="http://dougzuck.com/wp-content/uploads/2009/07/SRP4.png"><img class="size-medium wp-image-546 aligncenter" title="SRP4" src="http://dougzuck.com/wp-content/uploads/2009/07/SRP4-300x152.png" alt="SRP4" width="300" height="152" /></a></p>
<p style="text-align: center;">
<p style="text-align: left;">2. Open the domain Group Policy editor (or to apply to a single computer, open the local policy editor by going to Start &gt; Run &gt; gpedit.msc) and go to</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">Computer Configuration\Windows Settings\Security Settings\Software Restriction Policies</pre></div></div>

<p style="text-align: left;">If this is the first time you&#8217;ve looked at the Software Restriction Policies, the right hand pane will be empty.  To rectify this, click on Action  &gt; Create New Policies.  Once you&#8217;ve done this you should see &#8216;Security Levels&#8217; and &#8216;Additional Rules.&#8217;  Now click on &#8216;Security Levels&#8217; and verify that you see 3 options (Disallowed, Basic User, and Unrestricted).</p>
<p style="text-align: left;">If you do <em>not </em>see the &#8216;Basic User&#8217; option on the right-hand pane, close the GPO editor, go back to step 1 and make sure you&#8217;ve properly created the registry DWORD, then re-open the GPO editor (Note that the Basic User option is hidden in Windows XP until you add the Levels DWORD value).</p>
<p style="text-align: center;"><a href="http://dougzuck.com/wp-content/uploads/2009/07/SRP1.png"><img class="size-medium wp-image-545 aligncenter" title="SRP1" src="http://dougzuck.com/wp-content/uploads/2009/07/SRP1-300x267.png" alt="SRP1" width="300" height="267" /></a></p>
<p style="text-align: left;">3.  At this point you&#8217;re going to highlight &#8216;Additional Rules&#8217; and right click to create a new path rule. Specify the path to the application that you want to limit.  In the path entry you can use the asterisk (*) as a wild card for multiple letters/words.  The question mark symbol can be used as a wild card for a single letter.</p>
<p style="text-align: left;">Set the security level drop-down menu to Basic User.  This is the key ingredient that makes the magic happen.  Now any executable file in the specified path or its subfolders will launch with limited user privileges on a computer that receives this GPO.</p>
<p style="text-align: center;"><a href="http://dougzuck.com/wp-content/uploads/2009/07/SRP2.png"><img class="size-medium wp-image-547 aligncenter" title="SRP2" src="http://dougzuck.com/wp-content/uploads/2009/07/SRP2-300x272.png" alt="SRP2" width="300" height="272" /></a></p>
<p style="text-align: center;"><a href="http://dougzuck.com/wp-content/uploads/2009/07/SRP3.png"><img class="size-medium wp-image-548 aligncenter" title="SRP3" src="http://dougzuck.com/wp-content/uploads/2009/07/SRP3-300x268.png" alt="SRP3" width="300" height="268" /></a></p>
<p style="text-align: left;">4.  When you&#8217;re done creating the policy, link it to your workstations OU and test it!  That&#8217;s it.  Pretty simple, eh?</p>
<p style="text-align: left;">In this example, I&#8217;ve limited Firefox so that it can only be launched as a Basic User with no admin rights.  I&#8217;m able to verify this is the case by first closing all instances of Firefox, then launching it once again after the path rule has been created.  I browse to a website and download a software installation package.  I then try to launch the software package from within Firefox&#8217;s &#8216;Downloads&#8217; window, but I can&#8217;t perform the installation, so I know it works!</p>
<p style="text-align: left;"><a href="http://dougzuck.com/wp-content/uploads/2009/07/srp5.png"><img class="aligncenter size-medium wp-image-584" title="srp5" src="http://dougzuck.com/wp-content/uploads/2009/07/srp5-300x201.png" alt="srp5" width="300" height="201" /></a><a href="http://dougzuck.com/wp-content/uploads/2009/07/srp6.png"><img class="aligncenter size-medium wp-image-585" title="srp6" src="http://dougzuck.com/wp-content/uploads/2009/07/srp6-300x194.png" alt="srp6" width="300" height="194" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://dougzuck.com/decrease-malware-infections-using-software-restriction-policies/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>HTML Application &#8211; Retrieve the model, serial number, RAM amount, OS version, last boot time and more using WMI</title>
		<link>http://dougzuck.com/html-application-retrieve-model-serial-number-ram-os-last-boot-time-and-more</link>
		<comments>http://dougzuck.com/html-application-retrieve-model-serial-number-ram-os-last-boot-time-and-more#comments</comments>
		<pubDate>Thu, 25 Jun 2009 00:47:34 +0000</pubDate>
		<dc:creator>doug</dc:creator>
				<category><![CDATA[HTML Applications]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[VBScript]]></category>
		<category><![CDATA[HTA]]></category>
		<category><![CDATA[WMI]]></category>

		<guid isPermaLink="false">http://www.dougzuck.com/?p=474</guid>
		<description><![CDATA[You can find the full post here: http://www.dougzuck.com/hta]]></description>
			<content:encoded><![CDATA[<p>You can find the full post here: <a href="http://www.dougzuck.com/hta" target="_self">http://www.dougzuck.com/hta</a></p>
<p style="text-align: center;"><a href="http://dougzuck.com/wp-content/uploads/2009/06/Get_General_Info.png"><img class="aligncenter size-full wp-image-462" title="Get_General_Info" src="http://dougzuck.com/wp-content/uploads/2009/06/Get_General_Info.png" alt="Get_General_Info" width="584" height="404" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://dougzuck.com/html-application-retrieve-model-serial-number-ram-os-last-boot-time-and-more/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML Application &#8211; Retrieve SQL Backup History</title>
		<link>http://dougzuck.com/html-application-retrieve-sql-backup-history</link>
		<comments>http://dougzuck.com/html-application-retrieve-sql-backup-history#comments</comments>
		<pubDate>Thu, 25 Jun 2009 00:46:11 +0000</pubDate>
		<dc:creator>doug</dc:creator>
				<category><![CDATA[HTML Applications]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[VBScript]]></category>
		<category><![CDATA[HTA]]></category>

		<guid isPermaLink="false">http://www.dougzuck.com/?p=472</guid>
		<description><![CDATA[You can find the full post here: http://www.dougzuck.com/hta]]></description>
			<content:encoded><![CDATA[<p>You can find the full post here: <a href="http://www.dougzuck.com/hta" target="_self">http://www.dougzuck.com/hta</a></p>
<p style="text-align: center;"><a href="http://dougzuck.com/wp-content/uploads/2009/05/get_sql_backup_history.png"><img class="aligncenter size-full wp-image-375" title="get_sql_backup_history" src="http://dougzuck.com/wp-content/uploads/2009/05/get_sql_backup_history.png" alt="get_sql_backup_history" width="602" height="300" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://dougzuck.com/html-application-retrieve-sql-backup-history/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C# .NET &#8211; UI Threading Example</title>
		<link>http://dougzuck.com/c-ui-threading-example</link>
		<comments>http://dougzuck.com/c-ui-threading-example#comments</comments>
		<pubDate>Sun, 14 Jun 2009 22:14:30 +0000</pubDate>
		<dc:creator>doug</dc:creator>
				<category><![CDATA[C#.NET]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[threading]]></category>
		<category><![CDATA[ui]]></category>

		<guid isPermaLink="false">http://www.dougzuck.com/?p=396</guid>
		<description><![CDATA[This is the simplest way to execute work in a separate thread and have it report back to the UI thread When you&#8217;re creating a Windows Form Application using Visual C# 2008, there are some tricky threading issues that need to be dealt with in order to keep your application running smoothly.  Specifically, you have [...]]]></description>
			<content:encoded><![CDATA[<h2>This is the simplest way to execute work in a separate thread and have it report back to the UI thread</h2>
<p>When you&#8217;re creating a Windows Form Application using Visual C# 2008, there are some tricky threading issues that need to be dealt with in order to keep your application running smoothly.  Specifically, you have to be very aware of how your application does work.  If you simply create a worker function and then call it, it&#8217;s going to execute in the current thread, which is also the thread that&#8217;s handling the user interface.  The result really stinks because your UI will completely lock up until the worker thread is finished executing.  This is unacceptable in nearly all situations.</p>
<p>I want to show you what I believe is the absolute simplest way for executing a worker function in a separate thread while still allowing that separate thread to send information back to the main UI thread, whether it be to update a text box, a label, or a field in a datagridview.</p>
<p>In this example we&#8217;re going to click a button to launch our worker function, which will count from 1 to 15.  Our user interface will display each number as it counts.  </p>
<p>Also, please pardon the fact that I use &#8216;function&#8217; and &#8216;method&#8217; interchangeably in this post.  Technically, I should just be saying &#8216;method,&#8217; but &#8216;function&#8217; always slips out.</p>
<p>Download the entire Visual Studio project here: <a href="http://dougzuck.com/downloads/UI_Threading_Example.zip">UI_Threading_Example_CSharp.zip</a></p>
<p><a href="http://www.dougzuck.com/wp-content/uploads/2009/06/UI_Threading_Example.png"><img class="size-full wp-image-409 alignnone" title="UI_Threading_Example" src="http://www.dougzuck.com/wp-content/uploads/2009/06/UI_Threading_Example.png" alt="UI_Threading_Example" width="249" height="125" /></a><a href="http://www.dougzuck.com/wp-content/uploads/2009/06/UI_Threading_Example2.png"><img class="alignnone size-full wp-image-449" title="UI_Threading_Example(2)" src="http://www.dougzuck.com/wp-content/uploads/2009/06/UI_Threading_Example2.png" alt="UI_Threading_Example(2)" width="251" height="127" /></a></p>
<h3>Let&#8217;s take a look at the code:</h3>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">using</span> <span style="color: #008080;">System</span><span style="color: #008000;">;</span>
<span style="color: #0600FF;">using</span> <span style="color: #008080;">System.Windows.Forms</span><span style="color: #008000;">;</span>
<span style="color: #0600FF;">using</span> <span style="color: #008080;">System.Threading</span><span style="color: #008000;">;</span>
&nbsp;
<span style="color: #0600FF;">namespace</span> UI_Threading_Example
<span style="color: #000000;">&#123;</span>
    <span style="color: #008080; font-style: italic;">//declare the delegate that we'll use to launch our worker function in a separate thread</span>
    <span style="color: #0600FF;">public</span> <span style="color: #FF0000;">delegate</span> <span style="color: #0600FF;">void</span> workerFunctionDelegate<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">int</span> totalSeconds<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">//declare the delegate that we'll use to call the function that displays text in our text box</span>
    <span style="color: #0600FF;">public</span> <span style="color: #FF0000;">delegate</span> <span style="color: #0600FF;">void</span> poplateTextBoxDelegate<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">string</span> text<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #0600FF;">public</span> <span style="color: #0600FF;">partial</span> <span style="color: #FF0000;">class</span> Form1 <span style="color: #008000;">:</span> Form
    <span style="color: #000000;">&#123;</span>
       <span style="color: #0600FF;">public</span> Form1<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
       <span style="color: #000000;">&#123;</span>
          InitializeComponent<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
       <span style="color: #000000;">&#125;</span>
&nbsp;
       <span style="color: #008080; font-style: italic;">//this function will simply write text to our text box</span>
       <span style="color: #008080; font-style: italic;">//this function will later be called from a worker thread through the use of a delegate using the Invoke method on the form</span>
       <span style="color: #0600FF;">void</span> populateTextBox<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">string</span> text<span style="color: #000000;">&#41;</span>
       <span style="color: #000000;">&#123;</span>
          textBox1.<span style="color: #0000FF;">Text</span> <span style="color: #008000;">=</span> textBox1.<span style="color: #0000FF;">Text</span> <span style="color: #008000;">+</span> <span style="color: #666666;">&quot; &quot;</span> <span style="color: #008000;">+</span> text<span style="color: #008000;">;</span>
       <span style="color: #000000;">&#125;</span>
&nbsp;
       <span style="color: #008080; font-style: italic;">//this function simulates &quot;work&quot; by simply counting from 1 to totalSeconds</span>
       <span style="color: #0600FF;">void</span> workerFunction<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">int</span> totalSeconds<span style="color: #000000;">&#41;</span>
       <span style="color: #000000;">&#123;</span>
          <span style="color: #0600FF;">for</span> <span style="color: #000000;">&#40;</span><span style="color: #FF0000;">int</span> count <span style="color: #008000;">=</span> <span style="color: #FF0000;">1</span><span style="color: #008000;">;</span> count <span style="color: #008000;">&lt;=</span> totalSeconds <span style="color: #008000;">;</span> count<span style="color: #008000;">++</span><span style="color: #000000;">&#41;</span>
          <span style="color: #000000;">&#123;</span>
             <span style="color: #008080; font-style: italic;">//we use this.Invoke to send information back to our UI thread with a delegate</span>
             <span style="color: #008080; font-style: italic;">//if we were to try to access the text box on the UI thread directly from a different thread, there would be problems</span>
             <span style="color: #0600FF;">this</span>.<span style="color: #0000FF;">Invoke</span><span style="color: #000000;">&#40;</span><span style="color: #008000;">new</span> poplateTextBoxDelegate<span style="color: #000000;">&#40;</span>populateTextBox<span style="color: #000000;">&#41;</span>, <span style="color: #008000;">new</span> <span style="color: #FF0000;">object</span><span style="color: #000000;">&#91;</span><span style="color: #000000;">&#93;</span> <span style="color: #000000;">&#123;</span> count.<span style="color: #0000FF;">ToString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#125;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
             Thread.<span style="color: #0000FF;">Sleep</span><span style="color: #000000;">&#40;</span><span style="color: #FF0000;">1000</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
          <span style="color: #000000;">&#125;</span>
       <span style="color: #000000;">&#125;</span>   
&nbsp;
       <span style="color: #008080; font-style: italic;">//this function is executed when we click the first button in the windows form</span>
       <span style="color: #008080; font-style: italic;">//this is the PROPER WAY to do work in a UI situation</span>
       <span style="color: #008080; font-style: italic;">//the worker function is launched in a separate thread so that our UI will remain responsive while it does work</span>
       <span style="color: #0600FF;">private</span> <span style="color: #0600FF;">void</span> buttonNewThread_Click<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">object</span> sender, EventArgs e<span style="color: #000000;">&#41;</span>
       <span style="color: #000000;">&#123;</span>
          workerFunctionDelegate w <span style="color: #008000;">=</span> workerFunction<span style="color: #008000;">;</span>
          w.<span style="color: #0000FF;">BeginInvoke</span><span style="color: #000000;">&#40;</span><span style="color: #FF0000;">15</span>, <span style="color: #0600FF;">null</span>, <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
       <span style="color: #000000;">&#125;</span>
&nbsp;
       <span style="color: #008080; font-style: italic;">//this function is executed when we click the second button in the windows form</span>
       <span style="color: #008080; font-style: italic;">//it's an example of WHAT NOT TO DO because if we click this button</span>
       <span style="color: #008080; font-style: italic;">//the UI will become completely unresponsive for 15 seconds while the worker fucntion is executed</span>
       <span style="color: #0600FF;">private</span> <span style="color: #0600FF;">void</span> buttonCurrentThread_Click<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">object</span> sender, EventArgs e<span style="color: #000000;">&#41;</span>
       <span style="color: #000000;">&#123;</span>
          workerFunction<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">15</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
       <span style="color: #000000;">&#125;</span>
 <span style="color: #000000;">&#125;</span></pre></td></tr></table></div>

<p>OK, so here&#8217;s what we&#8217;ve got.  In Visual Studio (I&#8217;m using Visual C# 2008) I&#8217;ve created a new Windows Form Application and then in the designer window I added a text box (called textBox1) plus two buttons (called buttonNewThread and buttonCurrentThread).</p>
<p>In the code window I created two functions:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">void</span> populateTextBox<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">string</span> text<span style="color: #000000;">&#41;</span>
<span style="color: #0600FF;">void</span> workerFunction<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">int</span> totalSeconds<span style="color: #000000;">&#41;</span></pre></td></tr></table></div>

<p>plus a delegate for each function:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">public</span> <span style="color: #FF0000;">delegate</span> <span style="color: #0600FF;">void</span> poplateTextBoxDelegate<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">string</span> text<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">delegate</span> <span style="color: #0600FF;">void</span> workerFunctionDelegate<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">int</span> totalSeconds<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span></pre></td></tr></table></div>

<p>The first function is responsible for writing text to our text box.  The second function is responsible for doing &#8220;work,&#8221; which in this case is just counting from 1 to 15 and calling the function (using a delegate) to display the count in our text box.  Additionally there are two other functions (buttonCurrentThread_Click and buttonNewThread_Click) which handle the button clicks from our UI:</p>
<h3>What&#8217;s the deal with delegates in this example?</h3>
<p>In order to launch a worker function in a separate thread we have to declare a delegate for that function.  The delegate declaration must be outside the class declaration, and the delegate for each function must have the same format as the function that it&#8217;s going to be used to call.  So for example, if your worker function has 3 parameters, your delegate must also have 3 parameters.  And in this example, we not only need a delegate to handle launching our worker function in a new thread, but we also need to declare a delegate that we&#8217;ll use from within the worker thread to call a function to update the text box on the UI thread.  It is NOT ok to try to update a text box in the UI from a different thread without the use of a delegate.  If you don&#8217;t believe me then give it a shot and you&#8217;ll see for yourself that the results are funky.</p>
<h3>The WRONG way to execute the worker function (using the UI thread)</h3>
<p>When you click the button to execute the worker function in the current thread, which is the same thread that handles the UI, then you&#8217;ll see that for 15 seconds you can&#8217;t do anything with the UI or even move the form window to a new location.  At the end of 15 seconds the UI becomes responsive again and you see a &#8220;15&#8243; in the text box.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #008080; font-style: italic;">//This is the WRONG way to do it</span>
<span style="color: #0600FF;">private</span> <span style="color: #0600FF;">void</span> buttonCurrentThread_Click<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">object</span> sender, EventArgs e<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
   workerFunction<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">15</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></td></tr></table></div>

<h3>The RIGHT way to execute the worker function (using a separate thread)</h3>
<p>When you click the button to execute the worker function in a new thread, you watch the count from 1 to 15 displayed in the text box and the UI is not frozen.</p>
<p>Note that the null values are required by the BeginInvoke method.  If you have a function that requires more than one parameter, you would still pass all your parameters in first, followed by the two nulls.  In this example we&#8217;re effectively passing the value 15 to the worker function which will then execute for 15 seconds.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #008080; font-style: italic;">//This is the RIGHT way to do it</span>
<span style="color: #0600FF;">private</span> <span style="color: #0600FF;">void</span> buttonNewThread_Click<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">object</span> sender, EventArgs e<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
   workerFunctionDelegate w <span style="color: #008000;">=</span> workerFunction<span style="color: #008000;">;</span>
   w.<span style="color: #0000FF;">BeginInvoke</span><span style="color: #000000;">&#40;</span><span style="color: #FF0000;">15</span>, <span style="color: #0600FF;">null</span>, <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></td></tr></table></div>

<h3>The proper way to update the text box in the UI from the worker thread using the Invoke method of the main form</h3>
<p>The format can definitely get a little confusing, but hopefully you can follow along and mimic it for your application.  Instead of accessing the text box directly from the worker thread, which will cause problems, we instead invoke a method (using a delegate) that accesses the text box.  Note that our populateTextBox function has one parameter, which is a string.  We want to write the current count to the text box using that function, so we have to convert it to a string.  If we were passing multiple variables to the populateTextBox function, the format would still look the same, and we&#8217;d simply separate the variables inside the curly braces by a comma.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #008080; font-style: italic;">//update the text box by using a delegate to call a function on the UI thread that will do the update</span>
<span style="color: #0600FF;">void</span> workerFunction<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">int</span> totalSeconds<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
   <span style="color: #0600FF;">for</span> <span style="color: #000000;">&#40;</span><span style="color: #FF0000;">int</span> count <span style="color: #008000;">=</span> <span style="color: #FF0000;">1</span><span style="color: #008000;">;</span> count <span style="color: #008000;">&lt;=</span> totalSeconds <span style="color: #008000;">;</span> count<span style="color: #008000;">++</span><span style="color: #000000;">&#41;</span>
      <span style="color: #000000;">&#123;</span>
         <span style="color: #0600FF;">this</span>.<span style="color: #0000FF;">Invoke</span><span style="color: #000000;">&#40;</span><span style="color: #008000;">new</span> poplateTextBoxDelegate<span style="color: #000000;">&#40;</span>populateTextBox<span style="color: #000000;">&#41;</span>, <span style="color: #008000;">new</span> <span style="color: #FF0000;">object</span><span style="color: #000000;">&#91;</span><span style="color: #000000;">&#93;</span> <span style="color: #000000;">&#123;</span> count.<span style="color: #0000FF;">ToString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#125;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
         Thread.<span style="color: #0000FF;">Sleep</span><span style="color: #000000;">&#40;</span><span style="color: #FF0000;">1000</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
      <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://dougzuck.com/c-ui-threading-example/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Remote Reboot X &#8211; The WSUS Companion Tool &#8211; Install Windows Updates and Reboot LOTS of Machines Remotely with Real-Time Status Monitoring</title>
		<link>http://dougzuck.com/remote-reboot-the-way-to-reboot-lots-of-computer-simultaneously</link>
		<comments>http://dougzuck.com/remote-reboot-the-way-to-reboot-lots-of-computer-simultaneously#comments</comments>
		<pubDate>Fri, 12 Jun 2009 01:55:19 +0000</pubDate>
		<dc:creator>doug</dc:creator>
				<category><![CDATA[C#.NET]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Remote Reboot]]></category>
		<category><![CDATA[Windows updates]]></category>
		<category><![CDATA[WSUS]]></category>

		<guid isPermaLink="false">http://www.dougzuck.com/?p=387</guid>
		<description><![CDATA[The newest version of Remote Reboot X is now available here!  There is no app that can match the remote reboot capabilities of RemoteRebootX.  It will allow you to install WSUS updates and remotely reboot a very large number of computers simultaneously, while also being able to monitor their statuses. Remote Reboot X]]></description>
			<content:encoded><![CDATA[<p>The newest version of Remote Reboot X is now available <a href="http://dougzuck.com/remoterebootx" target="_self">here</a>!  There is no app that can match the remote reboot capabilities of RemoteRebootX.  It will allow you to install WSUS updates and remotely reboot a very large number of computers simultaneously, while also being able to monitor their statuses.</p>
<p><a href="http://dougzuck.com/remoterebootx" target="_self">Remote Reboot X</a></p>
<p style="text-align: center;"><a href="http://dougzuck.com/wp-content/uploads/2009/10/rrx1.5b.png"><img class="aligncenter size-full wp-image-701" title="rrx1.5b" src="http://dougzuck.com/wp-content/uploads/2009/10/rrx1.5b.png" alt="rrx1.5b" width="550" height="322" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://dougzuck.com/remote-reboot-the-way-to-reboot-lots-of-computer-simultaneously/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
