sharepoint - 从 fsx 脚本编译时 F# 管理引用
问题描述
我需要与 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
or解决了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
)
解决方案
我认为通过#r
F# Interactive 引用的 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)
推荐阅读
- c# - 如何在 Xamarin.Forms 中实现两指 PanGesture 实例
- javascript - 如何根据字符串值实例化对象
- python - Need help running spark-submit in Apache Airflow
- python - Bamboo - Docker image run Error - Connection refused
- django - 在 Django 中创建用户历史 API
- postgresql - 将 postgres JSON 转换为行
- excel - 如何通过范围内的 ID 和日期过滤找到最大值和最小值
- core-data - Previewing ContentView with CoreData
- multithreading - 优化 OpenCL 缓冲区写入?
- pandas - 递归地列出树/有向图中节点的邻居,对于图中的所有节点,一次一个“级别”?