12

I'm trying to write a F# script file. So I use Visual studio "File->New->Files->F# Script File" to generated a new fsx file. Now I want to add reference to FSharpData by opening the Package Manager Console and enter

Install-Package FSharp.Data

However I got the following error. Is solution always required to be created even for F# script file?

Install-Package : The current environment doesn't have a solution open.
At line:1 char:1
+ Install-Package FSharp.Data
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Install-Package], InvalidOperationException
    + FullyQualifiedErrorId : NuGetNoActiveSolution,NuGet.PowerShell.Commands.InstallPackageCommand
ca9163d9
  • 27,283
  • 64
  • 210
  • 413
  • well the easy way is to get the .dll from somewhere (make a one-time solution and grab it with nuget for example) and just put it right next to your .fsx file - then you can just move on and `#r` it and use it - aside from this you could call nuget.exe from your script to grab it yourself but that would be overkill IMO (and you would still need to have nuget.exe in your path or next to your file) – Random Dev Jun 30 '15 at 20:47
  • Note that you can now simply use `#r nuget: PkgName` – Abel Jul 27 '20 at 04:46

2 Answers2

20

Since late 2019, this is now natively supported:

#r "nuget: Suave" 
#r "nuget: FSharp.Data" 
#r "nuget: FSharp.Charting" 

Original answer:

There is a fun hack you can do that is documented on the suave.io web site, which downloads Paket and then uses it to download packages - and all of this in a few lines in a script file:

// Step 0. Boilerplate to get the paket.exe tool
open System
open System.IO     
Environment.CurrentDirectory <- __SOURCE_DIRECTORY__
 
if not (File.Exists "paket.exe") then
    let url = "https://github.com/fsprojects/Paket/releases/download/0.31.5/paket.exe"
    use wc = new Net.WebClient()
    let tmp = Path.GetTempFileName()
    wc.DownloadFile(url, tmp)
    File.Move(tmp,Path.GetFileName url)
 
// Step 1. Resolve and install the packages     
#r "paket.exe"     
Paket.Dependencies.Install """
source https://nuget.org/api/v2

nuget Suave
nuget FSharp.Data
nuget FSharp.Charting
""";;

It is a bit long for my taste, but it lets you do everything without leaving a script file and F# Interactive.

Abel
  • 56,041
  • 24
  • 146
  • 247
Tomas Petricek
  • 240,744
  • 19
  • 378
  • 553
  • Note for others. There is a newer version of the example `packet.exe` loader code that does not hard code a version. See: [Using Paket from F# Interactive](https://fsprojects.github.io/Paket/reference-from-repl.html). It uses `let url = "http://fsprojects.github.io/Paket/stable"`, `let stable = wc.DownloadString(url)` and `wc.DownloadFile(stable, tmp)`. For [NuGet Feed Locations](https://www.nuget.org/) with newer versions of NuGet installed use `https://api.nuget.org/v3/index.json` – Guy Coder Jun 16 '17 at 10:47
2

The new out-of-the-box way to do this is simply add this in your .fsx script:

#r "nuget: FSharp.Data, Version=3.3.3"

(The PR that implemented this, for reference; and the release where this is unveiled.)


OLD ANSWER:

For Linux users out there, if your distro is Debian-based (tested with Ubuntu 16.04), you could, inside your F# script, do:

  1. Install the nuget package if it's not installed already (use sudo apt install nuget).
  2. Do nuget install FSharp.Data -Version 2.3.2.
  3. Load the DLL via an #r line (e.g. #r "FSharp.Data.2.3.2/lib/net40/FSharp.Data.dll).

This way you don't need to download .exe files from some web server, which feels totally insecure.

PS: Beware, you would still be trusting the library (binary) received from (Microsoft's) Nuget server though.

knocte
  • 16,941
  • 11
  • 79
  • 125
  • Maybe you could go into more detail about step 3 – Sam Dec 22 '16 at 08:29
  • sorry for the very delayed answer, but what do you mean? I thought it was obvious, that `#r` line would go in your .fsx script – knocte Jul 27 '20 at 04:09