OSDN Git Service

159fa27ab933d43ad26475df15ae1978ee5db16a
[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                         DropDownItems.Clear();\r
54                         if (Directory.Exists(baseFolderPath)) {\r
55                                 thread = new Thread(new ThreadStart(buildItems));\r
56                                 thread.Start();\r
57                         }\r
58                 }\r
59                 \r
60                 #region スレッド処理\r
61                 \r
62                 private delegate int ToolStripItemCollection_AddDelegate(ToolStripItem item);\r
63                 private void _addToItemsInv(ToolStripItem item)\r
64                 {\r
65                         if (InvokerForm.InvokeRequired) {\r
66                                 InvokerForm.Invoke(new ToolStripItemCollection_AddDelegate(DropDownItems.Add), item);\r
67                         } else {\r
68                                 DropDownItems.Add(item);\r
69                         }\r
70                 }\r
71                 private delegate void ToolStripItemCollection_InsertDelegate(int index, ToolStripItem item);\r
72                 private void _insertToItemsInv(int index, ToolStripItem item)\r
73                 {\r
74                         if (InvokerForm.InvokeRequired) {\r
75                                 InvokerForm.Invoke(new ToolStripItemCollection_InsertDelegate(DropDownItems.Insert), index, item);\r
76                         } else {\r
77                                 DropDownItems.Insert(index, item);\r
78                         }\r
79                 }\r
80                 \r
81                         \r
82                 private void buildItems()\r
83                 {\r
84                         try {\r
85                                 string folderPath = baseFolderPath;\r
86                                 ToolStripSeparator sep = new ToolStripSeparator();\r
87                                 bool cmdIsAdded = false;\r
88                                 \r
89                                 _addToItemsInv(CreateMenuItemForFolder(folderPath));\r
90                                 _addToItemsInv(sep);\r
91                                 \r
92                                 if (Directory.Exists(folderPath)) {\r
93                                         foreach (string exeFile in Directory.GetFiles(folderPath, "*.exe")) {\r
94                                                 if (baseFolderPath != folderPath) return; // 途中でなんか操作されているならば終了\r
95                                                 \r
96                                                 switch (NaGet.InteropServices.PEFileInfoUtils.GetPEFileType(exeFile)) {\r
97                                                         case NaGet.InteropServices.PEFileInfoUtils.PEFileType.WinGUI:\r
98                                                                 _addToItemsInv(CreateMenuItemForFile(exeFile));\r
99                                                                 break;\r
100                                                         case NaGet.InteropServices.PEFileInfoUtils.PEFileType.WinConsole:\r
101                                                                 if (! cmdIsAdded) {\r
102                                                                         _insertToItemsInv(0, CreateMenuItemForCmdAt(folderPath));\r
103                                                                         cmdIsAdded = true;\r
104                                                                 }\r
105                                                                 break;\r
106                                                 }\r
107                                         }\r
108                                 }\r
109                         } catch (ThreadInterruptedException) {}\r
110                 }\r
111                 \r
112                 #endregion\r
113                 \r
114                 /// <summary>\r
115                 /// 与えられたフォルダを開くメニューアイテムを生成する\r
116                 /// </summary>\r
117                 /// <param name="folderPath"></param>\r
118                 /// <returns></returns>\r
119                 public static ToolStripMenuItem CreateMenuItemForFolder(string folderPath)\r
120                 {\r
121                         ToolStripMenuItem item = CreateMenuItemForFile(folderPath);\r
122                         item.Text = "フォルダを開く(&O)";\r
123                         return item;\r
124                 }\r
125 \r
126                 /// <summary>\r
127                 /// 与えられたファイルのランチャーに相当するメニューアイテムを生成する\r
128                 /// </summary>\r
129                 /// <param name="filePath">ファイルパス</param>\r
130                 /// <returns>生成されたメニューアイテム</returns>\r
131                 public static ToolStripMenuItem CreateMenuItemForFile(string filePath)\r
132                 {\r
133                         ToolStripMenuItem item = new ToolStripMenuItem();\r
134                         string fileName = Path.GetFileName(filePath);\r
135                         \r
136                         item.Text = fileName;\r
137                         item.ShowShortcutKeys = false;\r
138                         item.Tag = filePath;\r
139                         item.Click += new System.EventHandler(menuItemForFileClicked);\r
140                         \r
141                         if (File.Exists(filePath)) {\r
142                                 item.Image = Icon.ExtractAssociatedIcon(filePath).ToBitmap();\r
143                                 \r
144                                 StringBuilder sb = new StringBuilder();\r
145                                 sb.AppendFormat("場所: {0}", Path.GetDirectoryName(filePath));\r
146                                 try {\r
147                                         FileVersionInfo vInfo = FileVersionInfo.GetVersionInfo(filePath);\r
148                                         \r
149                                         if (! string.IsNullOrEmpty(vInfo.FileDescription))\r
150                                                 sb.AppendFormat("\r\nファイルの説明: {0}", vInfo.FileDescription);\r
151                                         if (! string.IsNullOrEmpty(vInfo.CompanyName))\r
152                                                 sb.AppendFormat("\r\n会社: {0}", vInfo.CompanyName);\r
153                                         if (! string.IsNullOrEmpty(vInfo.FileVersion))\r
154                                                 sb.AppendFormat("\r\nファイルバージョン: {0}", vInfo.FileVersion);\r
155                                 } catch (Exception) {}\r
156                                 item.ToolTipText = sb.ToString();\r
157                         } else {\r
158                                 item.ToolTipText = filePath;\r
159                         }\r
160                         \r
161                         return item;\r
162                 }\r
163                 \r
164                 /// <summary>\r
165                 /// <see cref="CreateMenuItemForFile" />により使われるイベントハンドラ\r
166                 /// </summary>\r
167                 /// <param name="sender"></param>\r
168                 /// <param name="e"></param>\r
169                 private static void menuItemForFileClicked(object sender, EventArgs e)\r
170                 {\r
171                         ToolStripMenuItem item = (ToolStripMenuItem) sender;\r
172                         \r
173                         ProcessStartInfo procInfo = new ProcessStartInfo(item.Tag.ToString());\r
174                         procInfo.WorkingDirectory = Path.GetDirectoryName(procInfo.FileName);\r
175                         Process.Start(procInfo);\r
176                 }\r
177                 \r
178                 /// <summary>\r
179                 /// 与えられたフォルダのところでコマンドプロンプトを開く。\r
180                 /// </summary>\r
181                 /// <param name="folderPath">カレントフォルダ及びパスに追加されるフォルダ</param>\r
182                 /// <returns>生成されたメニューアイテム</returns>\r
183                 public static ToolStripMenuItem CreateMenuItemForCmdAt(string folderPath)\r
184                 {\r
185                         string cmdPath = Environment.GetEnvironmentVariable("comspec");\r
186                         if (string.IsNullOrEmpty(cmdPath) || (!File.Exists(cmdPath)))\r
187                                 throw new FileNotFoundException(null, Environment.ExpandEnvironmentVariables("%comspec%"));\r
188                         \r
189                         ToolStripMenuItem item = new ToolStripMenuItem();\r
190                         \r
191                         item.Text = string.Format("この場所で{0}を開く(&C)", (cmdPath.EndsWith(@"\command.com"))? "MS-DOSプロンプト" : "コマンドプロンプト");\r
192                         item.Tag = folderPath;\r
193                         item.Click += new System.EventHandler(menuItemForCmdAtClicked);\r
194                         try {\r
195                                 item.Image = Icon.ExtractAssociatedIcon(cmdPath).ToBitmap();\r
196                         } catch (Exception) {}\r
197                         \r
198                         return item;\r
199                 }\r
200                 \r
201                 /// <summary>\r
202                 /// <see cref="CreateMenuItemForCmdAt" />により使われるイベントハンドラ\r
203                 /// </summary>\r
204                 /// <param name="sender"></param>\r
205                 /// <param name="e"></param>\r
206                 private static void menuItemForCmdAtClicked(object sender, EventArgs e)\r
207                 {\r
208                         ToolStripMenuItem item = (ToolStripMenuItem) sender;\r
209                         string cmdPath = Environment.GetEnvironmentVariable("comspec");\r
210                         \r
211                         ProcessStartInfo procInfo = new ProcessStartInfo(cmdPath);\r
212                         procInfo.UseShellExecute = false;\r
213                         procInfo.WorkingDirectory = item.Tag.ToString();\r
214                         procInfo.EnvironmentVariables["PATH"] = Environment.GetEnvironmentVariable("path")\r
215                                 + Path.PathSeparator + item.Tag.ToString();\r
216                         Process.Start(procInfo);\r
217                 }\r
218         }\r
219 }\r