<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>You had me at "Hello World" : Programming</title><link>http://blogs.msdn.com/helloworld/archive/tags/Programming/default.aspx</link><description>Tags: Programming</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>How to Give Authenticated Users or Everyone Access to Your Share Programmatically</title><link>http://blogs.msdn.com/helloworld/archive/2009/07/13/how-to-give-authenticated-users-or-everyone-access-to-your-share-programmatically.aspx</link><pubDate>Mon, 13 Jul 2009 19:41:40 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9831920</guid><dc:creator>HelloWorld</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/helloworld/comments/9831920.aspx</comments><wfw:commentRss>http://blogs.msdn.com/helloworld/commentrss.aspx?PostID=9831920</wfw:commentRss><description>&lt;p&gt;Another follow-up from my previous article, &lt;a href="http://blogs.msdn.com/helloworld/archive/2008/06/06/programmatically-configuring-permissions-on-a-share-in-c.aspx"&gt;Programmatically Configuring Permissions on a Share&lt;/a&gt;, David B asked a question, how to share a folder to Everyone, instead of to a specific users. This article will answer that question, based on the code on my previous article.&lt;/p&gt;  &lt;p&gt;That is an interesting question, since ‘Everyone’ can be replaced with ‘Authenticated Users’, ‘Network Service’, etc.&lt;/p&gt;  &lt;p&gt;First, if you need only to give Everyone read-only access permission, the easiest thing is to set the DACL property of Win32_SecurityDescriptor to null. This is not equal with an array of null. An array of null will lock everyone out from this share.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: #2b91af"&gt;ManagementObject &lt;/span&gt;secDescriptor = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ManagementClass&lt;/span&gt;(&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ManagementPath&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;Win32_SecurityDescriptor&amp;quot;&lt;/span&gt;), &lt;span style="color: blue"&gt;null&lt;/span&gt;);
secDescriptor[&lt;span style="color: #a31515"&gt;&amp;quot;ControlFlags&amp;quot;&lt;/span&gt;] = 4; &lt;span style="color: green"&gt;//SE_DACL_PRESENT 
&lt;/span&gt;secDescriptor[&lt;span style="color: #a31515"&gt;&amp;quot;DACL&amp;quot;&lt;/span&gt;] = &lt;span style="color: blue"&gt;null&lt;/span&gt;; &lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;If you need to be more explicit, or you need to assign other security principal different access, that method above will not work. As soon as you assign someone access to the share, ‘Everyone’ will lose its read access.&lt;/p&gt;

&lt;p&gt;To assign the permission explicitly, the key is to form the correct Win32_Trustee to represent that special account (Network Service, Everyone, Authenticated Users, etc.). Take a look at &lt;a href="http://msdn.microsoft.com/en-us/library/system.security.principal.genericprincipal.aspx"&gt;System.Security.Principal.WellKnownSidType&lt;/a&gt; enum. It has a number of well known sid that you might be interested with.&lt;/p&gt;

&lt;p&gt;What needs to be done is to assign the SID property of the Win32_Trustee object with the security identifier derived from the well known sid.&lt;/p&gt;

&lt;p&gt;Let assume you have this method:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;private byte&lt;/span&gt;[] GetWellKnwonSid(&lt;span style="color: #2b91af"&gt;WellKnownSidType &lt;/span&gt;SidType)
{
    &lt;span style="color: #2b91af"&gt;SecurityIdentifier &lt;/span&gt;Result = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SecurityIdentifier&lt;/span&gt;(SidType, &lt;span style="color: blue"&gt;null&lt;/span&gt;);
    &lt;span style="color: blue"&gt;byte&lt;/span&gt;[] sidArray = &lt;span style="color: blue"&gt;new byte&lt;/span&gt;[Result.BinaryLength];
    Result.GetBinaryForm(sidArray, 0);

    &lt;span style="color: blue"&gt;return &lt;/span&gt;sidArray;
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Then when Win32_Trustee object is created, assign the SID property as follow:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #2b91af"&gt;ManagementObject &lt;/span&gt;Trustee = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ManagementClass&lt;/span&gt;(&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ManagementPath&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;Win32_Trustee&amp;quot;&lt;/span&gt;), &lt;span style="color: blue"&gt;null&lt;/span&gt;);
Trustee[&lt;span style="color: #a31515"&gt;&amp;quot;SID&amp;quot;&lt;/span&gt;] = GetWellKnwonSid(&lt;span style="color: #2b91af"&gt;WellKnownSidType&lt;/span&gt;.WorldSid); &lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;That code above will create Win32_Trustee for ‘Everyone’. Use this Win32_Trustee to form the Win32_Ace, and you now explicitly assign ‘Everyone’ access to your share.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9831920" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/helloworld/archive/tags/Programming/default.aspx">Programming</category><category domain="http://blogs.msdn.com/helloworld/archive/tags/.Net+Framework/default.aspx">.Net Framework</category><category domain="http://blogs.msdn.com/helloworld/archive/tags/WMI/default.aspx">WMI</category></item><item><title>How to Programmatically Modify the IIS Virtual Directory</title><link>http://blogs.msdn.com/helloworld/archive/2009/05/29/how-to-programmatically-modify-the-iis-virtual-directory.aspx</link><pubDate>Fri, 29 May 2009 19:16:45 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9653837</guid><dc:creator>HelloWorld</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/helloworld/comments/9653837.aspx</comments><wfw:commentRss>http://blogs.msdn.com/helloworld/commentrss.aspx?PostID=9653837</wfw:commentRss><description>&lt;p&gt;If you have more than a dozen web servers in a cluster with identical setting, and you need to update the virtual directory, it is much more convenient to write a simple program to update it. This example shows how to do it. In this case, this snippet will change the physical path of a virtual directory.&lt;/p&gt;  &lt;p&gt;This snippet works on IIS 6 and IIS 7. PowerShell may not be installed in Server 2003, to make this snippet more generic, this snippet is written in C#, otherwise, PowerShell script may be a better option.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;private const string &lt;/span&gt;MetabasePath = &lt;span style="color: #a31515"&gt;&amp;quot;IIS://Localhost/W3SVC/1/Root&amp;quot;&lt;/span&gt;;

&lt;span style="color: green"&gt;//Get the virtual directory of IIS.
&lt;/span&gt;&lt;span style="color: blue"&gt;private static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DirectoryEntry &lt;/span&gt;GetVirtualDirectory(&lt;span style="color: #2b91af"&gt;DirectoryEntry &lt;/span&gt;IISDirectory, &lt;span style="color: blue"&gt;string &lt;/span&gt;vDirName)
{
    &lt;span style="color: blue"&gt;string &lt;/span&gt;ClassName = IISDirectory.SchemaClassName.ToString();

    &lt;span style="color: blue"&gt;if &lt;/span&gt;(!((ClassName.EndsWith(&lt;span style="color: #a31515"&gt;&amp;quot;Server&amp;quot;&lt;/span&gt;)) || (ClassName.EndsWith(&lt;span style="color: #a31515"&gt;&amp;quot;VirtualDir&amp;quot;&lt;/span&gt;))))
    {
        &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Exception&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;String&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;&amp;quot;Virtual Directory can be updated under site or virual directory node. Metabase:{0}, SchemaClassName={1}&amp;quot;&lt;/span&gt;, MetabasePath, ClassName));
    }

    &lt;span style="color: green"&gt;//Iterate through the children, as Find() method is having an issue with IIS 6, if more than one thread is accessing IIS, an AccessViolationException is thrown.
    //The fix is applying the a hot fix http://support.microsoft.com/kb/946517. Either use Find(), or use this method below.
    //Since IIS may not have the hot fix installed, this sample iterates the children.
    &lt;/span&gt;&lt;span style="color: blue"&gt;foreach &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;DirectoryEntry &lt;/span&gt;VirtualDir &lt;span style="color: blue"&gt;in &lt;/span&gt;IISDirectory.Children)
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;String&lt;/span&gt;.Compare(VirtualDir.Name, vDirName, &lt;span style="color: #2b91af"&gt;StringComparison&lt;/span&gt;.OrdinalIgnoreCase) == 0)
            &lt;span style="color: blue"&gt;return &lt;/span&gt;VirtualDir;

    &lt;span style="color: blue"&gt;return null&lt;/span&gt;;
}

