构建 Visual Studio 项目而不访问引用的 dll

发布于 2024-08-26 02:08:34 字数 410 浏览 7 评论 0原文

我有一个项目,它有一组二进制依赖项(我没有源代码的程序集 dll)。在运行时,这些依赖项需要预先安装在计算机上,并且在编译时,它们需要在源代码树中,例如在 lib 文件夹中。 由于我还提供了该程序的源代码,因此我希望为其提供简单的下载和构建体验。不幸的是,我无法重新分发这些 dll,这使事情变得复杂,因为 VS 不会在不访问引用的 dll 的情况下链接该项目。

是否有办法在没有真正引用的 dll 的情况下构建和链接该项目?

也许有一种方法可以告诉 VS 链接到 dll 自动生成的存根,以便它可以在没有原始版本的情况下重建?也许有第三方工具可以做到这一点?该领域有任何线索或最佳实践吗?

我意识到这个人必须有权访问 dll 才能运行代码,因此他可以将它们添加到构建过程中是有意义的,但我只是想让他们免去收集所有 dll 并将它们放入手动.lib文件夹。

I have a project which has a set of binary dependencies (assembly dlls for which I do no have the source code). At runtime those dependencies are required pre-installed on the machine and at compile time they are required in the source tree, e,g in a lib folder.
As I'm also making source code available for this program I would like to enable a simple download and build experience for it. Unfortunately I cannot redistribute the dlls, and that complicates things, since VS wont link the project without access to the referenced dlls.

Is there anyway to enable this project to be built and linked in absence of the real referenced dlls?

Maybe theres a way to tell VS to link against an auto generated stub of the dll, so that it can rebuild without the original? Maybe there's a third party tool that will do this? Any clues or best practices at all in this area?

I realize the person must have access to the dlls to run the code, so it makes sense that he could add them to the build process, but I'm just trying to save them the pain of collecting all the dlls and placing them in the lib folder manually.

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

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

发布评论

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

评论(5

九厘米的零° 2024-09-02 02:08:34

也许这些想法之一将帮助您解决问题:

  • 从第 3 方 dll 中的所有类派生接口。将这些接口放入自己的项目(同一解决方案)中,并添加对此接口程序集的引用。还要将 EventHandler 添加到 AppDomain.AssemblyResolve< /a> 并尝试在运行时查找并加载程序集。 (学分归NG)
    • 根据 dll 有多大以及对公共部分进行更改的频率,这可能会带来真正的痛苦。

  • 提供 readme.txt,其中说明如何获取所需的程序集以及用户应将它们放置在相对于项目路径的位置。通常,VS 足够聪明,可以在您将程序集放入项目引用它的正确位置后立即删除感叹号(也许您必须在解决方案资源管理器中按刷新)(感谢 Paul)
    • 不要忘记将 readme.txt 添加到您的解决方案中,方法是右键单击您的解决方案并选择“添加 -> 添加”。现有项目'。在这种情况下,它将在 Visual Studio 解决方案资源管理器中占据相当显着的位置,用户可以通过双击来阅读它。
  • 在您的解决方案中创建另一个项目,该项目能够自动下载所有需要的 dll 并将它们放入正确的位置。也许它应该在开始下载之前预先检查这些所需的文件是否已经存在。设置原始项目的项目依赖关系,使其依赖于此。所以它总是会在你原来的之前构建。然后在原始项目的预构建事件中启动此下载帮助程序工具,并且不要忘记使用 int 值退出程序。 0 表示成功,任何其他错误,因此 Visual Studio 也知道您的工具是否成功,并在挂起丢失的 dll 之前停止编译过程。
    • 也许自动下载文件几乎是不可能的,因为您需要登录网页或使用一些无法通过工具自动化的 cookie、flash、验证码等。

Maybe one of these ideas will help you to solve the problem:

  • Derive interfaces from all classes in the 3rd party dlls. Put these interfaces into an own project (same solution) and add a reference to this interface assembly. Also add an EventHandler to AppDomain.AssemblyResolve and try to find and load the assemblies at run-time. (Credits go to NG)
    • Depending on how big the dlls are and how often changes are made to the public part this can get a real pain.
  • Provide a readme.txt where you explain how to get the needed assemblies and where the user should put them relative to the project path. Normally VS is smart enough to remove the exclamation mark right after you put the assembly into the right spot, where the project references it from (maybe you have to press refresh in Solution Explorer) (Credits go to Paul)
    • Don't forget to add the readme.txt also to your solution by right clicking on your solution and select 'Add -> Existing Item'. In this case it will get a quite prominent place within visual studio Solution Explorer and the user can read it on a double click.
  • Create another project within your solution that is able to download all the needed dlls automatically and to put them into the right spot. Maybe it should check beforehand if these needed files are already there before it starts to download. Set the Project Dependencies of your original project, so that it will depend on this one. So it will always be built before your original one. Then start this download helper tool in the pre-build event of your original project and don't forget to exit your program with an int value. 0 means success, any other error and so also Visual Studio knows if your tool was successfull and stops the compile process before hanging on missing dlls.
    • Maybe it is nearly impossible to automatically download the files, cause you need a login to a webpage or some cookies, flash, captcha, etc. is used which can't be automated by a tool.
你是暖光i 2024-09-02 02:08:34

对于以上所有好的建议,同意。话虽这么说,也许存在一种通常不需要外部 DLL 的有效场景?所以这就是你要做的。你包裹并隔离它们。 (它比创建接口具有更高的抽象级别,因此更容易维护)。

在 Visual Studio 中,如果您不重新编译引用外部 DLL 的特定 VS 项目,那么您可以在不方便使用这些 DLL 的情况下编译 VS 解决方案的其余项目。因此,如果您以某种方式用自己的 DLL 包装外部 DLL,然后仅将这些包装器作为二进制文件分发,则共享源代码的人将不需要外部 DLL 来编译主解决方案。

注意事项
1. 将包装器代码分离到独立项目中的额外工作。
2. 其他 VS 项目必须添加对包装器 DLL 的引用,作为对“LIB”文件夹的“文件系统”引用,而不是“项目引用”。
3. VS 解决方案配置必须禁用包装器 DLL 的编译。如果需要,应添加新配置以显式重新编译它们。
4. 每个包装器 DLL 的 VS 项目定义应包含一个构建后事件,以将它们复制到预期的“LIB”文件夹位置。
5. 在运行时,外部 DLL 必须存在于应用程序的 bin 目录或计算机的 GAC 中,或者以其他方式显式加载。注意:如果它们丢失,只有当它们在运行时实际调用时,它们的缺失才会导致运行时错误。也就是说,如果代码在一般情况下没有调用它们,则不需要它们。
6. 在运行时,您可以捕获加载外部 DLL 的错误,并向用户显示一条漂亮的错误消息:“为了使用此功能,请安装以下产品:xyz”。这比显示“AssemblyLoadException...请使用 FusionLogViewer...等”更好
7. 在应用程序启动时,您可以测试和检测丢失的 DLL,然后禁用依赖于它们的特定功能。

例如:根据此模式,我可以拥有一个与 Microsoft CRM 和 SAP 集成的应用程序,但仅用于特定功能,即导入/导出。
在设计时,如果开发人员不需要更改包装器,他们将能够在没有这些外部 DLL 的情况下重新编译。
在运行时,如果用户从不调用此函数,应用程序将永远不会调用包装器,因此不需要外部 DLL。

To all the good advice above, agreed. That being said, maybe there is a valid scenario where the external DLL's are generally not needed? So here is what you do. You wrap and isolate them. (Its a higher level of abstraction than creating interfaces, so a bit easier to maintain).

In Visual Studio, if you do not recompile the specific VS Projects which reference the external DLL's then you can get away with compiling the rest of the VS Solution's Projects without having those DLL's handy. Thus if you somehow wrap the external DLL's with your own DLL's and then distribute those wrappers as binary only, the person sharing your source code will not need the external DLL's to compile the main solution.

Considerations:
1. Extra work to separate out the wrapper code into isolated Projects.
2. The other VS Projects must add references to your wrapper DLL's as "File System" references to a "LIB" folder, rather than "Project References".
3. The VS Solution configurations must disable compile for the wrapper DLL's. A new configuration should be added to explictly re-compile them, if needed.
4. The VS Project definition for each of the Wrapper DLL's should include a post-build event to copy them to the expected "LIB" folder location.
5. At runtime, the external DLL's must be present in the application's bin directory, or the machine's GAC, or otherwise explictly loaded. NOTE: If they are missing, it is only when they actually invoked at runtime that their absence will result in a runtime error. i.e. You do not need to have them if the code doesn't happen to call them in a general situation.
6. At runtime, you can catch errors loading the external DLL's and present a pretty error message to the user to say "In order to user this function, please install the following product: xyz". Which is better than displaying "AssemblyLoadException... please use FusionLogViewer... etc"
7. At application startup, you can test and detect missing DLL's and then disable specific functions which depend upon them.

For example: According to this pattern I could have an application which integrates with Microsoft CRM and SAP, but only for a specific function, i.e. Import/Export.
At design time, if the developer never neeeds to change the wrapper, they will be able to recompile without these external DLL's.
At runtime, if the user never invokes this function, the application will never invoke the wrapper and thus the external DLL's are not needed.

ゃ懵逼小萝莉 2024-09-02 02:08:34

我们可以省去他们收集所有程序集并自己将它们放入 lib 文件夹的痛苦。然后将它们与源代码一起提交到存储库中。这样,人们从存储库中检查代码也将获得编译项目所需的一切。

Well save them the pain of collecting all the assemblies and place them in the lib folder yourself. Then commit them along with the source code in the repository. This way people checking out the code from the repository will also get everything that is needed to compile the project.

魔法少女 2024-09-02 02:08:34

一种相当彻底的可能性是使用分离的接口模式并在运行时以编程方式加载 dll。

A rather drastic possibility would be to use the separated interface pattern and programatically load the dlls at runtime.

也只是曾经 2024-09-02 02:08:34

我宁愿编译时依赖使我的构建失败,也不愿出现可能需要一些时间来追踪的运行时错误。

在您的解决方案中放置一个 Readme.txt,并明确说明依赖项是什么、从哪里获取它们以及如何处理它们。

I'd rather have a compiletime dependancy fail my build than a runtime error that could take some time to track down.

Place a Readme.txt in your solution and spell out explicitly what the dependancies are, where to get them, and what to do with them.

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