Skip to content

Commit

Permalink
Updating to 3.4.4
Browse files Browse the repository at this point in the history
-= Video Acceleration, Disposal and Swaping Improvements =-

* Re-designs and improves Video Acceleration with custom hardware frame pool allocation, zero-copy, proper width/height alignments
* Re-designs and improves VideoDecoder's and MediaRenderer's disposal which resolves major memory leaks
* Re-designs of player's swap implementation with better perfomance (Uses the new static Player.SwapPlayers from now on for both WPF/WinForms)
* Renderer: Changes from Discard to FlipDiscard and from single backbuffer to two (for better performance and avoid memory leaks)
* Adds Master.RegisterPlugins to allow different path for plugins than default
* Plugins.YoutubeDL: Adds retries and fallback to manifest url support
* Controls.WPF: Adds PlayerDebug with all Player's properties
* Controls.WPF: Adds ZeroCopy to Video Settings
* Controls.WPF: Removes GPU Usage
* Controls.WPF: Updates MaterialDesign

[Issues]
* Fixes memory leaks caused by FFmpeg and VA by reseting the renderer on every new input
* Fixes an issue with Volume/Mute
* Fixes an issue with Enable/Disable Streams

[Important / Breaking Changes]
* Decoder:  ZeroCopy automatically detects padding and will be disabled (changes Config.Decoder.ZeroCopy from bool to enum with Auto/Enabled/Disabled)
* Renderer: FlipDiscard with two backbufffers can cause issues with win7/8
* Solution: Sample builds will not copy Libs and Plugins to the output
* Solution: Plugins.NET6 will be created in Plugins folder now
  • Loading branch information
SuRGeoNix committed Jan 6, 2022
1 parent e060633 commit 14e27c3
Show file tree
Hide file tree
Showing 41 changed files with 983 additions and 813 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ FlyleafLib/FlyleafLib.xml
/Plugins.NET4/
/Plugins.NET5/
/Plugins.NET6/
/Plugins/

# NuGet Pack
*.nuspec
Expand Down
4 changes: 2 additions & 2 deletions FlyleafLib.Controls.WPF/Flyleaf.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@
<ControlTemplate TargetType="local:Flyleaf">
<ControlTemplate.Resources>
<ResourceDictionary>
<Storyboard x:Key="fadeIn">
<Storyboard x:Key="fadeIn" Timeline.DesiredFrameRate="10">
<DoubleAnimation BeginTime="0:0:0" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.5" AutoReverse="False"/>
</Storyboard>

<Storyboard x:Key="fadeOut">
<Storyboard x:Key="fadeOut" Timeline.DesiredFrameRate="10">
<DoubleAnimation BeginTime="0:0:0" Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:2.0" AutoReverse="False"/>
</Storyboard>
</ResourceDictionary>
Expand Down
118 changes: 71 additions & 47 deletions FlyleafLib.Controls.WPF/Flyleaf.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;
Expand All @@ -10,7 +11,6 @@
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;

using WpfColorFontDialog;
using MaterialDesignThemes.Wpf;
Expand Down Expand Up @@ -65,6 +65,7 @@ public ObservableCollection<UITheme>
Brush _SubtitlesFontColor;

public TextBlock Subtitles { get; set; }
public int UniqueId { get; set; }

public string SelectedThemeStr
{
Expand Down Expand Up @@ -92,7 +93,7 @@ public UITheme SelectedTheme
theme.SetSecondaryColor(value.SecondaryColor);
theme.Paper = value.PaperColor;
Resources.SetTheme(theme);
settings.Resources.SetTheme(theme);
settings?.Resources.SetTheme(theme);

if (Config != null && Config.Video != null)
Config.Video.BackgroundColor = value.VideoView;
Expand Down Expand Up @@ -166,8 +167,25 @@ internal Settings
static Flyleaf()
{
Master.UIRefresh = true; // Allow UI Refresh for Activity Mode, Buffered Duration on Pause & Stats
}

Player.SwapCompleted += (o, e) =>
{
var flyleaf1 = (Flyleaf)e.Player1.Tag;
var flyleaf2 = (Flyleaf)e.Player2.Tag;
var saveMargin = flyleaf1.Subtitles.Margin;
var saveFontSize= flyleaf1.Subtitles.FontSize;
flyleaf1.Subtitles.Margin = flyleaf2.Subtitles.Margin;
flyleaf1.Subtitles.FontSize = flyleaf2.Subtitles.FontSize;
flyleaf2.Subtitles.Margin = saveMargin;
flyleaf2.Subtitles.FontSize = saveFontSize;
flyleaf1.Player = e.Player2;
flyleaf2.Player = e.Player1;
};
}
public Flyleaf()
{
InitializeComponent();
Expand Down Expand Up @@ -286,8 +304,6 @@ private void Initialize()
SubtitlesFontColor = Subtitles.Foreground;
}