&lt;span style="color: green"&gt;//Update the physical path of the site.
&lt;/span&gt;&lt;span style="color: blue"&gt;private static void &lt;/span&gt;UpdatePhysicalPath(&lt;span style="color: blue"&gt;string &lt;/span&gt;virtualDirectoryName, &lt;span style="color: blue"&gt;string &lt;/span&gt;newPath)
{
    &lt;span style="color: blue"&gt;using &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;DirectoryEntry &lt;/span&gt;Site = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DirectoryEntry&lt;/span&gt;(MetabasePath))
    {
        &lt;span style="color: #2b91af"&gt;DirectoryEntry &lt;/span&gt;StatsNet = GetVirtualDirectory(Site, virtualDirectoryName);

        &lt;span style="color: blue"&gt;if &lt;/span&gt;(StatsNet == &lt;span style="color: blue"&gt;null&lt;/span&gt;)
            &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Exception&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;String&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;&amp;quot;Site not found. Metabase={0}, virtualDirectory={1}&amp;quot;&lt;/span&gt;, MetabasePath, virtualDirectoryName));

        StatsNet.Properties[&lt;span style="color: #a31515"&gt;&amp;quot;Path&amp;quot;&lt;/span&gt;][0] = newPath;
        StatsNet.CommitChanges();
    }
}

