更新 GAC 中包含 Web 应用程序的 aspx 页面的 dll

发布于 2024-07-17 12:53:01 字数 2942 浏览 3 评论 0原文

请原谅我的编码员,因为我犯了罪。 我将一些代码放入 GAC 的 dll 中,现在我对 GAC 如何与 IIS 真正配合感到困惑。

在我们的 Intranet 环境中,我有几个相关的 Web 应用程序(大约 10 个)。 每个应用程序都从单独的 URL 运行,并且可能在其自己的应用程序池中运行。 目前所有应用程序都位于同一服务器上,但这不是必需的。 此设置允许我们单独控制、开发和迁移每个应用程序。 然而,我们希望每个应用程序的几个部分在所有应用程序中都是通用的(母版页、登录页面、菜单等)。管理层的要求是,对这些文件的更改可以是通用的,并且无需更改即可生效。必须重新编译并重新迁移每个网络应用程序。 有很多方法可以完成此任务,尽管有警告要避免使用 GAC,但这看起来确实是使用虚拟路径提供程序和存储在 GAC 中的 dll 有意义的情况。

我组装了一个虚拟路径提供程序,然后将我需要通用的文件和资源嵌入到一个 dll 中。 (我本来可以让 VPP 从数据库中提取文件,但我希望将文件嵌入到 dll 本身中会提高性能。

复杂性 #1

我不希望每个文件的开发人员应用程序必须扰乱自己的 GAC 来测试和运行他们的应用程序,因此在每个解决方案中,我只包含虚拟路径提供程序项目,并制作其结果 dll,复制本地(以及强命名),这意味着只要开发人员的 GAC 中没有该 dll 的版本(他们不应该这样做),就会使用本地 bin 副本。允许开发人员轻松更改和测试应用程序的文件以及每个应用程序通用的文件。 这也意味着,除非故意阻止,否则通用 dll 也将存在于生产中每个应用程序的 bin 目录中。 但是,由于 IIS 将始终使用 GAC 版本(如果存在),因此即使本地版本已过时,也始终使用 GAC 版本。

我目前认为这是合理的,因为当应用程序复制到服务器时,我找不到一种简单的方法来将 VPP.dll 复制到本地进行开发,但又不复制到 bin 目录。

复杂性 #2

实际上对应用程序进行编码,使其始终使用最新版本的 dll,而不是编译时使用的特定版本,这似乎是一件相当复杂的事情。 (我还没有看到如何做到这一点的好例子,但我认为我需要一系列发布者策略)尝试更明显的答案似乎更容易 – 在迁移新版本时保持 dll 的版本号不变向 GAC 发送 VPP dll 版本。 这似乎工作正常,直到它不起作用。

使用服务器上的 Windows / assembly 管理单元,我将 GAC 中 dll 的旧版本 v. 1.0.0.0 替换为 v. 1.0.0.0 的更新副本。 尽管我已经更新了 GAC 中的 dll,但我的应用程序仍继续使用旧版本的代码。 重新启动 IIS,甚至完全重新启动服务器似乎没有帮助。 真正让我大吃一惊的是,最终 IIS 会神秘地、出乎意料地进行自我修正,并开始使用来自 GAC 的 dll 的正确副本。

我见过很多此类与 GAC 相关的问题,这些问题似乎都以“突然之间我的网站又开始正常工作”结束。 我花了一段时间才发现这是 IIS 缓存强命名 dll 的结果,并且我错误地使用了强命名 dll 的工作方式。

接下来,我尝试从 GAC 中完全删除该 dll 的版本。 因为 bin 目录中仍然有我的 dll 的副本,所以我预计该过程要么失败,要么恢复/前进到 bin 目录中的版本。 然而,由于 bin 中的版本也是 1.0.0.0,IIS 继续使用该 dll 的缓存副本,而该副本现在已不再存在于计算机上。(这让我真的困惑了一段时间,因为我对 GAC 失去了信心) 可以

最后,我必须确保更新 dll 的唯一方法是从 GAC 中删除 dll 的副本,从 bin 目录中删除 dll 的副本,运行该站点,以便它 失败,然后将新版本的dll放入GAC中。 在此期间启动和停止 IIS 没有效果。 这始终让我的应用程序使用新代码,但是……

简单地将新版本的 dll 粘贴到 GAC 中并使其新效果无缝传播就这么多了。

在阅读了一些相关问题后,我现在正在尝试的是:

  1. 停止IIS
  2. 更新GAC中dll的软件(但仍然保留版本号) 1.0.0.0 处的新 dll )
  3. 删除其中的所有内容 'C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET 文件的文件夹(我认为这个 强制重新编译,但它是 大锤修复)
  4. 重新启动 IIS。

