Dynamics GP Add in “Cannot load file or assembly Microsoft.Lync.Utilities”

GP Add in raised exception

After applying GP2010 SP3 my GP add in started raising an exception on windows forms that used Entity Framework (EF). The error reported was

System.IO.FileNotFoundException: Could not load file or assembly ‘Microsoft.Lync.Utilities, Version=…"

…but I don’t use Lync…

But I know Dynamics GP does have integration with Lync. It had me puzzled for a while as I wondered why my form was causing this assembly to be required and attempting to load it. Eventually the penny dropped after studying the stack trace. The stack trace was mentioning about System.Reflection and System.Data.Metadata.Edm.DefaultAssemblyResolver.GetAllDiscoverableAssemblies().  I guessed there was some dynamic loading going on and got mislead reading up on MEF, thinking perhaps GP implemented it under the covers. I then hit lucky on Google with Craig Suntz’s blog that explained my issue. It is down to Entity Framework connection strings.

Entity Framework Connection Strings

In my EF connection string I was building my connection string like this from the SQL connection string.

Dim entityBuilder As New EntityClient.EntityConnectionStringBuilder()
entityBuilder.Provider = "System.Data.SqlClient"
entityBuilder.ProviderConnectionString = sqlBuilder.ToString
entityBuilder.Metadata = _
Return entityBuilder.ToString()

Notice the “res://*” bit, the Metadata reference. The files are embedded into the assembly as resources and this Metadata property is the pointer to them. Specifying * instructs a reflective search through all assemblies (even if not yet loaded)  that are referenced by the application, looking for the resources.

I guess that as Lync SDK was referenced by GP 2010 my attempt to create the connection was causing the Lync assembly to be loaded in order to check it for the meta file resource. The consequence of this is that we got an application exception as that assembly does not exist on the machines in our organisation.


The solution is to explicitly specify the assembly name that holds the resource as shown in the next code snippet. Making this exact reference is more efficient by it preventing unnecessary loading of assemblies and thus preventing the error . This is interesting as I’d experienced a performance hit on these windows vs ones not using EF. I assume some of that was down to this attempt to load all the assemblies.

Dim entityBuilder As New EntityClient.EntityConnectionStringBuilder()
entityBuilder.Provider = "System.Data.SqlClient"
entityBuilder.ProviderConnectionString = sqlBuilder.ToString
entityBuilder.Metadata = "res://GP AddIn GUI Library/Inventory.DAL.InventoryModel.csdl|res://GP AddIn GUI Library/Inventory.DAL.InventoryModel.ssdl|res://GP AddIn GUI Library/Inventory.DAL.InventoryModel.msl"
Return entityBuilder.ToString()


After recompiling and then deploying to the GP add in folder, my problem went away. I suspect if I spent some more time on this that the Lync assemblies are stuffed into the Global Assembly Cache by the SP3 installer, as we do copy deployments to the client machines we will be missing those assemblies. Hence not everyone may suffer this issue when using add ins if you run the full installer. However this guesswork needs researching and I’ve not got time right now to investigate.

About MEF (Microsoft Extensibility Framework)

In my Google search of the issue, it looks like you can get issues around MEF with dynamically loading assemblies, so for those of you finding this post through Google and not using Dynamics GP, then that might be a term to try on Google for a solution in your scenario.

Below is the original error

Raised by by Add-in for those still with an interest…


Formatting notes using GP econnect

Note to self:


My solution is to run in a stored procedure after econnect,

-- fix formatting of the notes field that gets screwed up by econnect loosing line breaks     
UPDATE  sy03900
    SET txtfield = replace(CAST (txtfield AS VARCHAR (MAX)), CHAR(10), char(13))
                    FROM   rm00101
                    WHERE  custnmbr = @CUSTNMBR);
UPDATE  sy03900
    SET txtfield = replace(CAST (txtfield AS VARCHAR (MAX)), CHAR(10), char(13))
                    FROM   sop10100
                    WHERE  soptype = @SOPTYPE
                           AND sopnumbe = @SOPNUMBE);

Solution to Excel Automation VB.NET/C# error running as a service 0x800A03EC - Microsoft.Office.Interop.Excel.Workbooks.Open

Overview of issue

When automating excel using a non-interactive session as a service or windows task scheduler it failed with an exception System.Runtime.InteropServices.COMException (0x800A03EC).

This did not happen when the same task was ran from the command prompt as the same user. The stack trace showed it was when we tried to open the excel sheet Microsoft.Office.Interop.Excel.Workbooks.Open

Automating Excel like this is strictly warned against by Microsoft as it is a pain. There are so many possible issues you have to work through.

Microsoft does not currently recommend, and does not support, Automation of Microsoft Office applications from any unattended, non-interactive client application or component (including ASP, ASP.NET, DCOM, and NT Services), because Office may exhibit unstable behaviour and/or deadlock when Office is run in this environment.

Microsoft strongly recommends that developers find alternatives to Automation of Office if they need to develop server-side solutions. Because of the limitations to Office's design, changes to Office configuration are not enough to resolve all issues. Microsoft strongly recommends a number of alternatives that do not require Office to be installed server-side, and that can perform most common tasks more efficiently and more quickly than Automation. Before you involve Office as a server-side component in your project, consider alternatives.
Considerations for server-side Automation of Office

However you may manage despite all these strong words to not do it. In our case we had some complex excel documents with complicated formatting that was populated through a datasource that was latterly removed before saving. I didn’t fancy trying that in OpenXML, also we were required to produce old xls type files for output.