&lt;span style="color: blue"&gt;static void &lt;/span&gt;Main(&lt;span style="color: blue"&gt;string&lt;/span&gt;[] args)
{
    UpdatePhysicalPath(&lt;span style="color: #a31515"&gt;&amp;quot;MySite&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;@&amp;quot;d:\http\MyNewSite&amp;quot;&lt;/span&gt;);
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;That snippet above shows how to change the path, there are a lot of properties that can be changed, at least this shows the basic idea. 

&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9653837" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/helloworld/archive/tags/Programming/default.aspx">Programming</category><category domain="http://blogs.msdn.com/helloworld/archive/tags/.Net+Framework/default.aspx">.Net Framework</category><category domain="http://blogs.msdn.com/helloworld/archive/tags/How+to/default.aspx">How to</category></item><item><title>C# 3.0 Automatic Property</title><link>http://blogs.msdn.com/helloworld/archive/2009/02/12/c-3-0-automatic-property.aspx</link><pubDate>Fri, 13 Feb 2009 02:30:06 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9416231</guid><dc:creator>HelloWorld</dc:creator><slash:comments>10</slash:comments><comments>http://blogs.msdn.com/helloworld/comments/9416231.aspx</comments><wfw:commentRss>http://blogs.msdn.com/helloworld/commentrss.aspx?PostID=9416231</wfw:commentRss><description>&lt;p&gt;C# introduces a number of syntactic sugar, including Automatic Property &lt;a href="http://msdn.microsoft.com/en-us/library/bb384054.aspx"&gt;link&lt;/a&gt;. A question was asked, why is this useful, what is the advantage of this approach compared to exposing the field as public field?&lt;/p&gt;  &lt;p&gt;The advantage of the automatic property is that while you have a much cleaner code, you still have encapsulation, you can restrict the setter, so only internal classes, or descendant classes can update the property.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;AutomaticPropertyClass
&lt;/span&gt;{
    &lt;span style="color: blue"&gt;public string &lt;/span&gt;PublicProperty { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
    &lt;span style="color: blue"&gt;public int    &lt;/span&gt;ReadOnlyProperty { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;private set&lt;/span&gt;; }
    &lt;span style="color: blue"&gt;public double &lt;/span&gt;InternalProperty { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;internal set&lt;/span&gt;; }
    &lt;span style="color: blue"&gt;public char   &lt;/span&gt;ProtectedProperty { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;protected set&lt;/span&gt;; }
}&lt;/pre&gt;

&lt;p&gt;&lt;font face="Verdana"&gt;That code is much simpler than having to declare private field and then the property, and the developer still can define the accessibility. Yes, this is quite old, but since I was asked that question, might as well blog about it. :)&lt;/font&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9416231" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/helloworld/archive/tags/Programming/default.aspx">Programming</category><category domain="http://blogs.msdn.com/helloworld/archive/tags/.Net+Framework/default.aspx">.Net Framework</category></item><item><title>How to Add Command Line Support with Your .MSI</title><link>http://blogs.msdn.com/helloworld/archive/2009/02/06/how-to-add-command-line-support-with-your-msi.aspx</link><pubDate>Fri, 06 Feb 2009 21:23:59 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9402677</guid><dc:creator>HelloWorld</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/helloworld/comments/9402677.aspx</comments><wfw:commentRss>http://blogs.msdn.com/helloworld/commentrss.aspx?PostID=9402677</wfw:commentRss><description>&lt;p&gt;One of the requirements in building setups was to allow the Operations team to execute the .msi file from the command line. GUI is not for expert! :)&lt;/p&gt;  &lt;p&gt;If you are familiar with Visual Studio setup, each of the UI element has a property, and you pass this property to your custom action, or use it as condition in your setup (whether to install the documentation, help, or whether to install to the gac or not, etc.).&lt;/p&gt;  &lt;p&gt;msiexec.exe allows you to pass some parameters to override those properties. Unfortunately the .msi file that Visual Studio generates always set the default values, default value being the values that the developers set during design time.&lt;/p&gt;  &lt;p&gt;After inspecting the .msi, there are some custom actions that will set the property value to the default. This custom actions are always executed, whether the users sets the property via command line parameter or not. That means, if the user pass some parameters to override the property, the setup will execute the custom action, reassign the property value to the original default value.&lt;/p&gt;  &lt;p&gt;So what needs to be done is to prevent the custom action from executing when the property is overridden by the user. This can be done quite easily with text box dialogs, checkbox dialogs are a little bit more difficult, I will cover it in other post.&lt;/p&gt;  &lt;p&gt;The property has blank value/null in the beginning, if the user overrides the property via command line parameter, this value will not be null. By giving custom actions a condition, to execute only if the property is blank, the value that the user gave via command line will not be overridden.&lt;/p&gt;  &lt;p&gt;You need to set the conditions in two different tables in your .msi file, InstallExecuteSequence and InstallUISequence. One to support GUI mode (interactive) and the other to support quiet/passive mode.&lt;/p&gt;  &lt;p&gt;This is the example on how to do it, repeat the steps for every property that you want to be able to override:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Identify the property that you want to override. From within Visual Studio, writes down the property that you want to be able to override. For example, you set a property &lt;strong&gt;SERVERNAME&lt;/strong&gt;, related to &lt;strong&gt;Edit1Property&lt;/strong&gt; on &lt;strong&gt;Textboxes (A)&lt;/strong&gt;, and the default value is 'DefaultServerName'.      &lt;br /&gt;&lt;a href="http://blogs.msdn.com/blogfiles/helloworld/WindowsLiveWriter/HowtoAddCommandLineSupportwithYour.MSI_80FA/image_6.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/helloworld/WindowsLiveWriter/HowtoAddCommandLineSupportwithYour.MSI_80FA/image_thumb_2.png" width="244" height="85" /&gt;&lt;/a&gt;&amp;#160; &lt;br /&gt;&amp;#160;&lt;/li&gt;    &lt;li&gt;Check the InstallUISequence and InstallExecuteSequence tables in the .msi using Orcas, you should see something like this:     &lt;br /&gt;&lt;a href="http://blogs.msdn.com/blogfiles/helloworld/WindowsLiveWriter/HowtoAddCommandLineSupportwithYour.MSI_80FA/image_4.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/helloworld/WindowsLiveWriter/HowtoAddCommandLineSupportwithYour.MSI_80FA/image_thumb_1.png" width="661" height="62" /&gt;&lt;/a&gt;       &lt;br /&gt;You know this is the action that you want from the Action name, it is CustomTextA, corresponds to the Textboxes (A), and it is the Edit1 control. If you check the CustomAction table, you will see something like this:      &lt;br /&gt;&lt;a href="http://blogs.msdn.com/blogfiles/helloworld/WindowsLiveWriter/HowtoAddCommandLineSupportwithYour.MSI_80FA/image_8.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/helloworld/WindowsLiveWriter/HowtoAddCommandLineSupportwithYour.MSI_80FA/image_thumb_3.png" width="664" height="43" /&gt;&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;To prevent the custom action from executing, add this condition on both &lt;u&gt;InstallUISequence and InstallExecuteSequence tables&lt;/u&gt;, &lt;strong&gt;SERVERNAME = &amp;quot;&amp;quot;&lt;/strong&gt;.      &lt;br /&gt;&lt;a href="http://blogs.msdn.com/blogfiles/helloworld/WindowsLiveWriter/HowtoAddCommandLineSupportwithYour.MSI_80FA/image_10.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/helloworld/WindowsLiveWriter/HowtoAddCommandLineSupportwithYour.MSI_80FA/image_thumb_4.png" width="663" height="56" /&gt;&lt;/a&gt;       &lt;br /&gt;This tells, if the SERVERNAME is blank (the user did not override), execute the custom action to assign the default value. Please pay attention that the condition is for an empty string (two double quotes).&lt;/li&gt;    &lt;li&gt;Save the .msi and close Orcas.&lt;/li&gt;    &lt;li&gt;Execute the .msi using this command:     &lt;br /&gt;msiexec /i [The msi name].msi SERVERNAME=&amp;quot;HELLOWORLDSERVER&amp;quot;&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;After executing those steps, the UI will show HELLOWORLDSERVER in the text box.&lt;/p&gt;  &lt;p&gt;To set this condition automatically as part of your build process, we need to use a script to modify the setup. This can be done by setting the post build event for your project.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Create a .js script. Call it CommandLineSupport.js, repeat the update statement for every property that you want to be able to override.     &lt;br /&gt;&lt;span style="color: green"&gt;//This script adds command-line support for MSI build with Visual Studio 2008.        &lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;msiOpenDatabaseModeTransact = 1;      &lt;br /&gt;      &lt;br /&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(WScript.Arguments.Length != 1)      &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; WScript.StdErr.WriteLine(WScript.ScriptName + &lt;span style="color: #a31515"&gt;&amp;quot; file&amp;quot;&lt;/span&gt;);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; WScript.Quit(1);      &lt;br /&gt;}      &lt;br /&gt;      &lt;br /&gt;WScript.Echo(WScript.Arguments(0));      &lt;br /&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;filespec = WScript.Arguments(0);      &lt;br /&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;installer = WScript.CreateObject(&lt;span style="color: #a31515"&gt;&amp;quot;WindowsInstaller.Installer&amp;quot;&lt;/span&gt;);      &lt;br /&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;database = installer.OpenDatabase(filespec, msiOpenDatabaseModeTransact);      &lt;br /&gt;      &lt;br /&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;sql      &lt;br /&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;view      &lt;br /&gt;      &lt;br /&gt;&lt;span style="color: blue"&gt;try       &lt;br /&gt;&lt;/span&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: green"&gt;//Update InstallUISequence to support command-line parameters in interactive mode.       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;sql = &lt;span style="color: #a31515"&gt;&amp;quot;UPDATE InstallUISequence SET Condition = 'SERVERNAME=\&amp;quot;\&amp;quot;' WHERE Action = 'CustomTextA_SetProperty_EDIT1'&amp;quot;&lt;/span&gt;;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; view = database.OpenView(sql);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; view.Execute();      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; view.Close();      &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: green"&gt;//Update InstallExecuteSequence to support command line in passive or quiet mode.       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;sql = &lt;span style="color: #a31515"&gt;&amp;quot;UPDATE InstallExecuteSequence SET Condition = 'SERVERNAME=\&amp;quot;\&amp;quot;' WHERE Action = 'CustomTextA_SetProperty_EDIT1'&amp;quot;&lt;/span&gt;;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; view = database.OpenView(sql);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; view.Execute();      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; view.Close();      &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; database.Commit();      &lt;br /&gt;}      &lt;br /&gt;&lt;span style="color: blue"&gt;catch&lt;/span&gt;(e)      &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; WScript.StdErr.WriteLine(e);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; WScript.Quit(1);      &lt;br /&gt;}      &lt;br /&gt;&lt;/li&gt;   &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;    &lt;li&gt;Save the CommandLineSupport.js in the same folder with your setup project file, and set PostBuildEvent for the setup project.     &lt;br /&gt;&amp;#160;&lt;a href="http://blogs.msdn.com/blogfiles/helloworld/WindowsLiveWriter/HowtoAddCommandLineSupportwithYour.MSI_80FA/image_16.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/helloworld/WindowsLiveWriter/HowtoAddCommandLineSupportwithYour.MSI_80FA/image_thumb_7.png" width="639" height="41" /&gt;&lt;/a&gt;       &lt;br /&gt;Make sure .msi name matches your .msi file name.&lt;/li&gt;    &lt;li&gt;Build the project. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Standard disclaimer applies, no warranty, use it at your own risk, always test the changes. Wow, this post is longer than what I thought it would be.... &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9402677" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/helloworld/archive/tags/Programming/default.aspx">Programming</category><category domain="http://blogs.msdn.com/helloworld/archive/tags/Setup+Project/default.aspx">Setup Project</category></item><item><title>When Building Multi-Threaded Applications using ThreadPool, Make the Number of Worker Threads Configurable</title><link>http://blogs.msdn.com/helloworld/archive/2008/12/16/when-building-multi-threaded-applications-using-threadpool-make-the-number-of-worker-threads-configurable.aspx</link><pubDate>Tue, 16 Dec 2008 14:14:14 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9224423</guid><dc:creator>HelloWorld</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/helloworld/comments/9224423.aspx</comments><wfw:commentRss>http://blogs.msdn.com/helloworld/commentrss.aspx?PostID=9224423</wfw:commentRss><description>&lt;p&gt;Just a simple thought, when creating a multi-threaded applications, make the number of threads configurable. ThreadPool has this behavior that it will immediately set the minimum worker threads equal to the number of logical processors in your machine, and set the maximum to 250 per logical processor, well documented in msdn (.Net Framework 2.0 SP1).&lt;/p&gt;  &lt;p&gt;ThreadPool will create a new thread every half second, also documented in msdn. This behavior could lead to thread explosions, where there are too much threads fighting for limited resources (memory, lock, disk IO, processor, etc.). Your app may run slower if the thread creation is not managed wisely.&lt;/p&gt;  &lt;p&gt;It is also a good idea to be able to throttle the application to use fewer threads. It is a good idea to be able to limit the number of threads in the system through configuration. Set the max number of threads by calling SetMaxThreads, and if the config value is less than the number of logical processors, do not forget to call SetMinThreads. Be aware that this can also lead to other issue, like thread starvation.&lt;/p&gt;  &lt;p&gt;This is just an idea, if you have been writing multi-threaded applications using ThreadPool, probably you have thought about this already. Keep in mind, your application needs as few thread as possible, but not fewer.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9224423" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/helloworld/archive/tags/Programming/default.aspx">Programming</category><category domain="http://blogs.msdn.com/helloworld/archive/tags/.Net+Framework/default.aspx">.Net Framework</category><category domain="http://blogs.msdn.com/helloworld/archive/tags/Multi+Thread/default.aspx">Multi Thread</category></item><item><title>String.Split has High Cost on Performance</title><link>http://blogs.msdn.com/helloworld/archive/2008/12/15/string-split-has-high-cost-on-performance.aspx</link><pubDate>Tue, 16 Dec 2008 01:59:24 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9224371</guid><dc:creator>HelloWorld</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/helloworld/comments/9224371.aspx</comments><wfw:commentRss>http://blogs.msdn.com/helloworld/commentrss.aspx?PostID=9224371</wfw:commentRss><description>&lt;p&gt;One application had a memory issue, it just consume too much resources. The application performed well, but it is very obvious when we saw the performance counters, something can be done to make it better. Reviewing the code did not reveal something significant, the code already allocated objects that are necessary. The code parses a text file and generate an object based on the content of that text file.&lt;/p&gt;  &lt;p&gt;After running &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=a362781c-3870-43be-8926-862b40aa0cd0&amp;amp;DisplayLang=en"&gt;CLR Profiler&lt;/a&gt;, I noticed that a lot of memory are consumed by int[], but there is no code that generates that kind of object. Digging a little bit deeper, I discovered that one method calls String.Split(). This method is one of the main method, it is being called about 80% of the time.&lt;/p&gt;  &lt;p&gt;String.Split() creates an array of strings, and in the process, it creates a helper array of int. The size of the helper array can be really huge. After the code had been modified to avoid calling String.Split(), the memory consumption was significantly reduced.&lt;/p&gt;  &lt;p&gt;If you need performance in a tight loop, avoid String.Split().&lt;/p&gt;  &lt;p&gt;If you are using Visual Studio 2008, I strongly recommend for you to step through the .Net framework source code using debugger. Check Shawn Burke's &lt;a href="http://blogs.msdn.com/sburke/archive/2008/01/16/configuring-visual-studio-to-debug-net-framework-source-code.aspx"&gt;post&lt;/a&gt; to do that.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9224371" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/helloworld/archive/tags/Programming/default.aspx">Programming</category><category domain="http://blogs.msdn.com/helloworld/archive/tags/.Net+Framework/default.aspx">.Net Framework</category></item><item><title>How to Create Custom Event Log for Windows Service</title><link>http://blogs.msdn.com/helloworld/archive/2008/12/11/creating-an-event-log.aspx</link><pubDate>Thu, 11 Dec 2008 20:52:42 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9197604</guid><dc:creator>HelloWorld</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/helloworld/comments/9197604.aspx</comments><wfw:commentRss>http://blogs.msdn.com/helloworld/commentrss.aspx?PostID=9197604</wfw:commentRss><description>&lt;p&gt;When you created a Windows Service, you usually add a Service Installer to allow this service to be installed using InstallUtil or installing it programmatically like this &lt;a href="http://blogs.msdn.com/helloworld/archive/2008/10/21/how-to-install-windows-service-programmatically.aspx"&gt;post&lt;/a&gt; shows you.&lt;/p&gt;  &lt;p&gt;The service installer will create the Event Log for the service, and by default it is &amp;quot;Application&amp;quot;, and the source is the name of your service.&lt;/p&gt;  &lt;p&gt;The Event Source is most likely to be fine, but the event log may need to be set to something else. Unfortunately, the option is not visible from the installer.&lt;/p&gt;  &lt;p&gt;The Installer object for your windows service, actually hosted several other Installer objects, one of the child Installer is responsible to create the Event Log. You need to find this object and then changed the Log property and it will create the appropriate event log. It is easy to find this object as this object is an instance of EventLogInstaller.&lt;/p&gt;  &lt;p&gt;The code:&lt;/p&gt;  &lt;p&gt;&lt;span style="color: blue"&gt;public partial class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MyServiceInstaller &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;Installer     &lt;br /&gt;&lt;/span&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;private const string&lt;/span&gt;LogName = &lt;span style="color: #a31515"&gt;&amp;quot;My Service Log&amp;quot;&lt;/span&gt;;    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public &lt;/span&gt;MyServiceInstaller()    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; InitializeComponent();    &lt;br /&gt;&lt;span style="color: green"&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: #2b91af"&gt;EventLogInstaller &lt;/span&gt;EventLogInstall = &lt;span style="color: blue"&gt;null&lt;/span&gt;;    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;foreach &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Installer &lt;/span&gt;I &lt;span style="color: blue"&gt;in this&lt;/span&gt;.serviceInstaller.Installers)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; EventLogInstall = I &lt;span style="color: blue"&gt;as &lt;/span&gt;&lt;span style="color: #2b91af"&gt;EventLogInstaller&lt;/span&gt;;    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;if&lt;/span&gt;(EventLogInstall != &lt;span style="color: blue"&gt;null&lt;/span&gt;)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; EventLogInstall.Log = LogName;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; EventLogInstall.UninstallAction = &lt;span style="color: #2b91af"&gt;UninstallAction&lt;/span&gt;.NoAction;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;break&lt;/span&gt;;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;}&lt;/p&gt;  &lt;p&gt;That code above shows how to create a custom Event Log for your service, the code also shows that the custom event log will never be uninstalled, depending on the requirements it can be easily changed.&lt;/p&gt;  &lt;p&gt;If the event source needs to be changed as well, simply change the Source property and you are set.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;One thing to pay attention&lt;/strong&gt;, if you create a custom event log, you install the service programmatically, and your service is running with a restricted account, &lt;u&gt;then you have to modify the code to install the service by adding a code to write one entry to the event log that you just created&lt;/u&gt;.&lt;/p&gt;  &lt;p&gt;After the service installer is executed, the log is 'registered', but not created yet. To create it, one event must be written. If the service runs using a restricted user account, that account may not have enough security permission to write the first log, as the log need to be created.&lt;/p&gt;  &lt;p&gt;When installing the service, the user must run the installer as Administrator, so the installer has all security privilege that it needs. So remember to write one event entry after programmatically installing the service. &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9197604" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/helloworld/archive/tags/Programming/default.aspx">Programming</category><category domain="http://blogs.msdn.com/helloworld/archive/tags/.Net+Framework/default.aspx">.Net Framework</category><category domain="http://blogs.msdn.com/helloworld/archive/tags/How+to/default.aspx">How to</category><category domain="http://blogs.msdn.com/helloworld/archive/tags/Windows+Service/default.aspx">Windows Service</category></item><item><title>How to Get IIS Web Sites Information Programmatically</title><link>http://blogs.msdn.com/helloworld/archive/2008/10/31/how-to-get-iis-web-sites-information-programmatically.aspx</link><pubDate>Fri, 31 Oct 2008 08:03:41 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9025275</guid><dc:creator>HelloWorld</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/helloworld/comments/9025275.aspx</comments><wfw:commentRss>http://blogs.msdn.com/helloworld/commentrss.aspx?PostID=9025275</wfw:commentRss><description>&lt;p&gt;I needed to get the location of IIS log files on my servers, after doing a quick investigation, I am quite amazed on how much information are exposed via managed code.&lt;/p&gt;  &lt;p&gt;This snippet will return the name of the sites and the location of the log files.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;foreach &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;DirectoryEntry &lt;/span&gt;Site &lt;span style="color: blue"&gt;in new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DirectoryEntry&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;IIS://&amp;quot; &lt;/span&gt;+ System.&lt;span style="color: #2b91af"&gt;Environment&lt;/span&gt;.MachineName + &lt;span style="color: #a31515"&gt;&amp;quot;/w3svc&amp;quot;&lt;/span&gt;).Children)
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;String&lt;/span&gt;.Compare(Site.SchemaClassName, &lt;span style="color: #a31515"&gt;&amp;quot;IIsWebServer&amp;quot;&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;StringComparison&lt;/span&gt;.OrdinalIgnoreCase) == 0)
        &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(Site.Properties[&lt;span style="color: #a31515"&gt;&amp;quot;ServerComment&amp;quot;&lt;/span&gt;].Value.ToString() + &lt;span style="color: #a31515"&gt;&amp;quot; == &amp;quot; &lt;/span&gt;+ Site.Properties[&lt;span style="color: #a31515"&gt;&amp;quot;LogFileDirectory&amp;quot;&lt;/span&gt;].Value.ToString());&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;To get more information about what fields and method you can access, please refer to this MSDN doc: &lt;a title="http://msdn.microsoft.com/en-us/library/ms524487.aspx" href="http://msdn.microsoft.com/en-us/library/ms524487.aspx"&gt;http://msdn.microsoft.com/en-us/library/ms524487.aspx&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Just remember, in Vista/Windows Server 2008, you will need to run that code with elevated privilege.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9025275" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/helloworld/archive/tags/Programming/default.aspx">Programming</category><category domain="http://blogs.msdn.com/helloworld/archive/tags/.Net+Framework/default.aspx">.Net Framework</category><category domain="http://blogs.msdn.com/helloworld/archive/tags/Windows/default.aspx">Windows</category></item><item><title>Watch PDC Videos Online</title><link>http://blogs.msdn.com/helloworld/archive/2008/10/30/watch-pdc-videos-online.aspx</link><pubDate>Thu, 30 Oct 2008 23:40:07 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9025239</guid><dc:creator>HelloWorld</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/helloworld/comments/9025239.aspx</comments><wfw:commentRss>http://blogs.msdn.com/helloworld/commentrss.aspx?PostID=9025239</wfw:commentRss><description>&lt;p&gt;PDC is almost over, did you know that you can access the recorded sessions online?&lt;/p&gt;  &lt;p&gt;Go to &lt;a href="http://www.microsoftpdc.com"&gt;http://www.microsoftpdc.com&lt;/a&gt;, and click on Agenda on the top. then click on Sessions tab. Pick the session that you want to watch, scroll down, you should see a Video tab.&lt;/p&gt;  &lt;p&gt;Much shorter shortcut, got to this link &lt;a title="https://sessions.microsoftpdc.com/public/timeline.aspx" href="https://sessions.microsoftpdc.com/public/timeline.aspx"&gt;https://sessions.microsoftpdc.com/public/timeline.aspx&lt;/a&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Today is Friday, 10/30, most likely today video is not available at this moment, but should be available soon.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9025239" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/helloworld/archive/tags/Programming/default.aspx">Programming</category></item><item><title>Advice for New Programmers</title><link>http://blogs.msdn.com/helloworld/archive/2008/08/26/advice-for-new-programmers.aspx</link><pubDate>Tue, 26 Aug 2008 11:47:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8896107</guid><dc:creator>HelloWorld</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/helloworld/comments/8896107.aspx</comments><wfw:commentRss>http://blogs.msdn.com/helloworld/commentrss.aspx?PostID=8896107</wfw:commentRss><description>&lt;p&gt;I was reading an old post that &lt;a href="http://www.removingalldoubt.com/"&gt;Chuck Jazdzewski&lt;/a&gt; wrote. This one is really good, it is not applicable only for new programmers, if you are a seasoned programmer, this article is still a good read. Jump to Chuck’s &lt;a href="http://www.removingalldoubt.com/PermaLink.aspx/a32977e2-cb7d-42ea-9d25-5e539423affd"&gt;fatherly advice for new programmers&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8896107" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/helloworld/archive/tags/Programming/default.aspx">Programming</category></item><item><title>In God We Trust, Everybody Else Must Bring Data</title><link>http://blogs.msdn.com/helloworld/archive/2008/08/25/in-god-we-trust-everybody-else-must-bring-data.aspx</link><pubDate>Mon, 25 Aug 2008 23:25:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8896064</guid><dc:creator>HelloWorld</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/helloworld/comments/8896064.aspx</comments><wfw:commentRss>http://blogs.msdn.com/helloworld/commentrss.aspx?PostID=8896064</wfw:commentRss><description>&lt;p&gt;One day, I was presented with a problem, that the finalizer was not called during application pool recycle. I was busy, so I did not have chance to respond. Later on, I checked the code, it was modified to inherit from CriticalFinalizerObject class, and a comment saying that even though the class is inherited from CriticalFinalizerObject, the finalizer sometimes is not getting called. There was a logic in the finalizer that is often not got executed, the &lt;em&gt;assumption&lt;/em&gt; was, the finalizer sometime was not called.&lt;/p&gt;  &lt;p&gt;After digging the code, I discovered what was going on, above the logic that often not get executed, there was one line of code that close a FileStream object that is also a field of this class.&lt;/p&gt;  &lt;p&gt;Managed code does not guarantee the order of the objects that are being garbage-collected, the finalizer may have accessed the garbage-collected objects. The code below the code that closes the FileStream object did not get executed if the FileStream has been garbage-collected.&lt;/p&gt;  &lt;p&gt;It does not matter whether the class is inherited from CriticalFinalizerObject or not, the exception will give the impression that the finalizer was not called.&lt;/p&gt;  &lt;p&gt;A quick look on ASP.Net Event Log shows ObjectDisposed exception whenever the logic is not called, a simple logging showed that the finalizer was always called. After isolating the issue, the fix is much simpler and guaranteed to work all the time.&lt;/p&gt;  &lt;p&gt;Next time you hear about a problem, ask for data, profiler, repro steps. Just like a Test Manager that I knew said, ‘In God we trust, everybody else must bring data’.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8896064" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/helloworld/archive/tags/Programming/default.aspx">Programming</category><category domain="http://blogs.msdn.com/helloworld/archive/tags/ASP.Net/default.aspx">ASP.Net</category><category domain="http://blogs.msdn.com/helloworld/archive/tags/.Net+Framework/default.aspx">.Net Framework</category></item><item><title>The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error</title><link>http://blogs.msdn.com/helloworld/archive/2008/08/22/the-server-did-not-provide-a-meaningful-reply-this-might-be-caused-by-a-contract-mismatch-a-premature-session-shutdown-or-an-internal-server-error.aspx</link><pubDate>Fri, 22 Aug 2008 17:30:09 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8888966</guid><dc:creator>HelloWorld</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/helloworld/comments/8888966.aspx</comments><wfw:commentRss>http://blogs.msdn.com/helloworld/commentrss.aspx?PostID=8888966</wfw:commentRss><description>&lt;p&gt;I am playing around with WCF, and I got that error message above. Searching did not really help in defining what was going on. And yes, it was working on my previous test environment. :)&lt;/p&gt;  &lt;p&gt;Luckily, I still had one of my test method, which just ping the service and did nothing else. That method works, so at least I know that the problem was not with the service, only with this operation.&lt;/p&gt;  &lt;p&gt;The problematic parameter took a parameter, an array of byte. Out of curiosity, I sent an empty array, lo behold, it worked.&lt;/p&gt;  &lt;p&gt;It turned out that my test data was too big, I used a file to create that array of byte, and it worked great. I lost that small file and randomly picked a file. I did not realize the file was 6 GB in size. After replacing that file with a smaller one, it worked.&lt;/p&gt;  &lt;p&gt;So, if you see that error above and you are passing an array of byte as parameter, probably this will help you to quickly fixed the issue.&lt;/p&gt;  &lt;p&gt;Disclaimer, I do not think this is the only cause for that error.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8888966" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/helloworld/archive/tags/Programming/default.aspx">Programming</category><category domain="http://blogs.msdn.com/helloworld/archive/tags/.Net+Framework/default.aspx">.Net Framework</category><category domain="http://blogs.msdn.com/helloworld/archive/tags/WCF/default.aspx">WCF</category></item><item><title>Replacing ASMX Web Service with WCF Web Service</title><link>http://blogs.msdn.com/helloworld/archive/2008/08/01/replacing-asmx-web-service-with-wcf-web-service.aspx</link><pubDate>Fri, 01 Aug 2008 22:38:10 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8803015</guid><dc:creator>HelloWorld</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/helloworld/comments/8803015.aspx</comments><wfw:commentRss>http://blogs.msdn.com/helloworld/commentrss.aspx?PostID=8803015</wfw:commentRss><description>&lt;p&gt;I found a good article about replacing ASMX web wervice with WCF web service here (&lt;a href="http://weblogs.manas.com.ar/waj/2007/05/31/asmx-to-wcf-migration/"&gt;ASMX to WCF migration&lt;/a&gt;). Very cool, and my client application do not need to be recompiled.&lt;/p&gt;  &lt;p&gt;Just one thing that I notice, I believe on step 3, instead of XmlSerializerAttribute it should be XmlSerializerFormat. Have fun!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8803015" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/helloworld/archive/tags/Programming/default.aspx">Programming</category><category domain="http://blogs.msdn.com/helloworld/archive/tags/ASP.Net/default.aspx">ASP.Net</category><category domain="http://blogs.msdn.com/helloworld/archive/tags/WCF/default.aspx">WCF</category></item><item><title>Boosting Performance with READ_COMMITTED_SNAPSHOT</title><link>http://blogs.msdn.com/helloworld/archive/2008/07/22/boosting-performance-with-read-committed-snapshot.aspx</link><pubDate>Tue, 22 Jul 2008 10:10:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8764191</guid><dc:creator>HelloWorld</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/helloworld/comments/8764191.aspx</comments><wfw:commentRss>http://blogs.msdn.com/helloworld/commentrss.aspx?PostID=8764191</wfw:commentRss><description>&lt;P&gt;I had a problem with one of our database in our testing environment, it performs OK, but we know it can be faster. There are millions of data in that database. Everything are properly indexed and the stored procedure plan is optimum.&lt;/P&gt;
