Friday, July 11, 2014

Web Service Installation Blocked by Disabled IIS Admin Service

I was trying to run an MSI I had built with Visual Studio 2010 to install an .asmx web service on my Windows 7 x64 machine, but it immediately halted with the error message
The installer was interrupted before Application could be installed. You need to restart the installer to try again.  Click "Close" to exit.
A google search result suggested I try getting details on the error using this:
msiexec /i myapp.msi /l*vx SomeFilename.log
and indeed I got the following info in the generated log file:
INFO : [07/11/2014 10:41:42:409] [SetTARGETSITE ]: Custom Action is starting...
INFO : [07/11/2014 10:41:42:409] [SetTARGETSITE ]: CoInitializeEx - COM initialization Apartment Threaded...
ERROR : [07/11/2014 10:41:42:429] [SetTARGETSITE ]: FAILED: -2147023838
ERROR : [07/11/2014 10:41:42:429] [SetTARGETSITE ]: Custom Action failed with code: '1058'
INFO : [07/11/2014 10:41:42:429] [SetTARGETSITE ]: Custom Action completed with return code: '1058'
That error number -2147023838 is also 0x80070422; it and error code 1508 also turned up a page which said the error indicated a required service was disabled.  Indeed, for some inscrutable reason, the "IIS Admin Service" was disabled.  I set it to manual, and then the MSI ran fine.

Friday, May 24, 2013

Finding All Files Checked Out From TFS For All Users

While working on a project maintained in TFS, I noticed that some of the files I was using were checked out by another TFS user who I thought had completed all his work on those files, so I wanted to let him know he still had those files checked out (and to ask him to undo those pending changes, to prevent unnecessary merging later on).  

I wondered if there were a way to find all files under a TFS directory which were checked out, and initial googling found a mention of something called "Team Foundation Server Power Tools", a Visual Studio add-on, which would allow you to do this from within Visual Studio.  But I was a little paranoid about adding something to my Visual Studio setup.

Fortunately, it's not too difficult to get this same information using the command-line TFS command, like this:

"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\tf" status "$/[your TFS path here]" /recursive /user:*

It's helpful to redirect this command's output to a text file since it's pretty wide.  And note you can select a specific user by specifying that user instead of the wildcard, like this:

"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\tf" status "$/[your TFS path here]" /recursive /user:DOMAIN\user.name >results.txt

Reference for the "tf" command: 
http://msdn.microsoft.com/en-us/library/z51z7zy0%28v=vs.100%29.aspx

Monday, June 18, 2012

Prefer XmlSerializer When Using svcutil To Generate Client Code From WSDL

I have a WSDL from a web service server which includes the following in its types:

<xs:element minOccurs="0" name="countryID" type="xs:int"/>

This is supposed to represent an optional int element named countryID.  When I run svcutil.exe (from C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin) against it, I get the following generated code:
        [System.Runtime.Serialization.DataMemberAttribute()]
public int countryID
{
    get
    {
        return this.countryIDField;
    }
    set
    {
        this.countryIDField = value;
    }
}

The "IsRequired=true" property is not set on the DataMemberAttribute.  But there's no way to indicate that I want a given instance to be absent!  Some googling revealed that I could modify the generated code (which I hate doing) to use "DataMemberAttribute(EmitDefaultValue=false)" (see http://msdn.microsoft.com/en-us/library/aa347792.aspx?ppud=4).  But if I do this, I cannot use a countryID value of zero, as this will be interpreted as the default value, and no countryID element will be generated!

The solution: add the "/serializer:XmlSerializer" command line option, which causes the following to be generated:


    [System.Xml.Serialization.XmlElementAttribute(Order=0)]
    public int countryID
    {
        get
        {
            return this.countryIDField;
        }
        set
        {
            this.countryIDField = value;
        }
    }
   
    ///
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool countryIDSpecified
    {
        get
        {
            return this.countryIDFieldSpecified;
        }
        set
        {
            this.countryIDFieldSpecified = value;
        }
    }


With this construct, as I described in my earlier post about optional attributes, setting countryIDFieldSpecified to "false" will not emit the countryID element.

Friday, June 8, 2012

Uncaught Exception From Delegate Passed To Task.Factory.StartNew() Causes Windows Service To Crash

We have a Windows service written in C# against the .NET 4.0 framework, and it began crashing with the following two items written into the Application event log each time:
EventType clr20r3, P1 x.exe, P2 1.8.1.0, P3 4fd0f5c1, P4 system, P5 4.0.0.0, P6 4ba1dff4, P7 2e49, P8 12d, P9 system.aggregateexception, P10 NIL.
Application: x.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.AggregateException
Stack:
   at System.Threading.Tasks.TaskExceptionHolder.Finalize()
Some googling around yielded the following helpful information:


in which it mentions a case in which an error gets thrown within that Finalize() call.

