Skip to content

Commit

Permalink
Add support for LRR_THUMB_OVERRIDE
Browse files Browse the repository at this point in the history
  • Loading branch information
Difegue committed Mar 10, 2021
1 parent 96e10cb commit de36505
Show file tree
Hide file tree
Showing 6 changed files with 202 additions and 106 deletions.
3 changes: 3 additions & 0 deletions Karen/App.config
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
<setting name="UseWSL2" serializeAs="String">
<value>False</value>
</setting>
<setting name="ThumbnailFolder" serializeAs="String">
<value />
</setting>
</Karen.Properties.Settings>
</userSettings>
</configuration>
227 changes: 140 additions & 87 deletions Karen/Interop/WslDistro.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,116 @@ public WslDistro()
Version = GetVersion();
}

public void ShowConsole()
{
ShowWindow(GetConsoleWindow(), SW_SHOW);
ShowWindow(GetConsoleWindow(), SW_RESTORE);
}

public void HideConsole()
{
ShowWindow(GetConsoleWindow(), SW_HIDE);
}

private string GetWSLPath(string winPath)
{
string wslPath = "/mnt/" + Char.ToLowerInvariant(winPath[0]);
return wslPath + winPath.Substring(1).Replace(":", "").Replace("\\", "/");
}

public bool? StartApp()
{
if (!Directory.Exists(Properties.Settings.Default.ContentFolder))
{
Version = "Content Folder doesn't exist!";
return false;
} else
Version = GetVersion(); //Show the version anew if the content folder is now set

Status = AppStatus.Starting;

// Spawn a new console
AllocConsole();

// Hide it
HideConsole();
HideConsoleOnClose.Enable();

// Get its handles
var stdIn = GetStdHandle(STD_INPUT_HANDLE);
var stdOut = GetStdHandle(STD_OUTPUT_HANDLE);
var stdError = GetStdHandle(STD_ERROR_HANDLE);

// Switch the distro to the specified WSL version
// (Does nothing if we're already using the proper one)
_ = Properties.Settings.Default.UseWSL2 ? SetWSLVersion(2) : SetWSLVersion(1);

// Map the user's content folder to its WSL equivalent
// This means lowercasing the drive letter, removing the : and replacing every \ by a /.
string winPath = Properties.Settings.Default.ContentFolder;
string thumbPath = Properties.Settings.Default.ThumbnailFolder;

MountIfNetworkDrive(winPath);
MountIfNetworkDrive(thumbPath);

string contentFolder = GetWSLPath(winPath);
string thumbnailFolder = string.IsNullOrWhiteSpace(thumbPath) ? contentFolder + "/thumb" : GetWSLPath(thumbPath);

// The big bazooper. Export port, folders and start both redis and the server.
string command = "export LRR_NETWORK=http://*:"+ Properties.Settings.Default.NetworkPort + " " +
"&& export LRR_DATA_DIRECTORY='"+contentFolder+"' " +
"&& export LRR_THUMB_DIRECTORY='"+thumbnailFolder+"' " +
(Properties.Settings.Default.ForceDebugMode ? "&& export LRR_FORCE_DEBUG=1 " : "") +
"&& cd /home/koyomi/lanraragi && rm -f script/hypnotoad.pid " +
"&& mkdir -p log && mkdir -p content && mkdir -p database && sysctl vm.overcommit_memory=1 " +
"&& redis-server /home/koyomi/lanraragi/tools/build/docker/redis.conf --dir '"+contentFolder+"'/ --daemonize yes " +
"&& perl ./script/launcher.pl -f ./script/lanraragi";

Console.WriteLine("Executing the following command on WSL: " + command);

// Start process in WSL and hook up handles
// This will direct WSL output to the new console window, or to Visual Studio if running with the debugger attached.
// See https://stackoverflow.com/questions/15604014/no-console-output-when-using-allocconsole-and-target-architecture-x86
WslApi.WslLaunch(Properties.Resources.DISTRO_NAME, command, false, stdIn,stdOut,stdError, out _lrrHandle);

// Get Process ID of the returned procHandle
int lrrId = GetProcessId(_lrrHandle);
_lrrProc = Process.GetProcessById(lrrId);

// Check that the returned process is still alive
if (_lrrProc != null && !_lrrProc.HasExited)
Status = AppStatus.Started;

return !_lrrProc?.HasExited;
}

public bool? StopApp()
{
// Kill WSL Process
if (_lrrProc != null && !_lrrProc.HasExited)
{
_lrrProc.Kill();

// Ensure child unix processes are killed as well by killing the distro. This is only possible on 1809 and up.
new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "wslconfig.exe",
Arguments = "/terminate " + Properties.Resources.DISTRO_NAME,
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true,
}
}.Start();
}

// No need to remove the attached console here in case the app is restarted later down
Status = AppStatus.Stopped;
return _lrrProc?.HasExited;
}

#region Various ProcessStartInfo calls to WSL
private bool CheckDistro()
{
//return WslApi.WslIsDistributionRegistered(DISTRO_NAME);
Expand All @@ -61,7 +171,7 @@ private bool CheckDistro()
while (!proc.StandardOutput.EndOfStream)
{
string line = proc.StandardOutput.ReadLine();
if (line.Replace("\0","").Contains(Properties.Resources.DISTRO_NAME))
if (line.Replace("\0", "").Contains(Properties.Resources.DISTRO_NAME))
{
return true;
}
Expand Down Expand Up @@ -144,109 +254,52 @@ private string GetVersion()
// Distro exists but the one-liner returns nothing
Status = AppStatus.NotInstalled;
return "WSL Distro doesn't function properly. Consider updating Windows 10.";

}

public void ShowConsole()
{
ShowWindow(GetConsoleWindow(), SW_SHOW);
ShowWindow(GetConsoleWindow(), SW_RESTORE);
}

public void HideConsole()
{
ShowWindow(GetConsoleWindow(), SW_HIDE);
}

public bool? StartApp()
/// <summary>
/// Check if the drive letter of the given path is a network drive, and create the mountpoint in WSL if it is.
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
private void MountIfNetworkDrive(string path)
{
if (!Directory.Exists(Properties.Settings.Default.ContentFolder))
{
Version = "Content Folder doesn't exist!";
return false;
} else
Version = GetVersion(); //Show the version anew if the content folder is now set

Status = AppStatus.Starting;

// Spawn a new console
AllocConsole();

// Hide it
HideConsole();
HideConsoleOnClose.Enable();

// Get its handles
var stdIn = GetStdHandle(STD_INPUT_HANDLE);
var stdOut = GetStdHandle(STD_OUTPUT_HANDLE);
var stdError = GetStdHandle(STD_ERROR_HANDLE);

// Switch the distro to the specified WSL version
// (Does nothing if we're already using the proper one)
_ = Properties.Settings.Default.UseWSL2 ? SetWSLVersion(2) : SetWSLVersion(1);

// Map the user's content folder to its WSL equivalent
// This means lowercasing the drive letter, removing the : and replacing every \ by a /.
string winPath = Properties.Settings.Default.ContentFolder;
string wslPath = "/mnt/" + Char.ToLowerInvariant(winPath[0]);
string contentFolder = wslPath + winPath.Substring(1).Replace(":", "").Replace("\\", "/");
if (string.IsNullOrWhiteSpace(path))
return;

// Check if the drive letter is a network drive, and create the mountpoint in WSL if it is.
string driveLetter = winPath.Split('\\')[0];
var driveLetter = path.Split('\\')[0];
var wslMountPoint = "/mnt/" + driveLetter.ToLowerInvariant();

// The big bazooper. Export port and content folder and start supervisord.
string command = (!IsLocalDrive(driveLetter) ? $"mkdir -p {wslPath} && mount -t drvfs {driveLetter} {wslPath} && " : "") +
"export LRR_NETWORK=http://*:"+ Properties.Settings.Default.NetworkPort + " " +
"&& export LRR_DATA_DIRECTORY='"+contentFolder+"' " +
(Properties.Settings.Default.ForceDebugMode ? "&& export LRR_FORCE_DEBUG=1 " : "") +
"&& cd /home/koyomi/lanraragi && rm -f script/hypnotoad.pid " +
"&& mkdir -p log && mkdir -p content && mkdir -p database && sysctl vm.overcommit_memory=1 " +
"&& redis-server /home/koyomi/lanraragi/tools/build/docker/redis.conf --dir '"+contentFolder+"'/ --daemonize yes " +
"&& perl ./script/launcher.pl -f ./script/lanraragi";

Console.WriteLine("Executing the following command on WSL: " + command);

// Start process in WSL and hook up handles
// This will direct WSL output to the new console window, or to Visual Studio if running with the debugger attached.
// See https://stackoverflow.com/questions/15604014/no-console-output-when-using-allocconsole-and-target-architecture-x86
WslApi.WslLaunch(Properties.Resources.DISTRO_NAME, command, false, stdIn,stdOut,stdError, out _lrrHandle);

// Get Process ID of the returned procHandle
int lrrId = GetProcessId(_lrrHandle);
_lrrProc = Process.GetProcessById(lrrId);

// Check that the returned process is still alive
if (_lrrProc != null && !_lrrProc.HasExited)
Status = AppStatus.Started;

return !_lrrProc?.HasExited;
}

public bool? StopApp()
{
// Kill WSL Process
if (_lrrProc != null && !_lrrProc.HasExited)
if (!IsLocalDrive(driveLetter))
{
_lrrProc.Kill();
var oneLiner = $"mkdir -p {wslMountPoint} && mount -t drvfs {driveLetter} {wslMountPoint}";

// Ensure child unix processes are killed as well by killing the distro. This is only possible on 1809 and up.
new Process
var proc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "wslconfig.exe",
Arguments = "/terminate " + Properties.Resources.DISTRO_NAME,
FileName = Environment.SystemDirectory + "\\wsl.exe",
Arguments = $"-d {Properties.Resources.DISTRO_NAME} --exec {oneLiner}",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true,
}
}.Start();
};
try
{
proc.Start();
while (!proc.StandardOutput.EndOfStream)
{
Console.WriteLine(proc.StandardOutput.ReadLine());
}
}
catch (Exception e)
{
Console.WriteLine($"Error while mounting Network Drive in WSL: {e}");
}
}

