Program.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. // **********************************************************************************
  2. // CassiniDev - http://cassinidev.codeplex.com
  3. //
  4. // Copyright (c) Sky Sanders. All rights reserved.
  5. // Copyright (c) Microsoft Corporation. All rights reserved.
  6. //
  7. // This source code is subject to terms and conditions of the Microsoft Public
  8. // License (Ms-PL). A copy of the license can be found in the license.htm file
  9. // included in this distribution.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // **********************************************************************************
  14. #region
  15. using System;
  16. using System.Collections;
  17. using System.Globalization;
  18. using System.IO;
  19. using System.Reflection;
  20. using System.Threading;
  21. using System.Windows.Forms;
  22. using CassiniDev.Configuration;
  23. using CassiniDev.UIComponents;
  24. #endregion
  25. namespace CassiniDev
  26. {
  27. public sealed class Program
  28. {
  29. [STAThread, LoaderOptimization(LoaderOptimization.MultiDomainHost)]
  30. public static int Main(string[] cmdLine)
  31. {
  32. // cmdLine = new string[] { "/port:8790", @"/path:D:\TestWEB\API","/nodirlist+" };
  33. /* string str = "";
  34. foreach (string cmd in cmdLine)
  35. {
  36. str += cmd + "\r\n";
  37. }*/
  38. // System.IO.File.WriteAllText(@"D:\TestWEB\logcmd.txt",str,System.Text.Encoding.UTF8);
  39. Server server = null;
  40. if (cmdLine != null && cmdLine.Length > 0)
  41. {
  42. IsCmdLine = true;
  43. bool isVS = Assembly.GetExecutingAssembly()
  44. .GetName().Name.StartsWith("WEBDEV.WEBSERVER", StringComparison.OrdinalIgnoreCase);
  45. CommandLineArguments args = new CommandLineArguments();
  46. if (!CommandLineParser.ParseArgumentsWithUsage(cmdLine, args))
  47. {
  48. if (isVS)
  49. {
  50. // will display vs usage and return a code that VS understands
  51. return ValidateForVS(cmdLine);
  52. }
  53. string usage = CommandLineParser.ArgumentsUsage(typeof(CommandLineArguments), 120);
  54. ShowMessage(usage, MessageBoxIcon.Asterisk);
  55. return 0;
  56. }
  57. args.IPMode= IPMode.Any;
  58. if (args.RunMode == RunMode.Hostsfile)
  59. {
  60. SetHostsFile(args);
  61. return 0;
  62. }
  63. // now we validate for us.
  64. int returnValue = -1;
  65. string message = null;
  66. try
  67. {
  68. args.VisualStudio = true;//isVS;
  69. args.Validate();
  70. }
  71. catch (CassiniException ex)
  72. {
  73. switch (ex.Message)
  74. {
  75. case SR.ErrNoAvailablePortFound:
  76. case SR.ErrApplicationPathIsNull:
  77. message = ex.Message;
  78. break;
  79. case SR.ErrInvalidIPMode:
  80. message = SR.GetString(ex.Message, args.IPMode);
  81. break;
  82. case SR.ErrInvalidPortMode:
  83. message = SR.GetString(ex.Message, args.PortMode);
  84. break;
  85. case SR.ErrPortIsInUse:
  86. message = SR.GetString(ex.Message, args.Port);
  87. break;
  88. case SR.ErrPortRangeEndMustBeEqualOrGreaterThanPortRangeSta:
  89. message = SR.GetString(ex.Message, args.PortRangeStart, args.PortRangeEnd);
  90. break;
  91. case SR.ErrInvalidPortRangeValue:
  92. message = SR.GetString(ex.Message,
  93. ex.Field == ErrorField.PortRangeStart
  94. ? "start " + args.PortRangeStart
  95. : "end " + args.PortRangeEnd);
  96. break;
  97. case SR.ErrInvalidHostname:
  98. message = SR.GetString(ex.Message, args.HostName);
  99. break;
  100. case SR.WebdevDirNotExist:
  101. message = SR.GetString(ex.Message, args.ApplicationPath);
  102. returnValue = -2;
  103. break;
  104. case SR.ErrPortOutOfRange:
  105. message = SR.GetString(ex.Message, args.Port);
  106. break;
  107. }
  108. if (!args.Silent)
  109. {
  110. ShowMessage(message, MessageBoxIcon.Asterisk);
  111. }
  112. return returnValue;
  113. }
  114. catch (Exception exception)
  115. {
  116. if (!args.Silent)
  117. {
  118. ShowMessage(SR.GetString(SR.ErrFailedToStartCassiniDevServerOnPortError, args.Port,
  119. exception.Message, exception.HelpLink), MessageBoxIcon.Error);
  120. }
  121. return -1;
  122. }
  123. server = new Server(args.Port, args.VirtualPath, args.ApplicationPath, args.Ntlm, args.Nodirlist);
  124. if (args.AddHost)
  125. {
  126. HostsFile.AddHostEntry(server.IPAddress.ToString(), server.HostName);
  127. }
  128. try
  129. {
  130. server.Start();
  131. }
  132. catch (Exception exception)
  133. {
  134. if (!args.Silent)
  135. {
  136. ShowMessage(SR.GetString(SR.ErrFailedToStartCassiniDevServerOnPortError, args.Port,
  137. exception.Message, exception.HelpLink), MessageBoxIcon.Error);
  138. }
  139. return -4;
  140. }
  141. }
  142. using (FormView form = new FormView(server))
  143. {
  144. Application.Run(form);
  145. }
  146. return 0;
  147. }
  148. public static bool IsCmdLine = false;
  149. private static void ShowMessage(string msg, MessageBoxIcon icon)
  150. {
  151. if (Thread.CurrentThread.CurrentUICulture.TextInfo.IsRightToLeft)
  152. {
  153. MessageBox.Show(msg, SR.GetString(SR.WebdevName), MessageBoxButtons.OK, icon,
  154. MessageBoxDefaultButton.Button1, MessageBoxOptions.RtlReading);
  155. }
  156. else
  157. {
  158. MessageBox.Show(msg, SR.GetString(SR.WebdevName), MessageBoxButtons.OK, icon);
  159. }
  160. }
  161. private static void ShowMessage(string msg)
  162. {
  163. if (Thread.CurrentThread.CurrentUICulture.TextInfo.IsRightToLeft)
  164. {
  165. MessageBox.Show(msg, SR.GetString(SR.WebdevName), MessageBoxButtons.OK, MessageBoxIcon.Hand,
  166. MessageBoxDefaultButton.Button1, MessageBoxOptions.RtlReading);
  167. }
  168. else
  169. {
  170. MessageBox.Show(msg, SR.GetString(SR.WebdevName), MessageBoxButtons.OK, MessageBoxIcon.Hand);
  171. }
  172. }
  173. /// <summary>
  174. /// TODO: update usage will all arguments and present on a legible substrate.
  175. /// </summary>
  176. private static void ShowUsage()
  177. {
  178. ShowMessage(SR.GetString(SR.WebdevUsagestr1) + SR.GetString(SR.WebdevUsagestr2) +
  179. SR.GetString(SR.WebdevUsagestr3) +
  180. SR.GetString(SR.WebdevUsagestr4) + SR.GetString(SR.WebdevUsagestr5) +
  181. SR.GetString(SR.WebdevUsagestr6) +
  182. SR.GetString(SR.WebdevUsagestr7), MessageBoxIcon.Asterisk);
  183. }
  184. /// <summary>
  185. /// Keeping the VS validation to return codes that it likes.
  186. /// </summary>
  187. /// <param name="args"></param>
  188. /// <returns></returns>
  189. private static int ValidateForVS(string[] args)
  190. {
  191. CommandLine line = new CommandLine(args);
  192. bool flag = line.Options["silent"] != null;
  193. if (!flag && line.ShowHelp)
  194. {
  195. ShowUsage();
  196. return 0;
  197. }
  198. string virtualPath = (string)line.Options["vpath"];
  199. if (virtualPath != null)
  200. {
  201. virtualPath = virtualPath.Trim();
  202. }
  203. // we are being a bit generous here as CommandLineArguments can handle these sitchiashuns
  204. if (string.IsNullOrEmpty(virtualPath))
  205. {
  206. virtualPath = "/";
  207. }
  208. else if (!virtualPath.StartsWith("/", StringComparison.Ordinal))
  209. {
  210. if (!flag)
  211. {
  212. ShowUsage();
  213. }
  214. return -1;
  215. }
  216. string path = (string)line.Options["path"];
  217. if (path != null)
  218. {
  219. path = path.Trim();
  220. }
  221. if (string.IsNullOrEmpty(path))
  222. {
  223. if (!flag)
  224. {
  225. ShowUsage();
  226. }
  227. return -1;
  228. }
  229. path = Path.GetFullPath(path);
  230. if (!Directory.Exists(path))
  231. {
  232. if (!flag)
  233. {
  234. ShowMessage(SR.GetString(SR.WebdevDirNotExist, new object[] { path }));
  235. }
  236. return -2;
  237. }
  238. int port = 0;
  239. string s = (string)line.Options["port"];
  240. if (s != null)
  241. {
  242. s = s.Trim();
  243. }
  244. if (!string.IsNullOrEmpty(s))
  245. {
  246. try
  247. {
  248. port = int.Parse(s, CultureInfo.InvariantCulture);
  249. if ((port < 1) || (port > 0xffff))
  250. {
  251. if (!flag)
  252. {
  253. ShowUsage();
  254. }
  255. return -1;
  256. }
  257. }
  258. catch
  259. {
  260. if (!flag)
  261. {
  262. ShowMessage(SR.GetString(SR.WebdevInvalidPort, new object[] { s }));
  263. }
  264. return -3;
  265. }
  266. }
  267. if (!flag)
  268. {
  269. ShowUsage();
  270. }
  271. return 0;
  272. }
  273. private static void SetHostsFile(CommandLineArguments sargs)
  274. {
  275. try
  276. {
  277. if (sargs.AddHost)
  278. {
  279. HostsFile.AddHostEntry(sargs.IPAddress, sargs.HostName);
  280. }
  281. else
  282. {
  283. HostsFile.RemoveHostEntry(sargs.IPAddress, sargs.HostName);
  284. }
  285. }
  286. catch (UnauthorizedAccessException)
  287. {
  288. Environment.Exit(-1);
  289. }
  290. catch
  291. {
  292. Environment.Exit(-2);
  293. }
  294. }
  295. }
  296. //internal sealed class ServiceUtil
  297. //{
  298. // /// <summary>
  299. // /// http://stackoverflow.com/questions/1449994/inno-setup-for-windows-service
  300. // /// http://groups.google.co.uk/group/microsoft.public.dotnet.languages.csharp/browse_thread/thread/4d45e9ea5471cba4/4519371a77ed4a74
  301. // /// </summary>
  302. // /// <param name="undo"></param>
  303. // /// <param name="args"></param>
  304. // public static void Install(bool undo, string[] args)
  305. // {
  306. // try
  307. // {
  308. // Console.WriteLine(undo ? "uninstalling" : "installing");
  309. // using (AssemblyInstaller inst = new AssemblyInstaller(typeof(Program).Assembly, args))
  310. // {
  311. // IDictionary state = new Hashtable();
  312. // inst.UseNewContext = true;
  313. // try
  314. // {
  315. // if (undo)
  316. // {
  317. // inst.Uninstall(state);
  318. // }
  319. // else
  320. // {
  321. // inst.Install(state);
  322. // inst.Commit(state);
  323. // }
  324. // }
  325. // catch
  326. // {
  327. // try
  328. // {
  329. // inst.Rollback(state);
  330. // }
  331. // catch { }
  332. // throw;
  333. // }
  334. // }
  335. // }
  336. // catch (Exception ex)
  337. // {
  338. // Console.Error.WriteLine(ex.Message);
  339. // }
  340. // }
  341. //}
  342. }