模仿 msbuild 进程的程序集解析

2024-02-02

我正在编写一个验证工具,用于检查项目中引用的文件的版本。我想使用与 MSBuild 相同的解析过程。

例如,Assembly.Load(..) 需要完全限定的程序集名称。然而,在项目文件中,我们可能只有“System.Xml”之类的东西。 MSBuild 可能使用项目的目标框架版本和其他一些启发式方法来决定加载哪个版本的 System.Xml。

您将如何模仿(或直接使用)msbuild 的程序集解析过程?

换句话说,在运行时,我想获取字符串“System.Xml”以及 .csproj 文件中找到的其他信息,并找到 msbuild 会找到的相同文件。


我今天遇到了这个问题,我找到了这篇关于如何做到这一点的旧博客文章:

http://blogs.msdn.com/b/jomo_fisher/archive/2008/05/22/programmatically-resolve- assembly-name-to-full-path-the-same-way-msbuild-does.aspx http://blogs.msdn.com/b/jomo_fisher/archive/2008/05/22/programmatically-resolve-assembly-name-to-full-path-the-same-way-msbuild-does.aspx

我尝试了一下,效果很好!我修改了代码以在可能的情况下查找 4.5.1 版本的程序集,这就是我现在所拥有的:

#if INTERACTIVE
#r "Microsoft.Build.Engine" 
#r "Microsoft.Build.Framework"
#r "Microsoft.Build.Tasks.v4.0"
#r "Microsoft.Build.Utilities.v4.0"
#endif

open System
open System.Reflection
open Microsoft.Build.Tasks
open Microsoft.Build.Utilities
open Microsoft.Build.Framework
open Microsoft.Build.BuildEngine

/// Reference resolution results. All paths are fully qualified.
type ResolutionResults = {
    referencePaths:string array
    referenceDependencyPaths:string array
    relatedPaths:string array
    referenceSatellitePaths:string array
    referenceScatterPaths:string array
    referenceCopyLocalPaths:string array
    suggestedBindingRedirects:string array
    }


let resolve (references:string array, outputDirectory:string) =
    let x = { new IBuildEngine with
                member be.BuildProjectFile(projectFileName, targetNames, globalProperties, targetOutputs) = true
                member be.LogCustomEvent(e) = ()
                member be.LogErrorEvent(e) = ()
                member be.LogMessageEvent(e) = ()
                member be.LogWarningEvent(e) = ()
                member be.ColumnNumberOfTaskNode with get() = 1
                member be.ContinueOnError with get() = true
                member be.LineNumberOfTaskNode with get() = 1
                member be.ProjectFileOfTaskNode with get() = "" }

    let rar = new ResolveAssemblyReference()
    rar.BuildEngine <- x
    rar.IgnoreVersionForFrameworkReferences <- true
    rar.TargetFrameworkVersion <- "v4.5.1"
    rar.TargetedRuntimeVersion <- "v4.5.1"
    rar.TargetFrameworkDirectories <- [||] //[|@"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\"|]
    rar.Assemblies <- [|for r in references -> new Microsoft.Build.Utilities.TaskItem(r) :> ITaskItem|]
    rar.AutoUnify <- true
    rar.SearchPaths <- [| "{CandidateAssemblyFiles}"
                          "{HintPathFromItem}"
                          "{TargetFrameworkDirectory}"
                         // "{Registry:Software\Microsoft\.NetFramework,v3.5,AssemblyFoldersEx}"
                          "{AssemblyFolders}"
                          "{GAC}"
                          "{RawFileName}"
                          outputDirectory |]

    rar.AllowedAssemblyExtensions <- [| ".exe"; ".dll" |]
    rar.TargetProcessorArchitecture <- "x86"
    if not (rar.Execute()) then
        failwith "Could not resolve"
    {
        referencePaths = [| for p in rar.ResolvedFiles -> p.ItemSpec |]
        referenceDependencyPaths = [| for p in rar.ResolvedDependencyFiles -> p.ItemSpec |]
        relatedPaths = [| for p in rar.RelatedFiles -> p.ItemSpec |]
        referenceSatellitePaths = [| for p in rar.SatelliteFiles -> p.ItemSpec |]
        referenceScatterPaths = [| for p in rar.ScatterFiles -> p.ItemSpec |]
        referenceCopyLocalPaths = [| for p in rar.CopyLocalFiles -> p.ItemSpec |]
        suggestedBindingRedirects = [| for p in rar.SuggestedRedirects -> p.ItemSpec |]
    }



[<EntryPoint>]
let main argv = 
    try
      let s = resolve([| "System"
                         "System.Data"
                         "System.Core, Version=4.0.0.0"
                         "Microsoft.SqlServer.Replication" |], "")
      printfn "%A" s.referencePaths
    finally
      ignore (System.Console.ReadKey())

    0
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

模仿 msbuild 进程的程序集解析 的相关文章

