Вопрос:

Директива #r в скрипте C # не поддерживает относительные пути

c# reference .net-assembly roslyn

131 просмотра

2 ответа

227 Репутация автора

Согласно этому посту: Есть ли способ настроить рабочий каталог для команд загрузки "r и"

#rДиректива может быть использование с относительным путем, но это старый пост , и я не смог найти любую соответствующую документацию в последнее время о том , что конкретно (вчера искал целый день)

Я могу добавить ссылку на мою сборку, когда я предоставляю полный абсолютный путь, но он не работает с относительным путем.

DLL находится в текущем каталоге запущенного скрипта (проверено Environment.CurrentDirectoryс помощью запущенного скрипта):

Я перепробовал все эти формы:

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

Работал только последний.

Я использую библиотеку Roslyn, полученную из NuGet:

Microsoft.CodeAnalysis.CSharp.Scripting

Версия 3.1.0

Была ли удалена поддержка относительного пути?

Автор: Francis P Источник Размещён: 11.06.2019 02:22

Ответы (2)


0 плюса

85932 Репутация автора

Решение

Откуда запускается скрипт сценария?


Если вы используете 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же, как каталог файлов вашего файла сценария (который, как я предполагаю, ваш пользовательский код приложения будет знать, загружает ли он файл каким-либо образом) до CSharpScript.EvaluateAsync()вызова.

Например, в вашем пользовательском приложении вы можете сделать следующее:

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 и », загрузка по- #r прежнему не работает при использовании относительного пути». Если это сработало, то да, похоже, что это регрессия с тех пор, как этот ответ был первоначально опубликован.

Автор: Ray Vega Размещён: 11.06.2019 09:22

0 плюса

667 Репутация автора

Я тоже столкнулся с этой проблемой и после некоторых копаний нашел решение для меня на 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);

Это решило проблему для меня, и теперь разрешены относительные пути относительно пути файла сценария.

Автор: JonC Размещён: 06.09.2019 12:59
Вопросы из категории :
32x32