簡體   English   中英

從fsx腳本編譯時的F#管理引用

[英]F# managing references when compiling from fsx script

我需要與SharePoint交互(在前提下),並決定嘗試F#。 僅使用CLI工具就可以做到這一點,或者應該足夠簡單。

我設法與一個網站進行交互並獲得了所需的信息。 我為所需的DLL苦苦掙扎,但最后

#if INTERACTIVE
#r @"C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll"
#r @"C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"

// seems to be required
#r @"[...]\Microsoft.Online.SharePoint.Client.Tenant.dll.15.0.4615.1001\Microsoft.Online.SharePoint.Client.Tenant.dll"

#r @"[...]\SharePointPnPCoreOnline.3.8.1904\lib\net45\OfficeDevPnP.Core.dll"

#endif

使用Fsi REPLFsi script.fsx ,但無論是fs文件還是fsx腳本,都無法編譯。

我的代碼是:

open Microsoft.SharePoint.Client;;

let main () = 
    let authnManager = OfficeDevPnP.Core.AuthenticationManager()
    printfn "%A" authnManager
    0

main()

使用fsi運行:

PS> fsi script.fsx
OfficeDevPnP.Core.AuthenticationManager #OK!

嘗試編譯:

PowerShell>  fsc --warn:5 -r "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll" `
>>      -r "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll" `
>>      -r "absolute\path\to\Microsoft.Online.SharePoint.Client.Tenant.dll.15.0.4615.1001\Microsoft.Online.SharePoint.Client.Tenant.dll" `
>>      -r "absolute\path\to\SharePointPnPCoreOnline.3.8.1904\lib\net45\OfficeDevPnP.Core.dll"  .\script.fsx
Microsoft (R) F# Compiler version 10.4.0 for F# 4.6
Copyright (c) Microsoft Corporation. All Rights Reserved.

> .\script.exe

Exception non gérée (unmanaged exception) : System.IO.FileNotFoundException: 
Impossible de charger le fichier ou l'assembly 'OfficeDevPnP.Core,
Version=3.8.1904.0, Culture=neutral, PublicKeyToken=5e633289e95c321a'
ou une de ses dépendances. Le fichier spécifié est introuvable.
   à Script.main()
   à <StartupCode$script>.$Script$fsx.main@()

為什么會有這種差異? 我想念什么? 如何使用fsc加載引用(因為nuget安裝了很多傳遞依賴項)? 當然,必須同時使用fsc和fsi對它們進行管理! (除非OfficeDevPnP.Core.dll出現特定問題……)

我認為在F#Interactive中通過#r引用的DLL必須處於依賴順序。 所以,如果在SharePoint的DLL取決於OfficeDevPnp DLL,然后OfficeDevPnp DLL需要先引用(這是#r行需要來將SharePoint前#r線)。 一旦您加載了DLL,就必須以正確的順序重新設置交互式會話。

通常,在F#交互中加載程序包依賴項非常棘手。 您可以查看一些F#工具(例如Paket) ,這可能會使您的生活更輕松一些。 如果您已經有了一個帶有所需引用的Visual Studio項目,則另一個選擇是使用該項目為腳本文件生成程序包引用。 您可以閱讀.fsproj文件並生成#r的項目使用的引用語句。 這樣的事情可能會起作用:

#r "System.Xml"
#r "System.Xml.Linq"

open System
open System.IO
open System.Linq
open System.Xml.Linq

let inline isNotNull o = o |> isNull |> not

let private getProject path =
    Directory.EnumerateFiles(path, "*.*proj") |> Seq.head |> XDocument.Load    

let generateDlls path =
    let projectFile = getProject path
    let references =
        projectFile.Descendants <| XName.Get("HintPath", "http://schemas.microsoft.com/developer/msbuild/2003")
        |> Seq.filter (fun reference -> reference.Value.ToLower().EndsWith(".dll"))
        |> Seq.filter (fun reference -> reference.Value.StartsWith("$") |> not)
        |> Seq.map (fun reference -> reference.Value)
    let projects =
        projectFile.Descendants <| XName.Get("ProjectReference", "http://schemas.microsoft.com/developer/msbuild/2003")
        |> Seq.map (fun reference -> reference.Elements(XName.Get("Name", "http://schemas.microsoft.com/developer/msbuild/2003")).SingleOrDefault())
        |> Seq.filter (fun nameElement -> nameElement |> isNotNull)
        |> Seq.map (fun nameElement -> nameElement.Value)
        |> Seq.map (fun reference -> sprintf "../%s/bin/debug/%s.dll" reference reference)

    references 
    |> Seq.append projects
    |> Seq.iter (fun reference -> printfn "#r @\"%s\"" reference)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM