OSDN Git Service

AppliStation-GUI,簡易ランチャーにてbinフォルダ以下も見るようにした。
[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(500)) {\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                 private void _insertItemFor(string filepath, ref bool cmdIsAdded, string basedir)\r
85                 {\r
86                         string extension = Path.GetExtension(filepath).ToLower();\r
87                         \r
88                         string dirname = Path.GetDirectoryName(filepath);\r
89                         string itemtext = NaGet.Utils.GetRelativePath(basedir, filepath);\r
90 #if DEBUG\r
91 Debug.Assert(! itemtext.Contains(".."), string.Format("{2} -- base:{0}, dirname:{1}", basedir, dirname, itemtext));\r
92 #endif\r
93                         \r
94                         if (extension == ".exe") {\r
95                                 switch (NaGet.InteropServices.PEFileInfoUtils.GetPEFileType(filepath)) {\r
96                                         case NaGet.InteropServices.PEFileInfoUtils.PEFileType.WinGUI:\r
97                                                 _addToItemsInv(CreateMenuItemForFile(filepath, itemtext));\r
98                                                 break;\r
99                                         case NaGet.InteropServices.PEFileInfoUtils.PEFileType.WinConsole:\r
100                                         case NaGet.InteropServices.PEFileInfoUtils.PEFileType.MSDosCom:\r
101                                                 if (! cmdIsAdded) {\r
102                                                         _insertToItemsInv(0, CreateMenuItemForCmdAt(basedir));\r
103                                                         cmdIsAdded = true;\r
104                                                 }\r
105                                                 break;\r
106                                 }\r
107                         } else if ((extension == ".bat") || (extension == ".lnk")) {\r
108                                 _addToItemsInv(CreateMenuItemForFile(filepath, itemtext));\r
109                         }\r
110                 }\r
111                 \r
112                         \r
113                 private void buildItems()\r
114                 {\r
115                         try {\r
116                                 string folderPath = Path.GetFullPath(baseFolderPath);\r
117                                 ToolStripSeparator sep = new ToolStripSeparator();\r
118                                 bool cmdIsAdded = false;\r
119                                 \r
120                                 _addToItemsInv(CreateMenuItemForFolder(folderPath));\r
121                                 _addToItemsInv(sep);\r
122                                 \r
123                                 if (Directory.Exists(folderPath)) {                                     \r
124                                         foreach (string filepath in Directory.GetFiles(folderPath)) {\r
125                                                 if (baseFolderPath != folderPath) return; // 途中でなんか操作されているならば終了\r
126                                                 \r
127                                                 _insertItemFor(filepath, ref cmdIsAdded, folderPath);\r
128                                         }\r
129                                         \r
130                                         string bindir = Path.Combine(folderPath, "bin");\r
131                                         if (Directory.Exists(bindir)) {\r
132                                                 foreach (string filepath in Directory.GetFiles(bindir)) {\r
133                                                         if (baseFolderPath != folderPath) return; // 途中でなんか操作されているならば終了\r
134                                                         \r
135                                                         _insertItemFor(filepath, ref cmdIsAdded, folderPath);\r
136                                                 }\r
137                                         }\r
138                                 }\r
139                         } catch (ThreadInterruptedException) {}\r
140                 }\r
141                 \r
142                 #endregion\r
143                 \r
144                 /// <summary>\r
145                 /// 与えられたフォルダを開くメニューアイテムを生成する\r
146                 /// </summary>\r
147                 /// <param name="folderPath"></param>\r
148                 /// <returns></returns>\r
149                 public static ToolStripMenuItem CreateMenuItemForFolder(string folderPath)\r
150                 {\r
151                         ToolStripMenuItem item = CreateMenuItemForFile(folderPath, "フォルダを開く(&O)");\r
152                         item.Image = GUIUtils.GetShellIconForFolder().ToBitmap();\r
153                         item.ShowShortcutKeys = true;\r
154                         return item;\r
155                 }\r
156 \r
157                 /// <summary>\r
158                 /// 与えられたファイルのランチャーに相当するメニューアイテムを生成する\r
159                 /// </summary>\r
160                 /// <param name="filePath">ファイルパス</param>\r
161                 /// <returns>生成されたメニューアイテム</returns>\r
162                 public static ToolStripMenuItem CreateMenuItemForFile(string filePath, string text)\r
163                 {\r
164                         ToolStripMenuItem item = new ToolStripMenuItem();\r
165                         \r
166                         item.Text = text;\r
167                         item.ShowShortcutKeys = false;\r
168                         item.Tag = filePath;\r
169                         item.Click += new System.EventHandler(menuItemForFileClicked);\r
170                         \r
171                         if (File.Exists(filePath)) {\r
172                                 item.Image = Icon.ExtractAssociatedIcon(filePath).ToBitmap();\r
173                                 \r
174                                 StringBuilder sb = new StringBuilder();\r
175                                 sb.AppendFormat("場所: {0}", Path.GetDirectoryName(filePath));\r
176                                 try {\r
177                                         FileVersionInfo vInfo = FileVersionInfo.GetVersionInfo(filePath);\r
178                                         \r
179                                         if (! string.IsNullOrEmpty(vInfo.FileDescription))\r
180                                                 sb.AppendFormat("\r\nファイルの説明: {0}", vInfo.FileDescription);\r
181                                         if (! string.IsNullOrEmpty(vInfo.CompanyName))\r
182                                                 sb.AppendFormat("\r\n会社: {0}", vInfo.CompanyName);\r
183                                         if (! string.IsNullOrEmpty(vInfo.FileVersion))\r
184                                                 sb.AppendFormat("\r\nファイルバージョン: {0}", vInfo.FileVersion);\r
185                                 } catch (Exception) {}\r
186                                 item.ToolTipText = sb.ToString();\r
187                         } else {\r
188                                 item.ToolTipText = filePath;\r
189                         }\r
190                         \r
191                         return item;\r
192                 }\r
193                 \r
194                 /// <summary>\r
195                 /// <see cref="CreateMenuItemForFile" />により使われるイベントハンドラ\r
196                 /// </summary>\r
197                 /// <param name="sender"></param>\r
198                 /// <param name="e"></param>\r
199                 private static void menuItemForFileClicked(object sender, EventArgs e)\r
200                 {\r
201                         ToolStripMenuItem item = (ToolStripMenuItem) sender;\r
202                         \r
203                         ProcessStartInfo procInfo = new ProcessStartInfo(item.Tag.ToString());\r
204                         procInfo.WorkingDirectory = Path.GetDirectoryName(procInfo.FileName);\r
205                         try {\r
206                                 Process.Start(procInfo);\r
207                         } catch (Win32Exception ex) {\r
208                                 MessageBox.Show(ex.Message, procInfo.FileName, MessageBoxButtons.OK, MessageBoxIcon.Error);\r
209                         }\r
210                 }\r
211                 \r
212                 /// <summary>\r
213                 /// 与えられたフォルダのところでコマンドプロンプトを開く。\r
214                 /// </summary>\r
215                 /// <param name="folderPath">カレントフォルダ及びパスに追加されるフォルダ</param>\r
216                 /// <returns>生成されたメニューアイテム</returns>\r
217                 public static ToolStripMenuItem CreateMenuItemForCmdAt(string folderPath)\r
218                 {\r
219                         string cmdPath = Environment.GetEnvironmentVariable("comspec");\r
220                         if (string.IsNullOrEmpty(cmdPath) || (!File.Exists(cmdPath)))\r
221                                 throw new FileNotFoundException(null, Environment.ExpandEnvironmentVariables("%comspec%"));\r
222                         \r
223                         ToolStripMenuItem item = new ToolStripMenuItem();\r
224                         \r
225                         item.Text = string.Format("この場所で{0}を開く(&C)", (cmdPath.EndsWith(@"\command.com"))? "MS-DOSプロンプト" : "コマンドプロンプト");\r
226                         item.Tag = folderPath;\r
227                         item.Click += new System.EventHandler(menuItemForCmdAtClicked);\r
228                         try {\r
229                                 item.Image = Icon.ExtractAssociatedIcon(cmdPath).ToBitmap();\r
230                         } catch (Exception) {}\r
231                         \r
232                         return item;\r
233                 }\r
234                 \r
235                 /// <summary>\r
236                 /// <see cref="CreateMenuItemForCmdAt" />により使われるイベントハンドラ\r
237                 /// </summary>\r
238                 /// <param name="sender"></param>\r
239                 /// <param name="e"></param>\r
240                 private static void menuItemForCmdAtClicked(object sender, EventArgs e)\r
241                 {\r
242                         ToolStripMenuItem item = (ToolStripMenuItem) sender;\r
243                         string cmdPath = Environment.GetEnvironmentVariable("comspec");\r
244                         \r
245                         ProcessStartInfo procInfo = new ProcessStartInfo(cmdPath);\r
246                         procInfo.UseShellExecute = false;\r
247                         procInfo.WorkingDirectory = item.Tag.ToString();\r
248                         procInfo.EnvironmentVariables["PATH"] = Environment.GetEnvironmentVariable("path")\r
249                                 + Path.PathSeparator + item.Tag.ToString();\r
250                         Process.Start(procInfo);\r
251                 }\r
252         }\r
253 }\r