F# Scripts—Reference Nirvana

Jomo Fisher—Last time I wrote about getting started with F# scripts. They’re the fastest way to just write and run some F#.  It’s reasonable to ask whether you can use them to do real work. After all, I just showed a toy example: reversing a linked list. In the real world you need use other people’s code. This is what the #r directive is for. You use it like this:


#r "c:\Program Files\Microsoft Visual Studio 9.0\Visual Studio Tools for Office\PIA\Office12\Microsoft.Office.Interop.Excel.dll"

open System.Reflection

open Microsoft.Office.Interop.Excel

let app = ApplicationClass(Visible=true)

let sheet = app.Workbooks


               .Worksheets.[1] :?> Worksheet

let range = sheet.Range("A1")


                 <- "Hello Excel"


Assuming you have all the stuff you need installed, when you run this script you’ll get an Excel spreadsheet:



One thing that is fragile about the script is that different people may have installed the needed assembly in different spots.

To help with this situation, we’ve done something that I think is pretty magical. F# will resolve the assemblies using the same industrial strength reference resolution engine that MSBuild uses. (I tipped our hand a bit on this here). So now, you can just reference the assembly like this:

#r "Microsoft.Office.Interop.Excel"

And F# will just find it. Now the script works in a lot more places.

You can even use it to reference a specific version of an assembly.

#r "Microsoft.Office.Interop.Excel, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c"


You would do this, for example, if your script only works with a particular version of an assembly or if you want to reference and older version.


The MSBuild algorithm is open to anyone who wants to publish their assembly (search for AssemblyFoldersEx). For example, here’s a screenshot of me referencing the XCeed chart library:


You can pick up the latest CTP of F# here:  http://msdn.com/fsharp


This posting is provided "AS IS" with no warranties, and confers no rights.

Comments (1)

  1. Martin says:

    HI Jomo,

    Thanks!  One can simplify the reading by using .Value2 rather than .Value:

    let range = sheet.Range("B1").Value2 <- "Hello Excel"

    – Martin

Skip to main content