I have a Console app that is using PowerShell SDK. The SDK produces additional directories (ref,runtimes) when building app. The folders ref and runtime are part of NuGet Microsoft.PowerShell.SDK - List of NuGet Package Folders/Files. I can remove those directories when I'm building the app by using custom target aka <Target Name="CustomAfterBuild" AfterTargets="Build">
.
I want to get rid of them for the single-file executable. I've tried "Before/AfterTargets" for "Build", "Publish", "BeforePublish", "BeforeBuild", "PrepareForPublish", "GetCopyToOutputDirectoryItems", "CopyFilesToOutputDirectory" etc
But this doesn't work when I'm usingIncludeAllContentForSelfExtract. The directory of the extracted app located in Temp\.net\ConsolePowerShellSDKApp
still has those folders.
Does ExcludeFromSingleFile
or anything else cover the scenario of excluding files from a single-file executable that is actually part of NuGet package?
Example: https://github.com/ALIENQuake/ConsolePowerShellSDKApp
ConsolePowerShellSDKApp.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
<Nullable>enable</Nullable>
<DelCmd Condition="'$(OS)' == 'Windows_NT'">rmdir /S /Q</DelCmd>
<DirCmd Condition="'$(OS)' == 'Windows_NT'">dir</DirCmd>
</PropertyGroup>
<Target Name="CustomAfterBuild" AfterTargets="Build">
<Message Text="CustomAfterBuild - AfterTargets - Build" Importance="High"/>
<Exec Command="$(DelCmd) "$(ProjectDir)$(OutputPath)ref""/>
<Exec Command="$(DelCmd) "$(ProjectDir)$(OutputPath)runtimes""/>
</Target>
<ItemGroup>
<PackageReference Include="Microsoft.PowerShell.SDK" Version="7.4.0-preview.1"/>
</ItemGroup>
</Project>
ConsolePowerShellSDKApp.cs
// See https://aka.ms/new-console-template for more information
using Microsoft.PowerShell;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
Console.WriteLine("Hello, World!");
//string AppDir = System.Diagnostics.Debugger.IsAttached ? Path.GetFullPath(AppContext.BaseDirectory) : Environment.CurrentDirectory;
var runspaceConfiguration = InitialSessionState.CreateDefault2();
if (OperatingSystem.IsWindows() == true)
{
runspaceConfiguration.ExecutionPolicy = ExecutionPolicy.Bypass;
}
var pipeline = PowerShell.Create(RunspaceFactory.CreateRunspace(runspaceConfiguration));
pipeline.Runspace.Open();
pipeline.Commands.AddCommand("Get-ChildItem");
var results = pipeline.Invoke();
foreach (var item in results)
{
Console.WriteLine(item);
}
if (!System.Diagnostics.Debugger.IsAttached)
{
Console.WriteLine(@"Press any key.");
Console.ReadKey();
}
I've tried every After/Before Targets:
AfterTargets="AfterBuild"
AfterTargets="Build"
BeforeTargets="Publish"
BeforeTargets="BeforePublish"
but nothing works.
With the help of dotnet guys, I did it! Use Regex.IsMatch instead of Contains because you can use slashes.
This is the 'Target' definition:
<Target Name="Custom_Before_GenerateSingleFileBundle_DependsOn_PrepareForBundle" BeforeTargets="GenerateSingleFileBundle" DependsOnTargets="PrepareForBundle">
<ItemGroup>
<FilesToBundle
Remove="@(_FilesToBundle)"
Condition=
"
$([System.Text.RegularExpressions.Regex]::IsMatch(%(_FilesToBundle.RelativePath), "ref\\"))
OR
$([System.Text.RegularExpressions.Regex]::IsMatch(%(_FilesToBundle.RelativePath), "runtimes\\"))
"
/>
</ItemGroup>
<Message Importance="High" Text="%(_FilesToBundle.RelativePath)"/>
<Message Importance="High" Text="@(FilesToBundle)"/>
Additional info: https://github.com/dotnet/designs/blob/main/accepted/2021/before_bundle_build_hook.md