【问题标题】:Do .NET projects in Visual Studio always compile into a single file?Visual Studio 中的 .NET 项目是否总是编译成单个文件?
【发布时间】:2009-12-10 03:43:05
【问题描述】:

这是其中一件非常简单的事情,以至于在我读过的任何教程中都没有人站出来说出来。

我一直在为其他程序创建一些独立的 .NET 应用程序以及一些基于 DLL 的插件。我注意到 Visual Studio 中的一个项目,至少包含 Windows 应用程序和类库,编译成单个文件(EXE 或 DLL)。

总是这样吗?在组织更大的应用程序方面,我是否应该始终认为 Visual Studio 中的项目对应于最终程序中的单个文件?

【问题讨论】:

    标签: .net visual-studio projects


    【解决方案1】:

    每个项目都编译成一个文件。 (网站项目除外)

    但是,如果您将项目中任何文件的“构建操作”设置为“始终复制”或“如果较新则复制”,则项目会将该文件复制到输出文件夹。
    另外,如果 EXE 项目有 App.config 文件,它也会被复制到输出文件夹中。

    如果您的项目引用了一个不属于核心框架的 DLL(无论是您自己的还是其他人的),它会将该 DLL 复制到项目的输出文件夹,从而生成两个文件(尽管其中只有一个包含项目本身的代码)

    此外,除了 DLL 和 EXE,Visual Studio 还将在输出文件夹中创建一个包含调试符号的 .pdb 文件。此文件由调试器使用,不得分发给您的用户。 (除非您希望他们为您调试代码)

    【讨论】:

      【解决方案2】:

      对于您的简单项目,是的,每个项目您总是会得到一个程序集。但是,如果您转向更多的生产就绪软件,答案就不同了。假设您要交付一个 DLL,但它包含必须向用户显示的文本。您可能希望将该文本本地化(提供英语和德语版本,甚至提供美国英语和英国英语 [think program vs. program])。您将把文本放入资源中,然后将这些资源编译成所谓的附属程序集。对于您选择支持的每个语言环境,您都会获得一个附属程序集。

      下面简要介绍了如何生成和使用附属程序集:http://sanjaysainitech.blogspot.com/2007/08/satellite-assemblies.html

      我看到人们在谈论网络模块和 ILMerge。我认为,如果您担心 netmodules,那么您就做错了,因为您没有使用 Microsoft 给您的工具(或者您在 Mono 领域,在这种情况下您没有 Microsoft 提供的任何工具)。我没有使用过 ILMerge,但在阅读了它之后,我不确定我是否信任它。 This person 表示除了 WPF/XAML 代码外它工作正常; this person 在运行 ILMerge 后无法访问嵌入式资源; this person 看到在运行 ILMerge 后无法通过调试器执行的优化代码。这足以告诉我,ILMerge 不是适用于所有场景的生产就绪工具。设计软件的一部分是弄清楚你将如何部署它。如果您想部署较少数量的程序集,您应该以这种方式设计您的软件,而不是在编译后在 IL 中乱七八糟。正如制图师常说的,“这里有龙。”

      【讨论】:

        【解决方案3】:

        示例如何创建多个模块并将主题链接到单个 dll:

        csc /t:module RarelyUsedTypes.cs
        csc /out:AllTypes.dll /t:library /addmodule:RarelyUsedTypes.netmodule AllTypes.cs 
        

        有关更多信息,请参阅 Richter 的书CLR via C#

        您可以为 Visual Studio 自动执行此过程。

        为您的每个项目创建一个网络模块或一个程序集,然后将它们全部编译/合并到一个程序集中。

        第一个替代方案。这是由Jay R. Wren提出的:

        这是一个可爱的 hack,但由于 CSC 和 VBC 都支持 /target:module/addmodule 选项,您实际上可以在没有 ILMerge 的情况下做到这一点使用 shell 脚本或 make 文件。

        Visual Studio 不支持“netmodule”类型,但 MSBuild 支持。

        将 VB 项目添加到您的解决方案中。卸载项目并编辑项目文件。

        将 OutputType 更改为模块:

        <OutputType>module</OutputType>
        

        我们没有添加对所需项目的引用,而是添加了一个模块。可悲的是,VStudio 在这里再次失败,但 MSBUILD 工作得很好。卸载项目并编辑项目文件。使用 AddModules 包含指令添加项目组。

        <ItemGroup><AddModules Include="..\VbXml\bin\Debug\VbXml.netmodule" /></ItemGroup>
        

        这将告诉 msbuild 告诉 CSC 使用 /addmodule 指令,就像 Studio 管理的参考项目组一样。

        主要缺点:添加的模块没有 Visual Studio Intellisense。我们已经有了引用,可惜我们没有模块。 [更新:正如@Ark-kun 指出的,Visual Studio 可以引用 .netmodule 项目并拥有 Intellisense。只需在更改输出类型之前添加项目引用。]

        SharpDevelop 有第一步,但第二步,“添加模块”gui 自 SD 2.0 以来已作为低优先级项目打开。

        第二种选择。great article(由 Scott Hanselman 撰写)描述了如何在使用 Visual Studio 时自动运行程序集。它确实为您提供 IntelliSense 支持,这与第一个替代方案不同

        【讨论】:

        • 所有三种方式都生成一个程序集。但只有第三种方式给你一个单一的文件
        • 您能否详细说明一下:“使用 AddModules 包含指令添加项目组。”将&lt;ItemGroup&gt;&lt;AddModules&gt;...&lt;/AddModules&gt;&lt;/ItemGroup&gt; 放在&lt;Project&gt;.csproj 标记内违反了架构。
        • @Ark-kun:架构违规应该不是问题。我会认为它们暗示可能有问题(除非您必须没有违规行为)。
        • Visual Studio 可以引用.netmodule 项目并拥有智能感知。只需在更改输出类型之前添加项目引用即可。
        • 我的问题是我应该把路径放到Include="" 属性。您的回答并不清楚这一点。
        【解决方案4】:

        不一定。如果您的项目具有面向文化的资源,它们通常被编译成单独的程序集 (dll)。此外,ASP.Net 项目不会编译为单个程序集,您将始终将您的 aspx/ascx 文件或其标记等价物与已编译的代码分开。

        【讨论】:

        • 网站项目不会被编译成单个程序集——它们根本不会被编译。 Web 应用程序项目 编译成单个程序集。
        • 好点——我做的所有网络东西都是一个网络应用程序项目,所以我忘了提到区别:)
        • 如果您使用 Web 部署项目,您仍然可以将它们编译为单个程序集。 Aspnet_merge.exe 发挥了魔力。
        【解决方案5】:

        对于 Visual Studio,是的。在 Internet 上搜索“netmodule”,您会找到您正在寻找的文档。我今天碰巧遇到了它们,因为我们正在寻找将多个项目组装到一个 DLL 中。

        MSDN:https://docs.microsoft.com/en-us/dotnet/framework/app-domains/how-to-build-a-multifile-assembly

        【讨论】:

        • 网络模块正好相反。我也被他们愚弄了。 Netmodules 允许您将程序集拆分为多个文件(例如,允许单独加载它们)。它们与普通引用的 dll 非常相似。正如您的链接所述,netmodules 允许您创建“多文件程序集”。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-06
        • 1970-01-01
        • 1970-01-01
        • 2016-12-13
        相关资源
        最近更新 更多