&lt;P&gt;I was not aware about read committed snapshot option when the dba suggested this option. I was reading more information and was convinced that this setting would help performance.&lt;/P&gt;
&lt;P&gt;We set this configuration, the application is now running really fast, processing hundreds of row per second. Our application has a lot of transactions per second, multiple read and multiple write within the same seconds. With this option, readers won’t block writers, and vice versa.&lt;/P&gt;
&lt;P&gt;Take a look at this option, it may give the performance boost that your application needs. Kimberley Tripp has a good article on msdn about this subject. &lt;A title=http://msdn.microsoft.com/en-us/library/ms345124.aspx href="http://msdn.microsoft.com/en-us/library/ms345124.aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms345124.aspx"&gt;http://msdn.microsoft.com/en-us/library/ms345124.aspx&lt;/A&gt;. A long read, but it has good information.&lt;/P&gt;
&lt;P&gt;Of course, you should always measure it, and nothing comes for free, it consumes more space in the temp db. &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8764191" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/helloworld/archive/tags/Programming/default.aspx">Programming</category><category domain="http://blogs.msdn.com/helloworld/archive/tags/Database/default.aspx">Database</category></item><item><title>Editing Share Permission</title><link>http://blogs.msdn.com/helloworld/archive/2008/07/22/editing-share-permission.aspx</link><pubDate>Tue, 22 Jul 2008 04:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8762733</guid><dc:creator>HelloWorld</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/helloworld/comments/8762733.aspx</comments><wfw:commentRss>http://blogs.msdn.com/helloworld/commentrss.aspx?PostID=8762733</wfw:commentRss><description>&lt;P&gt;In my previous post, I have shown you &lt;A href="http://blogs.msdn.com/helloworld/archive/2008/06/06/programmatically-configuring-permissions-on-a-share-in-c.aspx" mce_href="http://blogs.msdn.com/helloworld/archive/2008/06/06/programmatically-configuring-permissions-on-a-share-in-c.aspx"&gt;how to set up permission on a share&lt;/A&gt;. The thing with Win32_Share, when you set the permission, you basically overwrites the existing permission.&lt;/P&gt;
&lt;P&gt;If you want to edit permission on the share (grant a new user access to the share, or revoke an existing user's permission), then you have to get the security descriptor for that share, and modify it, and then call &lt;A href="http://msdn.microsoft.com/en-us/library/aa393598(VS.85).aspx" mce_href="http://msdn.microsoft.com/en-us/library/aa393598(VS.85).aspx"&gt;Win32_Share.SetShareInfo&lt;/A&gt; to set the share permission.&lt;/P&gt;
&lt;P&gt;To get security descriptor of a share, you can use &lt;A href="http://msdn.microsoft.com/en-us/library/aa394188.aspx" mce_href="http://msdn.microsoft.com/en-us/library/aa394188.aspx"&gt;Win32_LogicalShareSecuritySetting&lt;/A&gt; class. Then update the security descriptor and set that security descriptor back to the share.&lt;/P&gt;
&lt;P&gt;When calling ManagementObject.GetSecurityDescriptor, it will return a ManagementBaseObject instance, it has two properties, ReturnValue and Descriptor. ReturnValue is an integer value, that tells you whether the operation is successful or not. Look for the possible value &lt;A href="http://msdn.microsoft.com/en-us/library/aa390773(VS.85).aspx" mce_href="http://msdn.microsoft.com/en-us/library/aa390773(VS.85).aspx"&gt;here&lt;/A&gt;. The Descriptor property is an instance of SecurityDescriptor.&lt;/P&gt;
&lt;P&gt;To summarize (for those who love bullet points):&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Get the Win32_Ace instance for the new user.&lt;/LI&gt;
&lt;LI&gt;Get the current security descriptor.&lt;/LI&gt;
&lt;LI&gt;Get the DACL (Array of Win32_Ace) from the security descriptor.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Add&lt;/STRONG&gt; the Win32_Ace for the new user into the Win32_Ace array.&lt;/LI&gt;
&lt;LI&gt;Reassign the edited DACL back to the security descriptor.&lt;/LI&gt;
&lt;LI&gt;Call Win32_Share.SetShareInfo to set the permission.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;You can delete a particular user, or changing the existing permission, by modifying the DACL or SACL in the Security Descriptor.&lt;/P&gt;
&lt;P&gt;This snippet below is just an example on how to read, modify and assign permission on a share, this code was derived from the example on my previous &lt;A href="http://blogs.msdn.com/helloworld/archive/2008/06/06/programmatically-configuring-permissions-on-a-share-in-c.aspx" mce_href="http://blogs.msdn.com/helloworld/archive/2008/06/06/programmatically-configuring-permissions-on-a-share-in-c.aspx"&gt;post&lt;/A&gt;.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: green"&gt;//Create a new Win32_Ace instance. Please refer to my previous post about creating Win32_Ace.
&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;NTAccount &lt;/SPAN&gt;account = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;NTAccount&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"contoso"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #a31515"&gt;"janedoe"&lt;/SPAN&gt;);
&lt;SPAN style="COLOR: #2b91af"&gt;SecurityIdentifier &lt;/SPAN&gt;sid = (&lt;SPAN style="COLOR: #2b91af"&gt;SecurityIdentifier&lt;/SPAN&gt;)account.Translate(&lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;SecurityIdentifier&lt;/SPAN&gt;));
&lt;SPAN style="COLOR: blue"&gt;byte&lt;/SPAN&gt;[] sidArray = &lt;SPAN style="COLOR: blue"&gt;new byte&lt;/SPAN&gt;[sid.BinaryLength];
sid.GetBinaryForm(sidArray, 0);