// No need to remove the attached console here in case the app is restarted later down
Status = AppStatus.Stopped;
return _lrrProc?.HasExited;
}
#endregion

#region Your friendly neighborhood P/Invokes for console host wizardry

Expand Down
50 changes: 32 additions & 18 deletions Karen/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,28 @@
ui:WindowHelper.UseModernWindowStyle="True"
x:Class="Karen.MainWindow"
xmlns:p="clr-namespace:Karen.Properties"
Title="LANraragi Windows Settings" MinHeight="600" MinWidth="350" Width="350"
ResizeMode="CanResizeWithGrip"
Title="LANraragi Windows Settings"
MinWidth="500" MinHeight="480"
Width="500" Height="680"
Closing="OnClosing">
<DockPanel LastChildFill="False" Margin="10">
<ui:SimpleStackPanel VerticalAlignment="Top" DockPanel.Dock="Top" >
<ScrollViewer Margin="0,0,0,16">
<ui:SimpleStackPanel VerticalAlignment="Top" Margin="16">
<emoji:TextBlock Style="{StaticResource BaseTextBlockStyle}" Text="🗃 Content Folder Location" Margin="0,0,0,5"/>
<TextBlock Style="{StaticResource CaptionTextBlockStyle}">Where LANraragi looks for archives on your machine.</TextBlock>
<StackPanel Orientation="Horizontal">
<TextBox Width="245" Padding="6,6,6,0" Margin="0,0,10,0" IsReadOnly="True" Text="{Binding Source={x:Static p:Settings.Default}, Path=ContentFolder, Mode=TwoWay}"/>
<TextBox Width="370" Padding="6,6,6,0" Margin="0,0,10,0" IsReadOnly="True" Text="{Binding Source={x:Static p:Settings.Default}, Path=ContentFolder, Mode=TwoWay}"/>
<Button Height="30" Content="Browse" Click="PickFolder" Width="65" Style="{StaticResource AccentButtonStyle}"/>
</StackPanel>
<emoji:TextBlock Style="{StaticResource BaseTextBlockStyle}" Text="🖼 Thumbnail Folder Location" Margin="0,12,0,5"/>
<TextBlock Style="{StaticResource CaptionTextBlockStyle}">
Where LANraragi stores thumbnails for your content. <LineBreak/>
Defaults to a subfolder in the content folder if not set.
</TextBlock>
<StackPanel Orientation="Horizontal">
<TextBox Width="370" Padding="6,6,6,0" Margin="0,0,10,0" IsReadOnly="True" Text="{Binding Source={x:Static p:Settings.Default}, Path=ThumbnailFolder, Mode=TwoWay}"/>
<Button Height="30" Content="Browse" Click="PickThumbFolder" Width="65" Style="{StaticResource AccentButtonStyle}"/>
</StackPanel>
<emoji:TextBlock Style="{StaticResource BaseTextBlockStyle}" Text="🌐 Network Port" Margin="0,12,0,5"/>
<TextBlock Style="{StaticResource CaptionTextBlockStyle}">Port of your machine the server will run on.</TextBlock>
<ui:NumberBox HorizontalAlignment="Left" Width="245" SpinButtonPlacementMode="Compact" Maximum="65535" Minimum="0" Padding="0,6,0,0" Margin="0,0,10,0" Text="{Binding Source={x:Static p:Settings.Default}, Path=NetworkPort, Mode=TwoWay}" PreviewTextInput="NumberValidationTextBox"/>
Expand All @@ -33,25 +45,27 @@

