Visual Studio compile error: Cryptographic failure while signing assembly Access is denied

One of the development environment for developing BizTalk Server 2006 solutions I worked on had Windows XP and Visual Studio 2005 running on it. The environment was quite complicated with scripts and Domain Controller Policies executing each time you would log on the machine. Moreover, I think that the C:\Documents and Settings directory was mapped to some network resource as the directory would become inaccessible when network problems occurred.

Anyhow, one day while compiling a BizTalk solution in Visual Studio, I had the following error:

Cryptographic failure while signing assembly ‘MyAssemblyName’ Access is denied.

The cause was that I had lost access rights in the following directory: C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys.  I don’t know why I had lost access rights but it was probably due to one of those unusual scripts/policies loaded at startup… and I never had such error on any other environments. After giving myself full access rights on that folder, the BizTalk solution would compile without error.

In the following screenshot I gave full access right to “Everyone” for simplicity sake as more than one user needed the access rights.

crypto_RSA_Folder_ACL

 

Conclusion:

The underlying reason for the compilation error is that because BizTalk libraries are deployed to the GAC, they must be signed with a strong name key file. As the signing process uses the C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys folder, the assembly could not be signed without being able to access the folder and the compilation would faild. Once I fixed the access rights, the assembly could be signed and Visual Studio could compile the BizTalk solution successfully.

This means that this error can happen any time the folder is needed such as in the following scenarios:

  • Compiling a Visual Studio project which assembly is signed.
  • Compiling a project or solution containing strongly signed assemblies through msbuild and/or TFS.
  • Generating a strong name key file with Visual Studio or with the utility sn.exe
There are probably other scenarios this folder is used for but it will obviously always be related to cryptography.

 

Failure to configure BizTalk BRE on named SQL Server instance‏.

I was installing BizTalk on a multi server environment and it failed while configuring BizTalk Server Business Rules Engine (BRE) with an error I never had before so I thought to write a little post about it in case it helps someone some day.

The infrastructure was as follow:

  • BizTalk Server: Windows Server 2008.
  • SQL Server: Windows Server 2008 cluster (2 nodes).
  • The SQL Server was clustered, running on a named instance on a custom port (instead of the default TCP port 1433).
  • There is a Firewall between the BizTalk Server and SQL Server with only the necessary ports open.
  • SQL Browser is not running.

Symptoms:

When configuring BizTalk Server; Enterprise SSO, BizTalk Group, the BizTalk runtime and all their respective databases could be configured successfully but the BRE (Business Rules Engine) failed to be configured correctly.

When looking at the log file, I saw the following error:

[ Error RulesEngine] System.Net.Sockets.SocketException (0x80004005): No such host is known at System.Net.Dns.GetAddrInfo(String name) at System.Net.Dns.InternalGetHostByName(String hostName, Boolean includeIPv6)

Solution:

This was quite puzzling as I could not see why all BizTalk services and Databases could be configured correctly except for BRE. The only thing I could think of from the error message was that the tool configuring BRE was using a different way to connect to the SQL Server machine.
While defining the SQL Server Name in the BizTalk Server Configuration tool, I used the following syntax:
<SQLServerName>,<PortNumber>\<SQLInstanceName>.
I then tried to reconfigure BRE using an alternative syntax I knew of:
<SQLServerName>\<SQLInstanceName>,<PortNumber>.
This did the trick and BRE got configured correctly. As I said before, this is probably due to the underlying API used to connect to the SQL Server box.

As it was a little disturbing for me that the former syntax works in most cases (and particularly in SQL Server Management Studio) but does not work for the Business Rule Engine part of BizTalk Server configuration, I decided to dig out a little more to find out what was the actual canonical syntax. After a quick research, I realized that it is redundant to specify both the SQL Server Instance Name and the port number because a SQL Server instance is mapped to only one TCP port. This is actually what SQL Browser does, it converts the Instance Name to the TCP port number the Named Instance listens to. On a side note, SQL Browser will map the Instance Name to a named pipe when using the named pipe protocol instead of TCP.
So the actual canonical syntaxes are either:

  • <SQLServerName>\<SQLInstanceName> in case SQL Browser is running.
  • <SQLServerName>,<PortNumber> for TCP connection in case SQL Browser is not running.
  • <SQLServerName>\<pipe>\<pipename> for named pipe connections in case SQL Browser is not running.

Conclusion:

I shall stick to the canonical syntax instead of using uncommon alternatives, especially the one I was using: <SQLServerName>,<PortNumber>\<SQLInstanceName>.

References:

