<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8006259279050971331</id><updated>2011-08-02T19:31:01.904-07:00</updated><category term='Visual Studio'/><category term='WCF'/><category term='debugging'/><category term='forms recognition'/><category term='SQL Server'/><category term='Katrina'/><category term='noob'/><category term='VB.NET'/><category term='Mississippi'/><category term='Tips'/><category term='web services'/><category term='OCR'/><category term='.NET'/><category term='VS2008'/><category term='database'/><title type='text'>DotNet Stumbling</title><subtitle type='html'>Musings and snippets from my adventures in programming.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://dotnetstumbling.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8006259279050971331/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://dotnetstumbling.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Morrison's Garage</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>13</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8006259279050971331.post-2450454617404395496</id><published>2009-10-16T11:37:00.000-07:00</published><updated>2009-10-16T11:58:36.776-07:00</updated><title type='text'>Easy MD5 password hashing in C#</title><content type='html'>There are a ton of members in System.Security.Cryptography and some of them will compute a hash for you based on whatever algorithm you wish. A common one to use for hashing passwords is MD5.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You'll want to store your passwords in your database as hashed values - don't store the passwords in plain text. &lt;br /&gt;An easy class to use in .NET to hash any string is not in &lt;i&gt;System.Security.Cryptography&lt;/i&gt; but rather in &lt;i&gt;System.Web.Security.FormsAuthentication&lt;/i&gt;.&lt;br /&gt;Use it like so:&lt;br /&gt;&lt;code&gt;&lt;br /&gt; string hashedPassword = FormsAuthentication.HashPasswordForStoringInConfigFile(myPassword, "MD5");&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Then, just compare this hashed value with the one you've stored in your database. If they match, the user is authenticated.&lt;br /&gt;&lt;br /&gt;Now, before you go asking me how to decrypt the hash and get the original password, you can't. It's a one-way operation. You only hash the password for the purposes of comparing it to an already hashed value. &lt;br /&gt;&lt;br /&gt;Hashed passwords are still vulnerable to so-called 'dictionary' attacks, whereby the hacker simply computes the hash for every word in the dictionary and tries all of them. If your password is a simple english word, this sort of brute force attack will work. To thwart this, add a 'salt' value to your password before you hash it and store it in your user database. In other words, instead of storing the hash of 'password' you would store the hash of 'blahpassword' where 'blah' is the salt.  This works against dictionary attacks because 'blahpassword' is not a real word.  This is even more effective if your salt is a garble, like '4^e#t'. Add the same salt to the user's inputted password before you hash it and compare it to your stored hash.&lt;br /&gt;&lt;br /&gt;You can use this same function to hash passwords as you save them in the database. If you manually create the passwords for the users, you could make a simple application to take the password and return to you the hashed value. If you automatically create the password, create a function to accept the password and return the hash string before you save it to the database.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8006259279050971331-2450454617404395496?l=dotnetstumbling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetstumbling.blogspot.com/feeds/2450454617404395496/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8006259279050971331&amp;postID=2450454617404395496' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8006259279050971331/posts/default/2450454617404395496'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8006259279050971331/posts/default/2450454617404395496'/><link rel='alternate' type='text/html' href='http://dotnetstumbling.blogspot.com/2009/10/easy-md5-password-hashing-in-c.html' title='Easy MD5 password hashing in C#'/><author><name>Morrison's Garage</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8006259279050971331.post-6693020529527220568</id><published>2009-01-27T11:16:00.000-08:00</published><updated>2009-01-27T13:42:08.160-08:00</updated><title type='text'>Make my structure sortable</title><content type='html'>In a previous entry I showed how to create a structure. The object I described with my structure is an area of an image on the screen that I'm calling a "Zone". Today I've discovered the need to sort my Zones by the "ordinal" property, but the Zone objects don't inherently know how to be sorted. The solution is to implement an interface, namely IComparable.  Any object that implements IComparable can be sorted on anything you want. It's quite easy. First inside the structure, right after the structure declaration and before any variable declaration, you add &lt;code&gt;Implements IComparable&lt;/code&gt;. As soon as you add this line, Visual Studio will tell you that need to include a CompareTo method, which goes something like this:&lt;BR&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Public Function CompareTo(ByVal obj As Object) As Integer _&lt;br /&gt;   Implements System.IComparable.CompareTo&lt;br /&gt;            If Not TypeOf obj Is Zone Then&lt;br /&gt;                Throw New Exception("Object is not a Zone")&lt;br /&gt;            End If&lt;br /&gt;            Dim Compare As Zone = CType(obj, Zone)&lt;br /&gt;            Dim result As Integer = Me.Ordinal.CompareTo(Compare.Ordinal)&lt;br /&gt;&lt;br /&gt;            If result = 0 Then&lt;br /&gt;                result = Me.Ordinal.CompareTo(Compare.Ordinal)&lt;br /&gt;            End If&lt;br /&gt;            Return result&lt;br /&gt;        End Function&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Now I can call the .sort method on any collection of Zone objects.&lt;br /&gt;&lt;br /&gt;The code for my CompareTo method came from &lt;A href = "http://www.knowdotnet.com/articles/sortarraylistofobjects.html"&gt;http://www.knowdotnet.com/articles/sortarraylistofobjects.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8006259279050971331-6693020529527220568?l=dotnetstumbling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetstumbling.blogspot.com/feeds/6693020529527220568/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8006259279050971331&amp;postID=6693020529527220568' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8006259279050971331/posts/default/6693020529527220568'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8006259279050971331/posts/default/6693020529527220568'/><link rel='alternate' type='text/html' href='http://dotnetstumbling.blogspot.com/2009/01/make-my-structure-sortable.html' title='Make my structure sortable'/><author><name>Morrison's Garage</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8006259279050971331.post-9172576657997060422</id><published>2009-01-20T11:53:00.001-08:00</published><updated>2009-01-20T12:12:34.474-08:00</updated><title type='text'>Convert a Word 2007 docx to PDF with VB.NET</title><content type='html'>I recently had to write a program to convert about 500,000 text files into PDFs. My initial thought was to buy a third-party .NET component to produce the PDFs, but I found that Word 2007 has a free plug-in to enable output to PDF or XPS format, and that those functions can be automated with VB.NET. My strategy is to convert each text file into a .docx file so I can apply some style and format and then do the PDF conversion. Here's the basic method:&lt;br&gt;&lt;br /&gt;Your machine must have Word 2007 and the free PDF/XPS converter plugin installed. Download the plug-in &lt;A href = "http://www.microsoft.com/downloads/details.aspx?FamilyId=F1FC413C-6D89-4F15-991B-63B07BA5F2E5&amp;displaylang=en" target = "_blank"&gt;HERE&lt;/a&gt;. You need not have Adobe Acrobat installed on the machine.&lt;br&gt;&lt;br /&gt;&lt;br /&gt;In your VB project, set a reference to the .NET assembly Microsoft.Office.Interop.Word. Put an IMPORTS Microsoft.Office.Interop.Word at the top of your code file to save you some typing. &lt;br&gt;&lt;br /&gt;&lt;br /&gt;Assuming you already have a Word 2007 doc on disk, all you have to do is invoke ExportAsFixedFormat on the Word Document object that you create. Here's a bit of sample code:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Dim wordApp As ApplicationClass = New ApplicationClass()&lt;br /&gt;    Dim wordDoc As Document = Nothing&lt;br /&gt;    Dim strSource As String = "C:\Temp\Test.docx"&lt;br /&gt;&lt;br /&gt; Try&lt;br /&gt;            wordDoc = wordApp.Documents.Open(strSource)&lt;br /&gt;            wordDoc .ExportAsFixedFormat("C:\Temp\Test.pdf", _&lt;br /&gt;WdExportFormat.wdExportFormatPDF, False, _&lt;br /&gt;WdExportOptimizeFor.wdExportOptimizeForOnScreen, _ &lt;br /&gt;WdExportRange.wdExportAllDocument)&lt;br /&gt;&lt;br /&gt;        Catch ex As Exception&lt;br /&gt;            MessageBox.Show(ex.Message)&lt;br /&gt;        End Try&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;It works like a charm! It takes a few seconds for each file so for my 500,000 files I am going to have to crank up several machines to get it all done in a reasonable amount of time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8006259279050971331-9172576657997060422?l=dotnetstumbling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetstumbling.blogspot.com/feeds/9172576657997060422/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8006259279050971331&amp;postID=9172576657997060422' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8006259279050971331/posts/default/9172576657997060422'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8006259279050971331/posts/default/9172576657997060422'/><link rel='alternate' type='text/html' href='http://dotnetstumbling.blogspot.com/2009/01/convert-word-2007-docx-to-pdf-with.html' title='Convert a Word 2007 docx to PDF with VB.NET'/><author><name>Morrison's Garage</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8006259279050971331.post-5352870125075840100</id><published>2009-01-15T10:50:00.000-08:00</published><updated>2009-01-15T11:48:58.411-08:00</updated><title type='text'>Structures 101</title><content type='html'>&lt;P&gt;Also referred to as User-defined Types, or &lt;i&gt;structs&lt;/i&gt;, structures are similar to classes. Structures contain composites of other types and are a useful way to represent more complex objects, but simpler than a full-blown class. Sometimes structures are referred to as lightweight classes. The primary difference, though, is that a class defines a reference type and a structure defines a value type. Being value types, structures are stored on the stack instead of the heap. Structures cannot be inherited, and only inherit from System.Valuetype. Classes can inherit from any other reference type. A much better discussion of the differences can be found &lt;A href = "http://msdn.microsoft.com/en-us/library/2hkbth2a.aspx" target = "_blank"&gt;HERE&lt;/a&gt; so I won't go any further on that lest I get in over my head.&lt;BR&gt;&lt;br /&gt;The classic example from the .NET Foundations book is the &lt;i&gt;Point&lt;/i&gt; structure. It represents a point on the screen and is composed of just two integers, X and Y.&lt;br /&gt;&lt;BR&gt;Ok, so here's a little more elaborate example that I used recently. I needed to define a Zone, or an area of an image. Just a rectangle won't cut it because I need my zone to have a couple other attributes. First I need it to have an ordinal value, so that I can process them in a given order and be able to change that order. Second, I need the zone to have a string value I'm calling "type" (not to be confused with a .NET Type), and it may or may not also have a value in a "FigureText" property. Finally, I want to define the default "ToString" method to give me the FigureText, and just for the heck of it I'll define a "ToRectangle" method as well that will give me a rectangle object.  Whatever, the details aren't important, but you'll see how to declare one of these beasties.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt; Structure Zone&lt;br /&gt;        Dim _rect As Rectangle&lt;br /&gt;        Dim _ordinal As Integer&lt;br /&gt;        Dim _type As String&lt;br /&gt;        Dim _figureText As String&lt;br /&gt;&lt;br /&gt;        Public Sub New(ByVal rect As Rectangle, ByVal ordinal As Integer, ByVal type As String, Optional ByVal figureText As String = Nothing)&lt;br /&gt;            _rect = rect : _ordinal = ordinal : _type = type : _figureText = figureText&lt;br /&gt;        End Sub&lt;br /&gt;&lt;br /&gt;        Public Property Ordinal() As Integer&lt;br /&gt;            Get&lt;br /&gt;                Return _ordinal&lt;br /&gt;            End Get&lt;br /&gt;            Set(ByVal value As Integer)&lt;br /&gt;                _ordinal = value&lt;br /&gt;            End Set&lt;br /&gt;        End Property&lt;br /&gt;        &lt;br /&gt;Public Property Rect() As Rectangle&lt;br /&gt;            Get&lt;br /&gt;                Return _rect&lt;br /&gt;            End Get&lt;br /&gt;            Set(ByVal value As Rectangle)&lt;br /&gt;                _rect = value&lt;br /&gt;            End Set&lt;br /&gt;        End Property&lt;br /&gt;        &lt;br /&gt;Public Property Type() As String&lt;br /&gt;            Get&lt;br /&gt;                Return _type&lt;br /&gt;            End Get&lt;br /&gt;            Set(ByVal value As String)&lt;br /&gt;                _type = value&lt;br /&gt;            End Set&lt;br /&gt;        End Property&lt;br /&gt;        &lt;br /&gt;Public Property FigureText() As String&lt;br /&gt;            Get&lt;br /&gt;                Return _figureText&lt;br /&gt;            End Get&lt;br /&gt;            Set(ByVal value As String)&lt;br /&gt;                _figureText = value&lt;br /&gt;            End Set&lt;br /&gt;        End Property&lt;br /&gt;        &lt;br /&gt;Public Overrides Function ToString() As String&lt;br /&gt;            Return FigureText.ToString&lt;br /&gt;        End Function&lt;br /&gt;        &lt;br /&gt;Public Function ToInteger() As Integer&lt;br /&gt;            Return Ordinal&lt;br /&gt;        End Function&lt;br /&gt;        &lt;br /&gt;Public Function ToRectangle() As Rectangle&lt;br /&gt;            Return Rect&lt;br /&gt;        End Function&lt;br /&gt;    End Structure&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;BR&gt;Note that you have to overridde the ToString method, but you don't have to override ToInteger or ToRectangle because those methods are not defined by default.&lt;br /&gt;&lt;BR&gt;Later in my code when I need to make a Zone, I simply declare it like an object and pass in some values for the constructor, which is defined in the struct in Public Sub New&lt;BR&gt;&lt;br /&gt;&lt;code&gt;Dim myZone As New Zone(myRectangle, myOrdinal, myType, myFigureText)&lt;/code&gt;&lt;br /&gt;&lt;BR&gt;I could have used a class and it would work exactly the same but I'm going to be defining hundreds of these beasties and I think the structure will be more efficient.&lt;br&gt;&lt;br /&gt;As always, be careful with the line breaks in my sample code as the blog doesn't format things just right.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8006259279050971331-5352870125075840100?l=dotnetstumbling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetstumbling.blogspot.com/feeds/5352870125075840100/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8006259279050971331&amp;postID=5352870125075840100' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8006259279050971331/posts/default/5352870125075840100'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8006259279050971331/posts/default/5352870125075840100'/><link rel='alternate' type='text/html' href='http://dotnetstumbling.blogspot.com/2009/01/structures-101.html' title='Structures 101'/><author><name>Morrison's Garage</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8006259279050971331.post-8839227096943675239</id><published>2008-11-13T05:57:00.001-08:00</published><updated>2008-11-13T06:08:17.321-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='VS2008'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><category scheme='http://www.blogger.com/atom/ns#' term='debugging'/><title type='text'>Fix for annoying VS2008 hanging problem</title><content type='html'>&lt;P&gt;I've been experiencing this problem for a few months now and finally went searching for a solution. Here's the issue - when debugging an application in VS2008 on a machine that is NOT connected to the internet, after closing your application VS hangs for 5-10 seconds and randomly minimizes and maximizes itself, and then often get stuck as "always on top". It's maddening I tell you.  Anyway, I found &lt;a href="http://social.msdn.microsoft.com/forums/en-US/vsdebug/thread/e9c5da47-a194-4051-a3d5-28b404263b3f#page:2"&gt;this thread on the msdn forums&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;To save you some reading, here's the solution.&lt;br /&gt;Open up your hosts file in windows\system32\drivers\etc\ and add an entry like this:&lt;BR&gt;&lt;br /&gt;&lt;code&gt;127.0.0.1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;crl.microsoft.com&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Hope it works for you. It worked like a charm for me.&lt;/p&gt;&lt;br /&gt;&lt;P&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8006259279050971331-8839227096943675239?l=dotnetstumbling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetstumbling.blogspot.com/feeds/8839227096943675239/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8006259279050971331&amp;postID=8839227096943675239' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8006259279050971331/posts/default/8839227096943675239'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8006259279050971331/posts/default/8839227096943675239'/><link rel='alternate' type='text/html' href='http://dotnetstumbling.blogspot.com/2008/11/fix-for-annoying-vs2008-hanging-problem.html' title='Fix for annoying VS2008 hanging problem'/><author><name>Morrison's Garage</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8006259279050971331.post-4385278512943057843</id><published>2008-10-12T17:26:00.000-07:00</published><updated>2008-10-12T17:32:53.534-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tips'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><title type='text'>My top 11 SQL Server tips</title><content type='html'>Ok, this is not really .NET but should be useful if you have any involvement with developing database apps.  I can't take credit for all of these. I picked most of them up at the Tampa Code Camp event last year.  Here goes:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;1. Avoid nested views - a view that references another view in its definition.  This can have big implications for performance because the SQL under the covers gets very ugly. &lt;br /&gt;&lt;li&gt;2. Avoid "select *" - aside from most likely returning more data than you really need, it's also slower as it makes the optimizer to more work. &lt;br /&gt;&lt;li&gt;3. Use output parameters - rather than return a dataset with one column, or just a few columns, and one row, use output parameters.  Less overhead.  For one single value, you can use a scalar function as well, but output params allow you to return more than one value &lt;br /&gt;&lt;li&gt;4.  Pick the right data type.  Mainly to avoid storing and transmitting more data than you need.  Avoid Unicode datatypes (nvarchar, nchar, etc.) unless you need them because they take up twice as much space.  Also use a smalldatetime unless you need the additional precision of the datetime.  Smalldatetime is 4 bytes vs 8 bytes for datetime.  Every byte counts, especially when you start talking about very large datasets with billions or trillions of rows. &lt;br /&gt;&lt;li&gt;5. Avoid loops.  If you HAVE to use a loop, a while loop is better than a cursor, but if you can find a way to do the job without any loop at all, that is the best option.   &lt;br /&gt;&lt;li&gt;6. Avoid dynamic SQL.  This is a security thing, too, but from a performance standpoint parameterized SQL is optimized better by the engine.  Take two examples - "select * from person where first_name = 'Lucy'" and "select * from person where first_name = @first_name".  The first one is less optimizable by the SQL engine.  It will get cached but is not reusable, so when the next query comes through as "select * from person where first_name = 'Bill'" it is seen as a different query and the optimizer has to make a new execution plan and put another query in the cache.  The parameterized version will be reused for @first_name = 'Bill'" and the engine does not put another copy in the cache or construct a new execution plan.  In the worst case, you can end up with many thousands of similar yet slightly different queries in the cache and it can really eat up system resources. &lt;br /&gt;&lt;li&gt;7. Avoid "NOT IN". This is a really useful construct, but you're far better off with using an outer join.  With NOT IN, the engine has to do a compare on every record in the second table.  Also NOT EXISTS is also a lot better. &lt;br /&gt;&lt;li&gt;8. In SQL Server 2005, if you use GUID's as indentities, use NewSequentialID.  This generates the GUID in sequential order and thus it makes a suitable clustered index.  Personally, I don't recommend you use GUID's for identities unless you have a specific business reason for doing so.  I like the good old int, although it does have it's drawbacks (for instance, someone can easily guess other identities in your table. &lt;br /&gt;&lt;li&gt;9.  Use table variables rather than temp tables.  &lt;br /&gt;&lt;li&gt;10. Learn to use the profiler, and learn to evaluate execution plans in Server Management Studio. &lt;br /&gt;&lt;li&gt;11.  Use indexes wisely.&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Hope these help!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8006259279050971331-4385278512943057843?l=dotnetstumbling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetstumbling.blogspot.com/feeds/4385278512943057843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8006259279050971331&amp;postID=4385278512943057843' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8006259279050971331/posts/default/4385278512943057843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8006259279050971331/posts/default/4385278512943057843'/><link rel='alternate' type='text/html' href='http://dotnetstumbling.blogspot.com/2008/10/my-top-11-sql-server-tips.html' title='My top 11 SQL Server tips'/><author><name>Morrison's Garage</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8006259279050971331.post-4991857868291821589</id><published>2008-09-17T11:52:00.000-07:00</published><updated>2008-09-17T11:57:07.462-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='VB.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='forms recognition'/><category scheme='http://www.blogger.com/atom/ns#' term='OCR'/><title type='text'>Forms Recognition and Zonal OCR</title><content type='html'>So I've been working hard on a project here at OTHS, to create an application to do automated forms recognition and zonal OCR. I wish I were smart enough to do all this on my own, but I'm using the SDK from &lt;A href = "http://www.pegasusimaging.com" target = "_blank"&gt;Pegasus Imaging&lt;/a&gt;. It's a very powerful suite of components and very easy to work with thanks to all the sample code they provide.  I plan to post more about it in this space in the future, but for right now I just wanted to post about what I'm working on. It's pretty cool stuff.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8006259279050971331-4991857868291821589?l=dotnetstumbling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetstumbling.blogspot.com/feeds/4991857868291821589/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8006259279050971331&amp;postID=4991857868291821589' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8006259279050971331/posts/default/4991857868291821589'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8006259279050971331/posts/default/4991857868291821589'/><link rel='alternate' type='text/html' href='http://dotnetstumbling.blogspot.com/2008/09/forms-recognition-and-zonal-ocr.html' title='Forms Recognition and Zonal OCR'/><author><name>Morrison's Garage</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8006259279050971331.post-6524843307795073542</id><published>2008-08-20T11:07:00.000-07:00</published><updated>2008-08-20T11:19:28.160-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mississippi'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><category scheme='http://www.blogger.com/atom/ns#' term='Katrina'/><title type='text'>Visual Studio Tips book</title><content type='html'>Sara Ford at Microsoft just wrote a book about Tips for Visual Studio 2008 and she's donating all of her author royalties to benefit her hometown of Waveland, Mississippi, which was virtually destroyed by hurricane Katrina in 2005.  I'm from the Mississippi Coast as well so her cause hits close to home for me.  &lt;a href="http://blogs.msdn.com/saraford/archive/2008/08/11/microsoft-visual-studio-tips-helps-katrina-survivors-rebuild-lives.aspx"&gt;Read about it here&lt;/a&gt; and buy a copy of the book.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8006259279050971331-6524843307795073542?l=dotnetstumbling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetstumbling.blogspot.com/feeds/6524843307795073542/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8006259279050971331&amp;postID=6524843307795073542' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8006259279050971331/posts/default/6524843307795073542'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8006259279050971331/posts/default/6524843307795073542'/><link rel='alternate' type='text/html' href='http://dotnetstumbling.blogspot.com/2008/08/visual-studio-tips-book.html' title='Visual Studio Tips book'/><author><name>Morrison's Garage</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8006259279050971331.post-2307146364090105648</id><published>2008-07-28T11:47:00.001-07:00</published><updated>2008-07-28T12:22:05.159-07:00</updated><title type='text'>Find a file in a directory tree.</title><content type='html'>Here&amp;#39;s a little function that will take a filename and look at a&lt;br&gt;folder and its subfolders and return the full path to the file if it&lt;br&gt;exists there.&lt;br /&gt;&lt;P&gt;&lt;code&gt;Private Function FindFileOnDisk(ByVal fileName as String, ByVal&lt;br&gt;targetFolder as String) As String&lt;p&gt;        Dim dirInfo As New DirectoryInfo(targetFolder)&lt;br&gt;        Dim FileExists As Boolean = False&lt;br&gt;        Dim fsiFolder As FileSystemInfo&lt;br&gt;        Dim FullFileName As String = String.Empty&lt;p&gt;        For Each fsiFolder In dirInfo.GetDirectories&lt;br&gt;            FullFileName = fsiFolder.FullName &amp;amp; &amp;quot;\&amp;quot; &amp;amp; fileName&lt;br&gt;            Dim f As New FileInfo(FullFileName)&lt;br&gt;            If f.Exists Then&lt;br&gt;                FileExists = True&lt;br&gt;                Exit For&lt;br&gt;            End If&lt;br&gt;        Next&lt;p&gt;        If FileExists Then&lt;br&gt;            Return FullFileName&lt;br&gt;        Else&lt;br&gt;            Return String.Empty&lt;br&gt;        End If&lt;p&gt;    End Function&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Actually, I think this will look only in subfolders. If the file is in&lt;br&gt;targetFolder it won&amp;#39;t see it because the for..each loop is using&lt;br&gt;GetDirectories. If you use GetFileSystemInfos you&amp;#39;ll loop through both&lt;br&gt;subfolders and files and you&amp;#39;ll have to to adjust accordingly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8006259279050971331-2307146364090105648?l=dotnetstumbling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetstumbling.blogspot.com/feeds/2307146364090105648/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8006259279050971331&amp;postID=2307146364090105648' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8006259279050971331/posts/default/2307146364090105648'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8006259279050971331/posts/default/2307146364090105648'/><link rel='alternate' type='text/html' href='http://dotnetstumbling.blogspot.com/2008/07/find-file-in-directory-tree.html' title='Find a file in a directory tree.'/><author><name>Morrison's Garage</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8006259279050971331.post-3431262683531746906</id><published>2008-07-25T11:28:00.000-07:00</published><updated>2008-09-17T12:02:43.030-07:00</updated><title type='text'>Open a multiframe TIFF file and display it in a Picturebox</title><content type='html'>Just what the title says...&lt;br /&gt;Assume a form with a button named cmdOpen&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Imports System&lt;br /&gt;Imports System.IO&lt;br /&gt;Imports System.Drawing&lt;br /&gt;Imports System.Drawing.Drawing2D&lt;br /&gt;Imports System.Drawing.Imaging&lt;br /&gt;Imports System.Collections&lt;br /&gt;Imports System.ComponentModel&lt;br /&gt;Imports System.Windows.Forms&lt;br /&gt;Imports System.Data&lt;br /&gt;&lt;br /&gt;Private Sub cmdOpen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdOpen.Click&lt;br /&gt;        &lt;br /&gt;        Try&lt;br /&gt;&lt;br /&gt;            Dim dlg As New OpenFileDialog&lt;br /&gt;            Dim fs As FileStream&lt;br /&gt;            Dim objImage As Image&lt;br /&gt;&lt;br /&gt;            dlg.Filter = "Image files|*.bmp;*.jpg;*.gif;*.tif;*.png"&lt;br /&gt;&lt;br /&gt;            If dlg.ShowDialog() = DialogResult.OK Then&lt;br /&gt;&lt;br /&gt;                fs = File.Open(dlg.FileName, FileMode.Open, FileAccess.Read)&lt;br /&gt;                objImage = Image.FromStream(fs)&lt;br /&gt;&lt;br /&gt;                If objImage.GetFrameCount(FrameDimension.Page) &gt; 1 Then&lt;br /&gt;&lt;br /&gt;                    Dim i As Integer&lt;br /&gt;                    For i = 0 To (objImage.GetFrameCount(FrameDimension.Page)) - 1&lt;br /&gt;&lt;br /&gt;                        objImage.SelectActiveFrame(FrameDimension.Page, i)&lt;br /&gt;                        Dim temp As New Bitmap(objImage.Width, objImage.Height)&lt;br /&gt;                        DisplayImage(temp)&lt;br /&gt;&lt;br /&gt;                    Next i&lt;br /&gt;                Else&lt;br /&gt;                    DisplayImage(objImage)&lt;br /&gt;                End If&lt;br /&gt;                                &lt;br /&gt;            End If&lt;br /&gt;        Catch ex As FileLoadException&lt;br /&gt;            MsgBox("There was an error loading the file. " &amp; ex.Message.ToString)&lt;br /&gt;        Catch ex As FileNotFoundException&lt;br /&gt;            MsgBox("The file wasa not found." &amp; ex.Message.ToString)&lt;br /&gt;        End Try&lt;br /&gt;    End Sub&lt;br /&gt;&lt;br /&gt;    Private Sub DisplayImage(ByVal img As Image, Optional ByVal pos As Integer = 1)&lt;br /&gt;&lt;br /&gt;        objImage.SelectActiveFrame(FrameDimension.Page, pos - 1)&lt;br /&gt;        pbImage.Image = objImage&lt;br /&gt;&lt;br /&gt;    End Sub&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Essentially here I'm looping through the frames in the image and putting them into the PictureBox control. Then you use SelectActiveFrame to set the visible frame. I've also got a couple buttons in my app that allow you to flip back and forth through the frames.&lt;br /&gt;&lt;br /&gt;EDIT - 9.17.2008: After working with some large TIFF files I've found that if you have more than a few frames in your image it very quickly uses up all of your available memory.  I've gotten around it by using a third-party image component but if I ever get a chance I want to come up with my own way to manage it. I presume it would involve loading only the current frame you are displaying into memory, as you switch between frames.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8006259279050971331-3431262683531746906?l=dotnetstumbling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetstumbling.blogspot.com/feeds/3431262683531746906/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8006259279050971331&amp;postID=3431262683531746906' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8006259279050971331/posts/default/3431262683531746906'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8006259279050971331/posts/default/3431262683531746906'/><link rel='alternate' type='text/html' href='http://dotnetstumbling.blogspot.com/2008/07/open-multiframe-tiff-file-and-display.html' title='Open a multiframe TIFF file and display it in a Picturebox'/><author><name>Morrison's Garage</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8006259279050971331.post-5643818631998061743</id><published>2008-07-24T13:17:00.000-07:00</published><updated>2008-07-24T13:25:41.364-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='noob'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='web services'/><category scheme='http://www.blogger.com/atom/ns#' term='WCF'/><title type='text'>Saying goodbye to ASP.NET web services</title><content type='html'>I've been creating and using ASP.NET web services for a good long time now and when I'm comfortable with something, I'm not overly quick to jump ship and learn the next new thing (remember web classes?). Well, I've finally come to grips with WCF and the need to start moving in that direction with my new development. I first saw WCF services back in 2005 or so at VSLive in Orlando, and it looked quite simple and powerful, but I never had the time to step back and really learn it. So, I'm still a WCF n00b.&lt;br /&gt;It IS pretty simple, though, and I found a great video for WCF n00bs at Microsoft's MSDN Channel9 site.&lt;br /&gt;&lt;a href="http://channel9.msdn.com/posts/rojacobs/endpointtv-The-Total-Noobs-Guide-to-WCF-Lesson-1-My-First-WCF-Service/"&gt;Here it is.&lt;/a&gt;&lt;br /&gt;&lt;P&gt;So, going forward I'm going to put all my services in WCF.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8006259279050971331-5643818631998061743?l=dotnetstumbling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetstumbling.blogspot.com/feeds/5643818631998061743/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8006259279050971331&amp;postID=5643818631998061743' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8006259279050971331/posts/default/5643818631998061743'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8006259279050971331/posts/default/5643818631998061743'/><link rel='alternate' type='text/html' href='http://dotnetstumbling.blogspot.com/2008/07/saying-goodbye-to-aspnet-web-services.html' title='Saying goodbye to ASP.NET web services'/><author><name>Morrison's Garage</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8006259279050971331.post-1793508953177921669</id><published>2008-07-21T13:07:00.001-07:00</published><updated>2008-07-21T13:22:15.172-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='VB.NET'/><title type='text'>How to write to a text file in VB.NET</title><content type='html'>This is really super simple and I don't want to insult anyone's intelligence, but just to start things off, here's how you write to a text file. I had to google this once myself.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt; Private Sub WriteLogFile()&lt;br /&gt;        Dim MyFileStream As FileStream&lt;br /&gt;        Dim MyStreamWriter As StreamWriter&lt;br /&gt;        Dim LogString as string  &lt;br /&gt;        Dim FileLocation as string = "C:\test\log.txt"&lt;br /&gt;&lt;br /&gt;'create your string you want to log here using StringBuilder or whatever&lt;br /&gt;&lt;br /&gt;'now write it to a file&lt;br /&gt;  Try&lt;br /&gt;            MyFileStream = New FileStream(FileLocation , FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite, 8)&lt;br /&gt;            MyStreamWriter = New StreamWriter(MyFileStream)&lt;br /&gt;            MyStreamWriter .BaseStream.Seek(0, SeekOrigin.End)  'append to the end of the file&lt;br /&gt;            MyStreamWriter .WriteLine(LogString)&lt;br /&gt;            MyStreamWriter .Close()&lt;br /&gt;&lt;br /&gt;        Catch ex As ApplicationException&lt;br /&gt;            'do something&lt;br /&gt;        End Try&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    End Sub&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Watch those line breaks. Posting in this blog sort of messed up the formatting.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8006259279050971331-1793508953177921669?l=dotnetstumbling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetstumbling.blogspot.com/feeds/1793508953177921669/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8006259279050971331&amp;postID=1793508953177921669' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8006259279050971331/posts/default/1793508953177921669'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8006259279050971331/posts/default/1793508953177921669'/><link rel='alternate' type='text/html' href='http://dotnetstumbling.blogspot.com/2008/07/how-to-write-to-text-file-in-vbnet.html' title='How to write to a text file in VB.NET'/><author><name>Morrison's Garage</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8006259279050971331.post-3986719911502807128</id><published>2008-07-21T12:52:00.000-07:00</published><updated>2008-07-21T12:56:01.295-07:00</updated><title type='text'>First Post</title><content type='html'>Yes, as you can see from the title, this is the first post in this blog. The purpose of this blog is simply to be a conduit through which I can share things with the .NET community when I accidentally learn something, or figure out how to do something that I think others may benefit from.  I am by no means a guru, and those of you who are will probably find things in my code that you disagree with. I will endeavor, however, to post code that I know works and hopefully isn't rife with errors and bad practices. &lt;br /&gt;&lt;br /&gt;More on the way soon!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8006259279050971331-3986719911502807128?l=dotnetstumbling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetstumbling.blogspot.com/feeds/3986719911502807128/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8006259279050971331&amp;postID=3986719911502807128' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8006259279050971331/posts/default/3986719911502807128'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8006259279050971331/posts/default/3986719911502807128'/><link rel='alternate' type='text/html' href='http://dotnetstumbling.blogspot.com/2008/07/first-post.html' title='First Post'/><author><name>Morrison's Garage</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