随机推荐

  • 无法更改 Google Cardboard 相机的 FOV

    我正在使用 Google Card Board Unity SDK 开发 Android 狙击手游戏 现在需要调整相机的 FOV 这导致我与 CardBoard cs 中名为 mockFieldOfView 的变量进行交互 在 Unity
  • Vue-cli 3:“命令失败:npm install --loglevel 错误”

    每次我尝试创建一个新项目 vue create my project 我收到此错误 错误 命令失败 npm install loglevel 错误 我使用的是 PC Windows 10 Vue cli 3 2 1 Node 8 11 3
  • 如何将 ReadonlyArray 转换为 any[]?

    一些本机角度函数返回 ReadonlyArray 一些本机角度回调传递 ReadonlyArrays 由于我的打字稿代码可能以多种方式调用 因此我不想要求传递给我的函数的所有数组都是 ReadonlyArrays 因此我需要将 Readon
  • 在 Android 中使用新 Material Design 主题的颜色

    我正在设计 Android 应用程序 并决定尝试新的 Material 主题 我在网上找到了新主题的所有可用配色方案 但无法找到包含调色板中所有颜色的相应 xml 文件 有谁知道我在哪里可以找到这个 以便我可以在我的风格中使用这些颜色 这是
  • 无法将脚本名称识别为 cmdlet、函数等;在简单的脚本中也找不到位置参数

    我正在尝试做我的第一个剧本 要简单地让 PowerShell 提取在记事本中输入的脚本并保存为标题为 test 的 ps1 文件 也尝试过脚本 但知道名称与它无关 Write Host Hello World 在 PowerShell 中我
  • ImageView和设置位置

    我有 imageView 活动 我如何在我的活动中设置此 imageView 的位置 我知道如何在 xml 文件中执行此操作 但我想在活动中执行此操作 因为我有 onTouch 方法 可以在其中获取单击的坐标 并且我想在此坐标中绘制此图像
  • 编辑链接列表中的节点

    我正在创建一个学生列表 链接列表 可以添加 查看和编辑学生信息 我有两个字段 即学生姓名和学生成绩 我在列表中添加新学生 其方式是根据学生的成绩降序排列 我已经完成了添加和查看部分 问题出在编辑部分 因为我需要编辑信息 然后我需要再次对其进
  • 将数据表放入shinyjs模式中

    我将 Shiny 与 Shiny Semantic 库一起使用 以使应用程序看起来不错 使用 showModal modalDialog 的标准 Shiny 弹出消息不适用于 Semantic UI 因此我求助于shinyjs 来使用一些
  • 使用 Javascript 更改 CSS 值

    使用 javascript 设置内联 CSS 值很容易 如果我想改变宽度并且我有这样的html div style width 10px div 我需要做的就是 document getElementById id style width
  • 单选按钮组 XAML

    我在 XAML 中有六个单选按钮 我想创建两个组 WPF 似乎没有单选按钮组元素 那么我该怎么做呢 您必须为元素指定一个 GroupName
  • dockerfile 中的 RUN 命令产生的结果与在容器内手动运行相同命令的结果不同

    我正在创建一个包含 gcc 4 8 5 的 Ubuntu 12 04 docker 映像 我正在获取 gcc 4 8 5 源代码并自己构建它 该容器将在 Ubuntu 18 04 主机上运行 引用底部的代码 如果我不将其放入 dockerf
  • 加密 JWT 安全令牌支持的算法

    我正在尝试使用以下代码片段对我的 JWt 进行签名和编码 var claims new Claim new SomeClaimes var scKey Encoding UTF8 GetBytes SOME KEY var ecKey En
  • 从单个单词中获取所有可能的词性标签

    我目前正在尝试使用 Python 获取单个单词的所有可能的 pos 标签 从传统的词性标注器中 如果您输入单个单词 您只能返回一个标签 有没有办法获得所有的可能性 是否可以在语料库 例如 Brown 中搜索特定单词而不仅仅是类别 亲切的问候
  • 在 Javascript 中处理多个图像后备

    有没有办法在纯 Javascript 或 React 中处理多个图像回退 我知道我们可以处理一张后备图像onError 如果我们想做另一个后备图像怎么办 提前致谢 每次设置导致错误的 src 时 都会调用图像的 onerror 回调 因此
  • 如何使用 Pipe 和 purrr 获取列表名称和切片名称

    我想知道在使用 purrr 的管道操作时如何获取列表名称或组名称作为标志 例如 我想使用传递给 ggsave 函数的每个列表名称的动态参数 require purrr require ggplot2 lst list a1 data fra
  • 在复杂的 React 组件中查找重复的键

    我有一个反应组件 它一次生成许多键 我不确定哪个不是唯一的 错误如下 有什么简单的方法可以帮助调试吗 谢谢 React js 19500 警告 数组或迭代器中的每个子项都应该有一个唯一的 key 属性 检查渲染方法MyGrid 请参阅 ht
  • Java支持关联数组吗? [复制]

    这个问题在这里已经有答案了 我想知道Java中的数组是否可以做这样的事情 int a new int 10 a index0 100 a index1 100 我知道我在其他语言中看到过类似的功能 但我不太熟悉任何细节 只是有一些方法可以将
  • 如何在窗口调整大小时更改高度 div?

    我的网站上有一个 div 应该是窗口的高度 这就是我得到的 document ready function var bodyheight document height sidebar height bodyheight 但是 当调整窗口大
  • 给定 AWS 访问/密钥对,如何检索其 IAM 权限?

    给定一个 AWS 访问密钥和一个 AWS 密钥的输入 我如何使用 AWS 开发工具包查找该账户可以执行哪些权限 我想为客户执行 XYZ 因此客户需要向我提供访问密钥和秘密密钥 以便以编程方式执行 XYZ 但是 在尝试执行任何这些操作之前 我
  • 模仿 msbuild 进程的程序集解析

    我正在编写一个验证工具 用于检查项目中引用的文件的版本 我想使用与 MSBuild 相同的解析过程 例如 Assembly Load 需要完全限定的程序集名称 然而 在项目文件中 我们可能只有 System Xml 之类的东西 MSBuil