settings = new Settings(this);

ITheme theme = Resources.GetTheme();
defaultTheme = new UITheme(this, defaultTheme) { Name = "Default", PrimaryColor = theme.PrimaryMid.Color, SecondaryColor = theme.SecondaryMid.Color, PaperColor = theme.Paper, VideoView = Config != null && Config.Video != null ? Config.Video.BackgroundColor : Colors.Black};

Expand All @@ -310,39 +326,22 @@ private void Initialize()
SelectedTheme = UIThemes[3];

Raise(null);
settings.Raise(null);
settings?.Raise(null);
}
private void InitializePlayer(Player oldPlayer = null)
{
// Updates the key binding actions with the new instances in case of swap or initial load
bool SubsYUp = false, SubsYDown = false, SubsFontIncrease = false, SubsFontDecrease = false;
Action aSubsYUp = () => { Thickness t = Subtitles.Margin; t.Bottom += 2; Subtitles.Margin = t; Raise(nameof(Subtitles)); };
Action aSubsYDown = () => { Thickness t = Subtitles.Margin; t.Bottom -= 2; Subtitles.Margin = t; Raise(nameof(Subtitles)); };
Action aSubsFontIncrease = () => { Subtitles.FontSize += 2; };
Action aSubsFontDecrease = () => { Subtitles.FontSize -= 2; };

Config.Player.ActivityMode = true; // To allow Idle mode on flyleafBar
Config.Player.KeyBindings.FlyleafWindow = true; // To allow keybindings also on front window
Player.SubscribeEvents();

// Ensure Player Events will re-subscribed / No need to re-subscribe on VideoView/Control as it will be the same (Possible also Raise(null); / settings?.Raise(null);)
if (oldPlayer != null)
return;

Unloaded += (o, e) => { Dispose(); };
Player.Control.MouseClick += (o, e) => { if (e.Button == System.Windows.Forms.MouseButtons.Right & popUpMenu != null) popUpMenu.IsOpen = true; };
MouseDown += (o, e) => { Player?.Activity.ForceFullActive(); };
MouseMove += (o, e) => { Player?.Activity.ForceFullActive(); };

if (defaultTheme != null)
defaultTheme.VideoView = Config.Video.BackgroundColor;

if (SelectedTheme != null)
Config.Video.BackgroundColor = SelectedTheme.VideoView;

// Additional Key Bindings for Subtitles
if (Config.Player.KeyBindings.Enabled)
{
bool SubsYUp = false, SubsYDown = false, SubsFontIncrease = false, SubsFontDecrease = false;

Action aSubsYUp = () => { Thickness t = Subtitles.Margin; t.Bottom += 2; Subtitles.Margin = t; Raise(nameof(Subtitles)); };
Action aSubsYDown = () => { Thickness t = Subtitles.Margin; t.Bottom -= 2; Subtitles.Margin = t; Raise(nameof(Subtitles)); };
Action aSubsFontIncrease = () => { Subtitles.FontSize += 2; };
Action aSubsFontDecrease = () => { Subtitles.FontSize -= 2; };

// Update Actions if loaded from Config file (TBR: possible also on swap?)
foreach (var binding in Config.Player.KeyBindings.Keys)
{
Expand Down Expand Up @@ -372,23 +371,42 @@ private void InitializePlayer(Player oldPlayer = null)
break;
}
}

// Add Actions if not already loaded
if (!Config.Loaded)
{
if (!SubsYUp)
Config.Player.KeyBindings.AddCustom(Key.Up, false, aSubsYUp, "SubsYUp", true);
if (!SubsYDown)
Config.Player.KeyBindings.AddCustom(Key.Down, false, aSubsYDown, "SubsYDown", true);
if (!SubsFontIncrease)
Config.Player.KeyBindings.AddCustom(Key.Right, false, aSubsFontIncrease, "SubsFontIncrease", true);
if (!SubsFontDecrease)
Config.Player.KeyBindings.AddCustom(Key.Left, false, aSubsFontDecrease, "SubsFontDecrease", true);
}

}

