【问题标题】:How can you access the Visual Studio solution level platform from a C# project's build event?如何从 C# 项目的构建事件访问 Visual Studio 解决方案级别平台?
【发布时间】:2011-09-20 17:22:40
【问题描述】:

我们有一个大型的 VS 2010 解决方案,主要是 C# 代码,但也有一些本地 DLL 是各种 C# 项目所依赖的(包括我们的单元测试 DLL)。我们正在尝试支持我们的库的 32 位和 64 位版本。所以我们现在将本地 DLL 构建为 32 位和 64 位。问题是我们的许多 C# 项目都有构建后事件,这些事件将所需的本机 DLL 复制到项目的 TargetDir 中。现在我们有两个不同版本的本地 DLL(32 位和 64 位),我需要能够指定正确的目录来复制本地 DLL。我原本以为我可以像这样在路径中简单地使用 $(Platform):

copy $(SolutionDir)\NativeDll\$(Platform)\$(Configuration) $(TargetDir)

但这不起作用,因为 $(Platform) 是项目的平台,而不是解决方案级别的平台。在这种情况下,$(Platform) 是“任何 CPU”。从我看到的 C# 项目中的构建后事件宏来看,似乎没有一种方法可以访问正在构建的解决方案级平台。有没有更好的方法来实现我的目标?

【问题讨论】:

  • 如果您使用 xcopy /s /d /i /y 而不是复制,您将获得更快的构建(将跳过未更改的文件)。

标签: c# visual-studio 64-bit 32bit-64bit post-build-event


【解决方案1】:

我相信解决方案的平台,与项目的平台不同,只是文本。

我过去的失望是:

  1. 从解决方案中删除 Win32 和“混合平台”(并在添加项目后继续这样做)。

  2. 将所有 C# DLL 设置为在解决方案平台 AnyCPU、x86、x64 中构建为 AnyCPU。 (如果您希望能够在 Blend 中打开或者如果您在解决方案中有任何纯托管应用程序,请不要删除 AnyCPU。)

  3. 将 C# EXE 和单元测试设置为在 x86 解决方案平台中构建 x86 以及在 x64 解决方案平台中构建 x64,而不是在 AnyCPU 解决方案平台中构建。

  4. 当解决方案为 x86 并输出到 $(ProjectDir)\bin\x86\$(Configuration) 并在路径中而不是 bin 中与 obj 相同时,将所有本机设置为在 Win32 中构建。 x64 与 x64 相同,而不是 x86 和 Win32。

  5. 设置 C# EXE 和单元测试的预构建事件,以从具有项目配置名称的相对路径复制它们所依赖的本机 DLL:$(Config)

  6. 设置单元测试的类初始化以将测试 bin 目录(当然是正确的平台和配置)的全部内容复制到测试的输出目录。使用 if #DEBUG 和 unsafe sizeof(IntPtr) 来告诉在哪里查找测试的 bin 目录。

  7. 手动(使用记事本)将相对引用路径添加到解决方案外部的 .csproj 文件,这些文件使用解决方案部署位置的 x86/x64 程序集,因此路径将包括 $(Platform) 和 $(Configuration) 并且不会按照用户。

微软:Visual Studio 中更好的 32/64 位支持将真正到位。

【讨论】:

  • 好消息!是的,Visual Studio 中更好的 32/64 位支持会非常好。
  • #4 顺便说一句,为什么不将相同的目录 $(Platform)\$(Configuration) 用于中间目录和输出目录?
  • 这样最终输出可以使用构建事件(DLL、PDB、资源)轻松复制,而不是中间体。尽管如此,我还是推荐使用比 . 更好的过滤器的 xcopy。 (例如 *.dll、*.pdb、*.xml)
  • ...比星点星更好的过滤器,也就是说(星在这里是特殊字符)。
  • 另一个有用的提示:编写一个递归的 clean.exe 来清空 VS 的 clean 遗漏的旧文件中的 bin 和 obj 目录。 (删除资源,删除或重命名项目,...)。这可以防止在使用多个 bin 目录时出现难以理解的编译错误。
【解决方案2】:

当我不得不这样做时,我只是将我的所有程序集构建为 x86 或 x64 而不是 AnyCPU,并且有两个单独的输出包。如果你知道你的进程必须是 32 位或 64 位,那么 AnyCPU 真的没有意义。

【讨论】:

  • 同意,但这些是我们希望作为位中性提供的库程序集 (DLL)。这样我们的客户就可以在 32 位或 64 位进程中使用它们,只要我们提供他们所依赖的 32 位和 64 位本机 DLL。
【解决方案3】:

我自己没有使用过,但是 Build -> Batch Build 可能是你想要的。有了它,您可以构建多个平台。

http://msdn.microsoft.com/en-us/library/169az28z.aspx

当然,这实际上并不能让您访问解决方案的“平台”,但您不需要这样做,因为您将分别构建每个平台。

更新: 如果要自动构建,请创建一个包含以下内容的批处理文件

"c:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv" ../solution.sln /rebuild "platform"

其中“平台”是“Release|Any CPU”、“Release|x86”等,并为您需要构建的每个配置重复该行。使用配置管理器为 x86 和 x64 的构建设置每个项目,您应该拥有所需的内容。

【讨论】:

    【解决方案4】:

    我认为“活动解决方案配置”没有等效的宏属性。

    我的建议是在所有 .csproj 文件中手动添加自定义属性,如下所示(请参阅为每个配置/平台组合添加的新 MyVar 自定义属性):

    <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      ...
      <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
        ...
        <MyVar>MyDebugAnyCpu</MyVar>
      </PropertyGroup>
      <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
        ...
        <MyVar>MyReleaseAnyCpu</MyVar>
      </PropertyGroup>
    

    您可以在 Visual Studio 中使用“卸载项目”和“编辑 MyProject.csproj”菜单来编辑 .csprojet。重要的是要知道 Visual Studio 不会破坏这些“未知”值,即使您使用普通的 GUI 编辑器保存它也是如此。

    然后在构建后事件中,可以使用这些值,例如:

    copy $(SolutionDir)\$(MyVar)\$(Platform)\$(Configuration) $(TargetDir)
    

    【讨论】:

      【解决方案5】:

      Francesco Pretto 有一个扩展可以帮助解决这个问题。它似乎有一些怪癖和不足,但这是一个开始。

      http://visualstudiogallery.msdn.microsoft.com/619d92a2-4ead-410d-a105-135f7b4b4df9

      github上有源码:

      https://github.com/ceztko/SolutionConfigurationName

      【讨论】:

        猜你喜欢
        • 2020-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-08
        相关资源
        最近更新 更多