2

I'm hoping I've overlooked something here but I've hit a problem, for which I can't find a happy work-around.

I'm using VSTS for my CI solution. Each commit, the BizTalk apps are fetched to a dedicated build server, compiled and the unit tests are executed.

I don't want any of my BizTalk solution assemblies to find their way into the GAC on the build server because Visual Studio will compile with these, rather than project references.

The problem comes when the build agent attempts to build a solution that contain a custom functoids project, I get the following error:

Functoid not found: guid (1d5de785-c639-4040-9704-c65a11127115) with functoid id (6003). Check if the assembly implementing this functoid is present in D:\Program Files (x86)\Microsoft BizTalk Server 2013 R2\Developer Tools\Mapper Extensions. If the functoid does not expose any inline code, make sure its assembly is made available in the GAC also

So, the functoid assembly needs to be in the GAC? Trouble is, that references a common.components assembly which means that will also need to be GAC'd, which puts me right back in the place I don't want to be! This is a problem because the next time the build agent tries to build a project with a reference to common.components, it will use the "old" version that happens to be kicking around in the GAC, rather that the latest version just pulled from the repo and sat alongside the dependent project in the same solution.

If anyone else has hit the same problem, I'd love to hear from you.

Rob Bowman
  • 7,632
  • 22
  • 93
  • 200
  • I'm going to say the correct solution is to update the GAC, which is where all BizTalk App related Assemblies should be always, that's just how it works. "it seems BizTalk projects will use these, rather than project references" that's how .Net resolves Assemblies. Nothing really to do with BizTalk. – Johns-305 Feb 15 '17 at 16:09
  • Thanks for your answer @Johns-305, I agree the assembly resolution is nothing to do with BizTalk (https://msdn.microsoft.com/en-us/library/yx7xezcf(v=vs.110).aspx). However, functoids needing to be in the GAC is what causes this problem. No custom functoids, no problem! If the common.components is in the GAC, then "old" version will be referenced on the build server each time a commit triggers an automated build. The build agent will fetch the latest code for common.components from the remote repo but dependent projects will be build using whatever version happens to be in the GAC – Rob Bowman Feb 15 '17 at 17:33
  • 2
    Sorry, I still don't get the problem. The build should update everything necessary. Meaning, there shouldn't be 'old' versions of anything in the GAC. They should get updated at build time as well, either naturally or as a specific build step. – Johns-305 Feb 15 '17 at 17:50
  • Ah, so have a post build step in VS for the common.components project to update the GAC. I think that could work! I'll give it a try – Rob Bowman Feb 15 '17 at 17:53

2 Answers2

1

I typically put something like the following in my BizTalk related projects as a post-build step:

call "$(DevEnvDir)..\tools\vsvars32.bat"
gacutil.exe /if "$(TargetPath)"

I'm fairly sure that $(DevEnvDir) won't resolve on the build server though. There are a few work arounds - you can make sure to install the Windows SDK and set the proper registry key (like here Running MSBuild fails to read SDKToolsPath), or you could just otherwise set an environment varaible on the build server that has the path to gacutil, or you could use something like the MSBuild community tasks (https://github.com/loresoft/msbuildtasks) which has a GacUtil task, or perhaps even run a powershell script like so:

#Note that you should be running PowerShell as an Administrator
[System.Reflection.Assembly]::Load("System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")            
$publish = New-Object System.EnterpriseServices.Internal.Publish            
$publish.GacInstall("C:\Path\To\DLL.dll")

(from https://www.andrewcbancroft.com/2015/12/16/using-powershell-to-install-a-dll-into-the-gac/).

Do note that the build process will need to run with (local) administrative privileges to successfully GAC the library.

Edit: Since I've run into this problem locally, I've used this and it works in every environment I've tested (regardless of which windows SDK is installed or whether the admin of the machine put it on the C, D, or other drive...):

powershell -c "[System.Reflection.Assembly]::Load('System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'); $publish = New-Object System.EnterpriseServices.Internal.Publish; $publish.GacInstall('$(TargetPath)');"
Community
  • 1
  • 1
Dan Field
  • 20,885
  • 5
  • 55
  • 71
0

Thanks to @Johns-305 for the answer - I was overthinking this one!

I added the following as a post build event for the Common.Components project:

"C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\gacutil.exe"  /i "$(TargetPath)"
Rob Bowman
  • 7,632
  • 22
  • 93
  • 200