MSBuild doesn't copy references (DLL files) if using project dependencies in solution

前端 未结 19 1331
Happy的楠姐
Happy的楠姐 2020-11-22 07:24

I have four projects in my Visual Studio solution (everyone targeting .NET 3.5) - for my problem only these two are important:

  1. MyBaseProject &
相关标签:
19条回答
  • 2020-11-22 08:08

    As Alex Burtsev mentioned in a comment anything that’s only used in a XAML resource dictionary, or in my case, anything that’s only used in XAML and not in code behind, isn't deemed to be 'in use' by MSBuild.

    So simply new-ing up a dummy reference to a class/component in the assembly in some code behind was enough convince MSBuild that the assembly was actually in use.

    0 讨论(0)
  • 2020-11-22 08:09

    This requires adding a .targets file to your project and setting it to be included in the project's includes section.

    See my answer here for the procedure.

    0 讨论(0)
  • 2020-11-22 08:09

    I had a similar issue today, and this is most certainly not the answer to your question. But I'd like to inform everyone, and possibly provide a spark of insight.

    I have a ASP.NET application. The build process is set to clean and then build.

    I have two Jenkins CI scripts. One for production and one for staging. I deployed my application to staging and everything worked fine. Deployed to production and was missing a DLL file that was referenced. This DLL file was just in the root of the project. Not in any NuGet repository. The DLL was set to do not copy.

    The CI script and the application was the same between the two deployments. Still after the clean and deploy in the staging environment the DLL file was replaced in the deploy location of the ASP.NET application (bin/). This was not the case for the production environment.

    It turns out in a testing branch I had added a step to the build process to copy over this DLL file to the bin directory. Now the part that took a little while to figure out. The CI process was not cleaning itself. The DLL was left in the working directory and was being accidentally packaged with the ASP.NET .zip file. The production branch never had the DLL file copied in the same way and was never accidentally deploying this.

    TLDR; Check and make sure you know what your build server is doing.

    0 讨论(0)
  • 2020-11-22 08:10

    I had the same problem.

    Check if the framework version of your project is the same of the framework version of the dll that you put on reference.

    In my case, my client was compiled using "Framework 4 Client" and the DLL was in "Framework 4".

    0 讨论(0)
  • 2020-11-22 08:15

    I'm not sure why it is different when building between Visual Studio and MsBuild, but here is what I have found when I've encountered this problem in MsBuild and Visual Studio.

    Explanation

    For a sample scenario let's say we have project X, assembly A, and assembly B. Assembly A references assembly B, so project X includes a reference to both A and B. Also, project X includes code that references assembly A (e.g. A.SomeFunction()). Now, you create a new project Y which references project X.

    So the dependency chain looks like this: Y => X => A => B

    Visual Studio / MSBuild tries to be smart and only bring references over into project Y that it detects as being required by project X; it does this to avoid reference pollution in project Y. The problem is, since project X doesn't actually contain any code that explicitly uses assembly B (e.g. B.SomeFunction()), VS/MSBuild doesn't detect that B is required by X, and thus doesn't copy it over into project Y's bin directory; it only copies the X and A assemblies.

    Solution

    You have two options to solve this problem, both of which will result in assembly B being copied to project Y's bin directory:

    1. Add a reference to assembly B in project Y.
    2. Add dummy code to a file in project X that uses assembly B.

    Personally I prefer option 2 for a couple reasons.

    1. If you add another project in the future that references project X, you won't have to remember to also include a reference to assembly B (like you would have to do with option 1).
    2. You can have explicit comments saying why the dummy code needs to be there and not to remove it. So if somebody does delete the code by accident (say with a refactor tool that looks for unused code), you can easily see from source control that the code is required and to restore it. If you use option 1 and somebody uses a refactor tool to clean up unused references, you don't have any comments; you will just see that a reference was removed from the .csproj file.

    Here is a sample of the "dummy code" that I typically add when I encounter this situation.

        // DO NOT DELETE THIS CODE UNLESS WE NO LONGER REQUIRE ASSEMBLY A!!!
        private void DummyFunctionToMakeSureReferencesGetCopiedProperly_DO_NOT_DELETE_THIS_CODE()
        {
            // Assembly A is used by this file, and that assembly depends on assembly B,
            // but this project does not have any code that explicitly references assembly B. Therefore, when another project references
            // this project, this project's assembly and the assembly A get copied to the project's bin directory, but not
            // assembly B. So in order to get the required assembly B copied over, we add some dummy code here (that never
            // gets called) that references assembly B; this will flag VS/MSBuild to copy the required assembly B over as well.
            var dummyType = typeof(B.SomeClass);
            Console.WriteLine(dummyType.FullName);
        }
    
    0 讨论(0)
  • 2020-11-22 08:15

    Changing the target framework from .NET Framework 4 Client Profile to .NET Framework 4 fixed this problem for me.

    So in your example: set the target framework on MyWebProject1 to .NET Framework 4

    0 讨论(0)
提交回复
热议问题