这似乎有效,但不得不费尽心思似乎仍然有问题。 有没有更简单的方法来强制 IIS 使用 GAC dll 的当前实例? 有没有更好的方法来达到我想要的效果。 (一些常见文件 .aspx 和 .xml 文件在各种应用程序之间共享,可以与应用程序本身分开更新。)

编辑:根据 shahkalpesh 的评论,我在 microsoft
找到了此页面 http://msdn.microsoft.com/en-us /library/7wd6ex19(VS.80).aspx

它包含了这个小知识:

重定向程序集版本 要将一个版本重定向到另一版本,请使用 元素。 oldVersion 属性可以指定单个版本或版本范围。 例如, 指定运行时应使用版本 2.0.0.0,而不是之间的程序集版本1.1.0.0 和 1.2.0.0。

这意味着,与我的 dll 一起,我可以推送一个将所有内容重定向到最新版本的发布者策略文件。 这减轻了我认为是噩梦般的策略链,我必须维护从每个可能版本到最新版本的链接...

我将尝试这个,看看更新这样的版本是否也会触发 IIS 使用新文件的正确版本(重置应用程序池后)

Forgive me coder for I have sinned. I put some code into a dll in the GAC, and now I am confused about how the GAC is really working with IIS.

In our intranet environment I have several related web applications (about 10). Each application runs from a separate url, and potentially runs in its own app pool. For now all of the apps are on the same server, but that is not required. This setup allows us to control, develop and migrate each app separately. However, there are several parts of each app that we wanted to be common across all of our applications (master pages, logon pages, menus ect.) The request from management was that changes to these files could be universal, and would take effect without having to re-compile and re-migrate each web app. There are lots of ways to accomplish this task, and despite warnings to avoid the GAC, this really seemed like a case where using a Virtual path provider and a dll stored in the GAC made sense.

I put together a Virtual path provider, and then embedded the files and resources I needed to be common into a dll. (I could have had the VPP pull the files from a database, but I was hoping that embedding the files into the dll itself would be more performant.

Complication #1

I didn’t want the developers of each app to have to mess with their own GAC to test and run their application, so in each solution I just included the Virtual Path Provider project, and made its result dll, copy local, (as well as strongly named), this means that the provider dll, along with its embedded files are copied to the bin directory of the application. As long as the developer doesn’t have a version of this dll in their GAC (which they shouldn’t) the local bin copy is used. This allows the developer to easily change and test both the app’s files and the files that are common to every application.
This also means that unless it is deliberately prevented, the common dll will exist in the bin directory of every app in production as well. However, since IIS will always use the GAC version if it exists, even if the local version is out of date, the GAC version is always used.

I accepted this as reasonable for now since I couldn’t find an easy way to both have the VPP.dll copy local for development, and yet not copy to the bin directory, when the app was copied to the server.

Complication #2

Actually coding an app so that it always uses the latest version of the dll instead of the specific version that it was compiled with seems like a fairly complicated matter. ( I have yet to see a good example of how to do it, but I think I would need a chain of publisher policies) It seemed much easier to try the more obvious answer – leave the version number of the dll unchanged when migrating a new version of the VPP dll to the GAC. This seemed to work ok, until it didn’t.

Using the Windows /assembly snap-in on the server, I replaced an older version of v. 1.0.0.0 of my dll in the GAC with an updated copy of v. 1.0.0.0 . Even though I had updated the dll in the GAC, my apps continued to use the old version of the code. Restarting IIS, and even rebooting the server entirely did not seem to help. What really flipped me out was that eventually IIS would mysteriously and unexpectedly correct itself and start using the correct copy of the dll from the GAC.

I have seen many GAC related questions of this type that all seemed to end with “all of the sudden my website started working correctly again”. It took a while for me to see that this was an effect of how IIS was caching my strongly named dll, and that I was mis-using the way strongly named dll’s were supposed to work.

Next I tried removing the version of the dll from the GAC entirely. Because there was still a copy of my dll in the bin directory, I expected that the process would either fail, or revert/advance to the version that was in the bin directory. However because the version in the bin was also 1.0.0.0, IIS continued to use the cached copy of the dll, which now no longer existed on the machine.(That had me really baffled for a while, because I lost confidence that the GAC version was ever running at all)

Finally the only way I had to assuredly get the dll to update was to remove the copy of the dll from the GAC, remove the copy of the dll from the bin directory, run the site so that it would fail, and then put the new version of the dll into the GAC. Starting and stopping IIS during this had no effect. This consistently got my applications to use the new code but…

So much for simply sticking a new version of a dll into the GAC and having its new effects propagate seamlessly.

After reading some related issues, What I am trying now is:

  1. Stopping IIS
  2. Updating thesoftware of the dll in the GAC (but still leaving the version number of
    the new dll at 1.0.0.0 )
  3. deleting everything in the
    'C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary
    ASP.NET Files' folder ( I think this
    forces a recompile, but it’s a
    sledgehammer of a fix)
  4. restart IIS.

