Repository navigation
Building and Distributing Plugins
Jamie Head edited this page Aug 5, 2026
·
4 revisions
Place this target near the end of the plugin .csproj:
<Target Name="CopyPluginToSimulcastUtility" AfterTargets="Build">
<PropertyGroup>
<PluginName Condition="'$(SolutionName)' != ''">$(SolutionName)</PluginName>
<PluginName Condition="'$(PluginName)' != ''">$(AssemblyName)</PluginName>
<PluginName Condition="'$(PluginName)' == '' and '$(SolutionName)' == ''">Example_Plugin_Name</PluginName>
<PluginDirectory>$(LOCALAPPDATA)\SimulcastUtility\Plugins\$(PluginName)</PluginDirectory>
</PropertyGroup>
<MakeDir Directories="$(PluginDirectory)" />
<ItemGroup>
<PluginFiles Include="$(TargetPath)" />
<PluginFiles Include="$(TargetDir)$(AssemblyName).pdb" Condition="'$(Configuration)' == 'Debug' and Exists('$(TargetDir)$(AssemblyName).pdb')" />
<PluginFiles Include="$(TargetDir)Your.Private.Dependency.dll" Condition="Exists('$(TargetDir)Your.Private.Dependency.dll')" />
</ItemGroup>
<Copy SourceFiles="@(PluginFiles)" DestinationFolder="$(PluginDirectory)" SkipUnchangedFiles="true" />
</Target>Do not copy $(TargetDir)*.*; it includes host contracts and framework assemblies that should not be packaged.
Set host references to Private=false:
<Reference Include="SimulcastUtility.Plugins">
<HintPath>lib\SimulcastUtility.Plugins.dll</HintPath>
<Private>false</Private>
</Reference>Do the same for SimulcastUtility.Application and SimulcastUtility.Core. The host must supply these assemblies so plugin types share the same identity as application interfaces.
- Main plugin DLL.
- Plugin-owned WPF resources not embedded as
Page/Resource. - Private managed dependencies not supplied by the host.
- Native runtime files required by private dependencies.
-
.deps.jsonwhen required for dependency discovery. - PDB files only in debug/developer packages.
SimulcastUtility.Plugins.dllSimulcastUtility.Application.dllSimulcastUtility.Core.dll-
Microsoft.Extensions.*assemblies already supplied by the target application unless a truly private/version-specific dependency requires otherwise - WPF and .NET runtime assemblies
- Test assemblies, XML docs you do not intend to ship, and unrelated build output
- User data or developer-specific settings
- Plugin .pdb files if not in a debug environment
Manage Plugins accepts a single DLL, a selected collection of DLLs, or a ZIP archive. Prefer ZIP for plugins with dependencies or native assets. Use one clearly named top-level folder and keep the main DLL easy to identify.
Example:
MyPlugin/
MyPlugin.dll
MyPlugin.deps.json
ThirdParty.Library.dll
runtimes/
win-x64/
native/
native-library.dll
- Build Release for
net10.0-windowsand the target architecture requirements. - Test import from a clean plugin directory.
- Test enable, disable, re-enable, refresh, directory reload, and deletion.
- Confirm no contract DLLs are included.
- Confirm settings survive restart and plugin-data directory changes.
- Confirm all UI follows default and custom themes.
- Confirm logs contain useful structured messages without secrets.
- Test with no receivers and with the selected receiver changing.
- Document application compatibility and plugin version.