&lt;SPAN style="COLOR: #2b91af"&gt;ManagementObject &lt;/SPAN&gt;Trustee = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ManagementClass&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ManagementPath&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"Win32_Trustee"&lt;/SPAN&gt;), &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;);
Trustee[&lt;SPAN style="COLOR: #a31515"&gt;"Domain"&lt;/SPAN&gt;] = &lt;SPAN style="COLOR: #a31515"&gt;"contoso"&lt;/SPAN&gt;;
Trustee[&lt;SPAN style="COLOR: #a31515"&gt;"Name"&lt;/SPAN&gt;]   = &lt;SPAN style="COLOR: #a31515"&gt;"janedoe"&lt;/SPAN&gt;;
Trustee[&lt;SPAN style="COLOR: #a31515"&gt;"SID"&lt;/SPAN&gt;]   = sidArray; 

&lt;SPAN style="COLOR: #2b91af"&gt;ManagementObject &lt;/SPAN&gt;ACE = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ManagementClass&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ManagementPath&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"Win32_Ace"&lt;/SPAN&gt;), &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;); 
ACE[&lt;SPAN style="COLOR: #a31515"&gt;"AccessMask"&lt;/SPAN&gt;] = 2032127; 
ACE[&lt;SPAN style="COLOR: #a31515"&gt;"AceFlags"&lt;/SPAN&gt;]   = 3; 
ACE[&lt;SPAN style="COLOR: #a31515"&gt;"AceType"&lt;/SPAN&gt;]    = 0; 
ACE[&lt;SPAN style="COLOR: #a31515"&gt;"Trustee"&lt;/SPAN&gt;]    = Trustee; 