Timeline.DesiredFrameRateProperty.OverrideMetadata(typeof(Timeline), new FrameworkPropertyMetadata { DefaultValue = (int) Config.Player.IdleFps });
Player.Tag = this;

if (oldPlayer != null)
{
Log($"Assigning {Player.PlayerId} | {(oldPlayer != null ? $"Old {oldPlayer.PlayerId}" : "")}");
return;
}

UniqueId = Player.PlayerId;
Log($"Assigning {Player.PlayerId} | {(oldPlayer != null ? $"Old {oldPlayer.PlayerId}" : "")}");

Unloaded += (o, e) => { Dispose(); };
Player.Control.MouseClick += (o, e) => { if (e.Button == System.Windows.Forms.MouseButtons.Right & popUpMenu != null) popUpMenu.IsOpen = true; };
MouseDown += (o, e) => { Player?.Activity.ForceFullActive(); };
MouseMove += (o, e) => { Player?.Activity.ForceFullActive(); };

if (defaultTheme != null)
defaultTheme.VideoView = Config.Video.BackgroundColor;

if (SelectedTheme != null)
Config.Video.BackgroundColor = SelectedTheme.VideoView;

// Additional Key Bindings for Subtitles
if (Config.Player.KeyBindings.Enabled && !Config.Loaded)
{
if (!SubsYUp)
Config.Player.KeyBindings.AddCustom(Key.Up, false, aSubsYUp, "SubsYUp", true);
if (!SubsYDown)
Config.Player.KeyBindings.AddCustom(Key.Down, false, aSubsYDown, "SubsYDown", true);
if (!SubsFontIncrease)
Config.Player.KeyBindings.AddCustom(Key.Right, false, aSubsFontIncrease, "SubsFontIncrease", true);
if (!SubsFontDecrease)
Config.Player.KeyBindings.AddCustom(Key.Left, false, aSubsFontDecrease, "SubsFontDecrease", true);
}

Raise(null);
settings?.Raise(null);
Expand All @@ -409,7 +427,7 @@ public void Dispose()

//VideoView?.WindowFront?.Close();
Player?.Dispose();
settings.Dispose();
settings?.Dispose();
settings = null;

popUpMenu?.Resources?.MergedDictionaries.Clear();
Expand Down Expand Up @@ -460,14 +478,18 @@ void RegisterCommands()
public ICommand OpenSettings { get; set; }
public async void OpenSettingsAction(object obj = null)
{
if (Config == null || dialogSettingsIdentifier == null) return;
if (Config == null || dialogSettingsIdentifier == null)
return;

if (DialogHost.IsDialogOpen(dialogSettingsIdentifier))
{
DialogHost.Close(dialogSettingsIdentifier, "cancel");
return;
}

if (settings == null)
settings = new Settings(this);

Config.Player.ActivityMode = false;
Config.Player.KeyBindings.Enabled = false;

Expand Down Expand Up @@ -617,5 +639,7 @@ protected void Set<T>(ref T field, T value, bool check = true, [CallerMemberName
}
}
#endregion

private void Log(string msg) { Debug.WriteLine($"[{DateTime.Now.ToString("hh.mm.ss.fff")}] [#{UniqueId}] [Player] {msg}"); }
}
}
9 changes: 6 additions & 3 deletions FlyleafLib.Controls.WPF/FlyleafLib.Controls.WPF.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,20 @@
<TargetFrameworks>net6.0-windows;net5.0-windows;net472</TargetFrameworks>
<UseWindowsForms>true</UseWindowsForms>
<UseWPF>true</UseWPF>
<Version>1.1.17</Version>
<Version>1.1.18</Version>
<Authors>SuRGeoNix</Authors>
<Copyright>SuRGeoNix © 2021</Copyright>
<Copyright>SuRGeoNix © 2022</Copyright>
<PackageLicenseExpression>LGPL-3.0-or-later</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/SuRGeoNix/Flyleaf</PackageProjectUrl>
<PackageIcon>Flyleaf.png</PackageIcon>
<PackageIconUrl />
<PackageTags>flyleaf flyleaflib video audio media player element control</PackageTags>
<Description>WPF Media Player Control/Element (based on FlyleafLib)</Description>
<PackageReleaseNotes>
Updates FlyleafLib to v3.4.3
* Adds PlayerDebug with all Player's properties
* Adds ZeroCopy to Video Settings
* Removes GPU Usage
* Updates FlyleafLib and MaterialDesign
</PackageReleaseNotes>
</PropertyGroup>

