.NET 参考“复制本地”根据 GAC 内容设置真/假

发布于 2024-08-25 19:52:44 字数 668 浏览 8 评论 0原文

我们在 Win Forms 项目中遇到了一个非常有趣的问题。已经解决了。我们知道发生了什么,但我们想了解为什么会发生。这可能会帮助将来遇到类似问题的其他人。

WinForms 项目在我们客户的 2 台 PC 上失败了。该错误是一个不起眼的 kernel.dll 错误。该项目在另外 3 台 PC 上运行良好。

我们发现我们的发布文件夹中缺少 .DLL(log4net.dll - 一个非常流行的开源日志记录库)。它以前位于我们的发布文件夹中。为什么在最新版本中缺少它?

它丢失了,因为我必须在我的开发盒上安装了一个使用 log4net.dll 的程序,并且它已添加到全局程序集缓存中。

当我检查 log4net.dll 的解决方案引用时,它们被更改为“copy local=FALSE”。它们一定是自动更改的,因为 log4net.dll 存在于我的 GAC 中。

这就是我的问题的开始:

为什么我对 log4net.dll 的引用从 COPY LOCAL = TRUE 更改为 COPY LOCAL = FALSE?我怀疑这是因为它被另一个程序添加到我的 GAC 中。

我们怎样才能防止这种情况再次发生?就目前情况而言,如果我安装一个使用公共库的软件并将其添加到我的 GAC 中,那么引用该 DLL 的 SLN 将从 Copy Local TRUE 更改为 FALSE。

We had a very interesting problem with a Win Forms project. It's been resolved. We know what happened, but we want to understand why it happened. This may help other people out in the future who have a similar problem.

The WinForms project failed on 2 of our client's PCs. The error was an obscure kernel.dll error. The project ran fine on 3 other PCs.

We found that a .DLL (log4net.dll - a very popular open-source logging library) was missing from our release folder. It was previously in our release folder. Why was it missing in this latest release?

It was missing because I must have installed a program on my Dev box that used log4net.dll and it was added to the Global Assembly Cache.

When I checked the solution's references for log4net.dll, they were changed to "copy local=FALSE". They must have changed automatically because log4net.dll was present in my GAC.

Here's where my question starts:

Why did my reference for log4net.dll get changed from COPY LOCAL = TRUE to COPY LOCAL = FALSE? I suspect it's because it was added to my GAC by another program.

How can we prevent this from happening again? As it stands now, if I install a piece of software that uses a common library and it adds it to my GAC, then my SLNs that reference that DLL will change from Copy Local TRUE to FALSE.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

时光与爱终年不遇 2024-09-01 19:52:44

发生这种情况是因为如果程序集安装在 GAC 中,则 Copy Local = True 没有任何意义。由于永远不会使用该本地副本,因此始终首先搜索 GAC。保持不变会导致严重混乱,您会认为您正在使用本地副本,但实际上却获得了另一个副本。更改它也会导致混乱,如果您没有注意到它,这可能可以在解决方案加载时通过消息框解决。

Log4net 是一个麻烦制造者,有太多的版本,没有任何部署过程来确保这些版本不会相互影响。 Apache 显然不想解决这个问题,而是将其留给程序员。拥有依赖 Log4net 并针对已知的 DLL Hell 风险采取措施的产品在某种程度上是不可避免的。给你一个 DLL Hell 问题作为回报。

除了了解计算机上安装的内容之外,没有干净简单的答案。考虑发布到 connect.microsoft.com 以在 Visual Studio 自动更新“复制本地”属性时请求警告。这是一个合理的要求。

That happened because it doesn't make any sense to have Copy Local = True if an assembly is installed in the GAC. Because that local copy will never be used, the GAC is always searched first. Leaving it unchanged would cause major confusion, you'd think you are using the local copy but get another one instead. Changing it causes a confusion too, if you don't notice it, that could perhaps have been addressed with a message box at solution load time.

Log4net is a troublemaker, there are way too many versions in the wild without any deployment procedure that ensures that those versions don't bite each other. Something Apache apparently just didn't want to address, leaving it up to the programmer instead. Having products that take a dependency on Log4net and do something about the perceived DLL Hell risk is somewhat inevitable. Giving you a DLL Hell problem in return.

No clean simple answers, beyond being aware what's installed on your machine. Consider posting to connect.microsoft.com to ask for a warning when Visual Studio automatically updates the Copy Local property. It is a reasonable ask.

鸩远一方 2024-09-01 19:52:44

我在我们的构建服务器上找到了一个解决方案。

问题:
在某个特定日期,无缘无故(我现在假设该文件已添加到 GAC 中),程序集 System.Web.MVC.dll 从我们的许多项目中消失了。我确信这适用于任何有问题的 dll。

解决方案:
在 Visual Studio 中更改引用(假设 Copy Local 已经为 True)。

  1. 将 Copy Local = True 更改为 Copy Local = False
  2. 将 Copy Local Back 更改为 True
  3. 请注意,在 .csproj 文件中添加了 True
  4. 现在编译,您将看到 dll 确实被包含在内,尽管消息保持不变。