&lt;SPAN style="COLOR: green"&gt;//After we have the new Win_32Ace, now we need to get the existing Ace instances (DACL).
//Create an instance of Win32_LogicalSecuritySetting, set the path to the server and the share.
&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ManagementObject &lt;/SPAN&gt;Win32LogicalSecuritySetting = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ManagementObject&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;@"\\ContosoServer\root\cimv2:Win32_LogicalShareSecuritySetting.Name='JohnShare'"&lt;/SPAN&gt;);

&lt;SPAN style="COLOR: green"&gt;//Call the GetSecurityDescriptor method. This method returns one out parameter.
&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ManagementBaseObject &lt;/SPAN&gt;Return = Win32LogicalSecuritySetting.InvokeMethod(&lt;SPAN style="COLOR: #a31515"&gt;"GetSecurityDescriptor"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;);
    
&lt;SPAN style="COLOR: green"&gt;//The return value of that call above has two properties, ReturnValue, which you can use
//to read the status of the call (failed, success, etc.), and Descriptor, which is an instance
//of Win32_SecurityDescriptor.
&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Int32 &lt;/SPAN&gt;ReturnValue = &lt;SPAN style="COLOR: #2b91af"&gt;Convert&lt;/SPAN&gt;.ToInt32(Return.Properties[&lt;SPAN style="COLOR: #a31515"&gt;"ReturnValue"&lt;/SPAN&gt;].Value);

&lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(ReturnValue != 0)
    &lt;SPAN style="COLOR: blue"&gt;throw new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Exception&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;String&lt;/SPAN&gt;.Format(&lt;SPAN style="COLOR: #a31515"&gt;"Error when calling GetSecurityDescriptor. Error code : {0}."&lt;/SPAN&gt;, ReturnValue));

&lt;SPAN style="COLOR: green"&gt;//Retrieve the array of DACL from the Security Descriptor.
&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ManagementBaseObject &lt;/SPAN&gt;SecurityDescriptor = Return.Properties[&lt;SPAN style="COLOR: #a31515"&gt;"Descriptor"&lt;/SPAN&gt;].Value &lt;SPAN style="COLOR: blue"&gt;as &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ManagementBaseObject&lt;/SPAN&gt;;
&lt;SPAN style="COLOR: #2b91af"&gt;ManagementBaseObject&lt;/SPAN&gt;[] DACL = SecurityDescriptor[&lt;SPAN style="COLOR: #a31515"&gt;"DACL"&lt;/SPAN&gt;] &lt;SPAN style="COLOR: blue"&gt;as &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ManagementBaseObject&lt;/SPAN&gt;[];

&lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(DACL == &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;)
    DACL = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ManagementBaseObject&lt;/SPAN&gt;[] { ACE };
