C#脚本中的#r指令不支持相对路径

时间:2019-06-11 14:22:57

标签: c# reference .net-assembly roslyn

根据此帖子: Is there a way to setup a working directory for "r and "load commands

#r指令可以与相对路径一起使用,但这是一篇旧文章,我未能找到有关该文件的任何相关最新文档(昨天整个下午都在搜索)

当我提供完整的绝对路径时,我可以添加我的程序集的引用,但是它不适用于相对路径。

该dll位于运行脚本的当前目录中(通过运行脚本中的Environment.CurrentDirectory进行了验证):

我尝试了所有这些形式:

#r ".\MyLib.dll"
#r "MyLib.dll"
#r "D:\Absolute\Path\To\MyLib.dll"

只有最后一个在工作。

我正在使用从NuGet检索的Roslyn库:

Microsoft.CodeAnalysis.CSharp.Scripting

版本3.1.0

是否删除了相对路径支持?

2 个答案:

答案 0 :(得分:0)

脚本的脚本执行器从哪里执行?


如果您通过命令行使用 csi.exe ,例如:

C:\dir1>csi.exe .\path\to\script\myScript.csx 

Environment.CurrentDirectory将是启动csi.exe的当前目录(即c:\dir1),而不是脚本文件的当前目录(即c:\dir1\path\to\script)。


如果您正在使用 Visual Studio C#交互式窗口#load文件,则该文件为c:\Users\<your user name>,而不是脚本的文件路径。


如果您正在使用引用Microsoft.CodeAnalysis.CSharp.Scripting库的自定义应用程序,则Environment.CurrentDirectory将是自定义应用程序的文件位置,而不是脚本。

解决此问题的一种方法是将Environment.CurrentDirectory设置为与脚本文件的文件目录相同(我假设您的自定义应用程序代码会知道脚本是否以某种方式加载了该文件),位于{{1 }} 叫做。

例如,在您的自定义应用中,您可以执行以下操作:

CSharpScript.EvaluateAsync()

不幸的是,即使按照Is there a way to setup a working directory for “r and ”load commands的建议using Microsoft.CodeAnalysis.CSharp.Scripting; // ... var scriptDirectory = @"c:\dir1\path\to\script"; // <-- or however else you are getting this. will use this later var scriptFilename = "myScript.csx"; var scriptFilepath = Path.Combine(scriptDirectory, scriptFilename); var scriptCode = File.ReadAllText(scriptFilepath); Environment.CurrentDirectory = scriptDirectory; // <-- set this before running the script below var result = await CSharpScript.EvaluateAsync(scriptCode); 进行了Environment.CurrentDirectory的测试后,#r在使用相对路径时仍然不起作用。如果该方法一次成功,那么自从最初发布该答案以来,它看起来似乎是回归的。

答案 1 :(得分:0)

我也遇到了这个问题,经过一番挖掘,我在github上找到了适合我的解决方案。我现在找不到链接,但是如果我再次找到它,我将进行更新。

根据github上问题的答案,相对路径仅在直接执行脚本文件时有效。 Roslyn不再使用Environment.CurrentDirectory搜索库。问题在于,使用CSharpScript.EvaluateAsync时,您没有运行脚本文件,而是在评估字符串,因此roslyn甚至都不会尝试解析任何相对路径。

解决方案是在ScriptOptions中提供文件的路径:

var scriptCode = File.ReadAllText(scriptFilepath);

var opt = ScriptOptions.Default
            .WithFilePath(scriptFilePath);

var result = await CSharpScript.EvaluateAsync(scriptCode, options: opt);

这为我解决了这个问题,相对路径现在相对于脚本文件的路径已解决。

更新:链接发布到github https://github.com/dotnet/roslyn/issues/36417