<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://weblogs.asp.net/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Miscellaneous Debris</title><subtitle type="html">Avner Kashtan&amp;#39;s Frustrations and Exultations</subtitle><id>http://weblogs.asp.net/avnerk/atom.aspx</id><link rel="alternate" type="text/html" href="http://weblogs.asp.net/avnerk/default.aspx" /><link rel="self" type="application/atom+xml" href="http://weblogs.asp.net/avnerk/atom.aspx" /><generator uri="http://communityserver.org" version="3.0.20510.895">Community Server</generator><updated>2007-08-28T19:08:50Z</updated><entry><title>Upgrading all projects to .NET 3.5</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/avnerk/archive/2008/05/25/upgrading-all-projects-to-net-3-5.aspx" /><id>http://weblogs.asp.net/avnerk/archive/2008/05/25/upgrading-all-projects-to-net-3-5.aspx</id><published>2008-05-25T08:56:14Z</published><updated>2008-05-25T08:56:14Z</updated><content type="html">&lt;p&gt;A simple macro to change the Target Framework for a project from .NET 2.0 to .NET 3.5, hacked together in a few minutes. This will fail for C++/CLI projects, and possibly VB.NET projects (haven't checked). Works fine for regular C# projects, as well as web projects:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;div&gt;   &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;For&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Each&lt;/span&gt; proj &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Project &lt;span style="color: #0000ff"&gt;In&lt;/span&gt; DTE.Solution.Projects
   &lt;span style="color: #0000ff"&gt;Try&lt;/span&gt;
       proj.Properties.Item(&lt;span style="color: #006080"&gt;&amp;quot;TargetFramework&amp;quot;&lt;/span&gt;).Value = 196613
       Debug.Print(&lt;span style="color: #006080"&gt;&amp;quot;Upgraded {0} to 3.5&amp;quot;&lt;/span&gt;, proj.Name)
   &lt;span style="color: #0000ff"&gt;Catch&lt;/span&gt; ex &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Exception
       Debug.Print(&lt;span style="color: #006080"&gt;&amp;quot;Failed to upgrade {0} to 3.5&amp;quot;&lt;/span&gt;, proj.Name)
   &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Try&lt;/span&gt;

