Friday, November 25, 2016

Solving the dreaded MQ_ERROR_CORRUPTED_SECURITY_DATA (0xC00E0030) MSMQ error

I recently started getting a the error MQ_ERROR_CORRUPTED_SECURITY_DATA (0xC00E0030) when trying to execute tests on my development box while publishing to MSMQ queues. As indicated by the error, the cause was corrupted security data. I had recently changed my development machine from one directory over to another. Going into the MSMQ Server properties in compmgmt.msc (Computer Management) and clearing out all the certifticates for my user, renewing them and reregistering the certificates with Active Directory fixed the issue.

Saturday, November 19, 2016

Switching environments, data sources, and other dynamically changeable settings in TFS Lab (on-premise) for 2013

Thanks to a post on this blog, we can access the settings inject into Lab-managed builds in TFS 2012 and 2013. Even though this is 2016 and many people are moving to the cloud with VSTS, there are still a good number of companies out there with considerable infrastructure "on-premise", and TFS can help with executing automated tests in those environments. I'm going to be building a library for helping others out with retrieving settings dynamically from TFS and I'll update my blog when it's available.

Monday, November 14, 2016

DevExpress and their licensing model suck for professional developers

If you're using a build machine, delete all of your *.licx files out of source control. Otherwise you're just asking for trouble.

Friday, November 11, 2016

Data-driven testing with MSTest via configuration-defined data sources and XML as a data source

I've done data driven testing with MSTest before. Prior to now, it's been solely with XML file data sources that have been defined inline in the [DataSource] attribute on my test.

I wanted to try using the app.config to define my data sources so that I could make them dynamic and configure them at test execution time so that I could point my tests at different environments.

I started following this tutorial on MSDN. It shows how to define data sources in the app.config for the tests. Then I followed the guidance in this post on the MSDN forums for how configure XML data sources in the app.config. Once I did that, I set up my XML data file similarly to the following:

<?xml version="1.0" encoding="utf-8" ?>
<Rows>
<dev>
<ShouldExist>True</ShouldExist>
<ProjectNumber>1721202</ProjectNumber>
</dev>
<dev>
<ShouldExist>False</ShouldExist>
<ProjectNumber>00000</ProjectNumber>
</dev>
</Rows>

The second-level "dev" elements are the "data table" in the connection parameters for the data source. By naming these appropriately, I can now select the environment in which to run my tests as part of my automated builds (yay ALM).

Wednesday, November 09, 2016

Solving "System.Net.WebException: The remote server returned an error: (417) Expectation Failed" with a WCF service

I recently started getting the following error message when trying to connect to a web service we had put on an Azure VM running behind an Azure load balancer:

System.ServiceModel.ProtocolException: The remote server returned an unexpected response: (417) Expectation Failed. ---> System.Net.WebException: The remote server returned an error: (417) Expectation Failed.

It turns out the fix was to put the following element in my <configuration> :

<system.net>
<settings>
<!-- This is required when running in Azure VMs behind an Azure load balancer -->
<servicePointManager expect100Continue="true" />
</settings>
</system.net>

Solving "System.Net.WebException: The remote server returned an error: (417) Expectation Failed" with a WCF service

I recently started getting the following error message when trying to connect to a web service we had put on an Azure VM running behind an Azure load balancer:

System.ServiceModel.ProtocolException: The remote server returned an unexpected response: (417) Expectation Failed. ---> System.Net.WebException: The remote server returned an error: (417) Expectation Failed.

It turns out the fix was to put the following element in my <configuration> :

<system.net>
<settings>
<!-- This is required when running in Azure VMs behind an Azure load balancer -->
<servicePointManager expect100Continue="true" />
</settings>
</system.net>

Thursday, November 03, 2016

Solving the error "We could not add the account: network_not_available: The network is down so authentication cannot proceed" when trying to sign into Visual Studio

This has been driving me nuts for years. The solution, as it turns out, is ridiculously simple: at the top right of Visual Studio, go to your signed in account => Account Settings ...

On the dialog that pops up, sign out of all accounts and close the window.

While signed out, close and restart Visual Studio.

Sign in again with your accounts. You should be good to go.