<Separator Height="11.5" Margin="0"/>
<TextBlock Style="{StaticResource BodyTextBlockStyle}">
You're using the <Hyperlink NavigateUri="https://github.com/Difegue/Karen" RequestNavigate="Hyperlink_RequestNavigate">Karen</Hyperlink> Bootstrapper,
<LineBreak/> Version 1.9. <emoji:TextBlock Text="🐝"/>
You're using the <Hyperlink NavigateUri="https://github.com/Difegue/Karen" RequestNavigate="Hyperlink_RequestNavigate">Karen</Hyperlink> Bootstrapper for <Hyperlink NavigateUri="https://github.com/Difegue/LANraragi" RequestNavigate="Hyperlink_RequestNavigate">LANraragi</Hyperlink>,
<LineBreak/> Version 2.0 <emoji:TextBlock Text="🐝"/>
<LineBreak/>
<Hyperlink NavigateUri="https://github.com/Difegue/LANraragi" RequestNavigate="Hyperlink_RequestNavigate">https://github.com/Difegue/LANraragi</Hyperlink>
<emoji:TextBlock Text=""/> Consider installing <Hyperlink NavigateUri="ms-windows-store://pdp/?ProductId=9MZ6BWWVSWJH" RequestNavigate="Hyperlink_RequestNavigate">LRReader</Hyperlink> from the Microsoft Store! <emoji:TextBlock Text=""/>
<LineBreak/>
</TextBlock>

<Expander Header="License">
<TextBlock DockPanel.Dock="Bottom" TextWrapping="Wrap">
<Run FontSize="10">
Copyright 2020-2021 Difegue</Run>
<LineBreak/>
<Run FontSize="9">
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
</Run>
<LineBreak/>
</TextBlock>
</Expander>

</ui:SimpleStackPanel>

<TextBlock DockPanel.Dock="Bottom" TextWrapping="Wrap">
<Run FontSize="10">
Copyright 2020 Difegue</Run>
<LineBreak/>
<Run FontSize="9">
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
</Run>
<LineBreak/>
</TextBlock>

</DockPanel>
</ScrollViewer>

</Window>
11 changes: 11 additions & 0 deletions Karen/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@ private void PickFolder(object sender, RoutedEventArgs e)
}
}

private void PickThumbFolder(object sender, RoutedEventArgs e)
{
FolderBrowserDialog dlg = new FolderBrowserDialog();
dlg.Description = "Select your LANraragi Thumbnail Folder.";

if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
Properties.Settings.Default.ThumbnailFolder = dlg.SelectedPath;
}
}

private void OnClosing(object sender, CancelEventArgs e)
{
// Set first launch to false
Expand Down
Loading

0 comments on commit de36505

Please sign in to comment.