-->

Embedding F# Interactive Example Throwing Exceptio

2019-06-19 02:39发布

问题:

I am working through the Embedding F# Interactive example from http://fsharp.github.io/FSharp.Compiler.Service/interactive.html but am having an issue with the following line throwing an exception:

let fsiSession = FsiEvaluationSession.Create(fsiConfig, allArgs, inStream, outStream, errStream)

The exception thrown is:

"An unhandled exception of type 'System.Exception' occurred in FSharp.Compiler.Service.dll Additional information: Error creating evaluation session: StopProcessing null"

My project is being run from VS2015 Enterprise Update 1, setup as a simple F# console app, with Target F# runtime being F# 4.0 with the Target Framework as 4.6. The version of FSharp.Compiler.Service downloaded from nuget is 2.0.0.2.

The Program.Fs file code I am running is here (a direct port of the example):

open System
open System.IO
open System.Text
open Microsoft.FSharp.Compiler.SourceCodeServices
open Microsoft.FSharp.Compiler.Interactive.Shell

[<EntryPoint>]
let main argv =

    let sbOut = new StringBuilder()
    let sbErr = new StringBuilder()
    let inStream = new StringReader("")
    let outStream = new StringWriter(sbOut)
    let errStream = new StringWriter(sbErr)

    // Build command line arguments & start FSI session
    let argv = [| "C:\\fsi.exe" |]
    let allArgs = Array.append argv [|"--noninteractive"|]

    let fsiConfig = FsiEvaluationSession.GetDefaultConfiguration()
    let fsiSession = FsiEvaluationSession.Create(fsiConfig, allArgs, inStream, outStream, errStream)

    /// Evaluate expression & return the result
    let evalExpression text =
        match fsiSession.EvalExpression(text) with
        | Some value -> printfn "%A" value.ReflectionValue
        | None -> printfn "Got no result!"

    evalExpression "42+1" // prints '43'

    Console.ReadLine() |> ignore

    0  // return integer

Any thoughts would be appreciated.

回答1:

The key to your problem is found at Compiler Services: Notes on FSharp.Core.dll

If doing dynamic compilation and execution you may also need to include an FSharp.Core.optdata and FSharp.Core.sigdata, see below for guidance.

When you build the application the output directory with FSharp.Core.dll is missing two files:

FSharp.Core.optdata  
FSharp.Core.sigdata

You will need to find these two files and the correct versions of the files that agree with FSharp.Core.dll and copy them to the build output directory.

How to find the files using Visual Studio

From menu View -> Solution Explorer
Expand Project
Expand References
Right click FSharp.Core and select properties.

The Full Path gives the directory that should have at least the three files. Use a file explorer to open the directory in Full Path.

Copy the two files

FSharp.Core.optdata  
FSharp.Core.sigdata

to the build directory.

How to find the build directory using Visual Studio

From menu View -> Solution Explorer
Select Project
Press F4 to open the Properties Page

The Project Folder with \bin\Debug is the default when debugging with VS.

Change location of fsi.exe

Now that you have the two needed files you will also need to change the location of fsi.exe

let argv = [| "C:\\fsi.exe" |]

because I doubt that fsi.exe is in the root of your C drive.