GApp.cs
上传用户:szltgg
上传日期:2019-05-16
资源大小:604k
文件大小:18k
源码类别:

Telnet服务器

开发平台:

C#

  1. /*
  2. * Copyright (c) 2005 Poderosa Project, All Rights Reserved.
  3. * $Id: GApp.cs,v 1.2 2005/04/20 08:45:45 okajima Exp $
  4. */
  5. using System;
  6. using System.Resources;
  7. using System.Text;
  8. using System.Drawing;
  9. using System.Collections;
  10. using System.Diagnostics;
  11. using System.Globalization;
  12. using System.IO;
  13. using System.Windows.Forms;
  14. using System.Net;
  15. using System.Net.Sockets;
  16. using System.Threading;
  17. using Microsoft.Win32;
  18. using Poderosa.Toolkit;
  19. using Poderosa.Connection;
  20. using Poderosa.ConnectionParam;
  21. using Poderosa.Terminal;
  22. using Poderosa.Forms;
  23. using Poderosa.Communication;
  24. using Poderosa.Config;
  25. using Poderosa.MacroEnv;
  26. using Poderosa.Text;
  27. using Poderosa.UI;
  28. namespace Poderosa
  29. {
  30. internal class GApp
  31. {
  32. public static GFrame _frame;
  33. private static StringResources _strings;
  34. private static ConnectionHistory _history;
  35. private static MacroManager _macroManager;
  36. private static PoderosaContainer _container;
  37. private static ContainerGlobalCommandTarget _globalCommandTarget;
  38. private static ContainerInterThreadUIService _interThreadUIService;
  39. private static SSHKnownHosts _sshKnownHosts;
  40. private static ContainerOptions _options;
  41. public static IntPtr _globalMutex; //暋悢婲摦帪偺愝掕僼傽僀儖曐岇
  42. private static bool _closingApp; //傾僾儕廔椆帪偵棫偮僼儔僌 
  43. private static bool _closeWithoutSave;
  44. [STAThread]
  45. static void Main(string[] args) {
  46.             //Application.EnableVisualStyles();
  47.             //Application.SetCompatibleTextRenderingDefault(false);
  48.             //Application.Run(new MainForm());
  49.             
  50.             try {
  51. if(args.Length>0) {
  52. if(InterProcessService.SendShortCutFileNameToExistingInstance(args[0])) return;
  53. }
  54. GApp.Run(args);
  55. }
  56. catch(Exception e) {
  57. #if DEBUG
  58. Debug.WriteLine(e.Message);
  59. Debug.WriteLine(e.StackTrace);
  60. #else
  61. GUtil.ReportCriticalError(e);
  62. #endif
  63. }
  64. }
  65. private static IntPtr CheckDuplicatedInstance() {
  66. IntPtr t = Win32.CreateEvent(IntPtr.Zero, 0, 0, "PoderosaHandle");
  67. if(Win32.GetLastError()==Win32.ERROR_ALREADY_EXISTS) {
  68. Win32.CloseHandle(t);
  69. return IntPtr.Zero;
  70. }
  71. else
  72. return t;
  73. }
  74.         public static void CreateGFrame(string[] args)
  75.         {
  76.             InitialAction a = new InitialAction();
  77.             _globalMutex = Win32.CreateMutex(IntPtr.Zero, 0, "PoderosaGlobalMutex");
  78.             bool already_exists = (Win32.GetLastError() == Win32.ERROR_ALREADY_EXISTS);
  79.             if (_globalMutex == IntPtr.Zero) throw new Exception("Global mutex could not open");
  80.             LoadEnvironment(a);
  81.             Init(a, args, already_exists);
  82.             //System.Windows.Forms.Application.Run(_frame);
  83.             //_frame.Show();
  84.             
  85.             if (!_closeWithoutSave) SaveEnvironment();
  86.             GEnv.Terminate();
  87.             Win32.CloseHandle(_globalMutex);
  88.         }
  89. public static void Run(string[] args) {
  90. InitialAction a = new InitialAction();
  91. _globalMutex = Win32.CreateMutex(IntPtr.Zero, 0, "PoderosaGlobalMutex");
  92. bool already_exists = (Win32.GetLastError()==Win32.ERROR_ALREADY_EXISTS);
  93. if(_globalMutex==IntPtr.Zero) throw new Exception("Global mutex could not open");
  94. LoadEnvironment(a);
  95. Init(a, args, already_exists);
  96. //System.Windows.Forms.Application.Run(_frame);
  97.             //_frame.Show();
  98.             if(!_closeWithoutSave) SaveEnvironment();
  99. GEnv.Terminate();
  100. Win32.CloseHandle(_globalMutex);
  101. }
  102. public static void Init(InitialAction act, string[] args, bool already_exists) { //GFrame偺嶌惉偼僐儞僗僩儔僋僞偺屻偵偟側偄偲丄GuevaraApp偺儊僜僢僪傪僨儕僎乕僩偺堷悢偵偱偒側偄丅
  103. if(args.Length>0) {
  104. act.ShortcutFile = args[0];
  105. }
  106. _frame = new GFrame(act);
  107. _globalCommandTarget.Init(_frame);
  108. if(already_exists && _options.FrameState==FormWindowState.Normal) {
  109. Rectangle rect = _options.FramePosition;
  110. rect.Location += new Size(24,24);
  111. _options.FramePosition = rect;
  112. }
  113. _frame.DesktopBounds = _options.FramePosition;
  114. _frame.WindowState = _options.FrameState;
  115. _frame.AdjustMRUMenu();
  116. //僉儍僢僠偱偒側偐偭偨僄儔乕偺曗懌
  117. Application.ThreadException += new ThreadExceptionEventHandler(OnThreadException);
  118. }
  119. public static void LoadEnvironment(InitialAction act) {
  120. ThemeUtil.Init();
  121. OptionPreservePlace place = GetOptionPreservePlace();
  122. _options = new ContainerOptions();
  123. _history = new ConnectionHistory();
  124. _macroManager = new MacroManager();
  125. _container = new PoderosaContainer();
  126. _globalCommandTarget = new ContainerGlobalCommandTarget();
  127. _interThreadUIService = new ContainerInterThreadUIService();
  128. _sshKnownHosts = new SSHKnownHosts();
  129. //偙偺帪揰偱偼OS偺尵岅愝掕偵崌偭偨儕僜乕僗傪儘乕僪偡傞丅婲摦捈慜偱昁梫偵墳偠偰儕儘乕僪
  130. ReloadStringResource();
  131. GEnv.Init(_container);
  132. GEnv.Options = _options;
  133. GEnv.GlobalCommandTarget = _globalCommandTarget;
  134. GEnv.InterThreadUIService = _interThreadUIService;
  135. GEnv.SSHKnownHosts = _sshKnownHosts;
  136. string dir = GetOptionDirectory(place);
  137. LoadConfigFiles(dir, act);
  138. _options.OptionPreservePlace = place;
  139. //偙偙傑偱偒偨傜尵岅愝掕傪僠僃僢僋偟丄昁梫側傜撉傒捈偟
  140. if(GUtil.CurrentLanguage!=_options.Language) {
  141. System.Threading.Thread.CurrentThread.CurrentUICulture = _options.Language==Language.Japanese? new CultureInfo("ja") : CultureInfo.InvariantCulture;
  142. ReloadStringResource();
  143. }
  144. }
  145. private static void LoadConfigFiles(string dir, InitialAction act) {
  146. if(Win32.WaitForSingleObject(_globalMutex, 10000)!=Win32.WAIT_OBJECT_0) throw new Exception("Global mutex lock error");
  147. try {
  148. string optionfile = dir+"options.conf";
  149. bool config_loaded = false;
  150. bool macro_loaded = false;
  151. TextReader reader = null;
  152. try {
  153. if(File.Exists(optionfile)) {
  154. reader = new StreamReader(File.Open(optionfile, FileMode.Open, FileAccess.Read), Encoding.Default);
  155. if(VerifyConfigHeader(reader)) {
  156. ConfigNode root = new ConfigNode("root", reader).FindChildConfigNode("poderosa");
  157. if(root!=null) {
  158. _options.Load(root);
  159. config_loaded = true;
  160. _history.Load(root);
  161. _macroManager.Load(root);
  162. macro_loaded = true;
  163. }
  164. }
  165. }
  166. }
  167. catch(Exception ex) {
  168. //_errorOccurredOnBoot = true;
  169. Debug.WriteLine(ex.StackTrace);
  170. GUtil.WriteDebugLog(ex.StackTrace);
  171. act.AddMessage("Failed to read the configuration file.n" + ex.Message);
  172. }
  173. finally {
  174. if(!config_loaded) _options.Init();
  175. if(!macro_loaded)  _macroManager.SetDefault();
  176. if(reader != null) reader.Close();
  177. }
  178. GEnv.Options = _options; //偙傟偱DefaultRenderProfile偑弶婜壔偝傟傞
  179. string kh = dir+"ssh_known_hosts";
  180. if(File.Exists(kh)) {
  181. try {
  182. _sshKnownHosts.Load(kh);
  183. }
  184. catch(Exception ex) {
  185. _sshKnownHosts.Clear();
  186. act.AddMessage("Failed to read the 'ssh_known_hosts' file.n" + ex.Message);
  187. }
  188. }
  189. }
  190. finally {
  191. Win32.ReleaseMutex(_globalMutex);
  192. }
  193. }
  194. private static void ReloadStringResource() {
  195. _strings = new StringResources("Poderosa.strings", typeof(GApp).Assembly); 
  196. EnumDescAttribute.AddResourceTable(typeof(GApp).Assembly, _strings);
  197. GEnv.ReloadStringResource();
  198. }
  199. private static void InitConfig() {
  200. _options.Init();
  201. _macroManager.SetDefault();
  202. }
  203. private static void SaveEnvironment() {
  204. //OptionDialog偱丄儗僕僗僩儕傊偺彂偒崬傒尃尷偑側偄偲OptionPreservePlace偼曄峏偱偒側偄傛偆偵偟偰偁傞偺偱Writable側偲偒偩偗彂偄偰偍偗偽OK
  205. if(IsRegistryWritable) {
  206. RegistryKey g = Registry.CurrentUser.CreateSubKey(GCConst.REGISTRY_PATH);
  207. g.SetValue("option-place", EnumDescAttribute.For(typeof(OptionPreservePlace)).GetName(_options.OptionPreservePlace));
  208. }
  209. if(Win32.WaitForSingleObject(_globalMutex, 10000)!=Win32.WAIT_OBJECT_0) throw new Exception("Global mutex lock error");
  210. try {
  211. string dir = GetOptionDirectory(_options.OptionPreservePlace);
  212. TextWriter wr = null;
  213. try {
  214. if(!Directory.Exists(dir)) Directory.CreateDirectory(dir);
  215. _sshKnownHosts.WriteTo(dir+"ssh_known_hosts");
  216. wr = new StreamWriter(dir+"options.conf", false, Encoding.Default);
  217. }
  218. catch(Exception ex) {
  219. //GUtil.ReportCriticalError(ex);
  220. GUtil.Warning(Form.ActiveForm, String.Format(GApp.Strings.GetString("Message.GApp.WriteError"), ex.Message, dir));
  221. }
  222. if(wr!=null) {
  223. try {
  224. ConfigNode node = new ConfigNode("poderosa");
  225. _options.Save(node);
  226. _history.Save(node);
  227. _macroManager.Save(node);
  228. wr.WriteLine(GCConst.CONFIG_HEADER);
  229. node.WriteTo(wr);
  230. wr.Close();
  231. }
  232. catch(Exception ex) {
  233. GUtil.ReportCriticalError(ex);
  234. }
  235. }
  236. }
  237. finally {
  238. Win32.ReleaseMutex(_globalMutex);
  239. }
  240. }
  241. public static string GetOptionDirectory(OptionPreservePlace p) {
  242. if(p==OptionPreservePlace.InstalledDir) {
  243. string t = AppDomain.CurrentDomain.BaseDirectory;
  244. if(Environment.UserName.Length>0) t += Environment.UserName + "\";
  245. return t;
  246. }
  247. else
  248. return Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\poderosa\";
  249. }
  250. public static string GetCommonLogDirectory() {
  251. if(GetOptionPreservePlace()==OptionPreservePlace.InstalledDir)
  252. return AppDomain.CurrentDomain.BaseDirectory + "\";
  253. else
  254. return Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\";
  255. }
  256. public static string BaseDirectory {
  257. get {
  258. return AppDomain.CurrentDomain.BaseDirectory;
  259. }
  260. }
  261. public static ConnectionHistory ConnectionHistory {
  262. get {
  263. return _history;
  264. }
  265. }
  266. public static MacroManager MacroManager {
  267. get {
  268. return _macroManager;
  269. }
  270. }
  271. public static void UpdateOptions(ContainerOptions opt) {
  272. GEnv.Options = opt;
  273. _frame.ApplyOptions(_options, opt); 
  274. _history.LimitCount(opt.MRUSize);
  275. _frame.AdjustMRUMenu();
  276. if(_options.Language!=opt.Language) { //尵岅偺儕儘乕僪偑昁梫側偲偒
  277. System.Threading.Thread.CurrentThread.CurrentUICulture = opt.Language==Language.Japanese? new CultureInfo("ja") : CultureInfo.InvariantCulture;
  278. GApp.ReloadStringResource();
  279. Granados.SSHC.Strings.Reload();
  280. GApp.MacroManager.ReloadLanguage();
  281. _frame.ReloadLanguage(opt.Language);
  282. }
  283. //僨僼僅儖僩偺傑傑偱偁偭偨応崌偵偼峏怴傪偐偗傞
  284. RenderProfile newprof = new RenderProfile(opt);
  285. foreach(ConnectionTag ct in GEnv.Connections) {
  286. if(ct.RenderProfile==null && ct.AttachedPane!=null) ct.AttachedPane.ApplyRenderProfile(newprof);
  287. }
  288. GEnv.DefaultRenderProfile = newprof;
  289. _options = opt;
  290. }
  291. internal static StringResources Strings {
  292. get {
  293. return _strings;
  294. }
  295. }
  296. internal static ContainerInterThreadUIService InterThreadUIService {
  297. get {
  298. return _interThreadUIService;
  299. }
  300. }
  301. internal static GFrame Frame {
  302. get {
  303. return _frame;
  304. }
  305. }
  306. internal static ContainerOptions Options {
  307. get {
  308. return _options;
  309. }
  310. }
  311. internal static ContainerGlobalCommandTarget GlobalCommandTarget {
  312. get {
  313. return _globalCommandTarget;
  314. }
  315. }
  316. public static bool ClosingApp {
  317. get {
  318. return _closingApp;
  319. }
  320. set {
  321. _closingApp = value;
  322. }
  323. }
  324. public static bool CloseWithoutSave {
  325. get {
  326. return _closeWithoutSave;
  327. }
  328. set {
  329. _closeWithoutSave = value;
  330. }
  331. }
  332. public static bool IsRegistryWritable {
  333. get {
  334. try {
  335. RegistryKey g = Registry.CurrentUser.CreateSubKey(GCConst.REGISTRY_PATH);
  336. if(g==null)
  337. return false;
  338. else
  339. return true;
  340. }
  341. catch(Exception) {
  342. return false;
  343. }
  344. }
  345. }
  346. private static OptionPreservePlace GetOptionPreservePlace() {
  347. RegistryKey g = Registry.CurrentUser.OpenSubKey(GCConst.REGISTRY_PATH, false);
  348. if(g==null)
  349. return OptionPreservePlace.InstalledDir;
  350. else {
  351. string v = (string)g.GetValue("option-place");
  352. if(v==null || v.Length==0)
  353. return OptionPreservePlace.InstalledDir;
  354. else
  355. return (OptionPreservePlace)Enum.Parse(typeof(OptionPreservePlace), v);
  356. }
  357. }
  358. public static ContainerConnectionCommandTarget GetConnectionCommandTarget() {
  359. TerminalConnection con = GEnv.Connections.ActiveConnection;
  360. return con==null? null : new ContainerConnectionCommandTarget(con);
  361. }
  362. public static ContainerConnectionCommandTarget GetConnectionCommandTarget(TerminalConnection con) {
  363. return new ContainerConnectionCommandTarget(con); 
  364. }
  365. public static ContainerConnectionCommandTarget GetConnectionCommandTarget(ConnectionTag tag) {
  366. return new ContainerConnectionCommandTarget(tag.Connection); 
  367. }
  368. public static void OnThreadException(object sender, ThreadExceptionEventArgs e) {
  369. GUtil.ReportThreadException(e.Exception);
  370. /*
  371. string msg = DateTime.Now.ToString() + " : " + "OnThreadException() sender=" + sender.ToString() + "rn  StackTrace=" + new StackTrace(true).ToString();
  372. Debug.WriteLine(msg);
  373. GUtil.WriteDebugLog(msg);
  374. throw e.Exception;
  375. */
  376. }
  377. private static bool VerifyConfigHeader(TextReader reader) {
  378. string l = reader.ReadLine();
  379. return l==GCConst.CONFIG_HEADER;
  380. }
  381. }
  382. internal class GCConst {
  383. private static string _productWeb;
  384. public static string PRODUCT_WEB {
  385. get {
  386. if(_productWeb==null)
  387. _productWeb = GApp.Strings.GetString("Util.GApp.ProductWebSite");
  388. return _productWeb;
  389. }
  390. }
  391. public const string REGISTRY_PATH = "Software\Poderosa Project\Poderosa";
  392. public const string CONFIG_HEADER = "Poderosa Config 3.0";
  393. }
  394. internal class PoderosaContainer : IPoderosaContainer {
  395. public void RemoveConnection(ConnectionTag ct) {
  396. GApp.Frame.RemoveConnection(ct);
  397. }
  398. public void ActivateConnection(ConnectionTag ct) {
  399. GApp.GlobalCommandTarget.ActivateConnection2(ct);
  400. }
  401. public void RefreshConnection(ConnectionTag ct) {
  402. GApp.Frame.RefreshConnection(ct);
  403. }
  404. public void OnDragDrop(DragEventArgs args) {
  405. GApp.Frame.OnDragDropInternal(args);
  406. }
  407. public void OnDragEnter(DragEventArgs args) {
  408. GApp.Frame.OnDragEnterInternal(args);
  409. }
  410. public System.Drawing.Size TerminalSizeForNextConnection {
  411. get {
  412. return GApp.Frame.PaneContainer.TerminalSizeForNextConnection;
  413. }
  414. }
  415. public int PositionForNextConnection {
  416. get {
  417. return GApp.Frame.PaneContainer.PositionForNextConnection;
  418. }
  419. }
  420. public void IndicateBell() {
  421. GApp.Frame.StatusBar.IndicateBell();
  422. }
  423. public void SetStatusBarText(string text) {
  424. GApp.Frame.StatusBar.SetStatusBarText(text);
  425. }
  426. public void ShowContextMenu(System.Drawing.Point pt, ConnectionTag ct) {
  427. //GApp.Frame.CommandTargetConnection = ct.Connection;
  428. //儊僯儏乕偺UI挷惍
  429. //GApp.Frame.AdjustContextMenu(true, ct.Connection);
  430. //GApp.Frame.ContextMenu.Show(GApp.Frame.PaneContainer, pt);
  431.             
  432.             //foreach (TerminalPane p in GApp.Frame._multiPaneControl._panes)
  433.             //{
  434.                 //if (p.Visible)
  435.                     //GApp.Frame.ContextMenu.Show(p, pt);
  436.             //}
  437. }
  438. public void SetSelectionStatus(SelectionStatus status) {
  439. if(status==SelectionStatus.Auto)
  440. GApp.Frame.StatusBar.IndicateAutoSelectionMode();
  441. else if(status==SelectionStatus.Free)
  442. GApp.Frame.StatusBar.IndicateFreeSelectionMode();
  443. else
  444. GApp.Frame.StatusBar.ClearSelectionMode();
  445. }
  446. public bool MacroIsRunning {
  447. get {
  448. return GApp.MacroManager.MacroIsRunning;
  449. }
  450. }
  451. public CommandResult ProcessShortcutKey(Keys key) {
  452. return GApp.Options.Commands.ProcessKey(key, GApp.MacroManager.MacroIsRunning);
  453. }
  454. public Form AsForm() {
  455. return GApp.Frame;
  456. }
  457. public System.IntPtr Handle {
  458. get {
  459. return GApp.Frame.Handle;
  460. }
  461. }
  462. public bool IgnoreErrors {
  463. get {
  464. return GApp.ClosingApp;
  465. }
  466. }
  467. }
  468. internal class InterProcessService {
  469. public const int OPEN_SHORTCUT = 7964;
  470. public const int OPEN_SHORTCUT_OK = 485;
  471. public static bool SendShortCutFileNameToExistingInstance(string filename) {
  472. unsafe {
  473. //find target
  474. IntPtr hwnd = Win32.FindWindowEx(IntPtr.Zero,IntPtr.Zero,null,null);
  475. bool success = false;
  476. char[] name = new char[256];
  477. char[] mf  = new char[256];
  478. while(hwnd!=IntPtr.Zero) {
  479. int len = Win32.GetWindowText(hwnd, name, 256);
  480. if(new string(name, 0, len).IndexOf("Poderosa")!=-1) { //Window Class傪妋擣偡傞偲偐壗偲偐偡傋偒偐傕丄偩偑
  481. success = TryToSend(hwnd, filename); 
  482. if(success) break;
  483. }
  484. hwnd = Win32.FindWindowEx(IntPtr.Zero,hwnd,null,null);
  485. }
  486. return success;
  487. }
  488. }
  489. private unsafe static bool TryToSend(IntPtr hwnd, string filename) {
  490. char[] data = filename.ToCharArray();
  491. char* b = stackalloc char[data.Length+1];
  492. for(int i=0; i<data.Length; i++) b[i] = data[i];
  493. b[data.Length] = '';
  494. //string t = ReadFileName(hglobal);
  495. Win32.COPYDATASTRUCT cddata = new Win32.COPYDATASTRUCT();
  496. cddata.dwData = OPEN_SHORTCUT;
  497. cddata.cbData = (uint)(sizeof(char) * (data.Length+1));
  498. cddata.lpData = b;
  499. int lresult = Win32.SendMessage(hwnd, Win32.WM_COPYDATA, IntPtr.Zero, new IntPtr(&cddata));
  500. //Debug.WriteLine("TryToSend "+lresult);
  501. return lresult==OPEN_SHORTCUT_OK;
  502. }
  503. }
  504. internal class InitialAction {
  505. private ArrayList _messages;  //message box傪弌偡傋偒撪梕
  506. private string _shortcutFile; //嵟弶偵奐偔僔儑乕僩僇僢僩僼傽僀儖丗晄梫側偲偒偼null
  507. public InitialAction() {
  508. _messages = new ArrayList();
  509. }
  510. public void AddMessage(string msg) {
  511. _messages.Add(msg);
  512. }
  513. public string ShortcutFile {
  514. get {
  515. return _shortcutFile;
  516. }
  517. set {
  518. _shortcutFile = value;
  519. }
  520. }
  521. public IEnumerable Messages {
  522. get {
  523. return _messages;
  524. }
  525. }
  526. }
  527. }