mirror of
https://github.com/lidarr/lidarr.git
synced 2025-07-15 01:23:53 -07:00
pretty...
This commit is contained in:
parent
beaf0cf939
commit
afafc6b032
285 changed files with 32688 additions and 784 deletions
241
CassiniDev/CassiniDevServerOP.cs
Normal file
241
CassiniDev/CassiniDevServerOP.cs
Normal file
|
@ -0,0 +1,241 @@
|
|||
// /* **********************************************************************************
|
||||
// *
|
||||
// * Copyright (c) Sky Sanders. All rights reserved.
|
||||
// *
|
||||
// * This source code is subject to terms and conditions of the Microsoft Public
|
||||
// * License (Ms-PL). A copy of the license can be found in the license.htm file
|
||||
// * included in this distribution.
|
||||
// *
|
||||
// * You must not remove this notice, or any other, from this software.
|
||||
// *
|
||||
// * **********************************************************************************/
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
|
||||
namespace CassiniDev
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Made a go at spinning the server up from this process but after dealing with
|
||||
/// irratic behaviour regarding apartment state, platform concerns, unloaded app domains,
|
||||
/// and all the other issues that you can find that people struggle with I just decided
|
||||
/// to strictly format the console app's output and just spin up an external process.
|
||||
/// Seems robust so far.
|
||||
/// </summary>
|
||||
public class CassiniDevServerOP
|
||||
{
|
||||
//private bool _disposed;
|
||||
|
||||
private string _hostname;
|
||||
private StreamWriter _input;
|
||||
private IPAddress _ipAddress;
|
||||
private Thread _outputThread;
|
||||
private string _rootUrl;
|
||||
private Process _serverProcess;
|
||||
private const int TimeOut = 60000;
|
||||
private const int WaitForPort = 5000;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
{
|
||||
if (_serverProcess != null)
|
||||
{
|
||||
StopServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The root URL of the running web application
|
||||
/// </summary>
|
||||
public string RootUrl
|
||||
{
|
||||
get { return _rootUrl; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Combine the RootUrl of the running web application with the relative url specified.
|
||||
/// </summary>
|
||||
/// <param name="relativeUrl"></param>
|
||||
/// <returns></returns>
|
||||
public string NormalizeUrl(string relativeUrl)
|
||||
{
|
||||
return CassiniNetworkUtils.NormalizeUrl(RootUrl, relativeUrl);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Will start specified application as "localhost" on loopback and first available port in the range 8000-10000 with vpath "/"
|
||||
/// </summary>
|
||||
/// <param name="applicationPath">Physical path to application.</param>
|
||||
public void StartServer(string applicationPath)
|
||||
{
|
||||
StartServer(applicationPath, CassiniNetworkUtils.GetAvailablePort(8000, 10000, IPAddress.Loopback, true), "/", "localhost");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Will start specified application on loopback
|
||||
/// </summary>
|
||||
/// <param name="applicationPath">Physical path to application.</param>
|
||||
/// <param name="port">Port to listen on.</param>
|
||||
/// <param name="virtualPath">Optional. defaults to "/"</param>
|
||||
/// <param name="hostName">Optional. Is used to construct RootUrl. Defaults to "localhost"</param>
|
||||
public void StartServer(string applicationPath, int port, string virtualPath, string hostName)
|
||||
{
|
||||
// WebHost.Server will not run on any other IP
|
||||
IPAddress ipAddress = IPAddress.Loopback;
|
||||
|
||||
if (!CassiniNetworkUtils.IsPortAvailable(ipAddress, port))
|
||||
{
|
||||
throw new Exception(string.Format("Port {0} is in use.", port));
|
||||
}
|
||||
|
||||
applicationPath = Path.GetFullPath(applicationPath);
|
||||
|
||||
virtualPath = String.Format("/{0}/", (virtualPath ?? string.Empty).Trim('/')).Replace("//", "/");
|
||||
hostName = string.IsNullOrEmpty(hostName) ? "localhost" : hostName;
|
||||
|
||||
StartServer(applicationPath, ipAddress, port, virtualPath, hostName);
|
||||
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
/// <param name="applicationPath">Physical path to application.</param>
|
||||
/// <param name="ipAddress">IP to listen on.</param>
|
||||
/// <param name="port">Port to listen on.</param>
|
||||
/// <param name="virtualPath">Optional. default value '/'</param>
|
||||
/// <param name="hostName">Optional. Used to construct RootUrl. Defaults to 'localhost'</param>
|
||||
public virtual void StartServer(string applicationPath, IPAddress ipAddress, int port, string virtualPath, string hostName)
|
||||
{
|
||||
|
||||
_hostname = hostName;
|
||||
_ipAddress = ipAddress;
|
||||
|
||||
// massage and validate arguments
|
||||
if (string.IsNullOrEmpty(virtualPath))
|
||||
{
|
||||
virtualPath = "/";
|
||||
}
|
||||
if (!virtualPath.StartsWith("/"))
|
||||
{
|
||||
virtualPath = "/" + virtualPath;
|
||||
}
|
||||
if (_serverProcess != null)
|
||||
{
|
||||
throw new InvalidOperationException("Server is running");
|
||||
}
|
||||
|
||||
|
||||
string commandLine = (new CommandLineArguments
|
||||
{
|
||||
Port = port,
|
||||
ApplicationPath = string.Format("\"{0}\"", Path.GetFullPath(applicationPath).Trim('\"').TrimEnd('\\')),
|
||||
HostName = hostName,
|
||||
IPAddress = ipAddress.ToString(),
|
||||
VirtualPath = string.Format("\"{0}\"", virtualPath),
|
||||
TimeOut = TimeOut,
|
||||
WaitForPort = WaitForPort,
|
||||
IPMode = IPMode.Specific,
|
||||
PortMode = PortMode.Specific
|
||||
}).ToString();
|
||||
|
||||
|
||||
_serverProcess = new Process
|
||||
{
|
||||
StartInfo = new ProcessStartInfo
|
||||
{
|
||||
UseShellExecute = false,
|
||||
ErrorDialog = false,
|
||||
CreateNoWindow = true,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardInput = true,
|
||||
#if NET40 //TODO: find out the real flag
|
||||
FileName = "CassiniDev4-console.exe",
|
||||
#else
|
||||
FileName = "CassiniDev-console.exe",
|
||||
#endif
|
||||
|
||||
Arguments = commandLine,
|
||||
WorkingDirectory = Environment.CurrentDirectory
|
||||
}
|
||||
};
|
||||
|
||||
// we are going to monitor each line of the output until we get a start or error signal
|
||||
// and then just ignore the rest
|
||||
|
||||
string line = null;
|
||||
|
||||
_serverProcess.Start();
|
||||
|
||||
_outputThread = new Thread(() =>
|
||||
{
|
||||
string l = _serverProcess.StandardOutput.ReadLine();
|
||||
while (l != null)
|
||||
{
|
||||
if (l.StartsWith("started:") || l.StartsWith("error:"))
|
||||
{
|
||||
line = l;
|
||||
}
|
||||
l = _serverProcess.StandardOutput.ReadLine();
|
||||
}
|
||||
});
|
||||
_outputThread.Start();
|
||||
|
||||
// use StandardInput to send the newline to stop the server when required
|
||||
_input = _serverProcess.StandardInput;
|
||||
|
||||
// block until we get a signal
|
||||
while (line == null)
|
||||
{
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
|
||||
if (!line.StartsWith("started:"))
|
||||
{
|
||||
throw new Exception(string.Format("Could not start server: {0}", line));
|
||||
}
|
||||
|
||||
// line is the root url
|
||||
_rootUrl = line.Substring(line.IndexOf(':') + 1);
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>Stops the server, if running.</para>
|
||||
/// </summary>
|
||||
public virtual void StopServer()
|
||||
{
|
||||
StopServer(100);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Stops the server, if running.</para>
|
||||
/// </summary>
|
||||
protected virtual void StopServer(int delay)
|
||||
{
|
||||
Thread.Sleep(delay);
|
||||
if (_serverProcess != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
_input.WriteLine();
|
||||
_serverProcess.WaitForExit(10000);
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
_serverProcess.Dispose();
|
||||
_serverProcess = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue