Environment Setup
Follow the steps below to initialize your plugin project.
-
Prepare the Development Environment
- IDE: Visual Studio 2026
- SDK: .NET 10 SDK
- Host Source Code: You need the
BetterLyricssolution locally to referenceCoreandDevTools.
-
Create Project
Create a new Class Library project. We recommend naming it
BetterLyrics.Plugins.PluginType.YourPluginNameto maintain naming consistency.- Target Framework:
.NET 10(net10.0-windows10.0.26100.0) PluginTypecan beSource,Translator,Transliterator,AI, etc., depending on your plugin type and functional positioning.
- Target Framework:
-
Configure .csproj
Replace the content of your
.csprojfile with the template below. This template connects the entire automation toolchain.BetterLyrics.Plugins.PluginType.YourPluginName.csproj <Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><TargetFramework>net10.0-windows10.0.26100.0</TargetFramework><ImplicitUsings>enable</ImplicitUsings><Nullable>enable</Nullable><SupportedOSPlatformVersion>10.0.19041.0</SupportedOSPlatformVersion><RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers><EnableDynamicLoading>true</EnableDynamicLoading><Description>[TODO]Plugin Description</Description><Version>[TODO]Plugin Version</Version><Authors>[TODO]Plugin Author</Authors><RepositoryUrl>[TODO]Plugin GitHub Repository URL</RepositoryUrl><Copyright>[TODO]Plugin Copyright Info</Copyright><Company>$(Authors)</Company></PropertyGroup><ItemGroup><ProjectReference Include="..\..\BetterLyrics.Core\BetterLyrics.Core.csproj" ><Private>false</Private><ExcludeAssets>runtime</ExcludeAssets></ProjectReference></ItemGroup><Target Name="AutoExcludeSharedAssemblies" AfterTargets="ResolveAssemblyReferences"><PropertyGroup><HostOutputDir>..\..\BetterLyrics.WinUI3\bin\x64\$(Configuration)\$(TargetFramework)\</HostOutputDir></PropertyGroup><Message Text="[Debug] Searching for Host Assemblies in: $(HostOutputDir)" Importance="High" /><ItemGroup><FilesToCopy Include="@(ReferenceCopyLocalPaths)" /><SharedFiles Include="@(FilesToCopy)" Condition="Exists('$(HostOutputDir)%(Filename)%(Extension)')" /><ReferenceCopyLocalPaths Remove="@(SharedFiles)" /></ItemGroup><Message Text="[Smart Trim] Excluded shared assemblies:%0a@(SharedFiles->' -> %(Filename)%(Extension)', '%0a')" Importance="High" Condition="'@(SharedFiles)' != ''" /></Target><Target Name="RunDevTools" AfterTargets="PostBuildEvent"><PropertyGroup><AnalyzerPath>..\..\BetterLyrics.DevTools\bin\$(Configuration)\$(TargetFramework)\BetterLyrics.DevTools.exe</AnalyzerPath><MainAppConfigDir>..\..\BetterLyrics.WinUI3\PluginConfigs\</MainAppConfigDir><SourceLangDir>$(ProjectDir)Langs\</SourceLangDir><OutputLangDir>$(TargetDir)Langs\</OutputLangDir></PropertyGroup><Message Text="[Analyzer] Generating resources to Project Directory..." Importance="High" /><Exec Command=""$(AnalyzerPath)" "$(TargetPath)" All "$(ProjectDir)\"" /><ItemGroup><FreshLangFiles Include="$(SourceLangDir)*.json" /></ItemGroup><Copy SourceFiles="@(FreshLangFiles)" DestinationFolder="$(OutputLangDir)" /><Copy SourceFiles="$(TargetDir)$(ProjectName)_TrimmingConfig.cs" DestinationFolder="$(MainAppConfigDir)" SkipUnchangedFiles="true" /><Copy SourceFiles="$(TargetDir)$(ProjectName)_TrimmerRoots.xml" DestinationFolder="$(MainAppConfigDir)" SkipUnchangedFiles="true" /></Target><Target Name="PackagePluginToZip" AfterTargets="Build"><PropertyGroup><PackageOutputDir>$(ProjectDir)..\_Dist\$(Configuration)\</PackageOutputDir><ZipFileName>$(AssemblyName).v$(Version).blp</ZipFileName><FinalZipPath>$(PackageOutputDir)$(ZipFileName)</FinalZipPath><StagingDir>$(OutputPath)_TempStaging\</StagingDir></PropertyGroup><ItemGroup><FilesToPack Include="$(OutputPath)**\*" /><FilesToPack Remove="$(OutputPath)$(ProjectName)_TrimmingConfig.cs" /><FilesToPack Remove="$(OutputPath)$(ProjectName)_TrimmerRoots.xml" /><FilesToPack Remove="$(StagingDir)**\*" /></ItemGroup><RemoveDir Directories="$(StagingDir)" /><Copy SourceFiles="@(FilesToPack)" DestinationFolder="$(StagingDir)%(RecursiveDir)" /><ZipDirectory SourceDirectory="$(StagingDir)" DestinationFile="$(FinalZipPath)" Overwrite="true" /><RemoveDir Directories="$(StagingDir)" /><Message Text="[Packager] The plugin package has been generated in the parent directory: $(FinalZipPath)" Importance="High" /></Target></Project>
After a successful compilation, your project structure should look like this:
DirectoryBetterLyrics/
DirectoryBetterLyrics.WinUI3/
DirectoryPluginConfigs/
- BetterLyrics.Plugins.PluginType.YourPluginName_TrimmerRoots.xml
- BetterLyrics.Plugins.PluginType.YourPluginName_TrimmingConfig.cs
- …
DirectoryPlugins/
Directory_Dist/
Directory$(Configuration)/
- BetterLyrics.Plugins.PluginType.YourPluginName.vVersion.blp
- …
DirectoryBetterLyrics.Plugins.PluginType.YourPluginName/
DirectoryLangs/
- en.json
- …
- Config.cs
- Plugin.cs
- BetterLyrics.Plugins.PluginType.YourPluginName.csproj
- …