4

I have a custom MSBuild task(resides in assembly A) to build a custom project type(let's call it 'TestAppContent'). 'A' references another assembly 'B' that is currently under development.

To test 'B', I use a test program, TestApp. TestApp depends on TestAppContent getting build using our custom task.

The problem is that after the task is loaded, 'B' assembly is locked by MSBuild or VisualStudio process as the assembly that contains the task('A') has a reference to it.

As I can't simply 'unload' an assembly and using separated AppDomain doesn't work, how can I stop this lock?

I know that Microsoft XNA can do this as you can supply custom assemblies to the build process and they are released after it so you can rebuilt those custom assemblies.

Tim M.
  • 53,671
  • 14
  • 120
  • 163
greenboxal
  • 469
  • 3
  • 16

3 Answers3

2

The only way is to use an AppDomain and activate the Shadow Copy on it. I don't think you can activate shadow copy on current AppDomain, but you can try (see question here)

Or you can manually copy the dll elsewhere and load it (programmatically) so that the original dll will not be loaded and will remain unlocked. But you can't load the same dll twice... so you'll need a separate AppDomain if you want to unload and load a new version (or you restart your program)

EDIT: You can also use AppDomain.CurrentDomain.AssemblyResolve to intercept when you program try to load a dll. There you can copy it elsewhere and load this copy.

Community
  • 1
  • 1
Fabske
  • 2,106
  • 18
  • 33
  • I can't restart it because the program that load and lock it is Visual Studio. I'll try the shadow copy using a temporary directory, but it would copy the files each time I issue a build, too much disk waste. – greenboxal Apr 07 '13 at 02:19
  • Yes but shadow copy is handled by windows, which *should* delete the temp files regularly – Fabske Apr 07 '13 at 18:41
2

I think it won't help you that much since you're trying to achieve it automatically but one manual way to achieve this i found out was using sysinternals ProcessExplorer to kill the specific process using the dll. But killing doesn't seem to harm VS2013, which makes this is a workaround without the need to restart MSVS.

In this case my Visual Studio process instantiated an MSBuild instance which previously created the DesignLibrary assembly - now being locked, which the project SomeLibrary uses right within the build only. At this point it is not possible to rebuild the DesignLibrary assembly without killing the MSBuild task holding the lock.

I would like to have the MSBuild.exe checking during the build if it tries to rebuild a file created by itself, or maybe visual studio intervening this messy situation. Just another thought: Maybe it might be possible to inspect the process tree and kill the process automatically, like i did manually. A very hacky workaround ;)

isaias-b
  • 2,255
  • 2
  • 25
  • 38
0

One way I usually solve this is by having two solutions. The first builds the Tasks and then I hook it up to launch devenv.exe to load the second .sln when I press F5.

The second solution consumes the task built in the first causing it to be loaded into the second devenv.exe process. When you stop debugging the second Visual Studio will close and the assembly with the build task will be released.

justin.m.chase
  • 13,061
  • 8
  • 52
  • 100