开发者

Visual Studio 2008 .dll files cannot be overwritten, access denied

This one is weird. Visual Studio 2008 seems to not be releasing its handle to the .DLLs 开发者_开发百科getting created for my project, so the second time (and subsequent times) I build, when Studio attempts to overwrite the changed .dlls, it gets an access denied error. I also cannot copy/delete the .dll in question (Tasks.dll) while Visual Studio is open after I've built once. Process Explorer tells me that the file is in use by devenv.exe, so I know Visual Studio isn't letting go of it after the build finishes.

Has anyone seen this before, and if so, what can I do about it? Obviously, opening and closing visual studio between every build is not an acceptable solution, and the problem has persisted across system restarts.

Some more background: I am using the error-causing project's DLL (Tasks.dll) in a UsingTask MSBuild directive in another project, let's call it Test. Project build order is set so that Tasks is built before Test, and then Test's AfterBuild task calls a task from /bin/debug/Tasks.dll.


Sure. We had the same problem. I cannot say when exactly the problem occurs and what conditions are to reproduce it, but in our situation it happened in the project in which we had multiple modules and each module referenced multiple other modules, and referenced modules had also references to other modules etc.

It was really annoying, and we lost many hours trying to find out what is the problem, and how it can be solved, but unsuccessfully.

We couldn't refactor project to simplify references (too expensive), we couldn't also spend more time to investigate problem so we found workaround - not perfect, but it helped us, and we use it for years in that project. It is a little bit complicated, but I will try to describe it:

  1. First of all - example project structure
     - MyProject (dir)
       - Bin (dir)
         * Proj1.exe
         * Proj2.dll
         * Proj3.dll
       - Src (dir)
          - Proj1 (dir)
          - Proj2 (dir)
              - bin (dir)
          - Proj3 (dir)
              - bin (dir)

  2. Proj1 (which, let's assume is console/windows application - *.exe) has output dir set to MyProject/Bin

  3. Proj2 (.dll) has build output set by default to MyProject/Src/Proj2/bin/... in the postbuild event we copy result to "MyProject/Bin"

    copy "$(TargetDir)\$(TargetName).dll" "$(SolutionDir)Bin"
    copy "$(TargetDir)\$(TargetName).pdb" "$(SolutionDir)Bin"

  4. Proj3 (.dll) has build output set by default to MyProject/Src/Proj3/bin/... postbuild is the same like for Proj2

  5. And now references. Let's say Proj1 needs reference to Proj2 and Proj2 needs reference to Proj3.

    • for the first time build only Proj3, so that in the result of postbuild event commands it will be copied to MyProject/Bin
    • now to Proj2 add reference to assembly MyProject/Bin/Proj3.dll (browse to assembly file, do not reference project). In the project dependencies manually set that this project requires to build Proj3 first. Afterwards build "Proj2" so that it will be copied to MyProject/Bin (postbuild event commands)
    • and finally to Proj1 add reference to assembly MyProject/Bin/Proj2.dll (again browse to assembly). In the project dependencies manually set that this project requires Proj2 to build firs. And from now you can build whole solution.

Main problems with above approach:

  • complicated to configure and maintain, especially when project is growing and new projects are added often.
  • when you will checkout project to fresh directory and you are using tools like ReSharper which analyzes code, it will report lots of errors until first build.
  • to reduce compilation time you need to manually set for each reference that it should not be copied locally.
  • this is still sometimes happen that some files are in use, but in our environment it can happen sometimes once per week, sometimes once per month.


The easiest thing that you can do in this situation is use the taskkill command to kill the Visual Studio process and all of its child processes.

You can call this from the Command Prompt or from PowerShell.

taskkill -IM devenv.exe /F /T

The two arguments are for /Force and /T kills the child processes as well.

NOTE: enter taskkill -? on the command line for more info.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