OSDN Git Service

AppliStation-*,「インストール先フォルダ」アイテムをマルチスレッド化してフリーズ問題解決
authorttp <ttp@users.sourceforge.jp>
Sat, 23 Aug 2008 12:05:11 +0000 (12:05 +0000)
committerttp <ttp@users.sourceforge.jp>
Sat, 23 Aug 2008 12:05:11 +0000 (12:05 +0000)
 * ファイル数が多いところでやけに遅い件は、ファイルシーク及びNaGet.InteropServices.PEFileInfoUtils.GetPEFileTypeに時間がかかっているもよう(時間など詳細チェックせず)で、不可避とみた
 * そこでメニューアイテム生成部を別スレッド化してフリーズを回避。

git-svn-id: http://localhost/svn/AppliStation/trunk@951 34ed2c89-c49f-4a4b-abdb-c318350108cf

AppliStation/AppliStation.Util/GUIUtils.cs
AppliStation/AppliStation.Util/PetitLauncherMenuItemCreator.cs [new file with mode: 0644]
AppliStation/AppliStation.csproj
AppliStation/PackageListViewForm.Designer.cs
AppliStation/PackageListViewForm.cs

index 4f63287..486bfa8 100644 (file)
@@ -91,41 +91,5 @@ namespace AppliStation.Util
                                    GraphicsUnit.Pixel, ia);\r
                }\r
 \r
-               /// <summary>\r
-               /// 与えられたファイルのランチャーに相当するメニューアイテムを生成する\r
-               /// </summary>\r
-               /// <param name="filePath">ファイルパス</param>\r
-               /// <returns>生成されたメニューアイテム</returns>\r
-               public static System.Windows.Forms.ToolStripMenuItem CreateMenuItemForFile(string filePath)\r
-               {\r
-                       System.Windows.Forms.ToolStripMenuItem item = new System.Windows.Forms.ToolStripMenuItem();\r
-                       string fileName = Path.GetFileName(filePath);\r
-                       \r
-                       item.Text = fileName;\r
-                       item.ShowShortcutKeys = false;\r
-                       item.Tag = filePath;\r
-                       item.ToolTipText = string.Format("場所: {0}", filePath);\r
-                       item.Click += new System.EventHandler(GUIUtils.menuItemForFileClicked);\r
-                       try {\r
-                               item.Image = Icon.ExtractAssociatedIcon(filePath).ToBitmap();\r
-                       } catch (Exception) {}\r
-                       \r
-                       return item;\r
-               }\r
-               \r
-               /// <summary>\r
-               /// <see cref="CreateMenuItemForFile" />により使われるイベントハンドラ\r
-               /// </summary>\r
-               /// <param name="sender"></param>\r
-               /// <param name="e"></param>\r
-               private static void menuItemForFileClicked(object sender, EventArgs e)\r
-               {\r
-                       System.Windows.Forms.ToolStripMenuItem item = (System.Windows.Forms.ToolStripMenuItem) sender;\r
-                       \r
-                       System.Diagnostics.ProcessStartInfo procInfo = new System.Diagnostics.ProcessStartInfo(item.Tag.ToString());\r
-                       procInfo.WorkingDirectory = Path.GetDirectoryName(procInfo.FileName);\r
-                       System.Diagnostics.Process.Start(procInfo);\r
-               }\r
-       \r
        }\r
 }\r