Apparently signing out and closing Visual Studio is the only way to truly clear its credential caches. Fuck.

Solving the error "We could not add the account: network_not_available: The network is down so authentication cannot proceed" when trying to sign into Visual Studio

This has been driving me nuts for years. The solution, as it turns out, is ridiculously simple: at the top right of Visual Studio, go to your signed in account => Account Settings ...

On the dialog that pops up, sign out of all accounts and close the window.

While signed out, close and restart Visual Studio.

Sign in again with your accounts. You should be good to go.

Apparently signing out and closing Visual Studio is the only way to truly clear its credential caches. Fuck.

Solving the error "We could not add the account: network_not_available: The network is down so authentication cannot proceed" when trying to sign into Visual Studio

This has been driving me nuts for years. The solution, as it turns out, is ridiculously simple: at the top right of Visual Studio, go to your signed in account => Account Settings ...

On the dialog that pops up, sign out of all accounts and close the window.

While signed out, close and restart Visual Studio.

Sign in again with your accounts. You should be good to go.

Apparently signing out and closing Visual Studio is the only way to truly clear its credential caches. Fuck.

Monday, October 10, 2016

Getting started with creating custom Build and Release tasks for VSO

You'll need to follow the steps below in order to get started:
1) Install npm for Windows if you haven't already
2) Once npm is successfully installed and available in your PATH, execute the following command to install the TFX command line package: "install -g tfx-cli"
3) Once you've installed TFX, find a folder in which you want to work to create your package, and execute a command similar to the following: "tfx build tasks create"
4) After you finish answering the questions asked by the program, you'll have a template folder for your custom build task that you can bundle up with tfx and publish to VSO.

Friday, October 07, 2016

Passing parameters from a resource group template in Azure to a WebJob

As it turns out, WebJobs retrieve their connectionStrings and appSettings from the Azure app service blade settings, same as the web application in which they're running! You can just use the built-in "connectionstrings" and "appsettings" resources underneath a Web Application in your Resource group template to populate these values for the WebJobs right from your template. This is particularly useful for things like WebJobs dashboard and storage connection strings.  Microsoft could really have done a better job of advertising this fact.

Wednesday, September 07, 2016

MSMQ, WCF and IIS: Getting them to play nice: The extras, Part II

Here's another catch I've found that causes issues when trying to set up a 3-party queueing system: You need to log on interactively as the user that's accessing the queues on each of the machines where it's accessing the queues! This is so that a certificate can get created for the user on those machines to be used with Active Directory authentication.

Tuesday, September 06, 2016

Solving "m_safeCertContext is an invalid handle."

I've recently been trying to get an application working in Azure App Service that acts as a client who calls out to another service via WCF with TransportWithMessageCredential mode for security and Certificate mode for authentication. I've been getting the following error:

m_safeCertContext is an invalid handle.

According to this blog post, this error gets thrown when the certificate isn't correctly imported or has incorrect trust (for any of many possible reasons). Some of those reasons can include incorrect passwords, but there are others as well, like what I was encountering: in Azure App Service, there's no local user signed on when your application is running. Because of that, you run afoul of a subtle issue with managing certificates: all of the constructors, by default, use the user certificate store to temporarily store the PrivateKey of any loaded X509Certificate2 objects. Therefore, on an Azure App Service application, unless you use the new X509Certificate2(certBytes, passwordString, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable) constructor with the MachineKeySet | Exportable flags, your certificate will not be correctly read and will SILENTLY FAIL!!

Friday, September 02, 2016

Solving 'The remote certificate is invalid according to the validation procedure' with WCF channels

This typically happens most often (when using certificates) when the certificate Common Name (CN) doesn't match the DNS host name of the server.

Solving "Binding validation failed because the binding's MsmqAuthenticationMode property is set to WindowsDomain but MSMQ is installed with Active Directory integration disabled"

I've been trying to set up remote reads from an MSMQ queue to a WCF service hosted on another machine. I seem to have all my application settings correct, but I'm being screwed over by machine-level configuration on the service machine: the service machine won't run in Active Directory mode, no matter what I do.

