diff --git a/IISExpress/AppServer/applicationhost.config b/IISExpress/AppServer/applicationhost.config
index 7dee0612b..39716f173 100644
--- a/IISExpress/AppServer/applicationhost.config
+++ b/IISExpress/AppServer/applicationhost.config
@@ -1,4 +1,4 @@
-
+
-
-
+
+
@@ -156,7 +156,7 @@
-
+
diff --git a/NzbDrone.Core.Test/Fixtures.cs b/NzbDrone.Core.Test/Fixtures.cs
index c72442d7c..0f35747e4 100644
--- a/NzbDrone.Core.Test/Fixtures.cs
+++ b/NzbDrone.Core.Test/Fixtures.cs
@@ -27,7 +27,7 @@ namespace NzbDrone.Core.Test
[SetUp]
public void Setup()
{
- CentralDispatch.ConfigureNlog();
+ Instrumentation.Setup();
}
}
}
\ No newline at end of file
diff --git a/NzbDrone.Core/CentralDispatch.cs b/NzbDrone.Core/CentralDispatch.cs
index a62ef5b12..c8412f920 100644
--- a/NzbDrone.Core/CentralDispatch.cs
+++ b/NzbDrone.Core/CentralDispatch.cs
@@ -29,7 +29,7 @@ namespace NzbDrone.Core
string connectionString = String.Format("Data Source={0};Version=3;", Path.Combine(AppPath, "nzbdrone.db"));
var provider = ProviderFactory.GetProvider(connectionString, "System.Data.SQLite");
- provider.Log = new SonicTrace();
+ provider.Log = new Instrumentation.NlogWriter();
provider.LogParams = true;
_kernel.Bind().To().InSingletonScope();
@@ -62,60 +62,14 @@ namespace NzbDrone.Core
{
get
{
-
if (_kernel == null)
{
BindKernel();
}
-
return _kernel;
}
}
- public static void ConfigureNlog()
- {
- // Step 1. Create configuration object
- var config = new LoggingConfiguration();
-
- string callSight = "${callsite:className=false:fileName=true:includeSourcePath=false:methodName=true}";
-
- // Step 2. Create targets and add them to the configuration
- var debuggerTarget = new DebuggerTarget
- {
- Layout = callSight + "- ${logger}: ${message}"
- };
-
-
- var consoleTarget = new ColoredConsoleTarget
- {
- Layout = callSight + ": ${message}"
- };
-
-
- var fileTarget = new FileTarget
- {
- FileName = "${basedir}/test.log",
- Layout = "${message}"
- };
-
- config.AddTarget("debugger", debuggerTarget);
- config.AddTarget("console", consoleTarget);
- //config.AddTarget("file", fileTarget);
-
- // Step 3. Set target properties
- // Step 4. Define rules
- //LoggingRule fileRule = new LoggingRule("*", LogLevel.Trace, fileTarget);
- LoggingRule debugRule = new LoggingRule("*", LogLevel.Trace, debuggerTarget);
- LoggingRule consoleRule = new LoggingRule("*", LogLevel.Trace, consoleTarget);
-
- //config.LoggingRules.Add(fileRule);
- config.LoggingRules.Add(debugRule);
- config.LoggingRules.Add(consoleRule);
-
- // Step 5. Activate the configuration
- LogManager.Configuration = config;
- }
-
private static void ForceMigration(IRepository repository)
{
repository.GetPaged(0, 1);
diff --git a/NzbDrone.Core/Instrumentation.cs b/NzbDrone.Core/Instrumentation.cs
new file mode 100644
index 000000000..47564b0ee
--- /dev/null
+++ b/NzbDrone.Core/Instrumentation.cs
@@ -0,0 +1,114 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Text;
+using Exceptioneer.WindowsFormsClient;
+using NLog;
+using NLog.Config;
+using NLog.Targets;
+
+namespace NzbDrone.Core
+{
+ public static class Instrumentation
+ {
+ public static void Setup()
+ {
+ // Step 1. Create configuration object
+ var config = new LoggingConfiguration();
+
+ const string callSight = "${callsite:className=false:fileName=false:includeSourcePath=false:methodName=true}";
+ string layout = string.Concat("[${logger}](", callSight, "): ${message}");
+ // Step 2. Create targets and add them to the configuration
+ var debuggerTarget = new DebuggerTarget
+ {
+ Layout = layout
+ };
+
+ var consoleTarget = new ColoredConsoleTarget
+ {
+ Layout = layout
+ };
+
+ var fileTarget = new FileTarget
+ {
+ FileName = "${basedir}/test.log",
+ Layout = layout
+ };
+
+ config.AddTarget("debugger", debuggerTarget);
+ config.AddTarget("console", consoleTarget);
+ //config.AddTarget("file", fileTarget);
+
+ // Step 3. Set target properties
+ // Step 4. Define rules
+ //LoggingRule fileRule = new LoggingRule("*", LogLevel.Trace, fileTarget);
+ var debugRule = new LoggingRule("*", LogLevel.Trace, debuggerTarget);
+ var consoleRule = new LoggingRule("*", LogLevel.Trace, consoleTarget);
+
+ //config.LoggingRules.Add(fileRule);
+ config.LoggingRules.Add(debugRule);
+ config.LoggingRules.Add(consoleRule);
+
+ // Step 5. Activate the configuration
+ LogManager.Configuration = config;
+ }
+
+ public static void LogEpicException(Exception e)
+ {
+ try
+ {
+ LogManager.GetLogger("EPICFAIL").FatalException("Unhandled Exception", e);
+ }
+ catch (Exception totalFailException)
+ {
+ Console.WriteLine("TOTAL FAIL:{0}", totalFailException);
+ Console.WriteLine(e.ToString());
+ }
+
+ PublishExceptoion(e);
+ }
+
+
+ private static bool PublishExceptoion(Exception e)
+ {
+ //Don't publish exceptions when debugging the app.
+ if (Debugger.IsAttached)
+ return false;
+
+ return new Client
+ {
+ ApiKey = "43BBF60A-EB2A-4C1C-B09E-422ADF637265",
+ ApplicationName = "NZBDrone",
+ CurrentException = e
+ }.Submit();
+ }
+
+ public class NlogWriter : TextWriter
+ {
+ private static readonly Logger Logger = LogManager.GetLogger("DB");
+
+
+ public override void Write(char[] buffer, int index, int count)
+ {
+ Write(new string(buffer, index, count));
+ }
+
+ public override void Write(string value)
+ {
+ DbAction(value);
+ }
+
+ private static void DbAction(string value)
+ {
+ Logger.Trace(value);
+ }
+
+ public override Encoding Encoding
+ {
+ get { return Encoding.Default; }
+ }
+ }
+ }
+
+
+}
diff --git a/NzbDrone.Core/Libraries/Exceptioneer.WindowsFormsClient.dll b/NzbDrone.Core/Libraries/Exceptioneer.WindowsFormsClient.dll
new file mode 100644
index 000000000..52635882f
Binary files /dev/null and b/NzbDrone.Core/Libraries/Exceptioneer.WindowsFormsClient.dll differ
diff --git a/NzbDrone.Core/Libraries/log4net.dll b/NzbDrone.Core/Libraries/log4net.dll
deleted file mode 100644
index ffc57e112..000000000
Binary files a/NzbDrone.Core/Libraries/log4net.dll and /dev/null differ
diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj
index f4505ffa4..8d1e439ae 100644
--- a/NzbDrone.Core/NzbDrone.Core.csproj
+++ b/NzbDrone.Core/NzbDrone.Core.csproj
@@ -125,6 +125,10 @@
False
Libraries\Castle.Core.dll
+
+ False
+ Libraries\Exceptioneer.WindowsFormsClient.dll
+
@@ -150,6 +154,7 @@
+
@@ -158,7 +163,6 @@
-
@@ -211,6 +215,7 @@
+
diff --git a/NzbDrone.Core/SonicTrace.cs b/NzbDrone.Core/SonicTrace.cs
deleted file mode 100644
index 74fdf78d0..000000000
--- a/NzbDrone.Core/SonicTrace.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- *Source:http://stackoverflow.com/questions/1520945/nlog-to-output-db-out
- *DamienG
- */
-
-using System;
-using System.IO;
-using System.Text;
-using NLog;
-
-namespace NzbDrone.Core
-{
- class SonicTrace : TextWriter
- {
- private static readonly Logger Logger = LogManager.GetLogger("DB");
-
-
- public override void Write(char[] buffer, int index, int count)
- {
- Write(new string(buffer, index, count));
- }
-
- public override void Write(string value)
- {
- DbAction(value);
- }
-
- private static void DbAction(string value)
- {
- Logger.Trace(value);
- }
-
- public override Encoding Encoding
- {
- get { return Encoding.Default; }
- }
- }
-
-}
\ No newline at end of file
diff --git a/NzbDrone.Web/Global.asax.cs b/NzbDrone.Web/Global.asax.cs
index 5f3cc374b..550b09dbc 100644
--- a/NzbDrone.Web/Global.asax.cs
+++ b/NzbDrone.Web/Global.asax.cs
@@ -1,10 +1,13 @@
-using System.Web.Mvc;
+using System;
+using System.Diagnostics;
+using System.Web;
+using System.Web.Mvc;
using System.Web.Routing;
using Ninject;
using Ninject.Web.Mvc;
+using NLog;
using NzbDrone.Core;
-
namespace NzbDrone.Web
{
public class MvcApplication : NinjectHttpApplication
@@ -21,12 +24,11 @@ namespace NzbDrone.Web
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Series", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
-
}
protected override void OnApplicationStarted()
{
- CentralDispatch.ConfigureNlog();
+ Instrumentation.Setup();
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
base.OnApplicationStarted();
@@ -35,9 +37,15 @@ namespace NzbDrone.Web
protected override IKernel CreateKernel()
{
return CentralDispatch.NinjectKernel;
+ }
+ // ReSharper disable InconsistentNaming
+ protected void Application_Error(object sender, EventArgs e)
+ {
+ Instrumentation.LogEpicException(Server.GetLastError());
}
+
}
}
\ No newline at end of file
diff --git a/NzbDrone.Web/NzbDrone.Web.csproj b/NzbDrone.Web/NzbDrone.Web.csproj
index 3cb0eae85..a3833f209 100644
--- a/NzbDrone.Web/NzbDrone.Web.csproj
+++ b/NzbDrone.Web/NzbDrone.Web.csproj
@@ -260,16 +260,7 @@
- False
- True
- 21704
- /
- http://localhost/NzbDrone
- False
- False
-
-
- False
+ True
diff --git a/NzbDrone.Web/Views/Shared/Error.aspx b/NzbDrone.Web/Views/Shared/Error.aspx
index 1df0032b0..515fe7e5d 100644
--- a/NzbDrone.Web/Views/Shared/Error.aspx
+++ b/NzbDrone.Web/Views/Shared/Error.aspx
@@ -11,15 +11,3 @@
<%:Model.Exception.ToString()%>
-
diff --git a/NzbDrone.Web/Web.config b/NzbDrone.Web/Web.config
index ff2401b1b..0754d47f3 100644
--- a/NzbDrone.Web/Web.config
+++ b/NzbDrone.Web/Web.config
@@ -21,13 +21,9 @@
-
+
-
diff --git a/NzbDrone.vshost.exe b/NzbDrone.vshost.exe
new file mode 100644
index 000000000..bb84a51ac
Binary files /dev/null and b/NzbDrone.vshost.exe differ
diff --git a/NzbDrone/Config.cs b/NzbDrone/Config.cs
new file mode 100644
index 000000000..23ea03835
--- /dev/null
+++ b/NzbDrone/Config.cs
@@ -0,0 +1,79 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using NLog;
+using NLog.Config;
+using NLog.Targets;
+
+namespace NzbDrone
+{
+ class Config
+ {
+ private static string _projectRoot = string.Empty;
+ internal static string ProjectRoot
+ {
+ get
+ {
+ if (string.IsNullOrEmpty(_projectRoot))
+ {
+ var appDir = new FileInfo(Assembly.GetExecutingAssembly().Location).Directory;
+
+ while (appDir.GetDirectories("iisexpress").Length == 0)
+ {
+ if (appDir.Parent == null) throw new ApplicationException("Can't fine IISExpress folder.");
+ appDir = appDir.Parent;
+ }
+
+ _projectRoot = appDir.FullName;
+ }
+
+ return _projectRoot;
+ }
+
+ }
+
+ internal static void ConfigureNlog()
+ {
+ var config = new LoggingConfiguration();
+
+ var debuggerTarget = new DebuggerTarget
+ {
+ Layout = "${logger}: ${message}"
+ };
+
+
+ var consoleTarget = new ColoredConsoleTarget
+ {
+ Layout = "${logger}: ${message}"
+ };
+
+
+ config.AddTarget("debugger", debuggerTarget);
+ config.AddTarget("console", consoleTarget);
+ //config.AddTarget("file", fileTarget);
+
+ // Step 3. Set target properties
+ // Step 4. Define rules
+ //LoggingRule fileRule = new LoggingRule("*", LogLevel.Trace, fileTarget);
+ var debugRule = new LoggingRule("*", LogLevel.Trace, debuggerTarget);
+ var consoleRule = new LoggingRule("*", LogLevel.Trace, consoleTarget);
+
+ //config.LoggingRules.Add(fileRule);
+ config.LoggingRules.Add(debugRule);
+ config.LoggingRules.Add(consoleRule);
+
+ // Step 5. Activate the configuration
+ LogManager.Configuration = config;
+ }
+
+ internal static int Port
+ {
+ get { return Convert.ToInt32(ConfigurationManager.AppSettings.Get("port")); }
+ }
+
+ }
+}
diff --git a/NzbDrone/IISController.cs b/NzbDrone/IISController.cs
new file mode 100644
index 000000000..1d59bcbcb
--- /dev/null
+++ b/NzbDrone/IISController.cs
@@ -0,0 +1,109 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text;
+using Microsoft.Web.Administration;
+using NLog;
+
+namespace NzbDrone
+{
+ class IISController
+ {
+ public static Process IISProcess { get; private set; }
+ private static readonly Logger IISLogger = LogManager.GetLogger("IISExpress");
+ private static readonly Logger Logger = LogManager.GetLogger("IISController");
+ private static readonly string IISFolder = Path.Combine(Config.ProjectRoot, @"IISExpress\");
+ private static readonly string IISExe = Path.Combine(IISFolder, @"iisexpress.exe");
+
+
+ internal static string AppUrl
+ {
+ get { return string.Format("http://localhost:{0}/", Config.Port); }
+ }
+
+ internal static Process StartIIS()
+ {
+ Logger.Info("Preparing IISExpress Server...");
+ IISProcess = new Process();
+
+ IISProcess.StartInfo.FileName = IISExe;
+ IISProcess.StartInfo.Arguments = "/config:IISExpress\\Appserver\\applicationhost.config";
+ IISProcess.StartInfo.WorkingDirectory = Config.ProjectRoot;
+
+ IISProcess.StartInfo.UseShellExecute = false;
+ IISProcess.StartInfo.RedirectStandardOutput = true;
+ IISProcess.StartInfo.RedirectStandardError = true;
+ IISProcess.StartInfo.CreateNoWindow = true;
+
+ IISProcess.OutputDataReceived += ((s, e) => IISLogger.Trace(e.Data));
+ IISProcess.ErrorDataReceived += ((s, e) => IISLogger.Fatal(e.Data));
+
+ //Set Variables for the config file.
+ Environment.SetEnvironmentVariable("NZBDRONE_PATH", Config.ProjectRoot);
+ UpdateIISConfig();
+
+ Logger.Info("Starting process. [{0}]", IISProcess.StartInfo.FileName);
+ IISProcess.Start();
+
+ IISProcess.BeginErrorReadLine();
+ IISProcess.BeginOutputReadLine();
+ return IISProcess;
+ }
+
+ internal static void StopIIS()
+ {
+ KillProcess(IISProcess);
+ }
+
+ internal static void KillOrphaned()
+ {
+ Logger.Trace("================================================");
+ Logger.Info("Finding orphaned IIS Processes.");
+ foreach (var process in Process.GetProcessesByName("IISExpress"))
+ {
+ Logger.Trace("-------------------------");
+ string processPath = process.MainModule.FileName;
+ Logger.Info("[{0}]IIS Process found. Path:{1}", process.Id, processPath);
+ if (CleanPath(processPath) == CleanPath(IISExe))
+ {
+ Logger.Info("[{0}]Process is considered orphaned.", process.Id);
+ KillProcess(process);
+ }
+ else
+ {
+ Logger.Info("[{0}]Process has a different start-up path. skipping.", process.Id);
+ }
+ Logger.Trace("-------------------------");
+ }
+ Logger.Trace("================================================");
+ }
+
+
+
+ private static void KillProcess(Process process)
+ {
+ if (process == null) return;
+
+ Logger.Info("[{0}]Killing process", process.Id);
+ process.Kill();
+ Logger.Info("[{0}]Waiting for exit", process.Id);
+ process.WaitForExit();
+ Logger.Info("[{0}]Process terminated successfully", process.Id);
+ }
+
+ private static void UpdateIISConfig()
+ {
+ Logger.Info(@"Configuring server to: [http://localhost:{0}]", Config.Port);
+ var serverManager = new ServerManager(Path.Combine(IISFolder, @"AppServer\applicationhost.config"));
+ serverManager.Sites["NZBDrone"].Bindings[0].BindingInformation = string.Format("*:{0}:", Config.Port);
+ serverManager.CommitChanges();
+ }
+
+ private static string CleanPath(string path)
+ {
+ return path.ToLower().Replace("\\", "").Replace("//", "//");
+ }
+ }
+}
diff --git a/NzbDrone/Microsoft.Web.Administration.dll b/NzbDrone/Microsoft.Web.Administration.dll
new file mode 100644
index 000000000..07c9a8670
Binary files /dev/null and b/NzbDrone/Microsoft.Web.Administration.dll differ
diff --git a/NzbDrone/NzbDrone.csproj b/NzbDrone/NzbDrone.csproj
index c52ec3931..c5ce0d972 100644
--- a/NzbDrone/NzbDrone.csproj
+++ b/NzbDrone/NzbDrone.csproj
@@ -13,6 +13,21 @@
v4.0
512
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
x86
@@ -34,25 +49,72 @@
4
+
+ True
+
+
+ True
+
+
+ False
+ ..\NzbDrone.Core\Libraries\Exceptioneer.WindowsFormsClient.dll
+
+
+ True
+
False
..\NzbDrone.Core\Libraries\NLog.dll
+
+
+
+
+
+
+
+
+
+
+ False
+ Microsoft .NET Framework 4 %28x86 and x64%29
+ true
+
+
+ False
+ .NET Framework 3.5 SP1 Client Profile
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ false
+
+
+ False
+ Windows Installer 3.1
+ true
+
+
+
+
+
+