diff --git a/AppliStation/AppliStation.Util/PetitLauncherMenuItemCreator.cs b/AppliStation/AppliStation.Util/PetitLauncherMenuItemCreator.cs
new file mode 100644 (file)
index 0000000..07c6451
--- /dev/null
@@ -0,0 +1,139 @@
+using System;\r
+using System.Threading;\r
+using System.IO;\r
+using System.Drawing;\r
+using System.Windows.Forms;\r
+using System.Diagnostics;\r
+using System.Text;\r
+\r
+namespace AppliStation.Util\r
+{\r
+       public class ToolStripPetitLauncherMenuItem : ToolStripMenuItem\r
+       {\r
+               private Thread thread;\r
+               \r
+               private string baseFolderPath;\r
+               \r
+               /// <summary>\r
+               /// 親フォルダ\r
+               /// </summary>\r
+               public string BaseFolderPath {\r
+                       get { return baseFolderPath; }\r
+                       set {\r
+                               baseFolderPath = value;\r
+                               BuildItems();\r
+                       }\r
+               }\r
+               \r
+               /// <summary>\r
+               /// ドロップアイテムの(再)生成を行う\r
+               /// </summary>\r
+               public void BuildItems()\r
+               {\r
+                       if (thread != null) {\r
+                               if (! thread.Join(1000)) {\r
+                                       thread.Interrupt();\r
+                               }\r
+                               thread = null;\r
+                       }\r
+                       \r
+                       DropDownItems.Clear();\r
+                       if (Directory.Exists(baseFolderPath)) {\r
+                               thread = new Thread(new ThreadStart(buildItems));\r
+                               thread.Start();\r
+                       }\r
+               }\r
+               \r
+               #region スレッド処理\r
+               \r
+               private delegate int ToolStripItemCollection_AddDelegate(ToolStripItem item);\r
+               private void _addToItemsInv(ToolStripItem item)\r
+               {\r
+                       if (Parent.InvokeRequired) {\r
+                               Parent.Invoke(new ToolStripItemCollection_AddDelegate(DropDownItems.Add), item);\r
+                       } else {\r
+                               DropDownItems.Add(item);\r
+                       }\r
+               }\r
+                       \r
+               private void buildItems()\r
+               {\r
+                       try {\r
+                               string folderPath = baseFolderPath;\r
+                               ToolStripSeparator sep = new ToolStripSeparator();\r
+                               \r
+                               {\r
+                                       ToolStripMenuItem item = CreateMenuItemForFile(folderPath);\r
+                                       item.Text = "フォルダを開く(&O)";\r
+                                       \r
+                                       _addToItemsInv(item);\r
+                               }\r
+                               _addToItemsInv(sep);\r
+                               \r
+                               if (Directory.Exists(folderPath)) {\r
+                                       foreach (string exeFile in Directory.GetFiles(folderPath, "*.exe")) {\r
+                                               if (baseFolderPath != folderPath) return; // 途中でなんか操作されているならば終了\r
+                                               \r
+                                               if (NaGet.InteropServices.PEFileInfoUtils.GetPEFileType(exeFile) == NaGet.InteropServices.PEFileInfoUtils.PEFileType.WinGUI) {\r
+                                                       _addToItemsInv(CreateMenuItemForFile(exeFile));\r
+                                               }\r
+                                       }\r
+                               }\r
+                       } catch (ThreadInterruptedException) {}\r
+               }\r
+               \r
+               #endregion\r
+\r
+               /// <summary>\r
+               /// 与えられたファイルのランチャーに相当するメニューアイテムを生成する\r
+               /// </summary>\r
+               /// <param name="filePath">ファイルパス</param>\r
+               /// <returns>生成されたメニューアイテム</returns>\r
+               public static ToolStripMenuItem CreateMenuItemForFile(string filePath)\r
+               {\r
+                       ToolStripMenuItem item = new ToolStripMenuItem();\r
+                       string fileName = Path.GetFileName(filePath);\r
+                       \r
+                       item.Text = fileName;\r
+                       item.ShowShortcutKeys = false;\r
+                       item.Tag = filePath;\r
+                       item.Click += new System.EventHandler(menuItemForFileClicked);\r
+                       \r
+                       if (File.Exists(filePath)) {\r
+                               item.Image = Icon.ExtractAssociatedIcon(filePath).ToBitmap();\r
+                               \r
+                               StringBuilder sb = new StringBuilder();\r
+                               sb.AppendFormat("場所: {0}", Path.GetDirectoryName(filePath));\r
+                               try {\r
+                                       FileVersionInfo vInfo = FileVersionInfo.GetVersionInfo(filePath);\r
+                                       \r
+                                       if (! string.IsNullOrEmpty(vInfo.FileDescription))\r
+                                               sb.AppendFormat("\r\nファイルの説明: {0}", vInfo.FileDescription);\r
+                                       if (! string.IsNullOrEmpty(vInfo.CompanyName))\r
+                                               sb.AppendFormat("\r\n会社: {0}", vInfo.CompanyName);\r
+                                       if (! string.IsNullOrEmpty(vInfo.FileVersion))\r
+                                               sb.AppendFormat("\r\nファイルバージョン: {0}", vInfo.FileVersion);\r
+                               } catch (Exception) {}\r
+                               item.ToolTipText = sb.ToString();\r
+                       } else {\r
+                               item.ToolTipText = filePath;\r
+                       }\r
+                       \r
+                       return item;\r
+               }\r
+               \r
+               /// <summary>\r
+               /// <see cref="CreateMenuItemForFile" />により使われるイベントハンドラ\r
+               /// </summary>\r
+               /// <param name="sender"></param>\r
+               /// <param name="e"></param>\r
+               private static void menuItemForFileClicked(object sender, EventArgs e)\r
+               {\r
+                       ToolStripMenuItem item = (ToolStripMenuItem) sender;\r
+                       \r
+                       ProcessStartInfo procInfo = new ProcessStartInfo(item.Tag.ToString());\r
+                       procInfo.WorkingDirectory = Path.GetDirectoryName(procInfo.FileName);\r
+                       Process.Start(procInfo);\r
+               }\r
+       }\r
+}\r
index 319fb8f..54e7d21 100644 (file)
@@ -68,6 +68,7 @@
     <Compile Include="AppliStation.Util\ListViewItemSortComparer.cs" />\r
     <Compile Include="AppliStation.Util\NativeMethods.cs" />\r
     <Compile Include="AppliStation.Util\GUIUtils.cs" />\r
