构建 Visual Studio 项目而不访问引用的 dll
我有一个项目,它有一组二进制依赖项(我没有源代码的程序集 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
也许这些想法之一将帮助您解决问题:
Maybe one of these ideas will help you to solve the problem:
对于以上所有好的建议,同意。话虽这么说,也许存在一种通常不需要外部 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.
我们可以省去他们收集所有程序集并自己将它们放入 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.
一种相当彻底的可能性是使用分离的接口模式并在运行时以编程方式加载 dll。
A rather drastic possibility would be to use the separated interface pattern and programatically load the dlls at runtime.
我宁愿编译时依赖使我的构建失败,也不愿出现可能需要一些时间来追踪的运行时错误。
在您的解决方案中放置一个 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.