From: ttp Date: Sat, 23 Aug 2008 12:05:11 +0000 (+0000) Subject: AppliStation-*,「インストール先フォルダ」アイテムをマルチスレッド化してフリーズ問題解決 X-Git-Tag: v1.1.0~36 X-Git-Url: http://git.sourceforge.jp/view?p=applistation%2FAppliStation.git;a=commitdiff_plain;h=87b9ecae4c9bf16610b4ef200267f54fb386291b;ds=sidebyside AppliStation-*,「インストール先フォルダ」アイテムをマルチスレッド化してフリーズ問題解決 * ファイル数が多いところでやけに遅い件は、ファイルシーク及びNaGet.InteropServices.PEFileInfoUtils.GetPEFileTypeに時間がかかっているもよう(時間など詳細チェックせず)で、不可避とみた * そこでメニューアイテム生成部を別スレッド化してフリーズを回避。 git-svn-id: http://localhost/svn/AppliStation/trunk@951 34ed2c89-c49f-4a4b-abdb-c318350108cf --- diff --git a/AppliStation/AppliStation.Util/GUIUtils.cs b/AppliStation/AppliStation.Util/GUIUtils.cs index 4f63287..486bfa8 100644 --- a/AppliStation/AppliStation.Util/GUIUtils.cs +++ b/AppliStation/AppliStation.Util/GUIUtils.cs @@ -91,41 +91,5 @@ namespace AppliStation.Util GraphicsUnit.Pixel, ia); } - /// - /// 与えられたファイルのランチャーに相当するメニューアイテムを生成する - /// - /// ファイルパス - /// 生成されたメニューアイテム - public static System.Windows.Forms.ToolStripMenuItem CreateMenuItemForFile(string filePath) - { - System.Windows.Forms.ToolStripMenuItem item = new System.Windows.Forms.ToolStripMenuItem(); - string fileName = Path.GetFileName(filePath); - - item.Text = fileName; - item.ShowShortcutKeys = false; - item.Tag = filePath; - item.ToolTipText = string.Format("場所: {0}", filePath); - item.Click += new System.EventHandler(GUIUtils.menuItemForFileClicked); - try { - item.Image = Icon.ExtractAssociatedIcon(filePath).ToBitmap(); - } catch (Exception) {} - - return item; - } - - /// - /// により使われるイベントハンドラ - /// - /// - /// - private static void menuItemForFileClicked(object sender, EventArgs e) - { - System.Windows.Forms.ToolStripMenuItem item = (System.Windows.Forms.ToolStripMenuItem) sender; - - System.Diagnostics.ProcessStartInfo procInfo = new System.Diagnostics.ProcessStartInfo(item.Tag.ToString()); - procInfo.WorkingDirectory = Path.GetDirectoryName(procInfo.FileName); - System.Diagnostics.Process.Start(procInfo); - } - } } diff --git a/AppliStation/AppliStation.Util/PetitLauncherMenuItemCreator.cs b/AppliStation/AppliStation.Util/PetitLauncherMenuItemCreator.cs new file mode 100644 index 0000000..07c6451 --- /dev/null +++ b/AppliStation/AppliStation.Util/PetitLauncherMenuItemCreator.cs @@ -0,0 +1,139 @@ +using System; +using System.Threading; +using System.IO; +using System.Drawing; +using System.Windows.Forms; +using System.Diagnostics; +using System.Text; + +namespace AppliStation.Util +{ + public class ToolStripPetitLauncherMenuItem : ToolStripMenuItem + { + private Thread thread; + + private string baseFolderPath; + + /// + /// 親フォルダ + /// + public string BaseFolderPath { + get { return baseFolderPath; } + set { + baseFolderPath = value; + BuildItems(); + } + } + + /// + /// ドロップアイテムの(再)生成を行う + /// + public void BuildItems() + { + if (thread != null) { + if (! thread.Join(1000)) { + thread.Interrupt(); + } + thread = null; + } + + DropDownItems.Clear(); + 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 (Parent.InvokeRequired) { + Parent.Invoke(new ToolStripItemCollection_AddDelegate(DropDownItems.Add), item); + } else { + DropDownItems.Add(item); + } + } + + private void buildItems() + { + try { + string folderPath = baseFolderPath; + ToolStripSeparator sep = new ToolStripSeparator(); + + { + ToolStripMenuItem item = CreateMenuItemForFile(folderPath); + item.Text = "フォルダを開く(&O)"; + + _addToItemsInv(item); + } + _addToItemsInv(sep); + + if (Directory.Exists(folderPath)) { + foreach (string exeFile in Directory.GetFiles(folderPath, "*.exe")) { + if (baseFolderPath != folderPath) return; // 途中でなんか操作されているならば終了 + + if (NaGet.InteropServices.PEFileInfoUtils.GetPEFileType(exeFile) == NaGet.InteropServices.PEFileInfoUtils.PEFileType.WinGUI) { + _addToItemsInv(CreateMenuItemForFile(exeFile)); + } + } + } + } catch (ThreadInterruptedException) {} + } + + #endregion + + /// + /// 与えられたファイルのランチャーに相当するメニューアイテムを生成する + /// + /// ファイルパス + /// 生成されたメニューアイテム + 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); + Process.Start(procInfo); + } + } +} diff --git a/AppliStation/AppliStation.csproj b/AppliStation/AppliStation.csproj index 319fb8f..54e7d21 100644 --- a/AppliStation/AppliStation.csproj +++ b/AppliStation/AppliStation.csproj @@ -68,6 +68,7 @@ + diff --git a/AppliStation/PackageListViewForm.Designer.cs b/AppliStation/PackageListViewForm.Designer.cs index e9eafd0..99e3873 100644 --- a/AppliStation/PackageListViewForm.Designer.cs +++ b/AppliStation/PackageListViewForm.Designer.cs @@ -58,7 +58,7 @@ this.webResourcesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.webOfficialToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.webGoogleSearchToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.installedDirectoryStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.installedDirectoryStripMenuItem = new AppliStation.Util.ToolStripPetitLauncherMenuItem(); this.propertiesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.detailBox = new System.Windows.Forms.RichTextBox(); this.tableLayoutPanel1.SuspendLayout(); @@ -387,7 +387,7 @@ this.packageListContextMenuStrip.ResumeLayout(false); this.ResumeLayout(false); } - private System.Windows.Forms.ToolStripMenuItem installedDirectoryStripMenuItem; + private AppliStation.Util.ToolStripPetitLauncherMenuItem installedDirectoryStripMenuItem; private System.Windows.Forms.ToolStripSeparator packageCommandsToolStripSeparator; private System.Windows.Forms.ToolStripMenuItem propertiesToolStripMenuItem; private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; diff --git a/AppliStation/PackageListViewForm.cs b/AppliStation/PackageListViewForm.cs index 3a8b0d2..7ff3efd 100644 --- a/AppliStation/PackageListViewForm.cs +++ b/AppliStation/PackageListViewForm.cs @@ -127,29 +127,7 @@ namespace AppliStation private void buildInstalledDirectoryMenuItemStripChildren(InstalledPackage pkg) { - string targetDir = pkg.UninstallInfo.InstallLocation; - System.Collections.Generic.List items = new System.Collections.Generic.List(); - - if (Directory.Exists(targetDir)) { - foreach (string exeFile in Directory.GetFiles(targetDir, "*.exe")) { - if (NaGet.InteropServices.PEFileInfoUtils.GetPEFileType(exeFile) == NaGet.InteropServices.PEFileInfoUtils.PEFileType.WinGUI) { - items.Add(AppliStation.Util.GUIUtils.CreateMenuItemForFile(exeFile)); - } - } - - if (items.Count > 0) { - items.Add(new ToolStripSeparator()); - } - - { - ToolStripMenuItem item = AppliStation.Util.GUIUtils.CreateMenuItemForFile(targetDir); - item.Text = "フォルダを開く(&O)"; - items.Add(item); - } - } - - installedDirectoryStripMenuItem.DropDownItems.Clear(); - installedDirectoryStripMenuItem.DropDownItems.AddRange(items.ToArray()); + installedDirectoryStripMenuItem.BaseFolderPath = pkg.UninstallInfo.InstallLocation; } #region packageListViewのSort関連