using System; using System.Threading; using System.IO; using System.Drawing; using System.Windows.Forms; using System.Diagnostics; using System.Text; using System.ComponentModel; namespace AppliStation.Util { public class ToolStripPetitLauncherMenuItem : ToolStripMenuItem { private Thread thread; private string baseFolderPath; private Form invokerForm; /// /// 親フォルダ /// [ReadOnly(true)] public string BaseFolderPath { get { return baseFolderPath; } set { baseFolderPath = value; BuildItems(); } } /// /// 別スレッドからInvokeするときのオブジェクト /// public Form InvokerForm { get { return invokerForm; } set { invokerForm = value; } } /// /// ドロップアイテムの(再)生成を行う /// public void BuildItems() { if (thread != null) { if (! thread.Join(500)) { thread.Interrupt(); } thread = null; } try { DropDownItems.Clear(); } catch (NullReferenceException) { } if (Directory.Exists(baseFolderPath)) { thread = new Thread(new ThreadStart(buildItems)); thread.Start(); } } #region スレッド処理 private delegate int ToolStripItemCollection_AddDelegate(ToolStripItem item); private void _addToItemsInv(ToolStripItem item) { if (InvokerForm.InvokeRequired) { InvokerForm.Invoke(new ToolStripItemCollection_AddDelegate(DropDownItems.Add), item); } else { DropDownItems.Add(item); } } private delegate void ToolStripItemCollection_InsertDelegate(int index, ToolStripItem item); private void _insertToItemsInv(int index, ToolStripItem item) { if (InvokerForm.InvokeRequired) { InvokerForm.Invoke(new ToolStripItemCollection_InsertDelegate(DropDownItems.Insert), index, item); } else { DropDownItems.Insert(index, item); } } private void _insertItemFor(string filepath, ref bool cmdIsAdded) { string extension = Path.GetExtension(filepath).ToLower(); if (extension == ".exe") { switch (NaGet.InteropServices.PEFileInfoUtils.GetPEFileType(filepath)) { case NaGet.InteropServices.PEFileInfoUtils.PEFileType.WinGUI: _addToItemsInv(CreateMenuItemForFile(filepath)); break; case NaGet.InteropServices.PEFileInfoUtils.PEFileType.WinConsole: case NaGet.InteropServices.PEFileInfoUtils.PEFileType.MSDosCom: if (! cmdIsAdded) { _insertToItemsInv(0, CreateMenuItemForCmdAt(Path.GetDirectoryName(filepath))); cmdIsAdded = true; } break; } } else if ((extension == ".bat") || (extension == ".lnk")) { _addToItemsInv(CreateMenuItemForFile(filepath)); } } private void buildItems() { try { string folderPath = baseFolderPath; ToolStripSeparator sep = new ToolStripSeparator(); bool cmdIsAdded = false; _addToItemsInv(CreateMenuItemForFolder(folderPath)); _addToItemsInv(sep); if (Directory.Exists(folderPath)) { foreach (string filepath in Directory.GetFiles(folderPath)) { if (baseFolderPath != folderPath) return; // 途中でなんか操作されているならば終了 _insertItemFor(filepath, ref cmdIsAdded); } } } catch (ThreadInterruptedException) {} } #endregion /// /// 与えられたフォルダを開くメニューアイテムを生成する /// /// /// public static ToolStripMenuItem CreateMenuItemForFolder(string folderPath) { ToolStripMenuItem item = CreateMenuItemForFile(folderPath); item.Image = GUIUtils.GetShellIconForFolder().ToBitmap(); item.Text = "フォルダを開く(&O)"; return item; } /// /// 与えられたファイルのランチャーに相当するメニューアイテムを生成する /// /// ファイルパス /// 生成されたメニューアイテム public static ToolStripMenuItem CreateMenuItemForFile(string filePath) { ToolStripMenuItem item = new ToolStripMenuItem(); string fileName = Path.GetFileName(filePath); item.Text = fileName; item.ShowShortcutKeys = false; item.Tag = filePath; item.Click += new System.EventHandler(menuItemForFileClicked); if (File.Exists(filePath)) { item.Image = Icon.ExtractAssociatedIcon(filePath).ToBitmap(); StringBuilder sb = new StringBuilder(); sb.AppendFormat("場所: {0}", Path.GetDirectoryName(filePath)); try { FileVersionInfo vInfo = FileVersionInfo.GetVersionInfo(filePath); if (! string.IsNullOrEmpty(vInfo.FileDescription)) sb.AppendFormat("\r\nファイルの説明: {0}", vInfo.FileDescription); if (! string.IsNullOrEmpty(vInfo.CompanyName)) sb.AppendFormat("\r\n会社: {0}", vInfo.CompanyName); if (! string.IsNullOrEmpty(vInfo.FileVersion)) sb.AppendFormat("\r\nファイルバージョン: {0}", vInfo.FileVersion); } catch (Exception) {} item.ToolTipText = sb.ToString(); } else { item.ToolTipText = filePath; } return item; } /// /// により使われるイベントハンドラ /// /// /// private static void menuItemForFileClicked(object sender, EventArgs e) { ToolStripMenuItem item = (ToolStripMenuItem) sender; ProcessStartInfo procInfo = new ProcessStartInfo(item.Tag.ToString()); procInfo.WorkingDirectory = Path.GetDirectoryName(procInfo.FileName); try { Process.Start(procInfo); } catch (Win32Exception ex) { MessageBox.Show(ex.Message, procInfo.FileName, MessageBoxButtons.OK, MessageBoxIcon.Error); } } /// /// 与えられたフォルダのところでコマンドプロンプトを開く。 /// /// カレントフォルダ及びパスに追加されるフォルダ /// 生成されたメニューアイテム public static ToolStripMenuItem CreateMenuItemForCmdAt(string folderPath) { string cmdPath = Environment.GetEnvironmentVariable("comspec"); if (string.IsNullOrEmpty(cmdPath) || (!File.Exists(cmdPath))) throw new FileNotFoundException(null, Environment.ExpandEnvironmentVariables("%comspec%")); ToolStripMenuItem item = new ToolStripMenuItem(); item.Text = string.Format("この場所で{0}を開く(&C)", (cmdPath.EndsWith(@"\command.com"))? "MS-DOSプロンプト" : "コマンドプロンプト"); item.Tag = folderPath; item.Click += new System.EventHandler(menuItemForCmdAtClicked); try { item.Image = Icon.ExtractAssociatedIcon(cmdPath).ToBitmap(); } catch (Exception) {} return item; } /// /// により使われるイベントハンドラ /// /// /// private static void menuItemForCmdAtClicked(object sender, EventArgs e) { ToolStripMenuItem item = (ToolStripMenuItem) sender; string cmdPath = Environment.GetEnvironmentVariable("comspec"); ProcessStartInfo procInfo = new ProcessStartInfo(cmdPath); procInfo.UseShellExecute = false; procInfo.WorkingDirectory = item.Tag.ToString(); procInfo.EnvironmentVariables["PATH"] = Environment.GetEnvironmentVariable("path") + Path.PathSeparator + item.Tag.ToString(); Process.Start(procInfo); } } }