MSBuild doesn't release custom tasks assemblies after compile?
Hi,
I've been experimenting with custom tasks, after reading the great article:
http://msdn.microsoft.com/msdnmag/issues/06/06/InsideMSBuild/default.aspx
My question is:
I've built 2 projects, 1 containing a custom task, and the other containing this code in the csproj file:
<
Target Name="AfterBuild"><
CustomTask /></
Target>Everythings works fine the first time I build. But when editting the task and rebuilding, it says:
Error 1 Unable to copy file "d:\projects\tests\CustomBuild\CustomCompiler\bin\Debug\CustomCompiler.dll" to "bin\Debug\CustomCompiler.dll". The process cannot access the file 'bin\Debug\CustomCompiler.dll' because it is being used by another process.
I assume this is because <UsingTask> uses Assembly.LoadFrom(), and the AppDomain doesn't get unloaded after compilation.
Is there any solution for the problem?
Best Regards,
Tomer
Answers
- Hi there,
Unfortunately this is because MSBuild loads task assemblies in the primary appdomain. The CLR does not allow assemblies to unload from an appdomain as this allows important optimizations on their part.
The only workarounds I suggest is to call out to msbuild.exe to build the projects that use the task. To do this, create MSBuild.exe <<your project>> as an external tool in VS.
Dan
developer on msbuild- Marked As Answer byMike FourieModeratorSaturday, October 31, 2009 8:52 AM
- Try basing your task on the AppDomainIsolatedTask rather. http://msdn.microsoft.com/en-us/library/microsoft.build.utilities.appdomainisolatedtask.aspx
- Marked As Answer byMike FourieModeratorSaturday, October 31, 2009 8:51 AM
All Replies
I'm encountering the exact same problem. Has anybody discovered a solution for this? Right now, I have to close out VS2005 completely and restart it to have my custom task assembly released.
Regards,
RDollarhide
- I had this problem when the dll was registered in the GAC and you do a release and debug build. Then one is not able to deregister the DLL from the GAC.
- "Me too"
- Do you register the assembly for com interop? If so try without it.
That's the same as ComVisible, correct? It's currently set to false.
- Same here :-(
- Hi there,
Unfortunately this is because MSBuild loads task assemblies in the primary appdomain. The CLR does not allow assemblies to unload from an appdomain as this allows important optimizations on their part.
The only workarounds I suggest is to call out to msbuild.exe to build the projects that use the task. To do this, create MSBuild.exe <<your project>> as an external tool in VS.
Dan
developer on msbuild- Marked As Answer byMike FourieModeratorSaturday, October 31, 2009 8:52 AM
- HeyAnother workaround, as opposed to shutting down VS, is to rename the DLL. But the problem will still remain.
- Try basing your task on the AppDomainIsolatedTask rather. http://msdn.microsoft.com/en-us/library/microsoft.build.utilities.appdomainisolatedtask.aspx
- Marked As Answer byMike FourieModeratorSaturday, October 31, 2009 8:51 AM
- I gave AppDomainIsolatedTask a try but I still seem to be encountering a problem.In my scenario in Visual Studio I have ProjectB using ProjectA as a reference. ProjectA contains the task that is used by ProjectB's msbuild. Occasionally when compiling ProjectB I get an error along the lines of "Cannot copy ProjectA.dll to ProjectB/bin/debug/ProjectA.dll as another process is using this file".The structure of my task is
public class ProjectATask : Microsoft.Build.Utilities.AppDomainIsolatedTask { private string path = ""; [Required] public string Path {.........} public override object InitializeLifetimeService() { return base.InitializeLifetimeService(); } public override bool Execute() {..........} }
Is there anything else I can do to fix this problem? - You say 'occasionally'... Can you run processmon to see what has the lock on it. I'm guessing its VS, but you may be lucky and its the indexing / antivirus service, in which case disable that. Maybe you could stick a sleep into the BeforeBuild target in ProjectB.... not tried this. Did the AppDomainIsolatedTask help at all?
- The process that has captured it is devenv.exe (part of VS). Sadly AppDomainIsolatedTask does not seem to have helped at all. Normally the dll is grabbed after I modify ProjectA (but not always). The task in question does two things 1) Checks some code in ProjectA to verify that its correct (I'm using reflection to map between two layers instead of a switch statement - hence getting this working would be like using the compiler to verify my code. e.g. Command A maps to Task B - ensure that Command A has a correct string mapping to Task B's method name (dangerous I know - but time saving)). 2) Check a properties file in ProjectB to ensure it has defined all the required keys. If I could get this working it would really put a shine on the project.