SQL Server Browser Service

SqlConnection.ConnectionString Property

 

BizTalk Orchestration variables default values

I often forget if by default, a string variable in a BizTalk orchestration is null or an empty string. Most of the time it does not matter but sometimes it does. So this post about BizTalk Orchestration variables default values is mostly for my own use so that I don’t forget again!

To be short, the default value of a string variable in an orchestration is: String.Empty!

The problem of default values does not happen for orchestration variables of other basic types than string as they all incur a compile time error if the variable is used before a value is assigned to it. There are 2 ways to initialize an orchestration variable:

  • Set a value in the “Initial Value” property of the variable’s Properties window.
  • Assign a value to the variable in an Expression Shape.

The compile time error aforementioned looks like: error X2109: use of unassigned local variable ‘aVar’.

If the variable is not initialized and also not used, the compiler will not throw an error but a warning instead: warning X4005: ‘aVar’ is declared but never used.

The only exception to this rule is for boolean variables which are always initialized. Indeed when creating such a variable, the “Initial Value” property is “True” by default.

So the summary is:

Orchestration Variable Type Default Initial Value Compilation error if no value assigned Compilation Warning if variable not used
boolean True N/A Yes
string String.Empty N/A Yes
Other basic types (int32, byte, datetime, timespan…) None Yes Yes

Debug a process on a remote machine not having Visual Studio installed

This article will explain how to do remote debugging with Visual Studio.

I had to debug a BizTalk application that is running on a remote integration server on which Visual Studio is not installed. Actually, the remote server was a Virtual Machine but that does not change anything.
I took the following steps to be able to debug the remote BizTalk process from my development machine on which Visual Studio is installed:

  1. Copy the Remote Debugger folder from the development machine (having Visual Studio installed) to the remote machine. If you don’t find it, its location can be found from Visual Studio’s start menu. For VS 2005, VS 2008, VS 2010 it respectively is:
    1. <Program Files>\Microsoft Visual Studio 8\Common7\IDE\Remote Debugger\
    2. <Program Files>\Microsoft Visual Studio 9.0\Common7\IDE\Remote Debugger\
    3. <Program Files>\Microsoft Visual Studio 10.0\Common7\IDE\Remote Debugger\

    The <Program Files> token is Visual Studio installation folder which is by default C:\Program Files (x86)\ on 64 bit machines and C:\Program Files\ on 32 bit machines. Note that on 64 bit machines, VS 2005 has the 64 bit remote debugger in C:\Program Files\ and the 32 bit debugger in C:\Program Files (x86)\. VS2010 has all the debugger versions under C:\Program Files (x86)\.

  2. Start Visual Studio Remote Debugging Monitor on the remote machine. The process is called msvsmon.exe. I executed it with the “Run as” option using the domain user name that I use on my development machine to avoid credential issues and to give unrestricted access to the debugger process.
    msvsmon.exe run as
  3. After the remote debugging monitor process is started, copy the Server Name in the clipboard or in notepad. The Server Name is found by clicking Tools -> Options. The remote debugging monitor server name has the following format: DomainName\UserName@MachineName.
    msvsmon.exe Visual Studio Remote Debugging Monitor
  4. Copy the necessary libraries and symbol files (.dll and .pdb) in a directory on the remote machine. For the sake of this example let’s put them in C:\Code\Debug
  5. Configure Visual Studio on the local development machine so that it can instructs the remote debugging monitor on where to find the symbol files (.pdb). To do that, open Visual Studio and go to Tools -> Options -> Debugging -> Symbols and set the path where msvsmon.exe can find the pdb files on the remote machine. It is C:\Code\Debug in our example.
    Visual Studio Options Debugging Symbols Location
  6. Attach the remote process to debug by Visual Studio’s debugger. When the project is loaded in Visual Studio and breakpoints are set, go to Debug -> Attach to Process. In the Qualifier field, put the Server Name published by the remote debugging monitor that we took note of in step 3. Click refresh so that the processes of the remote server are displayed.
    Visual Studio Debugger Attach To Remote Process
  7. Select the process that you want to debug and click Attach. In our case we want to debug a BizTalk application so the BizTalk process (BTSNTSvc.exe) was chosen. Confirm “Attach” on the security warning dialog.
    Visual Studio Debugger Attach To Remote Process Warning

That’s it, it is now possible to debug on the remote server! For BizTalk scenarios this can prove very powerful to debug orchestrations when the Orchestration debugger is not enough or when we want to debug a .Net library that is loaded as part of some BizTalk processing (pipelines, orchestrations, maps …).