I am currently struggling with deployment problems caused by Microsoft.SqlServer.Types
and its associated unmanaged library, SqlServerSpatial110.dll
- both for Microsoft SQL Server 2012. The problems are trivially easy to solve, just typical missing DLL issues, but I am trying to decide on the perfect way to handle these dependencies.
Firstly, I must declare that I do not agree with the popular opinion that manually deploying either library (usually by copying them into your project's output directory or, horrifically, into System32
itself) is correct. Microsoft provide redistributable MSI installers for these files and those installers put the files into system locations. It seems obvious that they want us to depend on those redistributables being installed separately or as part of the tried and tested dependency mechanisms built into MSI itself.
At the time of posting, the latest version of these redistributables could be downloaded from: http://www.microsoft.com/en-gb/download/details.aspx?id=43339
For SqlServerSpatial110.dll
, there does not appear to be any problem. The MSI installers (platform specific) drop the file into either Windows\System32
or Windows\SysWOW64
as is appropriate and all is well.
The managed wrapper library, Microsoft.SqlServer.Types.dll
, is more confusing.
It seems to me that the file is dropped into the Global Assembly Cache - after running the MSIs, on my machine, I can see it located at C:\Windows\assembly\GAC_MSIL\Microsoft.SqlServer.Types\11.0.0.0__89845dcd8080cc91\Microsoft.SqlServer.Types.dll
and that file has the correct version and modified-date.
Oddly, I can't see it in Visual Studio's reference browser or in Windows Explorer directly - only in my very old fashioned file-system search tool by Mythicsoft. Why can't I see it?
Since the file is almost in the GAC, I would guess that projects referencing it should not make a local copy of it - they should rely on it being there on the target system. I tested this assumption and it worked:
Microsoft.SqlServer.Types.dll
from its location in C:\Windows\assembly\GAC_MSIL
Copy Local
set to False
Microsoft.SqlServer.Types.dll
is definitely not present in the output.So, if the assembly can be resolved from the GAC at runtime to satisfy this dependency, why isn't it shown in the reference browser when adding a reference? Why do I have to copy it out of the GAC and reference the copy?
In my mind, the ideal work-flow would be this:
Microsoft.SqlServer.Types
from the GAC using the reference browser just like any framework library. (Copy Local
will be set to False
by default.)Microsoft.SqlServer.Types
(platform agnostic) will be resolved from the GAC and the appropriate copy of the unmanaged library will be loaded from the system location depending on the process architecture.Clearly, step 3 doesn't happen. Am I missing something? Perhaps I am misunderstanding the GAC itself - it wouldn't be the first time. Why has Microsoft done it this way? Can I get closer to my ideal work-flow?
Perhaps there is an entirely different way of managing this dependency - something I have clearly not thought of. If so, what is it? How do you handle it?
If this is a one click deployment then go to the Project|Properties|Publish tab and click the "Application Files..." button. You should then select the dependent file and make sure The "Include(Auto)" is selected for the "Publish Status" value. The reason being is that is appears that VS is smart enough to determine if the file is part of a known redistributable and this giving you the option to depend on the external package during install as a dependency or manage the file yourself. If you depend on the package then the end user can uninstall via add remove programs and your app is busted :/