This appears to be working, but It still seems like there is something wrong with having to go to all this trouble. Is there an easier way to force IIS to use the current instance of the GAC’s dll? Is there a better way to accomplish the effect that I am after. (some common files .aspx and .xml files shared among various apps, that can be updated separately from the apps themselves.)

Edit: Based on a comment from shahkalpesh I found this page at microsoft
http://msdn.microsoft.com/en-us/library/7wd6ex19(VS.80).aspx

It included this tiny tidbit of knowledge:

Redirecting Assembly Versions
To redirect one version to another, use the <bindingRedirect> element. The oldVersion attribute can specify either a single version, or a range of versions. For example, <bindingRedirect oldVersion="1.1.0.0-1.2.0.0" newVersion="2.0.0.0"/> specifies that the runtime should use version 2.0.0.0 instead of the assembly versions between 1.1.0.0 and 1.2.0.0.

Which means that along with my dll, I could push a single publisher policy file that redirected everything to the latest. That sort of mitigates what I thought would be a nightmare chain of policies, where I had to maintain a link from every possible version to the latest...

I will try this and see if updating the version like this also triggers IIS to use the correct version of the new file (after resetting the app pool)

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

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

发布评论

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

评论(3

真心难拥有 2024-07-24 12:53:01

查看您的问题,您似乎希望在部署时使用更高版本的程序集。

在这种情况下,此 http://msdn.microsoft。 com/en-us/library/eftw1fys(VS.71).aspx 可能会有所帮助。

Looking at your question, it seems you wish to use a higher version of your assembly when deployed.

In that case, this http://msdn.microsoft.com/en-us/library/eftw1fys(VS.71).aspx might help.

不甘平庸 2024-07-24 12:53:01

请记住,程序集版本和文件版本是不同的..它们,也许尝试将它们作为全新版本读取并引用它(而不是 1.0.0.0)。

Remember that the assembly version and file version are different..them and maybe try readding them as a completely NEW version and reference THAT instead (not 1.0.0.0).

掌心的温暖 2024-07-24 12:53:01

为了让您放心 - 多年来我们一直在对我们的共享程序集做非常类似的事情。

使用 GAC 时要记住的事情:

  1. 如果要替换具有相同版本号的 DLL 的现有版本 - 您必须首先删除以前的版本(或者从 c:\windows 中删除) \ assembly 或 GACUtil /u) - 只需重新部署它/GACUtil/etc 不会有任何效果 - 它认为 DLL 已经存在并且不会更新它。
  2. 请记住 1,增加版本号会更容易,正如您所发现的,在配置链中的某个位置添加 BindingRedirect,通常我们使用 Machine.Config,因为我们希望影响服务器上的所有应用程序。

To put you at your ease - we been doing a very similar thing with our shared assemblies for years.

The things to remember when using the GAC:

  1. If you are going to replace an existing version of a DLL with the same version number - you have to REMOVE the previous version first (either delete from c:\windows\assembly, or GACUtil /u) - just re-deploying it/GACUtil/etc will not have any effect - it thinks the DLL already exists and doesn't update it.
  2. Bearing in mind 1, it's easier to just increment your version numbers, and as you discovered, add a BindingRedirect somewhere in the config chain, generally we use the Machine.Config as we want to affect all the apps on the servers.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文