Tag Archives: GAC

GAC folders

I keep forgetting exact GAC folders’ locations and whenever I try to Google this information it is always buried under some layers of misunderstanding and confused discussions. This steams from the fact that there are different locations depending on .NET version and bitness of your assemblies. So I’m just jotting down all the locations here for quick reference:

.NET 2.0 GAC:  C:\Windows\assembly

.NET 4.0 GAC: C:\Windows\Microsoft.NET\assembly

Now each of this folder has the following sub-folders:

GAC_32 for 32-bit assemblies (defines word size)

GAC_64 for 64-bit assemblies  (defines word size)

GAC_MSIL for assemblies that can be run in either 32-bit or 64-bit mode which are JIT compiled to the required word size as needed

On machines with x86/32-bit version of Windows (which is way too rare now, especially for Windows Server) there is only GAC_32 subfolder, and on x64 OS machines there are both GAC_32 and GAC_64 folders as 32-bit code is supported via emulation (WOW32).

“Method not found error” when attempting to add a new item into K2 Studio project

The other day I was about to build some tiny K2 test project using old-fashioned thick designer UI K2 Studio which I still prefer to use whenever I need to build some little K2 process. Unfortunately I bumped into this error:

Error message politely informs us about this:

Method not found: ‘Microsoft. Build. BuildEngine

BuildItem SourceCode. ProjectSystem. ProjectBuildItem


That’s not very obvious, right? But, trust me it just complains that some DLL is not properly added to GAC, or there is a mismatch between DLL version in GAC and in some other location.

Solution? If you run K2 environment without coldfixes just run a Repair from installation media. But most likely you’ve applied some coldfix recently. Verify if files which supposed to go to GAC were added to that location correctly. Remember that some files go to K2 installation directory, while some others may go to “[Program Files]Reference Assemblies\SourceCode\v4.0\” and into GAC v4, i.e. into “C:\Windows\Microsoft.NET\assembly\GAC_MSIL\”. In my case the error was caused by the fact that SourceCode.Workflow.Authoring.dll assembly was not updated in GACv4.

When something wrong with aforementioned DLL you will also see the same error when trying to deploy something with PnD:

So in case you getting this type of error you know what to check now.

Do I need to restart K2 host service if I added “NewtonJson.dll into GAC?

Today I was asked by my colleague something on the lines “Do I need to restart K2 host server service if I added “NewtonJson.dll into GAC?”

This is quite an interesting question which I would re-phrase as “Do I need to restart K2 host server service if I added DLL X in location Y?” Unfortunately there is no easy answer, though you may assume that developer should know this for sure. That’s a bit of a myth that “developer as a creator of a program can predict any output from the app for any given input”, and explanation to that phenomenon has surprising parallels with much sought after in middle ages explanation of “how is free will possible in the light of the fact that there is an almighty and all knowing creator in this universe”, buy I guess I will save this philosophical topic for separate blog post.

I’ve split this question into some sub-questions and checked with one of the developers (only to confirm all that was said above).

How K2 service loads DLLs?

It all differs from DLL to DLL.

Little clarification (as I was pointed out that I’m using outdated terminology): DLL stand’s for Dynamic-Link Library and I employ it to refer to any files with DLL extension since my DOS gaming days, whereas modern official term commonly used by developers is assembly. Term comes from the new Global Assembly Cache (GAC) infrastructure. This is machine-wide CLI assembly cache for the Common Language Infrastructure (CLI) in .NET Framewrok, which was designed to allow for specially controlled central repository which addresses the flaws of the shared library concept and helps to avoid DLL hell.

Getting back to the question above: some assemblies we may load in memory on startup and keep there till service restart, but some may be called as needed an then disposed (though again you can’t easily tell when they are disposed, except for service restart). Among those which “load on demand” some loaded by K2 service while others are loaded automatically by .NET. But we have two GAC repositories on modern Windows platform one for .NET v2 and another for .NET v4 and sometimes the same assembly exist in two versions and which one called depends on your application code.

As you can see things can be quite different and it all depends.

Just to illustrate: I remember an issue which may be reproduced in old (pre-4.7) versions of K2 when you erroneously place to GAC SourceCode.Workflow.Resolver.Data.dll. It should not be there in the first place, but if you place it there it is trying to call another DLLs (SourceCode.Workflow.Functions.dll) from current directory as both of them exist in K2 bin folder. Yet as soon as 1st DLL landed to GAC it takes priority over one from the Bin folder, but then errors out as it can’t see 2nd DLL in GAC. So on versions prior to 4.7 workflow will enter into Error state with the following error logged in Error profiles: Assembly ‘SourceCode.Workflow.Functions’ could not be found. In 4.7 workflow will enter into Error state with more actionable error message: “Please remove SourceCode.Workflow.Data.Resolvers from the Global Assembly Cache.”

Do I need to do K2 restart after I GACed NewtonJson.dll, for example?

Probably. NewtonJson.dll is a 3rd party dll K2 uses for JSON serialization and some other things. And whether restart is needed depends on what K2 DLL is using it, but the safest option is always perform a restart of the service. Even IIS sometimes keep a cached copy, and does not use the new one if you replace it until iisreset is performed.

Is there some (relatively) easy way to tell which DLLs can be safely replaced without K2 service restart?

Here we can think that some debug utilities should exist which may tell you which assemblies are used by specific process. I don’t know any of the top of my head and have to reseatch this separately. Normally, if you can overwrite the file, then it already means it is not being used at the moment. But, for example, IIS is different, as it keeps a cached copy in a temp folder somewhere. So it all depends on how specific DLL is loaded/used by each specific service – it may be loaded in memory or some sort of cache hence there is no easy way to determine if service restart is necessary after file replacement. Safe bet in most of the cases, is to perform a K2 service restart.

Just decided it is worth taking a note of this and share with other people who may potentially have similar questions.

Uninstalling assembly from .NET v2 GAC – Assembly Cache Viewer “Access Denied”

Most annoying and confusing part of installing K2 coldfixes (those which involve manual steps) is adding/removing assemblies from GAC – I keep seeing people utterly confused by this process and even despite doing this regularly myself keep bumping into different hurdles from time to time. And judging by amount of questions in the Internet a lot of people experience issues with adding/removing libraries to GAC too.

There is couple of issues with .NET v2 GAC which has so called “Assembly Cache Viewer” representation when you get while browsing to “C:\Windows\Assemlbly” folder. As with any thing designed with some good intentions it is a mixed blessing and especially so when it meets with UAC 🙂 On the one hand it allows for easy uninstall/registration by means of drag and drop, on the other sometimes you can’t uninstall items without cleaning up registry key first and sometimes you have hard time thanks to UAC and Explorer process being always run without elevation.

On my test boxes UAC is normally disabled completely making it easy to work with Assembly Cache Viewer, and in some other cases just disabling UAC by moving respective slider in control panel + reboot solves this or for those avoiding reboots killing explorer and then running it in elevated mode does the trick. But recently I bump into especially annoying scenario where previous battle tested workaround didn’t work for me. Symptoms – you trying to uninstall assembly from .NET v2 GAC – Assembly Cache Viewer and getting “Access Denied”, like that:

Running Exploerer in elevated mode doesn’t help, and if you look at UAC slider in control panel it is already moved to the lowest position pretending to be disabled. Welcome to the world of corporate GPO managed IT environments. This means that User Account Control: run all administrators in Admin Approval Mode policy is Enabled. Solution? gpedit.msc > Security Settings > Local Policies > Security Options > User Account Control: run all administrators in Admin Approval Mode, set this policy to disabled and reboot your machine. Yes, reboot is required. This is really good example of issues that sometimes on a user side/GUI GPOs just silently block stuff with no clear indication of this, consequently even for IT pros it takes some time to figure out that things are failing thanks to those things (think of UAC or IE Enterprise Mode) and unfortunately quickly solving these tiny hiccups largely depends on whether you seen this before or not 🙂

How to browse C:\Windows\Assembly like normal folder

Just a quick note on how to browse physical location of Windows GAC. Normally if you browse to C:\Windows\Assembly using Windows Explorer it will give you this specialized view which looks similar to this:

Assembly Folder

You may saw the same behavior for Fonts folder also. So what’s wrong about this view? Well it doesn’t show you actual files and you can not see file size for example. Quick answer to this will be use of CLI (e.g. cd and dir commands or Get-ChildItem in PowerShell) or alternate file managers (e.g. Total Commander).

But in case you want to do this with Windows Explorer you may just type in the following path using Run menu or Windows Explorer address bar:


Then move to the parent folder (by clicking on it in the explorer bar) to see all the GAC files in a normal explorer window. You can now copy, add and remove files as everywhere else.

See related question on stackoverflow.com – How to view the Folder and Files in GAC?