解决方案2:
手动添加 True 属性。

结论:
我对 的理解是它是 Copy Local,因此如果 Copy Local = True 则应添加 Private 属性,但在我们的情况下至少没有。

其他注意事项:

  1. 使用 Visual Studio 2013 和 2015 进行测试。
  2. 使用 msbuild 12 和 14 进行测试。
  3. 使用 TFS 构建模板进行测试。
  4. 我们的代码已从 2008 年的 Visual Studio 升级到 2015 年的 Visual Studio,当时该标志可能在某个地方被搞乱了,但直到程序集以某种方式添加到 GAC 中时问题才开始出现。

最终结果:

<Reference Include="System.Web.Mvc, Version=4.0.0.1, Culture=neutral,PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
 <HintPath>packages\Microsoft.AspNet.Mvc.4.0.40804.0\lib\net40\System.Web.Mvc.dll        </HintPath>
        <Private>True</Private>
    </Reference>

I found a solution for us on our build servers.

Problem:
In a specific date for no reason (I now assume the file was added to the GAC) the assembly System.Web.MVC.dll disappeared from many of our projects. I am sure this applies to any dll with the issue.

Solution:
In visual studio change the reference (assuming Copy Local is already True).

  1. Change Copy Local = True to Copy Local = False
  2. Change Copy Local Back to True
  3. Notice in the .csproj file a <Private>True</Private> is added.
  4. Compile now and you will see the dll does indeed get included even though the message remains the same.

Solution2:
Add the <private>True</private> property manually.

Conclusions:
My understanding of <Private> is it is the Copy Local so if Copy Local = True the Private property should be added, but in our case at least it was not.

Additional Considerations:

  1. Tested using Visual Studio 2013 and 2015.
  2. Tested using msbuild 12 and 14.
  3. Tested using TFS build Template.
  4. Our code has been upgraded from 2008 to 2015 visual studio, the flag may have gotten messed up somewhere in that time, but the issue did not start until the assembly was added to the GAC somehow.

End Result:

<Reference Include="System.Web.Mvc, Version=4.0.0.1, Culture=neutral,PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
 <HintPath>packages\Microsoft.AspNet.Mvc.4.0.40804.0\lib\net40\System.Web.Mvc.dll        </HintPath>
        <Private>True</Private>
    </Reference>
舂唻埖巳落 2024-09-01 19:52:44

在运行时,程序集必须位于两个位置之一:项目的输出路径或全局程序集缓存(请参阅使用程序集和全局程序集缓存)。如果项目包含对不在这些位置之一的对象的引用,则在构建项目时,必须将该引用复制到项目的输出路径。 CopyLocal 属性指示是否需要进行此复制。如果值为 true,则复制引用。如果为 false,则不会复制引用。

CopyLocal 的项目分配值按以下顺序确定:

  1. 如果引用是另一个项目(称为项目到项目引用),则该值为 true。
  2. 如果在全局程序集缓存中找到该程序集,则该值为 false。
  3. 作为一种特殊情况,mscorlib.dll 引用的值为 false。
  4. 如果在 Framework SDK 文件夹中找到该程序集,则该值为 false。
    否则,该值为 true。

问候...
Muse VS 扩展

At run time, assemblies must be in one of two locations: the output path of the project or the global assembly cache (see Working with Assemblies and the Global Assembly Cache). If the project contains a reference to an object that is not in one of these locations, then when the project is built, the reference must be copied to the output path of the project. The CopyLocal property indicates whether this copy needs to be made. If the value is true, the reference is copied. If false, the reference is not copied.

The project-assigned value of CopyLocal is determined in the following order:

  1. If the reference is another project, called a project-to-project reference, then the value is true.
  2. If the assembly is found in the global assembly cache, the value is false.
  3. As a special case, the value for the mscorlib.dll reference is false.
  4. If the assembly is found in the Framework SDK folder, then the value is false.
    Otherwise, the value is true.

Regards...
Muse VSExtensions

筑梦 2024-09-01 19:52:44

我刚刚在我们的构建服务器上也遇到了这个问题。这是 Visual Studio 非常烦人(且意外)的行为。两种解决方法:

  1. 从 GAC 中删除程序集。
  2. 添加 PostBuild 事件以手动将程序集复制到输出目录中。

I just encountered this problem on our build servers too. This is very annoying (and unexpected) behaviour by Visual Studio. Two workarounds:

  1. Remove the assemblies from the GAC.
  2. Add a PostBuild event to manually copy the assemblies into the output directory.
北城挽邺 2024-09-01 19:52:44

您能否通过向 msbuild/ 添加 hintpath 来确保使用您的路径项目文件?

从上面的链接:

HintPath:程序集的相对路径或绝对路径

Can you ensure yours is used by adding a hintpath to the msbuild/proj file?

From the above link:

HintPath : Relative or absolute path of the assembly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文