[英]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 REPL
或Fsi 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.