OSDN Git Service

AppliStation-GUI,ランチャーメニュー上での例外発生を修復
[applistation/AppliStation.git] / AppliStation / AppliStation.Util / ToolStripPetitLauncherMenuItem.cs
1 using System;\r
2 using System.Threading;\r
3 using System.IO;\r
4 using System.Drawing;\r
5 using System.Windows.Forms;\r
6 using System.Diagnostics;\r
7 using System.Text;\r
8 \r
9 using System.ComponentModel;\r
10 \r
11 namespace AppliStation.Util\r
12 {\r
13         public class ToolStripPetitLauncherMenuItem : ToolStripMenuItem\r
14         {\r
15                 private Thread thread;\r
16                 \r
17                 private string baseFolderPath;\r
18                 \r
19                 private Form invokerForm;\r
20                 \r
21                 /// <summary>\r
22                 /// 親フォルダ\r
23                 /// </summary>\r
24                 [ReadOnly(true)]\r
25                 public string BaseFolderPath {\r
26                         get { return baseFolderPath; }\r
27                         set {\r
28                                 baseFolderPath = value;\r
29                                 BuildItems();\r
30                         }\r
31                 }\r
32                 \r
33                 /// <summary>\r
34                 /// 別スレッドからInvokeするときのオブジェクト\r
35                 /// </summary>\r
36                 public Form InvokerForm {\r
37                         get { return invokerForm; }\r
38                         set { invokerForm = value; }\r
39                 }\r
40                 \r
41                 /// <summary>\r
42                 /// ドロップアイテムの(再)生成を行う\r
43                 /// </summary>\r
44                 public void BuildItems()\r
45                 {\r
46                         if (thread != null) {\r
47                                 if (! thread.Join(1000)) {\r
48                                         thread.Interrupt();\r
49                                 }\r
50                                 thread = null;\r
51                         }\r
52                         \r
53                         try {\r
54                                 DropDownItems.Clear();\r
55                         } catch (NullReferenceException) {\r
56                         }\r
57                         if (Directory.Exists(baseFolderPath)) {\r
58                                 thread = new Thread(new ThreadStart(buildItems));\r
59                                 thread.Start();\r
60                         }\r
61                 }\r
62                 \r
63                 #region スレッド処理\r
64                 \r
65                 private delegate int ToolStripItemCollection_AddDelegate(ToolStripItem item);\r
66                 private void _addToItemsInv(ToolStripItem item)\r
67                 {\r
68                         if (InvokerForm.InvokeRequired) {\r
69                                 InvokerForm.Invoke(new ToolStripItemCollection_AddDelegate(DropDownItems.Add), item);\r
70                         } else {\r
71                                 DropDownItems.Add(item);\r
72                         }\r
73                 }\r
74                 private delegate void ToolStripItemCollection_InsertDelegate(int index, ToolStripItem item);\r
75                 private void _insertToItemsInv(int index, ToolStripItem item)\r
76                 {\r
77                         if (InvokerForm.InvokeRequired) {\r
78                                 InvokerForm.Invoke(new ToolStripItemCollection_InsertDelegate(DropDownItems.Insert), index, item);\r
79                         } else {\r
80                                 DropDownItems.Insert(index, item);\r
81                         }\r
82                 }\r
83                 \r
84                         \r
85                 private void buildItems()\r
86                 {\r
87                         try {\r
88                                 string folderPath = baseFolderPath;\r
89                                 ToolStripSeparator sep = new ToolStripSeparator();\r
90                                 bool cmdIsAdded = false;\r
91                                 \r
92                                 _addToItemsInv(CreateMenuItemForFolder(folderPath));\r
93                                 _addToItemsInv(sep);\r
94                                 \r
95                                 if (Directory.Exists(folderPath)) {\r
96                                         foreach (string exeFile in Directory.GetFiles(folderPath, "*.exe")) {\r
97                                                 if (baseFolderPath != folderPath) return; // 途中でなんか操作されているならば終了\r
98                                                 \r
99                                                 switch (NaGet.InteropServices.PEFileInfoUtils.GetPEFileType(exeFile)) {\r
100                                                         case NaGet.InteropServices.PEFileInfoUtils.PEFileType.WinGUI:\r
101                                                                 _addToItemsInv(CreateMenuItemForFile(exeFile));\r
102                                                                 break;\r
103                                                         case NaGet.InteropServices.PEFileInfoUtils.PEFileType.WinConsole:\r
104                                                                 if (! cmdIsAdded) {\r
105                                                                         _insertToItemsInv(0, CreateMenuItemForCmdAt(folderPath));\r
106                                                                         cmdIsAdded = true;\r
107                                                                 }\r
108                                                                 break;\r
109                                                 }\r
110                                         }\r
111                                 }\r
112                         } catch (ThreadInterruptedException) {}\r
113                 }\r
114                 \r
115                 #endregion\r
116                 \r
117                 /// <summary>\r
118                 /// 与えられたフォルダを開くメニューアイテムを生成する\r
119                 /// </summary>\r
120                 /// <param name="folderPath"></param>\r
121                 /// <returns></returns>\r
122                 public static ToolStripMenuItem CreateMenuItemForFolder(string folderPath)\r
123                 {\r
124                         ToolStripMenuItem item = CreateMenuItemForFile(folderPath);\r
125                         item.Text = "フォルダを開く(&O)";\r
126                         return item;\r
127                 }\r
128 \r
129                 /// <summary>\r
130                 /// 与えられたファイルのランチャーに相当するメニューアイテムを生成する\r
131                 /// </summary>\r
132                 /// <param name="filePath">ファイルパス</param>\r
133                 /// <returns>生成されたメニューアイテム</returns>\r
134                 public static ToolStripMenuItem CreateMenuItemForFile(string filePath)\r
135                 {\r
136                         ToolStripMenuItem item = new ToolStripMenuItem();\r
137                         string fileName = Path.GetFileName(filePath);\r
138                         \r
139                         item.Text = fileName;\r
140                         item.ShowShortcutKeys = false;\r
141                         item.Tag = filePath;\r
142                         item.Click += new System.EventHandler(menuItemForFileClicked);\r
143                         \r
144                         if (File.Exists(filePath)) {\r
145                                 item.Image = Icon.ExtractAssociatedIcon(filePath).ToBitmap();\r
146                                 \r
147                                 StringBuilder sb = new StringBuilder();\r
148                                 sb.AppendFormat("場所: {0}", Path.GetDirectoryName(filePath));\r
149                                 try {\r
150                                         FileVersionInfo vInfo = FileVersionInfo.GetVersionInfo(filePath);\r
151                                         \r
152                                         if (! string.IsNullOrEmpty(vInfo.FileDescription))\r
153                                                 sb.AppendFormat("\r\nファイルの説明: {0}", vInfo.FileDescription);\r
154                                         if (! string.IsNullOrEmpty(vInfo.CompanyName))\r
155                                                 sb.AppendFormat("\r\n会社: {0}", vInfo.CompanyName);\r
156                                         if (! string.IsNullOrEmpty(vInfo.FileVersion))\r
157                                                 sb.AppendFormat("\r\nファイルバージョン: {0}", vInfo.FileVersion);\r
158                                 } catch (Exception) {}\r
159                                 item.ToolTipText = sb.ToString();\r
160                         } else {\r
161                                 item.ToolTipText = filePath;\r
162                         }\r
163                         \r
164                         return item;\r
165                 }\r
166                 \r
167                 /// <summary>\r
168                 /// <see cref="CreateMenuItemForFile" />により使われるイベントハンドラ\r
169                 /// </summary>\r
170                 /// <param name="sender"></param>\r
171                 /// <param name="e"></param>\r
172                 private static void menuItemForFileClicked(object sender, EventArgs e)\r
173                 {\r
174                         ToolStripMenuItem item = (ToolStripMenuItem) sender;\r
175                         \r
176                         ProcessStartInfo procInfo = new ProcessStartInfo(item.Tag.ToString());\r
177                         procInfo.WorkingDirectory = Path.GetDirectoryName(procInfo.FileName);\r
178                         try {\r
179                                 Process.Start(procInfo);\r
180                         } catch (Win32Exception ex) {\r
181                                 MessageBox.Show(ex.Message, procInfo.FileName, MessageBoxButtons.OK, MessageBoxIcon.Error);\r
182                         }\r
183                 }\r
184                 \r
185                 /// <summary>\r
186                 /// 与えられたフォルダのところでコマンドプロンプトを開く。\r
187                 /// </summary>\r
188                 /// <param name="folderPath">カレントフォルダ及びパスに追加されるフォルダ</param>\r
189                 /// <returns>生成されたメニューアイテム</returns>\r
190                 public static ToolStripMenuItem CreateMenuItemForCmdAt(string folderPath)\r
191                 {\r
192                         string cmdPath = Environment.GetEnvironmentVariable("comspec");\r
193                         if (string.IsNullOrEmpty(cmdPath) || (!File.Exists(cmdPath)))\r
194                                 throw new FileNotFoundException(null, Environment.ExpandEnvironmentVariables("%comspec%"));\r
195                         \r
196                         ToolStripMenuItem item = new ToolStripMenuItem();\r
197                         \r
198                         item.Text = string.Format("この場所で{0}を開く(&C)", (cmdPath.EndsWith(@"\command.com"))? "MS-DOSプロンプト" : "コマンドプロンプト");\r
199                         item.Tag = folderPath;\r
200                         item.Click += new System.EventHandler(menuItemForCmdAtClicked);\r
201                         try {\r
202                                 item.Image = Icon.ExtractAssociatedIcon(cmdPath).ToBitmap();\r
203                         } catch (Exception) {}\r
204                         \r
205                         return item;\r
206                 }\r
207                 \r
208                 /// <summary>\r
209                 /// <see cref="CreateMenuItemForCmdAt" />により使われるイベントハンドラ\r
210                 /// </summary>\r
211                 /// <param name="sender"></param>\r
212                 /// <param name="e"></param>\r
213                 private static void menuItemForCmdAtClicked(object sender, EventArgs e)\r
214                 {\r
215                         ToolStripMenuItem item = (ToolStripMenuItem) sender;\r
216                         string cmdPath = Environment.GetEnvironmentVariable("comspec");\r
217                         \r
218                         ProcessStartInfo procInfo = new ProcessStartInfo(cmdPath);\r
219                         procInfo.UseShellExecute = false;\r
220                         procInfo.WorkingDirectory = item.Tag.ToString();\r
221                         procInfo.EnvironmentVariables["PATH"] = Environment.GetEnvironmentVariable("path")\r
222                                 + Path.PathSeparator + item.Tag.ToString();\r
223                         Process.Start(procInfo);\r
224                 }\r
225         }\r
226 }\r