代码之家  ›  专栏  ›  技术社区  ›  Nathan Shively-Sanders

F#Powerpack的元数据无法将FSharp.Core识别为F#库

  •  2
  • Nathan Shively-Sanders  · 技术社区  · 14 年前

    下面是我用来隔离问题的测试代码:

    open Microsoft.FSharp.Metadata
    [<EntryPoint>]
    let main args =
      let core = FSharpAssembly.FromFile @"C:\Program Files\FSharp-2.0.0.0\\bin\FSharp.Core.dll"
      let core2 = FSharpAssembly.FSharpLibrary
      let core3 = System.AppDomain.CurrentDomain.GetAssemblies() 
                  |> Seq.find (fun a -> a.FullName.Contains "Core") 
                  |> FSharpAssembly.FromAssembly
    
      core.Entities |> Seq.iter (printfn "%A")
      0
    

    所有三个 let s应该给我同样的装配。相反,所有3个都抛出一个异常,即FSharp.Core不是F#程序集(下面的详细信息,为了可读性而重新格式化)。还有两条线索:

    1. 使用 core3 方法,我得到了与测试F#程序集本身相同的错误
    2. 我没有在FSI的错误后做 #r "@C:\Program Files...\FSharp.Powerpack.Metadata.dll" .

    有什么想法吗?我使用的是visualstudio2008,F#2.0和F#powerpack2.0.0.0(2010年5月20日)版本的旧XP虚拟机,我想它已经更新到SP3了。

    (我今天早上在powerpack1.9.9.9中遇到了这个错误,所以我升级到了2.0.0.0。我认为如果1.9.9.9不能识别F#的2.0.0.0程序集,那么powerpack2.0.0中的错误修复可能会有所帮助。)

    Unhandled Exception: System.TypeInitializationException: 
      The type initializer for 'Microsoft.FSharp.Metadata.AssemblyLoader' threw an
        exception. 
      ---> System.TypeInitializationException: The type initializer for
        '<StartupCode$FSharp-PowerPack-Metadata>.$Metadata' threw an exception. 
      ---> System.ArgumentException: could not produce an FSharpAssembly 
        object for the assembly 'FSharp.Core' because 
        this is not an F# assembly
    Parameter name: name
       at Microsoft.FSharp.Metadata.AssemblyLoader.Add(String name,Assembly assembly)
       at <StartupCode$FSharp-PowerPack-Metadata>.$Metadata..cctor()
       --- End of inner exception stack trace ---
       at Microsoft.FSharp.Metadata.AssemblyLoader..cctor()
       --- End of inner exception stack trace ---
       at Microsoft.FSharp.Metadata.AssemblyLoader.Get(Assembly assembly)
       at Microsoft.FSharp.Metadata.FSharpAssembly.FromAssembly(Assembly assembly)
       at Program.main(String[] args) in 
         C:\Documents an...\FSMetadataTest\Program.fs:line 11
    Press any key to continue . . .
    
    3 回复  |  直到 14 年前
        1
  •  3
  •   Dmitry Lomov    14 年前

    内森,伟大的调查,版本号确实没有更新,在原来的2010年5月发布,见 http://fsharppowerpack.codeplex.com/workitem/4548 我们已经上传了版本号正确的二进制文件。

        2
  •  3
  •   Nathan Shively-Sanders    14 年前

    我通过阅读报告找到了问题的直接原因 Powerpack source on Codeplex

    根据我的研究,大多数其他F#程序集在名为“FSharpSignatureData”的清单资源流中携带元数据。 包.名称

    代码在四个位置查找此目录名:

    1. @"SOFTWARE\Microsoft\.NETFramework\" + MSCorLibRunningRuntimeVersion + @"\AssemblyFoldersEx\Microsoft Visual F# 4.0"
    2. 注册表项 @"Software\Microsoft\.NETFramework\AssemblyFolders\Microsoft.FSharp-" + FSharpTeamVersionNumber ,其中FSharpTeamVersionNumber是 硬编码 作为“1.9.9.9”,至少在codeplex版本中是这样。我的机器上没有安装2010年5月版本的源代码。
    3. System.AppDomain.CurrentDomain.BaseDirectory。这是本地项目的“bin/Debug”目录, 你在fsi。然后是C:\ProgramFiles\FSharp-2.0.0.0\bin的一些变体。

    对我来说,四个都失败了:

    1. 我没有应用程序配置文件。我不太了解.NET生态系统,所以我不知道如何创建一个。
    2. 我没有安装VS2010。
    3. 我的本地项目在bin/Debug目录中没有FSharp.Core.sigdata的副本。

    可能 无论如何,在某个时候了解一下.NET的配置文件,所以这可能是最好的中期解决方案。创建注册表项“Microsoft.FSharp-1.9.9.9”或将FSharp.Core.sigdata复制到bin/Debug目录是一个非常简单的短期修复方法。

    我仍然不知道这个错误是否应该广泛存在,或者它是否只是由我从VS2005升级而来->2008和多个F#预览。通过阅读codeplex源代码,在我看来,其他没有vs2010的人也应该有这个问题,仅仅因为FSharpTeamVersionNumber被硬编码为1.9.9.9,并且没有更新到匹配注册表项2.0.0.0。但也许我升级到F#2.0和F#Powerpack2.0的顺序不正确地混合在一起产生了这种情况。或者可能没有足够的人使用元数据库来暴露错误。

        3
  •  1
  •   Tomas Petricek    14 年前

    这真的很让人困惑——我试着使用您描述的场景(VisualStudio2008中的F#2.0,以及CodePlex中最新的Powerpack2.0)运行代码,它毫无例外地工作。

    您还可以确保拥有最新版本的F#for Visual Studio 2008(在Visual Studio 2010最终版本之后不久发布),因为 FSharp.Core.dll FSharp.PowerPack.Metadata.dll . 另外,是 Metadata 库可以加载其他 dll 使用当前版本的F#编译器编译的库?

    如果这不起作用,那么(我想)是 元数据

    let a = System.Reflection.Assembly.GetExecutingAssembly()
         |> FSharpAssembly.FromAssembly
    printf "%A" a.Entities.Count
    

    如果下面的方法不起作用,那就是 真让人困惑 -不管是什么版本,图书馆都应该能够自己阅读!

    let a = FSharpAssembly.FromFile @"C:\...\bin\FSharp.PowerPack.Metadata.dll"
    printf "%A" a.Entities.Count