I ended up finding a library our application referenced in which the author called Task.Factory.StartNew(), passing in a delegate which had a catch block which could itself throw an exception--which would end up being considered unhandled in that Finalize() call, and crash the process during garbage collection at some point after the exception occurred.

We're in the process of having that library corrected.

Note that Parallel.ForEach() shouldn't have this problem, because it says that all its tasks' exceptions will be bundled up into an AggregateException and returned to the caller.

Thursday, April 5, 2012

Dropping All Tables In A SQL Server Database

While doing database logical model design, I found it convenient to create a SQL script I could repeatedly execute to ensure that my design was feasible in a real database.  But since my script was essentially a good number of CREATE TABLE statements, I needed to delete all the tables from my previous run.

Internet to the rescue:


which indicates that you can use the very handy command:

EXEC sp_MSforeachtable @command1 = "DROP TABLE ?"

to execute a DROP TABLE on each user table in the database.  If you have relational integrity constraints between tables, you may need to execute this command more than once until all the referencing tables have been deleted, at which point you can execute it again to drop the (previously) referenced tables.

BE WARNED: this will DROP ALL TABLES.  You may not want to do this.  You should not do it anywhere except in a scratch database (for example, one in which you're doing logical data model design).

Friday, August 12, 2011

Avoiding AddressAccessDeniedException: Change WCF Binding To netTcpBinding

I was trying to deploy a nifty new ASP.NET and Windows service application pair, in which the ASP.NET application included a WCF client which accessed the Windows service which hosted a WCF server.  But I found when deploying it to a Windows 2003 server (instead of my XP development box) that when I tried to start the service, I got the following error in the event log:

Service cannot be started. System.ServiceModel.AddressAccessDeniedException: HTTP could not register URL http://+:50621/XX1TestSuiteService/RemoteInterface/. Your process does not have access rights to this namespace (see http://go.microsoft.com/fwlink/?LinkId=70353 for details).

A little googling turned up this page (among others):


Certainly trying to reconfigure the server to allow for the registration of the use of an HTTP listener might eventually have gotten me where I needed to go.  But I only used the HTTP binding because it was the default for WCF.  These applications were going to be on the same server.  So between the performance improvement I understood the netTcpBinding provided and my desire to eliminate this error, I reconfigured my two apps to use that binding, with the help of a very detailed and easy process described by Microsoft here:


After re-installing the Windows service, it started without any error.

Tuesday, August 2, 2011

WCF Client Disposal Broken!

While running a recently-developed application I wrote through the Visual Studio 2010 code analyzer, I was told that I wasn't calling Dispose on an object which implemented IDispose.  Chagrined, I took a look and found that WCF client objects, derived from ClientBase, do indeed derive from IDispose.

Oddly, the autocomplete didn't allow me to test this, by attempting to call the Dispose method directly off the client object.  It turns out this is a known oddity; the Dispose method in ClientBase is private.  The reason that "using" would work is that using will effectively cast the client object back to IDisposable, where Dispose is once again callable:


But wait, that's not really why I'm posting.  Apparently the ClientBase's Dispose method calls Close, which can throw if there are errors performing the close.  Apparently, throwing exceptions out of Dispose is not recommended by Microsoft's own "Framework Design Guidelines":


What this means for a WCF client is that if you use the "using" approach for cleanup, any errors that occur during the implicit Dispose call at the end of the using block will mask any exceptions which occurred in the using block.

There is an extraordinarily ungainly approach recommended by Microsoft:


in which you create a try block with a call to Close() and explicitly provide catch blocks for each of CommunicationException, TimeoutException, and Exception; and in each of those blocks, you call Abort; and in the Exception catch block, you re-throw the original error after calling Abort().  No way I'm doing that.

Suggested elsewhere was what seemed a cleaner variation to me:

bool isSuccessful = false;
MyClient myClient = new MyClient();
try
{
    // use the client object here
    myClient.Close();
    isSuccessful = true;
}
finally
{
    if (!isSuccessful)
        myClient.Abort();
}

What a pain!  Why would the WCF developers do this to us?  Some notes on the internal discussion are available here:



and I think the pertinent part of that second link (well worth the read in its entirety!) is:
After much debate, IDisposable was left on ServiceHost and ClientBase, the theory being that for many users, it’s ok if Dispose throws, they still prefer the convenience of using(), and the marker that it should be eagerly cleaned up.  You can argue (and some of us did) that we should have removed it from those two classes as well, but for good or for ill we have landed where we have. It’s an area where you will never get full agreement, so we need to espouse best practices in our SDK samples, which is the try{Close}/catch{Abort} paradigm.
There were two decisions to make: should the client object inherit IDisposable; and if yes, should Dispose call Close or Abort?  All three outcomes (not IDisposable, Dispose calls Close, and Dispose calls Abort) are ugly in one way or another.  So how come other self-cleaning-up objects don't have this ugliness?

I guess I'm going to have to put up with warnings from code analyzer about missing calls to Dispose.  [sniff]