【问题标题】:Are there any examples of compiling CIL code from within a Visual Studio project是否有任何从 Visual Studio 项目中编译 CIL 代码的示例
【发布时间】:2011-05-03 09:02:55
【问题描述】:

我知道有人询问并回答说 Visual Studio 不支持 CIL/MSIL 项目。 MSBuildContrib 项目有一个 ILASM 任务,允许您在构建时编译 IL 文件。

Google 搜索到有关如何使用此任务的示例均未找到。

是否有任何将 ILASM 用作 Visual Studio 解决方案的一部分的示例? 我意识到#develope 和 ILIDE 支持 CIL...这里的目标是编译一些 CIL 文件作为 Visual Studio 解决方案的一部分

【问题讨论】:

  • 请问你为什么真的需要用 IL 编译?它有什么 C#/VB.NET/F# 不能做的?
  • @Leppie - 这是一个适合长时间辩论的话题,我只想说(诚然很少)使用 IL 比使用 C# 或 VB 更容易实现 - 特别是在创建有效的泛型时与代表。调皮地,IL 允许您在调用方法之前动态地 pcik 并选择要推送到堆栈的参数。 C# 和 VB 没有。通常是一件好事,但有时违反规则会打开新的大门。动态委托就是一个例子。
  • @Mark,您能否简要说明(或提供链接)您可以为使用 MSIL 的代表改进哪些方面?这可以帮助您编写适用于所有委托类型的方法吗?

标签: visual-studio cil il ilasm


【解决方案1】:

我感谢 Hans 回答了这个问题,但经过一些实验后,我得到了一个稍微接近实际的解决方案:

如何在 VISUAL STUDIO 中编译 CIL/MSIL

以下 hack 为您提供了一个项目:

  • 尊重 Visual Studio 中的调试与发布构建配置。
  • 可选择使用项目首选项中设置的密钥文件对生成的 CIL 程序集进行签名。
  • 可以添加到源代码管理中。

按照以下步骤操作:

  1. 创建一个空的 C# 类库
  2. 在解决方案文件夹中,右键单击项目并选择“卸载项目”
  3. 右键单击卸载的项目并选择“编辑项目”
  4. 在 csprof 文件中,向下滚动到底部,找到“Import ... Project="$(MSBuildBinPath)\Microsoft.CSharp.targets”行,并将其替换为http://pastebin.com/KEJtyQLu 处的代码(复制如下)

这是 XML:

  <Import Project="$(MSBuildToolsPath)\Microsoft.Common.targets" />

  <Target Name="CreateManifestResourceNames" />

  <Target Name="CoreCompile" Inputs="$(MSBuildAllProjects);@(Compile);" Outputs="@(IntermediateAssembly);$(NonExistentFile);">
    <GetFrameworkPath>
      <Output TaskParameter="Path" PropertyName="FrameworkPath" />
    </GetFrameworkPath>

    <PropertyGroup>
      <IlAsmCommand>&quot;$(FrameworkPath)\Ilasm.exe&quot; /NOLOGO /DLL /OUTPUT:&quot;@(IntermediateAssembly)&quot; </IlAsmCommand>
    </PropertyGroup>

    <PropertyGroup Condition=" '$(Configuration)' == 'Debug' " >
      <IlAsmCommand>$(IlAsmCommand) /DEBUG </IlAsmCommand>
    </PropertyGroup>

    <PropertyGroup Condition=" '$(Configuration)' == 'Release' " ><IlAsmCommand>$(IlAsmCommand) /OPTIMIZE </IlAsmCommand></PropertyGroup>

    <PropertyGroup Condition=" '$(AssemblyOriginatorKeyFile)' != '' " >
      <IlAsmCommand>$(IlAsmCommand) /KEY:&quot;$(AssemblyOriginatorKeyFile)&quot; </IlAsmCommand>
    </PropertyGroup>

    <Exec Command="$(IlAsmCommand) @(Compile->'&quot;%(FullPath)&quot;', ' ')" 
          Outputs="@(IntermediateAssembly)" />

    <CallTarget Targets="$(TargetsTriggeredByCompilation)" Condition="'$(TargetsTriggeredByCompilation)' != ''" />

  </Target>

【讨论】:

  • 谢谢,这给了我一个有用的起点。我使用的是 MonoDevelop,它通常可以很好地编译 CIL 项目,但无论是它还是我的缺陷,我都无法正常工作,并且根据上面对 ilproj 文件的更改对其进行了排序。对于单声道构建,将 &amp;quot;$(FrameworkPath)\Ilasm.exe&amp;quot; 替换为 ildasm(区分大小写)并放弃调试和发布添加(这两个命中特性 mono ildasm 尚不支持。相反,使用 MS 也可以很好地添加/RESOURCE:someResourceFile.res(我只是硬编码到第一个IlAsmCommand
  • 检查我,但在上述所有内容和MSBuild reserved and well-known properties 之间,我认为我有第一个正确包含资源文件的IlAsmCommand 元素的内容 - &lt;IlAsmCommand&gt;"$(FrameworkPath)\Ilasm.exe" /NOLOGO /DLL /RESOURCE:"@(Compile-&gt;'%(RelativeDir)%(Filename).res', ' ')" /OUTPUT:"@(IntermediateAssembly)" &lt;/IlAsmCommand&gt; 这假设 . res 文件与对应的.il 文件具有相同的路径和名称。
【解决方案2】:

您可以添加一个“makefile 项目”。该模板位于 Visual C++,General 下。此项目类型允许您为 Build、Clean 和 Rebuild 操作指定自定义构建命令。环境将自动设置,因此您不必弄乱路径。 C++ IDE 还支持创建自定义构建规则,以便您可以从文件扩展名 (.il) 自动触发正确的工具 (ilasm.exe)。

不过,这已经差不多了。项目中的多个 .il 文件不会自动映射到单个构建命令。需要编写一个 nmake.exe makefile 来获得它。并且要注意自定义构建规则支持在 vs2010 中被破坏了。

【讨论】:

  • 谢谢汉斯!这或多或少是我需要的。顺便说一句-知道为什么 Codeplex 上的 MSBUILD 模板已停产吗?我在 VS2010 中尝试过它们,但没有得到任何乐趣……似乎是一个有用的贡献。
  • 在使用 csproj、删除“csharp.targets”然后添加自定义构建任务来编译 IL 是否有任何危险?这在源代码控制方面会更好或更差吗?
  • 我在这个答案中发布的任何内容都与 MSBuild 无关。您可以像在构建前/构建后事件中指定它们一样提供构建命令。
猜你喜欢
  • 2012-09-26
  • 2021-12-27
  • 2017-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多