OSDN Git Service

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