Expand Down
13 changes: 10 additions & 3 deletions FlyleafLib.Controls.WPF/Settings.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,18 @@
<EventSetter Event="PreviewTextInput" Handler="ValidationNumeric"/>
</Style>

<ObjectDataProvider x:Key="dataFromEnum" MethodName="GetValues" ObjectType="{x:Type sys:Enum}">
<ObjectDataProvider x:Key="HDRtoSDRMethodEnum" MethodName="GetValues" ObjectType="{x:Type sys:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="fl:HDRtoSDRMethod"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>

<ObjectDataProvider x:Key="ZeroCopyEnum" MethodName="GetValues" ObjectType="{x:Type sys:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="fl:ZeroCopy"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>

</ResourceDictionary>
</UserControl.Resources>

Expand Down Expand Up @@ -303,13 +310,13 @@
<ToggleButton Grid.Row="3" Grid.Column="1" Tag="_save" IsChecked="{Binding Config.Video.VideoAcceleration, UpdateSourceTrigger=Explicit}" HorizontalAlignment="Left" Style="{StaticResource MaterialDesignSwitchDarkToggleButton}"/>

<TextBlock Grid.Row="4" Text="Zero Copy" VerticalAlignment="Center"/>
<ToggleButton Grid.Row="4" Grid.Column="1" Tag="_save" IsChecked="{Binding Config.Decoder.ZeroCopy, UpdateSourceTrigger=Explicit}" HorizontalAlignment="Left" Style="{StaticResource MaterialDesignSwitchDarkToggleButton}"/>
<ComboBox Grid.Row="4" Grid.Column="1" ItemsSource="{Binding Source={StaticResource ZeroCopyEnum}}" SelectedItem="{Binding Config.Decoder.ZeroCopy}"/>

<TextBlock Grid.Row="5" Text="Decoder Threads" VerticalAlignment="Center"/>
<TextBox Grid.Row="5" Grid.Column="1" Style="{StaticResource FLTextboxNP}" Text="{Binding Config.Decoder.VideoThreads, UpdateSourceTrigger=Explicit}"/>

<TextBlock Grid.Row="6" Text="HDR to SDR Method" VerticalAlignment="Center"/>
<ComboBox Grid.Row="6" x:Name="cmbHDRtoSDRMethod" Grid.Column="1" ItemsSource="{Binding Source={StaticResource dataFromEnum}}" SelectedItem="{Binding Config.Video.HDRtoSDRMethod}"/>
<ComboBox Grid.Row="6" Grid.Column="1" ItemsSource="{Binding Source={StaticResource HDRtoSDRMethodEnum}}" SelectedItem="{Binding Config.Video.HDRtoSDRMethod}"/>

<TextBlock Grid.Row="7" Text="HDR to SDR Tone" VerticalAlignment="Center"/>
<TextBox Grid.Row="7" Grid.Column="1" Style="{StaticResource FLTextbox}" Text="{Binding Config.Video.HDRtoSDRTone, UpdateSourceTrigger=LostFocus}"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
</ItemGroup>

