如何从C#项目的构建事件访问Visual Studio解决方案级平台?

13
我们有一个大型的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)为“Any CPU”。从我查看C#项目中的后期生成事件宏所看到的内容来看,似乎没有一种方法可以访问正在构建的解决方案级别平台。有没有更好的方法来实现我的目标?


2
如果你使用xcopy /s /d /i /y而不是copy,你将获得更快的构建速度(会跳过未更改的文件)。 - Danny Varod
5个回答

3
我相信解决方案的平台与项目不同,只是文本。
我以前做过的事情有:
  1. 从解决方案中删除Win32和“混合平台”(在添加项目后继续执行此操作)。

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

  3. 将C# EXE和单元测试设置为在x86解决方案平台中构建x86,在x64解决方案平台中构建x64,并且在AnyCPU解决方案平台中根本不构建。

  4. 在解决方案为x86时,将所有本机设置为构建为Win32,并输出到$(ProjectDir)\bin\x86\$(Configuration),并将中间内容设置为带有obj路径而不是bin的相同内容。 x64与x86相同,但使用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位将会非常不错。 - Keith Hill
顺便问一下,对于问题4,为什么不直接使用相同的目录 $(Platform)\$(Configuration) 作为中间文件和输出文件的目录呢? - Keith Hill
为了使最终输出可以通过构建事件(DLL、PDB、资源)轻松复制,而中间文件不会被复制。我建议使用比“*.”更好的筛选器来进行xcopy操作。(例如.dll、*.pdb、*.xml) - Danny Varod
比星点星更好的过滤器,即(这里的星号是特殊字符)。 - Danny Varod
另一个有用的提示:编写一个递归的clean.exe来清空bin和obj目录中旧文件,这些文件可能被VS的clean命令忽略了(已删除的资源、已移除或重命名的项目等)。这可以防止在使用多个bin目录时出现难以理解的编译错误。 - Danny Varod

2

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


同意,除了这些是我们想要提供为位中立的库程序集(DLL)。这样我们的客户就可以在32位或64位进程中使用它们,只要我们提供它们所依赖的32位和64位本机DLL。 - Keith Hill

1

我自己没有使用过,但“生成 -> 批量生成”可能是你想要的。使用它,你可以构建多个平台。

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"

其中'platform'是"Release|Any CPU"、"Release|x86"等,每个需要构建的配置都要重复此行。使用配置管理器为每个项目设置x86和x64的构建,你就可以得到想要的结果。


0

我认为“Active Solution Configuration”没有相应的宏属性。

我的建议是在所有.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>

你可以使用“卸载项目”和“编辑MyProject.csproj”菜单在Visual Studio中编辑.csprojet。重要的是要知道,即使您使用常规GUI编辑器保存它,Visual Studio也不会销毁这些“未知”值。

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

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

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接