如何在 msbuild 内联任务中使用 .NET 6 函数?

问题描述 投票:0回答:1

我有 Visual Studio 2022,并且安装了 .NET 9。

在构建期间(实际上是在构建开始之前),我需要创建一个符号链接,并且我需要以跨平台的方式这样做,因为我在 Windows 上,但 github actions 在 ubuntu 上运行。

因此,我创建了一个“内联任务”,又名“

UsingTask
”(https://learn.microsoft.com/en-us/visualstudio/msbuild/usingtask-element-msbuild?view=vs-2022)我想从中调用
System.IO.File.CreateSymbolicLink()
。 (https://learn.microsoft.com/en-us/dotnet/api/system.io.file.createsymboliclink?view=net-6.0)

这是我的代码:

<Project Sdk="Microsoft.NET.Sdk">
    ...
    <UsingTask TaskName="CreateFileSymbolicLink" 
            TaskFactory="RoslynCodeTaskFactory" 
            AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll" >
        <ParameterGroup>
            <path ParameterType="System.String" Required="true" />
            <pathToTarget ParameterType="System.String" Required="true" />
        </ParameterGroup>
        <Task>
            <Code Type="Fragment" Language="cs">
                //System.Console.WriteLine( $"x" );
                System.IO.File.CreateSymbolicLink( path, pathToTarget );
            </Code>
        </Task>
    </UsingTask>

失败了

错误 CS0117:“文件”不包含“CreateSymbolicLink”的定义。

我发现了这个:https://stackoverflow.com/a/51194833/773113(从2018年开始),我尝试使用字符串插值语法,并且该语法有效,但不是

CreateSymbolicLink()
方法。

我怎样才能让它工作,或者以其他方式实现我最初的目标,即在构建开始之前以跨平台方式创建到文件的符号链接?

c# visual-studio msbuild symlink .net-9.0
1个回答
0
投票

所以,我不得不放弃跨平台的想法。

这就是我最终所做的:

<UsingTask TaskName="CreateFileSymbolicLink" TaskFactory="RoslynCodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll" >
    <ParameterGroup>
        <path ParameterType="System.String" Required="true" />
        <targetPath ParameterType="System.String" Required="true" />
    </ParameterGroup>
    <Task>
        <Code Type="Fragment" Language="cs">
            //PEARL: We cannot simply use System.IO.File.CreateSymbolicLink() here, because RoslynCodeTaskFactory
            //       tasks target .NET Standard. See https://stackoverflow.com/q/79308054/773113

            [System.Runtime.InteropServices.DllImport( "Kernel32.dll", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Unicode )]
            [return: System.Runtime.InteropServices.MarshalAs( System.Runtime.InteropServices.UnmanagedType.I1 )]
            static extern bool CreateSymbolicLink( string lpSymlinkFileName, string lpTargetFileName, uint dwFlags );

            System.IO.File.Delete( path );

            //PEARL: The SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE has to be used, or else this will fail,
            //       and for this flag to be used, "Developer Mode" must be enabled in Windows.
            if( !CreateSymbolicLink( path, targetPath, /* File + SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE */ 0x2 ) )
                throw new System.ComponentModel.Win32Exception( System.Runtime.InteropServices.Marshal.GetLastWin32Error(), $"Failed to create symbolic link {path} {targetPath}" );
        </Code>
    </Task>
</UsingTask>
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.