首页 > 解决方案 > 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);
}

这是我发现的:

并且至少

更新 - 将路径值从 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=@&quot;$(ProjectDirEscaped)&quot;" />
    </Target>

主要问题是即使使用@&quot$(ProjectDir)&quot;还不够,因为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")));

标签: c#msbuildcode-generationlempec#

解决方案


#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""");替换(额外的引号是可选的),然后你可以在修改后的行中使用宏。

我没有想到可以使用precomputeinside compileTime,但是你可以并且它有效。所以例如你可以做##reference(precompute(System.IO.Path.Combine(@"dir", "Foo.dll")));.


推荐阅读