c# - Esharp LeMP #r "path" 仅适用于 compileTime 指令中的绝对路径
问题描述
我正在使用最新版本 2.8.1
我尝试了项目源和二进制相对路径但没有成功。这是代码:https://github.com/dadhi/LempTest/blob/strong text9ce17d16a8d7c71fc475921e1414e5bc64d72f9d/LibWithEcs/ServiceRegistrations.ecs.include#L3
另外,我不确定如何通过 --set:key=value 传递目录。我应该将键或值用引号括起来,转义斜杠吗?如果我成功通过,我可以在compileTime
部分中#get(key)并以某种方式将它用于#r吗?
更新 - 在玩了@Qwertie 答案之后
我创建了一个简单的 Test.ecs 文件来测试--set:key=value
输出
compileTime
{
using C = System.Console;
var a = #get(a);
C.WriteLine(a);
}
这是我发现的:
lemp Test.ecs --set:a="c:"
返回“错误:需要一个粒子(id、literal、{braces} 或(parens))。”lemp Test.ecs --set:a=@"c:"
返回“c:”lemp Test.ecs --set:a=@"c:\Code"
返回相同的“c:”lemp Test.ecs --set:a=@"c:\\Code"
再次返回相同的“c:”
并且至少
lemp Test.ecs --set:a="""c:\\Code"""
工作并输出“c:\Code”
更新 - 将路径值从 MSBuild Exec 目标传递到 Lemp
对我来说,最后一块拼图是传递命令行开关$(ProjectDir)
的值。set:key=value
这是最终的(实际上不是,请参阅下面的更新)解决方案:
<Target Name="LempTransform" BeforeTargets="BeforeBuild">
<PropertyGroup>
<ProjectDirEscaped>$(ProjectDir.Replace('\', '___'))</ProjectDirEscaped>
</PropertyGroup>
<!-- <Message Text="Project with escaped slashes is $(ProjectDirEscaped)" Importance="high"/> -->
<Exec WorkingDirectory="$(ProjectDir)"
Command="dotnet lemp %(EcsFile.Identity) --outext=.Generated.cs --set:ProjectDir=@"$(ProjectDirEscaped)"" />
</Target>
主要问题是即使使用@"$(ProjectDir)"
还不够,因为ProjectDir
输出带有单斜杠的路径,例如c:\foo\bar
. 那么就没有办法在字符串文字中转义它们了。所以我最终手动替换了斜杠string.Replace
,然后在使用.ecs
文件中的密钥时将它们替换回来:
compileTime
{
##reference(precompute(System.IO.Path.Combine(#get(ProjectDir).Replace("___", "\\"), @"..\AnotherLib\bin\Debug\netstandard2.0\AnotherLib.dll")));
using AnotherLib;
//...
更新 - 一个更简单的解决方案,通过每个 @Qwertie 评论用正斜杠替换向后
评论有很大帮助,所以我不需要Replace
在使用模板时转义值。
首先,我替换\
为,/
而不是___
仍然保持路径对 .NET BCL API 有效:
<PropertyGroup>
<ProjectDirEscaped>$(ProjectDir.Replace('\', '/'))</ProjectDirEscaped>
</PropertyGroup>
Replace
因此,在使用路径时我不需要##reference
:
##reference(precompute(System.IO.Path.Combine(#get(ProjectDir), @"..\AnotherLib\bin\Debug\netstandard2.0\AnotherLib.dll")));
解决方案
#r
在 Visual Studio 扩展中,相对路径对我有用。路径应该是相对于源文件位置的。
要找出文件“相信”它所在的输入文件夹,请在文件#get(#inputFolder);
顶部写入,然后查看 LeMP 的输出。如果输出显示_numget(_numinputFolder)
出现问题 - 变量未设置,但可以在命令行上设置其值:--set:#inputFolder="C:\\Dev\\MyFolder"
.
之后--set:
,key=value
被解析为赋值表达式,因此您应该将值括在引号中并用双反斜杠替换反斜杠。(表达式语法是LES或当前输入语言,如果有的话 ---inlang=ecs
用于增强型 C#)
你可以#get(key)
在里面使用compileTime
;但是,#r
由于指令的语法非常笨拙(与普通的 C# 字符串不同),该指令以非常笨拙的方式进行解析。这样一来,就不能#r
在线使用宏了。你可能不需要绕过这个限制,但如果你这样做了,你可以#r "dir\Foo.dll"
用它的等效Loyc 树 ##reference(@"""dir\\Foo.dll""");
替换(额外的引号是可选的),然后你可以在修改后的行中使用宏。
我没有想到可以使用precompute
inside compileTime
,但是你可以并且它有效。所以例如你可以做##reference(precompute(System.IO.Path.Combine(@"dir", "Foo.dll")));
.
推荐阅读
- html - TailwindCSS - 修复了 flex 父级的 div 全宽
- excel - excel无法下载图片
- python - 简单的熊猫数据框转换
- ios - Ionic 5 Capacitor - 如何在 IOS 上动态更改状态栏背景颜色
- php - 如何将一个项目与多个域链接?
- r - R中的Smote函数
- zsh - 带有空格的转义字符串传递给 ZSH 函数
- c++ - 从文本文件中读取并打印内容 c++
- python - 在我的 Mac 上使用 Pycharm 时,我得到了一个无效的 Python SDK
- python - 为什么 Numpy 在 sigma 裁剪的矢量化 for 循环上较慢