+    <Compile Include="AppliStation.Util\PetitLauncherMenuItemCreator.cs" />\r
     <Compile Include="AppliStation.Util\ToolStripWeb2LikeTextBox.cs" />\r
     <Compile Include="AssemblyInfo.cs" />\r
     <Compile Include="InstallerInfoForm.cs" />\r
index e9eafd0..99e3873 100644 (file)
@@ -58,7 +58,7 @@
                        this.webResourcesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\r
                        this.webOfficialToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\r
                        this.webGoogleSearchToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\r
-                       this.installedDirectoryStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\r
+                       this.installedDirectoryStripMenuItem = new AppliStation.Util.ToolStripPetitLauncherMenuItem();\r
                        this.propertiesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\r
                        this.detailBox = new System.Windows.Forms.RichTextBox();\r
                        this.tableLayoutPanel1.SuspendLayout();\r
                        this.packageListContextMenuStrip.ResumeLayout(false);\r
                        this.ResumeLayout(false);\r
                }\r
-               private System.Windows.Forms.ToolStripMenuItem installedDirectoryStripMenuItem;\r
+               private AppliStation.Util.ToolStripPetitLauncherMenuItem installedDirectoryStripMenuItem;\r
                private System.Windows.Forms.ToolStripSeparator packageCommandsToolStripSeparator;\r
                private System.Windows.Forms.ToolStripMenuItem propertiesToolStripMenuItem;\r
                private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;\r
index 3a8b0d2..7ff3efd 100644 (file)
@@ -127,29 +127,7 @@ namespace AppliStation
                \r
                private void buildInstalledDirectoryMenuItemStripChildren(InstalledPackage pkg)\r
                {\r
-                       string targetDir = pkg.UninstallInfo.InstallLocation;                   \r
-                       System.Collections.Generic.List<ToolStripItem> items = new System.Collections.Generic.List<ToolStripItem>();\r
-                       \r
-                       if (Directory.Exists(targetDir)) {\r
-                               foreach (string exeFile in Directory.GetFiles(targetDir, "*.exe")) {\r
-                                       if (NaGet.InteropServices.PEFileInfoUtils.GetPEFileType(exeFile) == NaGet.InteropServices.PEFileInfoUtils.PEFileType.WinGUI) {\r
-                                               items.Add(AppliStation.Util.GUIUtils.CreateMenuItemForFile(exeFile));\r
-                                       }\r
-                               }\r
-                               \r
-                               if (items.Count > 0) {\r
-                                       items.Add(new ToolStripSeparator());\r
-                               }\r
-                               \r
-                               {\r
-                                       ToolStripMenuItem item = AppliStation.Util.GUIUtils.CreateMenuItemForFile(targetDir);\r
-                                       item.Text = "フォルダを開く(&O)";\r
-                                       items.Add(item);\r
-                               }\r
-                       }\r
-                       \r
-                       installedDirectoryStripMenuItem.DropDownItems.Clear();\r
-                       installedDirectoryStripMenuItem.DropDownItems.AddRange(items.ToArray());\r
+                       installedDirectoryStripMenuItem.BaseFolderPath = pkg.UninstallInfo.InstallLocation;\r
                }\r
                \r
                #region packageListViewのSort関連\r