386 lines
12 KiB
C#
386 lines
12 KiB
C#
// **********************************************************************************
|
|
// CassiniDev - http://cassinidev.codeplex.com
|
|
//
|
|
// Copyright (c) Sky Sanders. All rights reserved.
|
|
// Copyright (c) Microsoft Corporation. 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.
|
|
//
|
|
// **********************************************************************************
|
|
|
|
#region
|
|
|
|
using System;
|
|
using System.Collections;
|
|
using System.Configuration.Install;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Reflection;
|
|
using System.Threading;
|
|
using System.Windows.Forms;
|
|
using CassiniDev.UIComponents;
|
|
|
|
#endregion
|
|
|
|
namespace CassiniDev
|
|
{
|
|
public sealed class Program
|
|
{
|
|
|
|
|
|
[STAThread, LoaderOptimization(LoaderOptimization.MultiDomainHost)]
|
|
public static int Main(string[] cmdLine)
|
|
{
|
|
Server server = null;
|
|
|
|
if (cmdLine != null && cmdLine.Length > 0)
|
|
{
|
|
bool isVS = Assembly.GetExecutingAssembly()
|
|
.GetName().Name.StartsWith("WEBDEV.WEBSERVER", StringComparison.OrdinalIgnoreCase);
|
|
|
|
CommandLineArguments args = new CommandLineArguments();
|
|
|
|
if (!CommandLineParser.ParseArgumentsWithUsage(cmdLine, args))
|
|
{
|
|
if (isVS)
|
|
{
|
|
// will display vs usage and return a code that VS understands
|
|
return ValidateForVS(cmdLine);
|
|
}
|
|
|
|
string usage = CommandLineParser.ArgumentsUsage(typeof(CommandLineArguments), 120);
|
|
ShowMessage(usage, MessageBoxIcon.Asterisk);
|
|
return 0;
|
|
}
|
|
|
|
|
|
if (args.RunMode == RunMode.Hostsfile)
|
|
{
|
|
SetHostsFile(args);
|
|
return 0;
|
|
}
|
|
|
|
|
|
// now we validate for us.
|
|
int returnValue = -1;
|
|
string message = null;
|
|
|
|
try
|
|
{
|
|
args.VisualStudio = isVS;
|
|
args.Validate();
|
|
}
|
|
catch (CassiniException ex)
|
|
{
|
|
switch (ex.Message)
|
|
{
|
|
case SR.ErrNoAvailablePortFound:
|
|
case SR.ErrApplicationPathIsNull:
|
|
message = ex.Message;
|
|
break;
|
|
case SR.ErrInvalidIPMode:
|
|
message = SR.GetString(ex.Message, args.IPMode);
|
|
break;
|
|
case SR.ErrInvalidPortMode:
|
|
message = SR.GetString(ex.Message, args.PortMode);
|
|
break;
|
|
case SR.ErrPortIsInUse:
|
|
message = SR.GetString(ex.Message, args.Port);
|
|
break;
|
|
case SR.ErrPortRangeEndMustBeEqualOrGreaterThanPortRangeSta:
|
|
message = SR.GetString(ex.Message, args.PortRangeStart, args.PortRangeEnd);
|
|
break;
|
|
case SR.ErrInvalidPortRangeValue:
|
|
message = SR.GetString(ex.Message,
|
|
ex.Field == ErrorField.PortRangeStart
|
|
? "start " + args.PortRangeStart
|
|
: "end " + args.PortRangeEnd);
|
|
break;
|
|
case SR.ErrInvalidHostname:
|
|
message = SR.GetString(ex.Message, args.HostName);
|
|
break;
|
|
case SR.WebdevDirNotExist:
|
|
message = SR.GetString(ex.Message, args.ApplicationPath);
|
|
returnValue = -2;
|
|
break;
|
|
case SR.ErrPortOutOfRange:
|
|
message = SR.GetString(ex.Message, args.Port);
|
|
break;
|
|
}
|
|
|
|
if (!args.Silent)
|
|
{
|
|
ShowMessage(message, MessageBoxIcon.Asterisk);
|
|
}
|
|
return returnValue;
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
if (!args.Silent)
|
|
{
|
|
ShowMessage(SR.GetString(SR.ErrFailedToStartCassiniDevServerOnPortError, args.Port,
|
|
exception.Message, exception.HelpLink), MessageBoxIcon.Error);
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
|
|
server = new Server(args.Port, args.VirtualPath, args.ApplicationPath, args.Ntlm, args.Nodirlist);
|
|
|
|
|
|
if (args.AddHost)
|
|
{
|
|
HostsFile.AddHostEntry(server.IPAddress.ToString(), server.HostName);
|
|
}
|
|
|
|
try
|
|
{
|
|
server.Start();
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
if (!args.Silent)
|
|
{
|
|
ShowMessage(SR.GetString(SR.ErrFailedToStartCassiniDevServerOnPortError, args.Port,
|
|
exception.Message, exception.HelpLink), MessageBoxIcon.Error);
|
|
}
|
|
return -4;
|
|
}
|
|
|
|
}
|
|
|
|
using (FormView form = new FormView(server))
|
|
{
|
|
Application.Run(form);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
private static void ShowMessage(string msg, MessageBoxIcon icon)
|
|
{
|
|
if (Thread.CurrentThread.CurrentUICulture.TextInfo.IsRightToLeft)
|
|
{
|
|
MessageBox.Show(msg, SR.GetString(SR.WebdevName), MessageBoxButtons.OK, icon,
|
|
MessageBoxDefaultButton.Button1, MessageBoxOptions.RtlReading);
|
|
}
|
|
else
|
|
{
|
|
MessageBox.Show(msg, SR.GetString(SR.WebdevName), MessageBoxButtons.OK, icon);
|
|
}
|
|
}
|
|
|
|
private static void ShowMessage(string msg)
|
|
{
|
|
if (Thread.CurrentThread.CurrentUICulture.TextInfo.IsRightToLeft)
|
|
{
|
|
MessageBox.Show(msg, SR.GetString(SR.WebdevName), MessageBoxButtons.OK, MessageBoxIcon.Hand,
|
|
MessageBoxDefaultButton.Button1, MessageBoxOptions.RtlReading);
|
|
}
|
|
else
|
|
{
|
|
MessageBox.Show(msg, SR.GetString(SR.WebdevName), MessageBoxButtons.OK, MessageBoxIcon.Hand);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// TODO: update usage will all arguments and present on a legible substrate.
|
|
/// </summary>
|
|
private static void ShowUsage()
|
|
{
|
|
ShowMessage(SR.GetString(SR.WebdevUsagestr1) + SR.GetString(SR.WebdevUsagestr2) +
|
|
SR.GetString(SR.WebdevUsagestr3) +
|
|
SR.GetString(SR.WebdevUsagestr4) + SR.GetString(SR.WebdevUsagestr5) +
|
|
SR.GetString(SR.WebdevUsagestr6) +
|
|
SR.GetString(SR.WebdevUsagestr7), MessageBoxIcon.Asterisk);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Keeping the VS validation to return codes that it likes.
|
|
/// </summary>
|
|
/// <param name="args"></param>
|
|
/// <returns></returns>
|
|
private static int ValidateForVS(string[] args)
|
|
{
|
|
CommandLine line = new CommandLine(args);
|
|
|
|
bool flag = line.Options["silent"] != null;
|
|
|
|
if (!flag && line.ShowHelp)
|
|
{
|
|
ShowUsage();
|
|
return 0;
|
|
}
|
|
|
|
string virtualPath = (string)line.Options["vpath"];
|
|
|
|
if (virtualPath != null)
|
|
{
|
|
virtualPath = virtualPath.Trim();
|
|
}
|
|
|
|
// we are being a bit generous here as CommandLineArguments can handle these sitchiashuns
|
|
if (string.IsNullOrEmpty(virtualPath))
|
|
{
|
|
virtualPath = "/";
|
|
}
|
|
|
|
else if (!virtualPath.StartsWith("/", StringComparison.Ordinal))
|
|
{
|
|
if (!flag)
|
|
{
|
|
ShowUsage();
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
string path = (string)line.Options["path"];
|
|
|
|
if (path != null)
|
|
{
|
|
path = path.Trim();
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(path))
|
|
{
|
|
if (!flag)
|
|
{
|
|
ShowUsage();
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
path = Path.GetFullPath(path);
|
|
|
|
if (!Directory.Exists(path))
|
|
{
|
|
if (!flag)
|
|
{
|
|
ShowMessage(SR.GetString(SR.WebdevDirNotExist, new object[] { path }));
|
|
}
|
|
return -2;
|
|
}
|
|
|
|
int port = 0;
|
|
|
|
string s = (string)line.Options["port"];
|
|
|
|
if (s != null)
|
|
{
|
|
s = s.Trim();
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(s))
|
|
{
|
|
try
|
|
{
|
|
port = int.Parse(s, CultureInfo.InvariantCulture);
|
|
if ((port < 1) || (port > 0xffff))
|
|
{
|
|
if (!flag)
|
|
{
|
|
ShowUsage();
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
}
|
|
catch
|
|
{
|
|
if (!flag)
|
|
{
|
|
ShowMessage(SR.GetString(SR.WebdevInvalidPort, new object[] { s }));
|
|
}
|
|
return -3;
|
|
}
|
|
}
|
|
|
|
if (!flag)
|
|
{
|
|
ShowUsage();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
private static void SetHostsFile(CommandLineArguments sargs)
|
|
{
|
|
try
|
|
{
|
|
if (sargs.AddHost)
|
|
{
|
|
HostsFile.AddHostEntry(sargs.IPAddress, sargs.HostName);
|
|
}
|
|
else
|
|
{
|
|
HostsFile.RemoveHostEntry(sargs.IPAddress, sargs.HostName);
|
|
}
|
|
}
|
|
catch (UnauthorizedAccessException)
|
|
{
|
|
Environment.Exit(-1);
|
|
}
|
|
catch
|
|
{
|
|
Environment.Exit(-2);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
internal sealed class ServiceUtil
|
|
{
|
|
/// <summary>
|
|
/// http://stackoverflow.com/questions/1449994/inno-setup-for-windows-service
|
|
/// http://groups.google.co.uk/group/microsoft.public.dotnet.languages.csharp/browse_thread/thread/4d45e9ea5471cba4/4519371a77ed4a74
|
|
/// </summary>
|
|
/// <param name="undo"></param>
|
|
/// <param name="args"></param>
|
|
public static void Install(bool undo, string[] args)
|
|
{
|
|
try
|
|
{
|
|
Console.WriteLine(undo ? "uninstalling" : "installing");
|
|
using (AssemblyInstaller inst = new AssemblyInstaller(typeof(Program).Assembly, args))
|
|
{
|
|
IDictionary state = new Hashtable();
|
|
inst.UseNewContext = true;
|
|
try
|
|
{
|
|
if (undo)
|
|
{
|
|
inst.Uninstall(state);
|
|
}
|
|
else
|
|
{
|
|
inst.Install(state);
|
|
inst.Commit(state);
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
try
|
|
{
|
|
inst.Rollback(state);
|
|
}
|
|
catch { }
|
|
throw;
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.Error.WriteLine(ex.Message);
|
|
}
|
|
}
|
|
}
|
|
} |