<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="if &quot;$(OutDir)&quot; == &quot;bin\Debug\net5.0-windows\&quot; (&#xD;&#xA; set plugindir=Plugins.NET5&#xD;&#xA;) else if &quot;$(OutDir)&quot; == &quot;bin\Release\net5.0-windows\&quot; (&#xD;&#xA; set plugindir=Plugins.NET5&#xD;&#xA;) else if &quot;$(OutDir)&quot; == &quot;bin\Debug\net6.0-windows\&quot; (&#xD;&#xA; set plugindir=Plugins.NET6&#xD;&#xA;) else if &quot;$(OutDir)&quot; == &quot;bin\Release\net6.0-windows\&quot; (&#xD;&#xA; set plugindir=Plugins.NET6&#xD;&#xA;) else if &quot;$(OutDir)&quot; == &quot;bin\Release\net472\&quot; (&#xD;&#xA; set plugindir=Plugins.NET4&#xD;&#xA;) else if &quot;$(OutDir)&quot; == &quot;bin\Debug\net472\&quot; (&#xD;&#xA; set plugindir=Plugins.NET4&#xD;&#xA;)&#xD;&#xA;&#xD;&#xA;set pluginname=BitSwarm&#xD;&#xA;&#xD;&#xA;if not exist &quot;$(SolutionDir)%25plugindir%25\%25pluginname%25&quot; mkdir &quot;$(SolutionDir)%25plugindir%25\%25pluginname%25&quot;&#xD;&#xA;if not exist &quot;$(SolutionDir)%25plugindir%25\SharedLibs&quot; mkdir &quot;$(SolutionDir)%25plugindir%25\SharedLibs&quot;&#xD;&#xA;&#xD;&#xA;move &quot;$(TargetDir)System*.dll&quot; &quot;$(SolutionDir)%25plugindir%25\SharedLibs\&quot;&#xD;&#xA;move &quot;$(TargetDir)*.dll&quot; &quot;$(SolutionDir)%25plugindir%25\%25pluginname%25\&quot;" />
<Exec Command="if &quot;$(OutDir)&quot; == &quot;bin\Debug\net5.0-windows\&quot; (&#xD;&#xA; set plugindir=Plugins.NET5&#xD;&#xA;) else if &quot;$(OutDir)&quot; == &quot;bin\Release\net5.0-windows\&quot; (&#xD;&#xA; set plugindir=Plugins.NET5&#xD;&#xA;) else if &quot;$(OutDir)&quot; == &quot;bin\Debug\net6.0-windows\&quot; (&#xD;&#xA; set plugindir=Plugins&#xD;&#xA;) else if &quot;$(OutDir)&quot; == &quot;bin\Release\net6.0-windows\&quot; (&#xD;&#xA; set plugindir=Plugins&#xD;&#xA;) else if &quot;$(OutDir)&quot; == &quot;bin\Release\net472\&quot; (&#xD;&#xA; set plugindir=Plugins.NET4&#xD;&#xA;) else if &quot;$(OutDir)&quot; == &quot;bin\Debug\net472\&quot; (&#xD;&#xA; set plugindir=Plugins.NET4&#xD;&#xA;)&#xD;&#xA;&#xD;&#xA;set pluginname=BitSwarm&#xD;&#xA;&#xD;&#xA;if not exist &quot;$(SolutionDir)%25plugindir%25\%25pluginname%25&quot; mkdir &quot;$(SolutionDir)%25plugindir%25\%25pluginname%25&quot;&#xD;&#xA;if not exist &quot;$(SolutionDir)%25plugindir%25\SharedLibs&quot; mkdir &quot;$(SolutionDir)%25plugindir%25\SharedLibs&quot;&#xD;&#xA;&#xD;&#xA;move &quot;$(TargetDir)System*.dll&quot; &quot;$(SolutionDir)%25plugindir%25\SharedLibs\&quot;&#xD;&#xA;move &quot;$(TargetDir)*.dll&quot; &quot;$(SolutionDir)%25plugindir%25\%25pluginname%25\&quot;" />
</Target>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
</ItemGroup>

<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="if &quot;$(OutDir)&quot; == &quot;bin\Debug\net5.0-windows\&quot; (&#xD;&#xA; set plugindir=Plugins.NET5&#xD;&#xA;) else if &quot;$(OutDir)&quot; == &quot;bin\Release\net5.0-windows\&quot; (&#xD;&#xA; set plugindir=Plugins.NET5&#xD;&#xA;) else if &quot;$(OutDir)&quot; == &quot;bin\Debug\net6.0-windows\&quot; (&#xD;&#xA; set plugindir=Plugins.NET6&#xD;&#xA;) else if &quot;$(OutDir)&quot; == &quot;bin\Release\net6.0-windows\&quot; (&#xD;&#xA; set plugindir=Plugins.NET6&#xD;&#xA;) else if &quot;$(OutDir)&quot; == &quot;bin\Release\net472\&quot; (&#xD;&#xA; set plugindir=Plugins.NET4&#xD;&#xA;) else if &quot;$(OutDir)&quot; == &quot;bin\Debug\net472\&quot; (&#xD;&#xA; set plugindir=Plugins.NET4&#xD;&#xA;)&#xD;&#xA;&#xD;&#xA;set pluginname=OpenSubtitlesOrg&#xD;&#xA;&#xD;&#xA;if not exist &quot;$(SolutionDir)%25plugindir%25\%25pluginname%25&quot; mkdir &quot;$(SolutionDir)%25plugindir%25\%25pluginname%25&quot;&#xD;&#xA;if not exist &quot;$(SolutionDir)%25plugindir%25\SharedLibs&quot; mkdir &quot;$(SolutionDir)%25plugindir%25\SharedLibs&quot;&#xD;&#xA;&#xD;&#xA;move &quot;$(TargetDir)Newtonsoft.Json.dll&quot; &quot;$(SolutionDir)%25plugindir%25\SharedLibs\&quot;&#xD;&#xA;move &quot;$(TargetDir)*.dll&quot; &quot;$(SolutionDir)%25plugindir%25\%25pluginname%25\&quot;" />
<Exec Command="if &quot;$(OutDir)&quot; == &quot;bin\Debug\net5.0-windows\&quot; (&#xD;&#xA; set plugindir=Plugins.NET5&#xD;&#xA;) else if &quot;$(OutDir)&quot; == &quot;bin\Release\net5.0-windows\&quot; (&#xD;&#xA; set plugindir=Plugins.NET5&#xD;&#xA;) else if &quot;$(OutDir)&quot; == &quot;bin\Debug\net6.0-windows\&quot; (&#xD;&#xA; set plugindir=Plugins&#xD;&#xA;) else if &quot;$(OutDir)&quot; == &quot;bin\Release\net6.0-windows\&quot; (&#xD;&#xA; set plugindir=Plugins&#xD;&#xA;) else if &quot;$(OutDir)&quot; == &quot;bin\Release\net472\&quot; (&#xD;&#xA; set plugindir=Plugins.NET4&#xD;&#xA;) else if &quot;$(OutDir)&quot; == &quot;bin\Debug\net472\&quot; (&#xD;&#xA; set plugindir=Plugins.NET4&#xD;&#xA;)&#xD;&#xA;&#xD;&#xA;set pluginname=OpenSubtitlesOrg&#xD;&#xA;&#xD;&#xA;if not exist &quot;$(SolutionDir)%25plugindir%25\%25pluginname%25&quot; mkdir &quot;$(SolutionDir)%25plugindir%25\%25pluginname%25&quot;&#xD;&#xA;if not exist &quot;$(SolutionDir)%25plugindir%25\SharedLibs&quot; mkdir &quot;$(SolutionDir)%25plugindir%25\SharedLibs&quot;&#xD;&#xA;&#xD;&#xA;move &quot;$(TargetDir)Newtonsoft.Json.dll&quot; &quot;$(SolutionDir)%25plugindir%25\SharedLibs\&quot;&#xD;&#xA;move &quot;$(TargetDir)*.dll&quot; &quot;$(SolutionDir)%25plugindir%25\%25pluginname%25\&quot;" />
</Target>

</Project>
Loading

0 comments on commit 14e27c3

Please sign in to comment.