&lt;span style="color: #0000ff"&gt;Next&lt;/span&gt; proj&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Why 196613, you ask? Well, when I see such a number my first instinct is to feed it into calc.exe and switch it to hexadecimal. And I was right: 196613 in decimal converts to 0x00030005 - You can see the framework version hiding in there. Major version in the high word, minor in the low word. The previous TargetFramework number was 131072 - 0x00020000, or 2.0.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;(Nitpickers might point out that I could simply set it to &amp;amp;30005 rather than messing with the obscure decimal number. They would be correct - but I got to this number through the debugger, so that's how it will stay)&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6219753" width="1" height="1"&gt;</content><author><name>Avner Kashtan</name><uri>http://weblogs.asp.net/members/Avner-Kashtan.aspx</uri></author><category term=".NET" scheme="http://weblogs.asp.net/avnerk/archive/tags/.NET/default.aspx" /><category term="CodeSnippets" scheme="http://weblogs.asp.net/avnerk/archive/tags/CodeSnippets/default.aspx" /><category term="Visual Studio" scheme="http://weblogs.asp.net/avnerk/archive/tags/Visual+Studio/default.aspx" /><category term="C#" scheme="http://weblogs.asp.net/avnerk/archive/tags/C_2300_/default.aspx" /><category term="C++/CLI" scheme="http://weblogs.asp.net/avnerk/archive/tags/C_2B002B002F00_CLI/default.aspx" /></entry><entry><title>Sneaking past the SharePoint Usage Log</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/avnerk/archive/2008/04/16/sneaking-past-the-sharepoint-usage-log.aspx" /><id>http://weblogs.asp.net/avnerk/archive/2008/04/16/sneaking-past-the-sharepoint-usage-log.aspx</id><published>2008-04-16T15:13:16Z</published><updated>2008-04-16T15:13:16Z</updated><content type="html">&lt;p&gt;I'm writing a piece of code that regularly polls a MOSS server and checks several files. This can happen quite a few times a day, and this totally skews my Usage Reports for my sites. &lt;/p&gt;  &lt;p&gt;Does anyone know of a way to tell MOSS to ignore calls made by a specific user, a specific IP (my code runs on a dedicated server), a specific UserAgent or whatever?&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6103478" width="1" height="1"&gt;</content><author><name>Avner Kashtan</name><uri>http://weblogs.asp.net/members/Avner-Kashtan.aspx</uri></author><category term="SharePoint" scheme="http://weblogs.asp.net/avnerk/archive/tags/SharePoint/default.aspx" /></entry><entry><title>Any signs of life for the SharePoint Extensions for Visual Studio?</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/avnerk/archive/2008/01/23/any-signs-of-life-for-the-sharepoint-extensions-for-visual-studio.aspx" /><id>http://weblogs.asp.net/avnerk/archive/2008/01/23/any-signs-of-life-for-the-sharepoint-extensions-for-visual-studio.aspx</id><published>2008-01-23T19:57:31Z</published><updated>2008-01-23T19:57:31Z</updated><content type="html">&lt;p&gt;Has anything been released - or, in fact, talked about - since August's release of the &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=3e1dcccd-1cca-433a-bb4d-97b96bf7ab63&amp;amp;displaylang=en"&gt;v1.1 CTP&lt;/a&gt;?&lt;/p&gt;  &lt;p&gt;Haven't done any web-part development in a while and wanted to get back in the game. I last used the v1.0 extensions, and was surprised that nothing much has changed in that field except for the CTP release, and even that can't be downloaded - I just get a broken link.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=5640711" width="1" height="1"&gt;</content><author><name>Avner Kashtan</name><uri>http://weblogs.asp.net/members/Avner-Kashtan.aspx</uri></author><category term=".NET" scheme="http://weblogs.asp.net/avnerk/archive/tags/.NET/default.aspx" /><category term="SharePoint" scheme="http://weblogs.asp.net/avnerk/archive/tags/SharePoint/default.aspx" /></entry><entry><title>Seeking advice - strong names and config files</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/avnerk/archive/2007/12/20/seeking-advice-strong-names-and-config-files.aspx" /><id>http://weblogs.asp.net/avnerk/archive/2007/12/20/seeking-advice-strong-names-and-config-files.aspx</id><published>2007-12-20T11:48:49Z</published><updated>2007-12-20T11:48:49Z</updated><content type="html">&lt;p&gt;I'll use my blog for a bit of fishing for advice and guidance on an issue that's been bugging me.&lt;/p&gt; &lt;p&gt;We've been moving towards using strong names on all of our assemblies. The benefits are obvious, and it's a must before we deploy to clients out in the wild.&lt;/p&gt; &lt;p&gt;The problem is that we have several different processes running, each with its own app.config or web.config file. These config files contain references to custom configuration sections, whether they're application configuration, Enterprise Library extensions or whatnot. Seeing as my DLLs are signed, I have to use the fully qualified assembly name in all my references. This means that in a nightly build scenario where my version number is bumped continuously, I have to change 5-6 references in 5-6 configuration files with every build. &lt;/p&gt; &lt;p&gt;Doing this kind of string manipulation on a large scale scares me, since it can break, or we miss something. I've tried using &amp;lt;assemblyBinding&amp;gt; and &amp;lt;bindingRedirect&amp;gt; directives, but they require a specific version to point to as well.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;I'm sure I'm not the first person to encounter this problem. What are the solutions that you use to bypass this? Scripts as part of the automated installation? Moving all configuration sections to a separate assembly whose version is static? What's the least painful way to manage this?&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=5477771" width="1" height="1"&gt;</content><author><name>Avner Kashtan</name><uri>http://weblogs.asp.net/members/Avner-Kashtan.aspx</uri></author><category term=".NET" scheme="http://weblogs.asp.net/avnerk/archive/tags/.NET/default.aspx" /><category term="General Software Development" scheme="http://weblogs.asp.net/avnerk/archive/tags/General+Software+Development/default.aspx" /></entry><entry><title>System.Diagnostics.EventLogEntry and the non-equal Equals.</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/avnerk/archive/2007/11/25/system-diagnostics-eventlogentry-and-the-non-equal-equals.aspx" /><id>http://weblogs.asp.net/avnerk/archive/2007/11/25/system-diagnostics-eventlogentry-and-the-non-equal-equals.aspx</id><published>2007-11-25T18:12:21Z</published><updated>2007-11-25T18:12:21Z</updated><content type="html">&lt;p&gt;Just a quick heads-up in case you're stumped with this problem, or just passing by:&lt;/p&gt; &lt;p&gt;The System.Diagnostics.EventLogEntry class implements the Equals method to check if two entries are identical, even if they're not the same instance. However, contrary to best practices, it does NOT overload the operator==, so these two bits of code will behave differently:&lt;/p&gt; &lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;EventLog myEventLog = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; EventLog(&lt;span style="color: #006080"&gt;"Application"&lt;/span&gt;);
EventLogEntry entry1 = myEventLog.Entries[0];
EventLogEntry entry2 = myEventLog.Entries[0];

&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; correct = entry1.Equals(entry2);
&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; incorrect = entry1 == entry2;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After running this code, &lt;em&gt;correct &lt;/em&gt;will be true while &lt;em&gt;incorrect &lt;/em&gt;will be false.&lt;/p&gt;
&lt;p&gt;Good to know, if you're reading event logs in your code.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=5336119" width="1" height="1"&gt;</content><author><name>Avner Kashtan</name><uri>http://weblogs.asp.net/members/Avner-Kashtan.aspx</uri></author><category term=".NET" scheme="http://weblogs.asp.net/avnerk/archive/tags/.NET/default.aspx" /><category term="CodeSnippets" scheme="http://weblogs.asp.net/avnerk/archive/tags/CodeSnippets/default.aspx" /><category term="C#" scheme="http://weblogs.asp.net/avnerk/archive/tags/C_2300_/default.aspx" /></entry><entry><title>Displaying live log file contents</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/avnerk/archive/2007/11/21/displaying-live-log-file-contents.aspx" /><id>http://weblogs.asp.net/avnerk/archive/2007/11/21/displaying-live-log-file-contents.aspx</id><published>2007-11-21T14:12:54Z</published><updated>2007-11-21T14:12:54Z</updated><content type="html">&lt;p&gt;I'm writing some benchmarking code, which involves a Console application calling a COM+ hosted process and measuring performance. I want to constantly display results on my active console, but since some of my code is running out-of-process, I can't really write directly to the console from all parts of the system. Not to mention the fact that I want it logged to a file as well.&lt;/p&gt; &lt;p&gt;So I cobbled together a quick Log class that does two things - it writes to a shared log file, keeping no locks so several processes can access it (I do serialize access to the WriteLine method itself, though). I don't mind the overhead of opening/closing the file every time, since this isn't production code.&lt;/p&gt; &lt;p&gt;The second method is the interesting one - it monitors the log file and returns every new line that is appended to it. If no lines are available, it will block until one is reached. The fun part was using the &lt;font face="Courier New"&gt;yield return&lt;/font&gt; keyword, which I've been looking for an excuse to use for quiet a while now.&lt;/p&gt; &lt;p&gt;Note that there are many places this code can go wrong or should be improved. There is no way to stop it running, only when the application is stopped. I bring this as the basic idea, and it can be cleaned up and improved later:&lt;/p&gt; &lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt; &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; IEnumerable&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt; ReadNextLineOrBlock()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt;         {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;             &lt;span style="color: #008000"&gt;// Open the file without locking it.&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (FileStream logFile = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; FileStream(Filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (StreamReader reader = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; StreamReader(logFile))&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;             {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;                 &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;                 {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;                     &lt;span style="color: #008000"&gt;// Read the next line.&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt;                     &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; line = reader.ReadLine();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt;                     &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.IsNullOrEmpty(line))&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt;                     {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  13:&lt;/span&gt;                         &lt;span style="color: #0000ff"&gt;yield&lt;/span&gt; &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; line;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  14:&lt;/span&gt;                     }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  15:&lt;/span&gt;                     &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  16:&lt;/span&gt;                     {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  17:&lt;/span&gt;                         Thread.Sleep(100);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  18:&lt;/span&gt;                     }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  19:&lt;/span&gt;                 }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  20:&lt;/span&gt;             }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  21:&lt;/span&gt;         }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This method can now be called from a worker thread:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; StartListenerThread()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt;         {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;             Thread t = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Thread(&lt;span style="color: #0000ff"&gt;delegate&lt;/span&gt;()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;             {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;                 &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;                 {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;                     &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; line &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; Log.ReadNextLineOrBlock())&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;                     {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;                         &lt;span style="color: #008000"&gt;// I added some formatting, too.&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt;                         &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (line.Contains(&lt;span style="color: #006080"&gt;"Total"&lt;/span&gt;))&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt;                             Console.ForegroundColor = ConsoleColor.Green;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt;                         &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  13:&lt;/span&gt;                         Console.WriteLine(line);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  14:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  15:&lt;/span&gt;                         Console.ForegroundColor = ConsoleColor.White;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  16:&lt;/span&gt;                     }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  17:&lt;/span&gt;                 }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  18:&lt;/span&gt;             });&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  19:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  20:&lt;/span&gt;             t.Start();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  21:&lt;/span&gt;         }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=5305166" width="1" height="1"&gt;</content><author><name>Avner Kashtan</name><uri>http://weblogs.asp.net/members/Avner-Kashtan.aspx</uri></author><category term=".NET" scheme="http://weblogs.asp.net/avnerk/archive/tags/.NET/default.aspx" /><category term="CodeSnippets" scheme="http://weblogs.asp.net/avnerk/archive/tags/CodeSnippets/default.aspx" /><category term="C#" scheme="http://weblogs.asp.net/avnerk/archive/tags/C_2300_/default.aspx" /></entry><entry><title>Another minor C#/C++ difference - adding existing files</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/avnerk/archive/2007/10/28/another-minor-c-c-difference-adding-existing-files.aspx" /><id>http://weblogs.asp.net/avnerk/archive/2007/10/28/another-minor-c-c-difference-adding-existing-files.aspx</id><published>2007-10-28T14:35:24Z</published><updated>2007-10-28T14:35:24Z</updated><content type="html">&lt;p&gt;Another minor detail that bit me for a few minutes today. I'm posting this so I'll see it and remember, and possibly lodge it in other people's consciousness.&lt;/p&gt; &lt;p&gt;Using Visual Studio 2005, adding an existing .cs file to a C# project will cause a copy of that file to be created in the project directory. If I want to link to the original file, I need to explicitly choose Add As Link from the dropdown on the Add button. &lt;/p&gt; &lt;p&gt;C++ projects, however, have the opposite behavior. Adding an existing item in a different folder will add a link to the original file in the original location. To create a copy, manually copy it to the project dir.&lt;/p&gt; &lt;p&gt;That is all.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=4801261" width="1" height="1"&gt;</content><author><name>Avner Kashtan</name><uri>http://weblogs.asp.net/members/Avner-Kashtan.aspx</uri></author><category term="Visual Studio" scheme="http://weblogs.asp.net/avnerk/archive/tags/Visual+Studio/default.aspx" /><category term="C#" scheme="http://weblogs.asp.net/avnerk/archive/tags/C_2300_/default.aspx" /><category term="C++/CLI" scheme="http://weblogs.asp.net/avnerk/archive/tags/C_2B002B002F00_CLI/default.aspx" /></entry><entry><title>Another Sharepoint Web Services rant : untyped data vs. incompletely typed data</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/avnerk/archive/2007/09/06/another-sharepoint-web-services-rant-untyped-data-vs-incompletely-typed-data.aspx" /><id>http://weblogs.asp.net/avnerk/archive/2007/09/06/another-sharepoint-web-services-rant-untyped-data-vs-incompletely-typed-data.aspx</id><published>2007-09-06T13:18:37Z</published><updated>2007-09-06T13:18:37Z</updated><content type="html">&lt;p&gt;Working with the Web Services in WSSv2 and v3 is an exercise in sheer frustration. I've written before about serious and &lt;a href="http://weblogs.asp.net/avnerk/archive/2007/07/02/no-per-item-permissions-in-wssv3-s-web-services.aspx"&gt;glaring&lt;/a&gt; &lt;a href="http://weblogs.asp.net/avnerk/archive/2007/07/18/some-more-glaring-omissions-in-the-sharepoint-2007-sdk-and-web-services.aspx"&gt;omissions&lt;/a&gt; in the Web Services API that Sharepoint exposes, but it's not only the things missing, it's the lack of consistency in the APIs that ARE implemented that's annoying.&lt;/p&gt; &lt;p&gt;For most of the APIs, the return value for most methods is an XmlNode, usually documented pretty well in the SDK. It means we have to fiddle with XML to extract data, but it's not so bad. For instance the Lists WS's GetListCollection()&amp;nbsp;returns a known, documented, schema-linked XML containing many properties for a given list.&lt;/p&gt; &lt;p&gt;For some reason, though, the SiteData web service chooses to return data as typed objects instead - oddly named objects at that (_sList, _sWebWithMetadata[], and so forth), but only for SOME data. The GetSite() method, for instance, will return a typed metadata object for the site metadata and the list of Lists, but a completely untyped STRING containing XML data for the list of groups and group members. &lt;/p&gt; &lt;p&gt;Futhermore, these XML snippets are sometimes undocumented, and you have to try it out to see what you get. What you get, sometimes, is the same XML you would get from a call to a different web service, but stripped of the namespace - so even though it's the same structure, you can't use the same code to parse both.&lt;/p&gt; &lt;p&gt;Similarly the GetListCollection() method in SiteData. It returns a typed array of _sList objects which map to the XML that's returned from the ListsWS method, only for some reason, some oft the XML attributes are NOT mapped, and are inaccessible. So if I want to see whether a list is Hidden or not, I am unable to use the typed objects and have to resort to the loose XML manipulation. &lt;/p&gt; &lt;p&gt;Seriously, these rants are adding up. Does anyone know who's in charge of the web services for Sharepoint and why they're so badly designed? No consistency, missing functionality, bad documentation - what's going on here? This isn't v1, either, but very little seems to have changed since the original documentation for WSS v2 in 2003.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=3766279" width="1" height="1"&gt;</content><author><name>Avner Kashtan</name><uri>http://weblogs.asp.net/members/Avner-Kashtan.aspx</uri></author></entry><entry><title>Return of the GC Hole: Another one from the C++/CLI trenches</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/avnerk/archive/2007/09/06/return-of-the-gc-hole-another-one-from-the-c-cli-trenches.aspx" /><id>http://weblogs.asp.net/avnerk/archive/2007/09/06/return-of-the-gc-hole-another-one-from-the-c-cli-trenches.aspx</id><published>2007-09-06T11:09:18Z</published><updated>2007-09-06T11:09:18Z</updated><content type="html">&lt;p&gt;A few days ago I wrote of a &lt;a href="http://weblogs.asp.net/avnerk/archive/2007/08/28/a-c-coder-in-a-c-cli-world-part-1.aspx"&gt;GC hole&lt;/a&gt; I accidently created in my C++/CLI code (with thanks to commenter &lt;a href="http://weblogs.asp.net/avnerk/archive/2007/08/28/a-c-coder-in-a-c-cli-world-part-1.aspx#3645664"&gt;Nish&lt;/a&gt; for the name of the phenomenon). I had the following&amp;nbsp;code snippet set inside a private function:&lt;/p&gt; &lt;p&gt;&lt;font face="courier new"&gt;&amp;nbsp;&amp;nbsp; pin_ptr&amp;lt;Byte&amp;gt; pinnedBuffer = &amp;amp;data[0];&lt;br&gt;&amp;nbsp;&amp;nbsp; char* buffer = (char*)pinnedBuffer;&lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;p&gt;Because the pin_ptr went out of scope when the function ended, I had a pointer to a memory location that was quickly moved by the GC, and got me a whole buffer full of garbage. To avoid that, I moved those two lines of code to my main method and pinned it throughout that method.  &lt;p&gt;I thought that was the end of that, but today I noticed that I was still getting garbage occasionally in my buffer. This stumped me for a bit - it seemed like the pin_ptr wasn't doing its job&amp;nbsp;- until I noticed how my C++ code looked: &lt;p&gt;&lt;font face="courier new"&gt;public void DoStuff (array&amp;lt;Byte&amp;gt;^ data)&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="courier new"&gt;char* buffer;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="courier new"&gt;if (data.Length &amp;gt; 0)&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;pin_ptr&amp;lt;Byte&amp;gt; pinnedBuffer = &amp;amp;data[0];&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;buffer = (char*)pinnedBuffer;&lt;br&gt;}&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;// Now do stuff&lt;/font&gt;&lt;/p&gt; &lt;p&gt;For C++ programmers this is probably obvious. For me and other C# devs, not so much.&amp;nbsp;C++'s scoping rules say that when the &lt;em&gt;if&lt;/em&gt; block terminates, the pin_ptr&amp;lt;Byte&amp;gt; goes out of scope immediately. This causes the pinned memory to be released, and allows the GC to move my array. Meanwhile my unmanaged code goes over the &lt;em&gt;buffer &lt;/em&gt;and reads data. If I'm lucky, the GC won't start until I'm finished and all is well. If the GC IS active, I can either get garbage data (whatever is now pointed to by &lt;em&gt;buffer&lt;/em&gt;) or, even worse, an access violation if I now point to protected memory. &lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=3765107" width="1" height="1"&gt;</content><author><name>Avner Kashtan</name><uri>http://weblogs.asp.net/members/Avner-Kashtan.aspx</uri></author></entry><entry><title>Windows Services, services.msc and the "This Service is marked for deletion" error.</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/avnerk/archive/2007/09/05/windows-services-services-msc-and-the-quot-this-service-is-marked-for-deletion-quot-error.aspx" /><id>http://weblogs.asp.net/avnerk/archive/2007/09/05/windows-services-services-msc-and-the-quot-this-service-is-marked-for-deletion-quot-error.aspx</id><published>2007-09-05T09:14:54Z</published><updated>2007-09-05T09:14:54Z</updated><content type="html">&lt;p&gt;In my current project, we have a windows service that we are developing and debugging, which involves a lot of installing/uninstalling the service. One common problem when uninstalling a service is that while the uninstallation is successful, you still see the service listed in the Services console(services.msc). If you try to start it, stop it or uninstall it again (using installutil.exe or &lt;em&gt;sc delete&lt;/em&gt;) you get an uninformative "This service has been marked for deletion".&lt;/p&gt; &lt;p&gt;The &lt;a href="http://support.microsoft.com/kb/823942"&gt;KB article&lt;/a&gt;&amp;nbsp;about this problem suggests you restart the computer, which is pretty much overkill. Sure, it'll work, but you'll never find out what caused it in the first place. Turns out it's a pretty simple affair: just make sure you close the Services console,&amp;nbsp;which apparently holds a handle of some sort to it.&amp;nbsp;You don't have to do it &lt;em&gt;before&lt;/em&gt; you uninstall. The minute you close the console, all services marked for deletion will be deleted, and all will be well. &lt;/p&gt; &lt;p&gt;When doing it on a server, it's important to make sure you've closed all Services consoles on all active sessions. I've seen this error happen when no console was open, and it was fixed by running Task Manager and killing all instances of mmc.exe. I could have logged on to the other sessions and closed it gracefully, but I was lazy. Did the trick.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=3746342" width="1" height="1"&gt;</content><author><name>Avner Kashtan</name><uri>http://weblogs.asp.net/members/Avner-Kashtan.aspx</uri></author><category term="General Software Development" scheme="http://weblogs.asp.net/avnerk/archive/tags/General+Software+Development/default.aspx" /><category term="Installer" scheme="http://weblogs.asp.net/avnerk/archive/tags/Installer/default.aspx" /></entry><entry><title>Dynamically creating a Sharepoint Web-Service proxy instance</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/avnerk/archive/2007/09/03/dynamically-creating-a-sharepoint-web-service-proxy-instance.aspx" /><id>http://weblogs.asp.net/avnerk/archive/2007/09/03/dynamically-creating-a-sharepoint-web-service-proxy-instance.aspx</id><published>2007-09-03T16:55:35Z</published><updated>2007-09-03T16:55:35Z</updated><content type="html">&lt;p&gt;In my current code, I find myself accessing many Sharepoint web services. In one run of code I can access 5-6 different web services on dozens of different sites, not necessarily even on the same server. Given that I find myself writing a lot of boilerplate code looking like this:&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;using (SiteData siteDataWS = new SiteData())&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp; siteDataWS.Credentials = CredentialsCache.DefaultNetworkCredentials;&lt;br&gt;&amp;nbsp;&amp;nbsp; siteDataWS.Url = currentSite.ToString() + "/_vti_bin/SiteData.asmx";&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; // Do something with the WS.&lt;br&gt;}&lt;/font&gt;&lt;/p&gt; &lt;p&gt;Seeing as this is quite wearisome, I've decided to go an genericize it. Given also that the name of the ASMX file for all Sharepoint services is the same as the name of the class to be instantiated, it gets even shorter:&lt;/p&gt; &lt;p&gt;&lt;font face="courier new"&gt;1: &amp;nbsp;public static WSType CreateWebService&amp;lt;WSType&amp;gt; (Uri siteUrl) where WSType : SoapHttpClientProtocol, new()&lt;br&gt;&lt;font face="courier new"&gt;2: &lt;/font&gt;{&lt;br&gt;&lt;font face="courier new"&gt;3: &lt;/font&gt;&amp;nbsp;&amp;nbsp; WSType webService = new WSType();&lt;br&gt;&lt;font face="courier new"&gt;4: &lt;/font&gt;&amp;nbsp;&amp;nbsp; webService.Credentials = CredentialCache.DefaultNetworkCredentials; &lt;/font&gt; &lt;p&gt;&lt;font face="courier new"&gt;&lt;font face="courier new"&gt;5: &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;string webServiceName = typeof(WSType).Name;&lt;br&gt;&lt;font face="courier new"&gt;6: &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;webService.Url = string.Format("{0}/_vti_bin/{1}.asmx", siteUrl, webServiceName); &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="courier new"&gt;&lt;font face="courier new"&gt;7: &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;return webService;&lt;br&gt;&lt;font face="courier new"&gt;8: &lt;/font&gt;}&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="tre"&gt;Line 1: Define a generic method that receives the type of Web Service and returns an instance of it. Note the generic constraints - the type must be a Web Service Proxy (SoapHttpClientProtocol) and must be instantiable. The last one is necessary for line 3 to compile.&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="tre"&gt;Line 5: Get the name of the type&amp;nbsp;- for our example above it would be "SiteData" - and build the URL based on the site URL and the web service name.&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="terb"&gt;Now I can transform the above snippet to this:&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;using (SiteData siteDataWS = WebServiceHelper.CreateWebService&amp;lt;SiteData&amp;gt;(currentSite))&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp; // Do something with the WS.&lt;br&gt;}&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="treb"&gt;Drastic change? No, not really.&amp;nbsp;But it keeps things clean.&lt;/font&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=3721575" width="1" height="1"&gt;</content><author><name>Avner Kashtan</name><uri>http://weblogs.asp.net/members/Avner-Kashtan.aspx</uri></author><category term=".NET" scheme="http://weblogs.asp.net/avnerk/archive/tags/.NET/default.aspx" /><category term="SharePoint" scheme="http://weblogs.asp.net/avnerk/archive/tags/SharePoint/default.aspx" /><category term="CodeSnippets" scheme="http://weblogs.asp.net/avnerk/archive/tags/CodeSnippets/default.aspx" /><category term="C#" scheme="http://weblogs.asp.net/avnerk/archive/tags/C_2300_/default.aspx" /><category term="Generics" scheme="http://weblogs.asp.net/avnerk/archive/tags/Generics/default.aspx" /></entry><entry><title>Visual Studio help-launcher rant</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/avnerk/archive/2007/09/03/visual-studio-help-launcher-rant.aspx" /><id>http://weblogs.asp.net/avnerk/archive/2007/09/03/visual-studio-help-launcher-rant.aspx</id><published>2007-09-03T12:34:00Z</published><updated>2007-09-03T12:34:00Z</updated><content type="html">&lt;p&gt;Yes, I know I am far from the first to bemoan the &lt;em&gt;atrocious&lt;/em&gt; behavior of Visual Studio 2005 when you press the F1 button, even accidently. The first time you do it - or other times, if it deems the contents sufficiently changed for some reason - you are treated to an obnoxious and uncancellable dialog saying Help is updating itself and showing an uninformative neverending progress bar. &lt;/p&gt; &lt;p&gt;Worse yet, this window, despite being non-modal (due to running in a different process, dexplorer.exe) still blocks the calling thread on devenv.exe, preventing me from working for up to 5 minutes(!) at a time. No Abort button, no way to tell it to skip this pointless operation - launching help from VS is simply&amp;nbsp;a giant waste of time.&lt;/p&gt; &lt;p&gt;What I now discovered is that I can't even use the task manager to kill the dexplore.exe process, because Visual Studio actively monitors it and RELAUNCHES it, apparently from scratch, if I try to do so.&lt;/p&gt; &lt;p&gt;So tell me, what program manager decided that this particular feature, launching the Help window in a completely different process, was so &lt;em&gt;amazingly &lt;/em&gt;important that it was allowed to take over my Visual Studio completely for whole minute while I just sat there and twiddled my thumbs?&lt;/p&gt; &lt;p&gt;Infuriating.&lt;/p&gt; &lt;p&gt;UPDATE: &lt;/p&gt; &lt;p&gt;Tools -&amp;gt; Customize -&amp;gt; Keyboard -&amp;gt; Show Commands Containing -&amp;gt; Help.F1Help -&amp;gt; Remove.&lt;/p&gt; &lt;p&gt;There. F1 is disabled. Peace is resumed.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=3719759" width="1" height="1"&gt;</content><author><name>Avner Kashtan</name><uri>http://weblogs.asp.net/members/Avner-Kashtan.aspx</uri></author></entry><entry><title>Wrong constructor called in COM+: sneaky, sneaky bug</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/avnerk/archive/2007/08/30/wrong-constructor-called-in-com-sneaky-sneaky-bug.aspx" /><id>http://weblogs.asp.net/avnerk/archive/2007/08/30/wrong-constructor-called-in-com-sneaky-sneaky-bug.aspx</id><published>2007-08-30T14:35:25Z</published><updated>2007-08-30T14:35:25Z</updated><content type="html">&lt;p&gt;Here's another nasty one that tried to bite me today. Let's say I have the following classes:&lt;/p&gt; &lt;div style="border-right: black 1px solid; border-top: black 1px solid; padding: 4px; border-left: black 1px solid; border-bottom: black 1px solid"&gt;&lt;font face="courier new"&gt;public class COMPlusClass : ServicedComponent&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp; public COMPlusClass()&lt;br&gt;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;Default initialization.&lt;br&gt;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; public COMPlusClass (string data)&lt;br&gt;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Parameterized initialization.&lt;br&gt;&amp;nbsp;&amp;nbsp; }&lt;br&gt;}&lt;br&gt;&lt;br&gt;public class Client&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Client()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; COMPlusClass cpc = new COMPlusClass("I am a client");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;}&lt;/font&gt;&lt;/div&gt; &lt;p&gt;Which constructor do you think will be called?&lt;/p&gt; &lt;p&gt;Naturally, I wouldn't ask if it was the second one. Much to my surprise, the first constructor was called when I instantiated the COM+ component. &lt;/p&gt; &lt;p&gt;Why is this? Because COM+, due to its COM heritage, requires all components to expose a default, public, parameterless constructor and always initializes through it. &lt;/p&gt; &lt;p&gt;Why didn't I get an error, then? Because I'm writing .NET classes that don't know in advance that they will be instantiated through COM+. If all I know of COMPlusClass came from a COM type library, the second ctor probably wouldb't be exposed. But since I see it as a .NET class, I can &lt;em&gt;believe&lt;/em&gt; I am instantiating the parametrized constructor. COM+ probably discards my precious string along the way.&lt;/p&gt; &lt;p&gt;Solution? Add some sort of &lt;em&gt;Initialize&lt;/em&gt; method to pass the construction data. &lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=3668155" width="1" height="1"&gt;</content><author><name>Avner Kashtan</name><uri>http://weblogs.asp.net/members/Avner-Kashtan.aspx</uri></author><category term=".NET" scheme="http://weblogs.asp.net/avnerk/archive/tags/.NET/default.aspx" /><category term="C#" scheme="http://weblogs.asp.net/avnerk/archive/tags/C_2300_/default.aspx" /><category term="COM+" scheme="http://weblogs.asp.net/avnerk/archive/tags/COM_2B00_/default.aspx" /></entry><entry><title>Unmanaged deployment is a true DLL Hell</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/avnerk/archive/2007/08/30/unmanaged-deployment-is-a-true-dll-hell.aspx" /><id>http://weblogs.asp.net/avnerk/archive/2007/08/30/unmanaged-deployment-is-a-true-dll-hell.aspx</id><published>2007-08-29T23:16:07Z</published><updated>2007-08-29T23:16:07Z</updated><content type="html">&lt;p&gt;By a staggering margin, most of my problems integrating&amp;nbsp;C++/CLI code into my C#-based project has been deployment problems. Without fail, every integration or test deployment will be plagued with inexplicable problems. I'll try to list a few, with their causes and (probable) solutions:&lt;/p&gt; &lt;p&gt;1) .NET assemblies are usually very loose in what they'll bind to. If I compiled A.DLL against B.DLL version 1.0.0.0, it will still work if it can only find B.DLL version 1.2.0.0. I don't have to rebuild and reversion everything every time. However, if my C# A.DLL has a reference to my CPPCLI.DLL v1.0.0.0, and I then put CPPCLI.DLL v1.1.0.0, I'll get an exception saying the referenced DLL wasn't found. Annoying.&lt;/p&gt; &lt;p&gt;Solution: If you're changing the version number of a C++/CLI assembly, make sure to recompile any assembly that references it.&lt;/p&gt; &lt;p&gt;2) C++/CLI can be compiled as a pure .NET assembly, just like C# or VB. I don't really see the point in that, unless I'm a C++ coder and refuse to switch syntax. There isn't a great deal of benefit to that over writing in C#, because I can't reference unmanaged code easily. The standard mode, /clr, allows me to mix both managed and unmanaged code. The problem is that a mixed-mode assembly has a dependency on the Visual C++ Runtime libraries. This means that if the machine I am installing on doesn't have it, I'll crash. Furthermore, if I developed my code on a machine running VS2005SP1, my MSVCRT version will be 8.0.50727.762, but on a machine with vanilla .NET2.0 and the corresponding runtimes, I'll just find 8.0.50727.42. Result? An inexplicable "FileNotFoundException", not saying what's missing.&lt;/p&gt; &lt;p&gt;Solution: Make sure your deployment scenario includes installing the relevant MSVC++ Runtime. VS2005 comes with a Merge Module (msm) so you can add it to any MSI project.&lt;/p&gt; &lt;p&gt;3) The usual reason to add C++/CLI code to a C# project is to act as a bridge to an unmanaged API. Usually this API is composed of various DLLs. These DLLs can come in many forms - some are statically linked to their respective runtimes, some link dynamically. Some expect other DLLs in the same directory, others expect them in the PATH. Many times we'll get cryptic Module Load Failed errors or FileLoadFailedExceptions. &lt;/p&gt; &lt;p&gt;One tool we have for this is Filemon and Procmon, SysInternals' wonderful debugging tools. Open them up, add a filter to weed out the noise and see what files receive a FILE_NOT_FOUND error. &lt;/p&gt; &lt;p&gt;Another indispensible tool is the Dependency Walker (depends.exe) that is shipped with Visual Studio (C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\Bin). This tool will show you all the DLLs that our file has a dependency on. First thing to look for is any dependencies highlighted in red, underneath the tree. These are our missing buddies. Ignore anything that has a little hourglass next to it - these are delay-load modules and probably not the source of the problem. &lt;/p&gt; &lt;p&gt;One thing to note when opening our C++/CLI DLLs in Depends is the dependencies on the MSVC++ Runtime. Look for a dependency on "MSVCP80.DLL". You might find instead "MSVCP80D.DLL" - this means that we're bound to the Debug build of the runtime, which probably doesn't exist on our servers. This usually means that we've compiled the project in DEBUG build, rather than RELEASE. &lt;/p&gt; &lt;p&gt;One last indispensible tool is trusty old Reflector. Open our managed A.DLL that contains a reference to CPPCLI.DLL, and we can see what version it was referenced against. This can help us find problems like I mentioned in section 1.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;There, that's all I can think of at the moment. Hope it gets some googlejuice and helps someone stuck as I am.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=3660179" width="1" height="1"&gt;</content><author><name>Avner Kashtan</name><uri>http://weblogs.asp.net/members/Avner-Kashtan.aspx</uri></author><category term=".NET" scheme="http://weblogs.asp.net/avnerk/archive/tags/.NET/default.aspx" /><category term="C++/CLI" scheme="http://weblogs.asp.net/avnerk/archive/tags/C_2B002B002F00_CLI/default.aspx" /></entry><entry><title>More Tales from the Unmanaged Side - System.String -&gt; char*</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/avnerk/archive/2007/08/28/more-tales-from-the-unmanaged-side-system-string-gt-char.aspx" /><id>http://weblogs.asp.net/avnerk/archive/2007/08/28/more-tales-from-the-unmanaged-side-system-string-gt-char.aspx</id><published>2007-08-28T16:08:50Z</published><updated>2007-08-28T16:08:50Z</updated><content type="html">&lt;p&gt;Today,&amp;nbsp;I had a very tight deadline to achieve a very simple task: pass a managed .NET string to an API function that expects a null-terminated char*. Trivial, you would expect? Unfortunately it wasn't.&lt;/p&gt; &lt;p&gt;My first though was to do the pinning trick that I mentioned in my last post, but in this case I needed my resulting char* to be null-terminated.&lt;/p&gt; &lt;p&gt;Second thought was to go to the System.Runtime.InteropServices.Marshal class and see what it had for me. I found two contenders:&lt;/p&gt; &lt;p&gt;1) Marshal::StringToBSTR() - this creates a COM-compatible BSTR. I found various tutorials about BSTRs saying that they MIGHT be, under SOME circumstances, compatibles with zero-terminated wide-character strings. Didn't seem to be safe enough.&lt;/p&gt; &lt;p&gt;2) Marshal::StringToHGlobalAuto() - this allocates a block of memory, copies the characters in and even null-terminates it for me. This looked like a winner. Stage one was done - we managed to get an unmanaged string. But can we use it now?&lt;/p&gt; &lt;p&gt;The next problem was that StringToHGlobalAuto returns an IntPtr, and&amp;nbsp;casting it to a char* led to a compilation error. The solution to that is either to cast the IntPtr to a (void*) before casting to (char*), or to do the same action by calling the IntPtr's ToPointer() method. The second option seems neater to those of us who like as few direct casts as possible - I'd rather my conversion was done by a method than by a possibly unsafe casting operation. I'm sure those more concerned with method-call overheads will disagree.&lt;/p&gt; &lt;p&gt;The next problem is that the result of this operation was a single character string - the first character from the expected string. C++ programmers who've struggled with Unicode will quickly spot the problem.&lt;/p&gt; &lt;p&gt;char* strings are null terminated - the first byte containing 00 is the terminator. For Unicode strings as returned by StringToHGlobal&lt;strong&gt;Auto&lt;/strong&gt;, each character takes 2 bytes. If it's a character from the lower reaches of the Unicode spectrum, the second byte, being the high-order byte, will usually be 00, thus terminating the string. There are two options:&lt;/p&gt; &lt;p&gt;1. Instead of char*, use wchar_t* - wide, 2-byte character string, terminated by two null bytes.&lt;br&gt;2. use StringToHGlobal&lt;strong&gt;ANSI&lt;/strong&gt;, which converts the string to standard 8-bit ANSI encoding. This should be used only if we know we can't receive any unicode characters, or (as in my case) when the API we call only acceptts char*. :(&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;So that's a bit more C++ that haunted and taunted me today. See you next time.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=3646045" width="1" height="1"&gt;</content><author><name>Avner Kashtan</name><uri>http://weblogs.asp.net/members/Avner-Kashtan.aspx</uri></author><category term=".NET" scheme="http://weblogs.asp.net/avnerk/archive/tags/.NET/default.aspx" /><category term="C#" scheme="http://weblogs.asp.net/avnerk/archive/tags/C_2300_/default.aspx" /><category term="C++/CLI" scheme="http://weblogs.asp.net/avnerk/archive/tags/C_2B002B002F00_CLI/default.aspx" /></entry></feed>