After searching for the problem, I found this page on John Breakwell's MSDN blog. It describes the problem: essentially there's a legacy msmq object left around when you install MSMQ Server and Active Directory Integration features together in the same transaction. Here's how you **actually** fix the problem:


  1. Uninstall all of the MSMQ features.
  2. Execute this PowerShell command (or one similar to it) to actually delete the Active Directory object described in the article (which doesn't go into nearly enough detail on this point):  get-adobject -filter “name -eq ‘msmq'” | Where { $_.DistinguishedName -eq ‘CN=msmq,CN=MyAffectedServerNameHere,OU=Web Servers,OU=Member Servers,DC=MyDomainNameHere,DC=Network,DC=ads’} | Remove-ADObject
  3. Reinstall **just** MSMQ server, then reboot your machine.
  4. Reinstall **just** MSMQ active directory integration, then reboot your machine.
You should now be good to go.

Solving "Binding validation failed because the binding's MsmqAuthenticationMode property is set to WindowsDomain but MSMQ is installed with Active Directory integration disabled"

I've been trying to set up remote reads from an MSMQ queue to a WCF service hosted on another machine. I seem to have all my application settings correct, but I'm being screwed over by machine-level configuration on the service machine: the service machine won't run in Active Directory mode, no matter what I do.

After searching for the problem, I found this page on John Breakwell's MSDN blog. It describes the problem: essentially there's a legacy msmq object left around when you install MSMQ Server and Active Directory Integration features together in the same transaction. Here's how you **actually** fix the problem:


  1. Uninstall all of the MSMQ features.
  2. Execute this PowerShell command (or one similar to it) to actually delete the Active Directory object described in the article (which doesn't go into nearly enough detail on this point):  get-adobject -filter “name -eq ‘msmq'” | Where { $_.DistinguishedName -eq ‘CN=msmq,CN=MyAffectedServerNameHere,OU=Web Servers,OU=Member Servers,DC=MyDomainNameHere,DC=Network,DC=ads’} | Remove-ADObject
  3. Reinstall **just** MSMQ server, then reboot your machine.
  4. Reinstall **just** MSMQ active directory integration, then reboot your machine.
You should now be good to go.

Thursday, September 01, 2016

Unblocking zip files, the permanent solution

My team recently migrated their code to Visual Studio Online (aka VSO aka VSTS), which means that any time we do our builds, we now have to download our build output through the browser as a zip file rather than copying from a file share as we formerly did when our code was built on-premise. As a consequence of this, we now stumble across a feature of Windows: automatic file blocking.

Any time we download a zip from the internet, any scripts extracted from it are automatically blocked by Windows using metadata attached to the file in the NTFS file system. This means we have to manually unblock our scripts every time we download a build and want to deploy it (But Alex, why aren't you deploying your systems automatically through a deployment manager ? Our company isn't there yet, but we're getting there). That said, there's a way to disable this feature, detailed here:

http://winaero.com/blog/disable-downloaded-files-from-being-blocked-in-windows-10/

The short of it is that there exists a group policy for disabling tracking of zone information for files downloaded from the Internet.

Start -> Run -> gpedit.msc -> Local Computer Policy -> User Configuration -> Administrative Templates -> Windows Components -> Attachment Manager -> "Do not preserve zone information in file attachments" : Enabled.

Done.

Wednesday, August 31, 2016

MSMQ, WCF and IIS: Getting them to play nice: The extras, Part I

I've recently been trying to set up queued publishing of data in my company within our internal applications so that we can publish that data out to other applications running in our hybrid cloud with Azure. To move the data around on-premise, I've been working off of the advice given to me by some very knowledgeable people in the IT space, and using architectural design patterns that have been proven to work (though not by me). To implement our new data-publishing architecture, I decided to leverage components I already had at my disposal and use WCF with MSMQ bindings to deal with unreliable connections from some of our remote sites. To help me get started, I began following the series of articles published here on MSDN by Tom Hollander. I was able to get past Part 1 of the tutorial without problem. I even needed the same architecture: a queued message client publishing to a service, via a queue hosted on a 3rd party system.

Part 2 however, securing the queue, proved to be a little bit harder, to the point where I needed to go to stackoverflow.com for help and posted this question. In the question, I kept running into an error when I tried to enable Transport security along with ActiveDirectory support. When I didn't enable ActiveDirectory support, I got a different error, with the code 0xC00E0030. Looking on the page for MSMQ queueing error codes on MSDN, I found that this error means that there was corrupted security data, somewhere. Here's what I had to do to resolve it:


  1. In the EndpointAddress for my WCF binding, I had to add an extra parameter to the constructor for the EndpointIdentity of my binding: New EndpointAddress(queueUri, EndpointIdentity.CreateDnsIdentity(queueUri.Host))
  2. I had to gain access to the server where I was hosting my MSMQ Server, and gain full access to the Server itself:  Computer Management -> Message Queueing -> Right-click -> Properties -> Security tab -> [my name] -> "Full Control"
  3. I had to re-register my own Internal Certificate for MSMQ on the server: [previous steps] -> User Certificate tab -> Internal Certificate section -> Renew....
After cleaning up the certificate and adding the endpoint, I was good to go, and I could now authenticate and send messages to the MSMQ server.

To be fair to Tom Hollander, he did say that there would be some extra specifics to getting Authentication working, and I guess these were mine. I have to send him a lot of thanks for going through what he did AND recording and publishing the steps. People like him make the world a better place.

Friday, August 26, 2016

Unable to add multiple listen rule keys or subscriptions to a Topic in an Azure Service Bus in an Azure Resource Group template

I recently ran across a problem wherein I was unable to add multiple Listen rules for my applications to my Topics in Azure Service Bus within an Azure Resource Group Template. I would run my template and it would fail to create the keys for the Topic or the Subscription for the topic of there was more than one of either of those for the Topic. It wouldn't even be consistent: it would switch back and forth between them between runs of the template. After a discussion with one of the Solution Architects at Microsoft, I found out there is, at the time of this writing, a bug in the Azure Resource Manager for Topics within Service Buses that prevents Topic access rules and subscriptions from being simultaneously created. As a work around, I was instructed to introduce an artificial dependency between each of the subscriptions to force the resource manager to create them serially rather than in parallel and this did the trick.

For example:

// TODO:

Tuesday, August 23, 2016

Getting verbose output from an Invoke-Command -ScriptBlock in PowerShell

It's often very useful to invoke commands on other machines, e.g. in deployment scripts. It can be even more useful to have logging of what actually gets executed on those other machines, e.g.

$myJob = Invoke-Command -AsJob -ScriptBlock {
    Param()

    Do-Thing -Verbose
}

However, in this instance, you wouldn't get the output of the Do-Thing command because it's writing to the Verbose stream of a script block being executed on a separate machine. Now, it's not that PowerShell can't collect the output of that Verbose stream for you, it can. You just need to instruct it how. The difference:

$myJob = Invoke-Command -AsJob -Verbose -ScriptBlock {
    [CmdletBinding()]
    Param()

    Do-Thing -Verbose
}

Now you'll be able to collect the Verbose output of your script block. The difference is that you need to pass the Verbose flag to the script block, and make it a cmdlet by adding the [CmdletBinding()] attribute to your block.

Tuesday, August 16, 2016

Wednesday, August 10, 2016

Finally ... how to debug the startup of a Windows Service application

Do what this guy says: http://einaregilsson.com/run-windows-service-as-a-console-program/

Pasted here for posterity, here's the example of how to write a Windows Service such that it can execute in a console and a developer can debug the startup routine:

using System;
using System.ServiceProcess;
 
public partial class DemoService : ServiceBase
{
    static void Main(string[] args)
    {
        DemoService service = new DemoService();
 
        if (Environment.UserInteractive)
        {
            service.OnStart(args);
            Console.WriteLine("Press any key to stop program");
            Console.Read();
            service.OnStop();
        }
        else
        {
            ServiceBase.Run(service);
        }
 
    }
    public DemoService()
    {
        InitializeComponent();
    }
 
    protected override void OnStart(string[] args)
    {
        // TODO: Add code here to start your service.
    }
 
    protected override void OnStop()
    {
        // TODO: Add code here to perform any tear-down
        //necessary to stop your service.
    }
}