&lt;SPAN style="COLOR: blue"&gt;else
&lt;/SPAN&gt;{
    &lt;SPAN style="COLOR: #2b91af"&gt;Array&lt;/SPAN&gt;.Resize(&lt;SPAN style="COLOR: blue"&gt;ref &lt;/SPAN&gt;DACL, DACL.Length + 1);
    DACL[DACL.Length - 1] = ACE;
}

&lt;SPAN style="COLOR: green"&gt;//Reassign the new DACL array with the new user Ace back to the Win32_SecurityDescriptor instance, and call the
//SetSecurityDescriptor method.
&lt;/SPAN&gt;SecurityDescriptor[&lt;SPAN style="COLOR: #a31515"&gt;"DACL"&lt;/SPAN&gt;] = DACL;&lt;SPAN style="COLOR: green"&gt;

&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ManagementObject &lt;/SPAN&gt;Share = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ManagementObject&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;@"\\ContosoServer\root\cimv2:Win32_Share.Name='JohnShare'"&lt;/SPAN&gt;);
ReturnValue = &lt;SPAN style="COLOR: #2b91af"&gt;Convert&lt;/SPAN&gt;.ToInt32(Share.InvokeMethod(&lt;SPAN style="COLOR: #a31515"&gt;"SetShareInfo"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;new object&lt;/SPAN&gt;[] {&lt;SPAN style="COLOR: #2b91af"&gt;Int32&lt;/SPAN&gt;.MaxValue, &lt;SPAN style="COLOR: #a31515"&gt;"This is John's share"&lt;/SPAN&gt;, SecurityDescriptor})); 

&lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(ReturnValue != 0)
    &lt;SPAN style="COLOR: blue"&gt;throw new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Exception&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;String&lt;/SPAN&gt;.Format(&lt;SPAN style="COLOR: #a31515"&gt;"Error when calling GetSecurityDescriptor. Error code : {0}."&lt;/SPAN&gt;, ReturnValue));&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8762733" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/helloworld/archive/tags/Programming/default.aspx">Programming</category><category domain="http://blogs.msdn.com/helloworld/archive/tags/.Net+Framework/default.aspx">.Net Framework</category><category domain="http://blogs.msdn.com/helloworld/archive/tags/WMI/default.aspx">WMI</category></item></channel></rss>