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);
}
}
}