From d77e489a312afb2db4612269f7275c6ac1fd17cc Mon Sep 17 00:00:00 2001 From: ttp Date: Tue, 26 Feb 2008 07:18:36 +0000 Subject: [PATCH 1/1] initial build for opensource git-svn-id: http://localhost/svn/AppliStation/trunk@848 34ed2c89-c49f-4a4b-abdb-c318350108cf --- AppliStation.proj | 42 ++ AppliStation.sln | 44 ++ .../ExceptionDialogForm.Designer.cs | 164 ++++++ .../AppliStation.Util/ExceptionDialogForm.cs | 60 ++ .../AppliStation.Util/ExceptionDialogForm.resx | 120 ++++ .../ExecutionProgressViewer.Designer.cs | 200 +++++++ .../AppliStation.Util/ExecutionProgressViewer.cs | 206 +++++++ .../AppliStation.Util/ExecutionProgressViewer.resx | 120 ++++ .../AppliStation.Util/ListViewItemSortComparer.cs | 43 ++ AppliStation/AppliStation.Util/NativeMethods.cs | 166 ++++++ AppliStation/AppliStation.csproj | 110 ++++ AppliStation/ArgParse.cs | 118 ++++ AppliStation/AssemblyInfo.cs | 31 + AppliStation/PackageListViewForm.Designer.cs | 406 +++++++++++++ AppliStation/PackageListViewForm.cs | 634 +++++++++++++++++++++ AppliStation/PackageListViewForm.resx | 358 ++++++++++++ .../PackageUninstallConfirmForm.Designer.cs | 180 ++++++ AppliStation/PackageUninstallConfirmForm.cs | 98 ++++ AppliStation/PackageUninstallConfirmForm.resx | 139 +++++ .../PackagesInstallConfirmForm.Designer.cs | 221 +++++++ AppliStation/PackagesInstallConfirmForm.cs | 212 +++++++ AppliStation/PackagesInstallConfirmForm.resx | 142 +++++ AppliStation/Program.cs | 140 +++++ AppliStation/SplashScreen.png | Bin 0 -> 7884 bytes all-get/AssemblyInfo.cs | 31 + all-get/Main.cs | 527 +++++++++++++++++ all-get/Util.cs | 24 + all-get/all-get.csproj | 54 ++ archive-inst/AssemblyInfo.cs | 31 + archive-inst/InstalledFileList.cs | 70 +++ archive-inst/MSBuild.cs | 26 + archive-inst/Program.cs | 329 +++++++++++ archive-inst/archive-inst.csproj | 58 ++ build.bat | 3 + na-get-lib/AssemblyInfo.cs | 32 ++ .../CommonArchiverExtracter.cs | 186 ++++++ .../NaGet.InteropServices/CreateProcessCaller.cs | 131 +++++ na-get-lib/NaGet.InteropServices/DllAccess.cs | 80 +++ .../NaGet.InteropServices/PEFileInfoUtils.cs | 142 +++++ na-get-lib/NaGet.InteropServices/ShellLink.cs | 280 +++++++++ na-get-lib/NaGet.Net/Downloader.cs | 323 +++++++++++ na-get-lib/NaGet.Packages.Install/Installation.cs | 410 +++++++++++++ .../NaGet.Packages.Install/InstallationLog.cs | 10 + .../NaGet.Packages.Install/InstalledPackage.cs | 48 ++ .../RegistriedUninstallers.cs | 123 ++++ .../NaGet.Packages.Install/UninstallInformation.cs | 227 ++++++++ .../NaGet.Packages.Install/Uninstallation.cs | 113 ++++ na-get-lib/NaGet.Packages/HashValue.cs | 96 ++++ na-get-lib/NaGet.Packages/Package.cs | 199 +++++++ na-get-lib/NaGet.Packages/PackageList.cs | 162 ++++++ na-get-lib/NaGet.Packages/PackageListsManager.cs | 187 ++++++ na-get-lib/NaGet.Packages/Platform.cs | 183 ++++++ na-get-lib/NaGet.Packages/ProviderList.cs | 41 ++ na-get-lib/NaGet.Packages/VersionComparetor.cs | 85 +++ na-get-lib/NaGet.SubCommands/NaGetInstall.cs | 214 +++++++ na-get-lib/NaGet.SubCommands/NaGetTask.cs | 71 +++ na-get-lib/NaGet.SubCommands/NaGetTaskSet.cs | 114 ++++ na-get-lib/NaGet.SubCommands/NaGetUninstall.cs | 122 ++++ na-get-lib/NaGet.SubCommands/NaGetUpdate.cs | 147 +++++ na-get-lib/NaGet/Env.cs | 102 ++++ na-get-lib/NaGet/Utils.cs | 481 ++++++++++++++++ na-get-lib/na-get-lib.csproj | 86 +++ provider.list.txt | 1 + 63 files changed, 9503 insertions(+) create mode 100644 AppliStation.proj create mode 100644 AppliStation.sln create mode 100644 AppliStation/AppliStation.Util/ExceptionDialogForm.Designer.cs create mode 100644 AppliStation/AppliStation.Util/ExceptionDialogForm.cs create mode 100644 AppliStation/AppliStation.Util/ExceptionDialogForm.resx create mode 100644 AppliStation/AppliStation.Util/ExecutionProgressViewer.Designer.cs create mode 100644 AppliStation/AppliStation.Util/ExecutionProgressViewer.cs create mode 100644 AppliStation/AppliStation.Util/ExecutionProgressViewer.resx create mode 100644 AppliStation/AppliStation.Util/ListViewItemSortComparer.cs create mode 100644 AppliStation/AppliStation.Util/NativeMethods.cs create mode 100644 AppliStation/AppliStation.csproj create mode 100644 AppliStation/ArgParse.cs create mode 100644 AppliStation/AssemblyInfo.cs create mode 100644 AppliStation/PackageListViewForm.Designer.cs create mode 100644 AppliStation/PackageListViewForm.cs create mode 100644 AppliStation/PackageListViewForm.resx create mode 100644 AppliStation/PackageUninstallConfirmForm.Designer.cs create mode 100644 AppliStation/PackageUninstallConfirmForm.cs create mode 100644 AppliStation/PackageUninstallConfirmForm.resx create mode 100644 AppliStation/PackagesInstallConfirmForm.Designer.cs create mode 100644 AppliStation/PackagesInstallConfirmForm.cs create mode 100644 AppliStation/PackagesInstallConfirmForm.resx create mode 100644 AppliStation/Program.cs create mode 100644 AppliStation/SplashScreen.png create mode 100644 all-get/AssemblyInfo.cs create mode 100644 all-get/Main.cs create mode 100644 all-get/Util.cs create mode 100644 all-get/all-get.csproj create mode 100644 archive-inst/AssemblyInfo.cs create mode 100644 archive-inst/InstalledFileList.cs create mode 100644 archive-inst/MSBuild.cs create mode 100644 archive-inst/Program.cs create mode 100644 archive-inst/archive-inst.csproj create mode 100644 build.bat create mode 100644 na-get-lib/AssemblyInfo.cs create mode 100644 na-get-lib/NaGet.InteropServices/CommonArchiverExtracter.cs create mode 100644 na-get-lib/NaGet.InteropServices/CreateProcessCaller.cs create mode 100644 na-get-lib/NaGet.InteropServices/DllAccess.cs create mode 100644 na-get-lib/NaGet.InteropServices/PEFileInfoUtils.cs create mode 100644 na-get-lib/NaGet.InteropServices/ShellLink.cs create mode 100644 na-get-lib/NaGet.Net/Downloader.cs create mode 100644 na-get-lib/NaGet.Packages.Install/Installation.cs create mode 100644 na-get-lib/NaGet.Packages.Install/InstallationLog.cs create mode 100644 na-get-lib/NaGet.Packages.Install/InstalledPackage.cs create mode 100644 na-get-lib/NaGet.Packages.Install/RegistriedUninstallers.cs create mode 100644 na-get-lib/NaGet.Packages.Install/UninstallInformation.cs create mode 100644 na-get-lib/NaGet.Packages.Install/Uninstallation.cs create mode 100644 na-get-lib/NaGet.Packages/HashValue.cs create mode 100644 na-get-lib/NaGet.Packages/Package.cs create mode 100644 na-get-lib/NaGet.Packages/PackageList.cs create mode 100644 na-get-lib/NaGet.Packages/PackageListsManager.cs create mode 100644 na-get-lib/NaGet.Packages/Platform.cs create mode 100644 na-get-lib/NaGet.Packages/ProviderList.cs create mode 100644 na-get-lib/NaGet.Packages/VersionComparetor.cs create mode 100644 na-get-lib/NaGet.SubCommands/NaGetInstall.cs create mode 100644 na-get-lib/NaGet.SubCommands/NaGetTask.cs create mode 100644 na-get-lib/NaGet.SubCommands/NaGetTaskSet.cs create mode 100644 na-get-lib/NaGet.SubCommands/NaGetUninstall.cs create mode 100644 na-get-lib/NaGet.SubCommands/NaGetUpdate.cs create mode 100644 na-get-lib/NaGet/Env.cs create mode 100644 na-get-lib/NaGet/Utils.cs create mode 100644 na-get-lib/na-get-lib.csproj create mode 100644 provider.list.txt diff --git a/AppliStation.proj b/AppliStation.proj new file mode 100644 index 0000000..9bbc716 --- /dev/null +++ b/AppliStation.proj @@ -0,0 +1,42 @@ + + + + + Debug + + dist + all-get/bin/$(Configuration) + archive-inst/bin/$(Configuration) + AppliStation/bin/$(Configuration) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AppliStation.sln b/AppliStation.sln new file mode 100644 index 0000000..631d282 --- /dev/null +++ b/AppliStation.sln @@ -0,0 +1,44 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +# SharpDevelop 2.2.1.2648 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "na-get-lib", "na-get-lib\na-get-lib.csproj", "{058E953D-3986-4F74-8516-5A50D267D36A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "all-get", "all-get\all-get.csproj", "{F212C7FF-0FC5-4319-BD72-87DB3A4CC55F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "archive-inst", "archive-inst\archive-inst.csproj", "{9D7ADB99-6E53-4E3E-A13B-6D82412B3671}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AppliStation", "AppliStation\AppliStation.csproj", "{0FC9CFF6-95CE-4C2D-833D-F6D697CD57EB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B4CD5E33-03CC-427D-A358-39360D6E4AD0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B4CD5E33-03CC-427D-A358-39360D6E4AD0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B4CD5E33-03CC-427D-A358-39360D6E4AD0}.Release|Any CPU.Build.0 = Release|Any CPU + {B4CD5E33-03CC-427D-A358-39360D6E4AD0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {25332B1A-85A4-47DB-AC50-97A6F418ED22}.Debug|Any CPU.Build.0 = Debug|Any CPU + {25332B1A-85A4-47DB-AC50-97A6F418ED22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {25332B1A-85A4-47DB-AC50-97A6F418ED22}.Release|Any CPU.Build.0 = Release|Any CPU + {25332B1A-85A4-47DB-AC50-97A6F418ED22}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F212C7FF-0FC5-4319-BD72-87DB3A4CC55F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F212C7FF-0FC5-4319-BD72-87DB3A4CC55F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F212C7FF-0FC5-4319-BD72-87DB3A4CC55F}.Release|Any CPU.Build.0 = Release|Any CPU + {F212C7FF-0FC5-4319-BD72-87DB3A4CC55F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {058E953D-3986-4F74-8516-5A50D267D36A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {058E953D-3986-4F74-8516-5A50D267D36A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {058E953D-3986-4F74-8516-5A50D267D36A}.Release|Any CPU.Build.0 = Release|Any CPU + {058E953D-3986-4F74-8516-5A50D267D36A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9D7ADB99-6E53-4E3E-A13B-6D82412B3671}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9D7ADB99-6E53-4E3E-A13B-6D82412B3671}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9D7ADB99-6E53-4E3E-A13B-6D82412B3671}.Release|Any CPU.Build.0 = Release|Any CPU + {9D7ADB99-6E53-4E3E-A13B-6D82412B3671}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0FC9CFF6-95CE-4C2D-833D-F6D697CD57EB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0FC9CFF6-95CE-4C2D-833D-F6D697CD57EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0FC9CFF6-95CE-4C2D-833D-F6D697CD57EB}.Release|Any CPU.Build.0 = Release|Any CPU + {0FC9CFF6-95CE-4C2D-833D-F6D697CD57EB}.Release|Any CPU.ActiveCfg = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/AppliStation/AppliStation.Util/ExceptionDialogForm.Designer.cs b/AppliStation/AppliStation.Util/ExceptionDialogForm.Designer.cs new file mode 100644 index 0000000..aae925b --- /dev/null +++ b/AppliStation/AppliStation.Util/ExceptionDialogForm.Designer.cs @@ -0,0 +1,164 @@ +namespace AppliStation.Util +{ + partial class ExceptionDialogForm + { + /// + /// Designer variable used to keep track of non-visual components. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Disposes resources used by the form. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing) { + if (components != null) { + components.Dispose(); + } + } + base.Dispose(disposing); + } + + /// + /// This method is required for Windows Forms designer support. + /// Do not change the method contents inside the source code editor. The Forms designer might + /// not be able to load this method if it was changed manually. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.detailTextBox = new System.Windows.Forms.TextBox(); + this.buttonsPanel = new System.Windows.Forms.FlowLayoutPanel(); + this.viewDetailButton = new System.Windows.Forms.Button(); + this.quitButton = new System.Windows.Forms.Button(); + this.continueButton = new System.Windows.Forms.Button(); + this.tableLayoutPanel1.SuspendLayout(); + this.buttonsPanel.SuspendLayout(); + this.SuspendLayout(); + // + // label1 + // + this.label1.Dock = System.Windows.Forms.DockStyle.Fill; + this.label1.Location = new System.Drawing.Point(8, 8); + this.label1.Margin = new System.Windows.Forms.Padding(8); + this.label1.Name = "label1"; + this.label1.RightToLeft = System.Windows.Forms.RightToLeft.No; + this.label1.Size = new System.Drawing.Size(408, 84); + this.label1.TabIndex = 0; + this.label1.Text = "ご迷惑をかけて申し訳ありません。AppliStationの実行中に予期せぬエラーが発生いたしました。\r\n\r\n動作を継続すればAppliStationはご利用いただ" + + "けますが、正常な動作をしないことがありえます。"; + this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.ColumnCount = 1; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 414F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + this.tableLayoutPanel1.Controls.Add(this.label1, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.detailTextBox, 0, 2); + this.tableLayoutPanel1.Controls.Add(this.buttonsPanel, 0, 1); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 3; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 100F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.Size = new System.Drawing.Size(424, 136); + this.tableLayoutPanel1.TabIndex = 0; + // + // detailTextBox + // + this.detailTextBox.Dock = System.Windows.Forms.DockStyle.Fill; + this.detailTextBox.ImeMode = System.Windows.Forms.ImeMode.Off; + this.detailTextBox.Location = new System.Drawing.Point(12, 148); + this.detailTextBox.Margin = new System.Windows.Forms.Padding(12); + this.detailTextBox.Multiline = true; + this.detailTextBox.Name = "detailTextBox"; + this.detailTextBox.ReadOnly = true; + this.detailTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; + this.detailTextBox.Size = new System.Drawing.Size(400, 1); + this.detailTextBox.TabIndex = 5; + this.detailTextBox.Visible = false; + // + // buttonsPanel + // + this.buttonsPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.buttonsPanel.AutoSize = true; + this.buttonsPanel.Controls.Add(this.viewDetailButton); + this.buttonsPanel.Controls.Add(this.quitButton); + this.buttonsPanel.Controls.Add(this.continueButton); + this.buttonsPanel.Location = new System.Drawing.Point(18, 103); + this.buttonsPanel.Name = "buttonsPanel"; + this.buttonsPanel.Size = new System.Drawing.Size(403, 30); + this.buttonsPanel.TabIndex = 4; + // + // viewDetailButton + // + this.viewDetailButton.Anchor = System.Windows.Forms.AnchorStyles.None; + this.viewDetailButton.AutoSize = true; + this.viewDetailButton.Location = new System.Drawing.Point(3, 4); + this.viewDetailButton.Margin = new System.Windows.Forms.Padding(3, 3, 10, 3); + this.viewDetailButton.Name = "viewDetailButton"; + this.viewDetailButton.Size = new System.Drawing.Size(125, 22); + this.viewDetailButton.TabIndex = 0; + this.viewDetailButton.Text = "エラーの詳細を表示(&D)"; + this.viewDetailButton.Click += new System.EventHandler(this.ViewDetailLabelLinkClicked); + // + // quitButton + // + this.quitButton.AutoSize = true; + this.quitButton.DialogResult = System.Windows.Forms.DialogResult.OK; + this.quitButton.Location = new System.Drawing.Point(141, 3); + this.quitButton.Name = "quitButton"; + this.quitButton.Size = new System.Drawing.Size(129, 24); + this.quitButton.TabIndex = 1; + this.quitButton.Text = "AppliStationを終了(&X)"; + this.quitButton.UseVisualStyleBackColor = true; + // + // continueButton + // + this.continueButton.AutoSize = true; + this.continueButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.continueButton.Location = new System.Drawing.Point(276, 3); + this.continueButton.Name = "continueButton"; + this.continueButton.Size = new System.Drawing.Size(124, 24); + this.continueButton.TabIndex = 2; + this.continueButton.Text = "強制的に動作継続(&C)"; + this.continueButton.UseVisualStyleBackColor = true; + // + // ExceptionDialogForm + // + this.AcceptButton = this.quitButton; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.AutoSize = true; + this.CancelButton = this.continueButton; + this.ClientSize = new System.Drawing.Size(424, 136); + this.Controls.Add(this.tableLayoutPanel1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.MaximizeBox = false; + this.Name = "ExceptionDialogForm"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "AppliStationのエラー発生"; + this.Shown += new System.EventHandler(this.Form_Shown); + this.tableLayoutPanel1.ResumeLayout(false); + this.tableLayoutPanel1.PerformLayout(); + this.buttonsPanel.ResumeLayout(false); + this.buttonsPanel.PerformLayout(); + this.ResumeLayout(false); + } + private System.Windows.Forms.FlowLayoutPanel buttonsPanel; + private System.Windows.Forms.TextBox detailTextBox; + private System.Windows.Forms.Button continueButton; + private System.Windows.Forms.Button quitButton; + private System.Windows.Forms.Button viewDetailButton; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + } +} diff --git a/AppliStation/AppliStation.Util/ExceptionDialogForm.cs b/AppliStation/AppliStation.Util/ExceptionDialogForm.cs new file mode 100644 index 0000000..2d414d6 --- /dev/null +++ b/AppliStation/AppliStation.Util/ExceptionDialogForm.cs @@ -0,0 +1,60 @@ +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace AppliStation.Util +{ + /// + /// Description of ExceptionDialogForm. + /// + public partial class ExceptionDialogForm : Form + { + public ExceptionDialogForm() + { + // + // The InitializeComponent() call is required for Windows Forms designer support. + // + InitializeComponent(); + } + + private static void Application_ThrowException(Exception e) + { + ExceptionDialogForm form = new ExceptionDialogForm(); + if (e != null) { + form.detailTextBox.Text = e.ToString() + System.Environment.NewLine + e.StackTrace; + } else { + form.viewDetailButton.Visible = false; + } + + switch (form.ShowDialog()) { + case DialogResult.Cancel: + return; + default: + Application.Exit(); + break; + } + } + + public static void Application_ThrowException(object sender, System.Threading.ThreadExceptionEventArgs e) + { + Application_ThrowException(e.Exception); + } + + public static void Application_ThrowException(object sender, UnhandledExceptionEventArgs e) + { + Application_ThrowException((Exception) e.ExceptionObject); + } + + void ViewDetailLabelLinkClicked(object sender, EventArgs e) + { + this.detailTextBox.Visible = true; + this.viewDetailButton.Enabled = false; + this.Size = new Size(this.Size.Width, this.Size.Height + 250); + } + + void Form_Shown(object sender, EventArgs e) + { + this.quitButton.Focus(); + } + } +} diff --git a/AppliStation/AppliStation.Util/ExceptionDialogForm.resx b/AppliStation/AppliStation.Util/ExceptionDialogForm.resx new file mode 100644 index 0000000..5ea0895 --- /dev/null +++ b/AppliStation/AppliStation.Util/ExceptionDialogForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/AppliStation/AppliStation.Util/ExecutionProgressViewer.Designer.cs b/AppliStation/AppliStation.Util/ExecutionProgressViewer.Designer.cs new file mode 100644 index 0000000..fe8ef84 --- /dev/null +++ b/AppliStation/AppliStation.Util/ExecutionProgressViewer.Designer.cs @@ -0,0 +1,200 @@ + +namespace AppliStation.Util +{ + partial class ExecutionProgressViewer + { + /// + /// Designer variable used to keep track of non-visual components. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Disposes resources used by the form. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing) { + if (components != null) { + components.Dispose(); + } + } + base.Dispose(disposing); + } + + /// + /// This method is required for Windows Forms designer support. + /// Do not change the method contents inside the source code editor. The Forms designer might + /// not be able to load this method if it was changed manually. + /// + private void InitializeComponent() + { + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.progressSubLabel = new System.Windows.Forms.Label(); + this.subtitleLabel = new System.Windows.Forms.Label(); + this.progressBar = new System.Windows.Forms.ProgressBar(); + this.progressLabel = new System.Windows.Forms.Label(); + this.progressBarSub = new System.Windows.Forms.ProgressBar(); + this.bottomPanel = new System.Windows.Forms.FlowLayoutPanel(); + this.okButton = new System.Windows.Forms.Button(); + this.cancelButton = new System.Windows.Forms.Button(); + this.logBox = new System.Windows.Forms.RichTextBox(); + this.tableLayoutPanel1.SuspendLayout(); + this.bottomPanel.SuspendLayout(); + this.SuspendLayout(); + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.ColumnCount = 1; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + this.tableLayoutPanel1.Controls.Add(this.progressSubLabel, 0, 5); + this.tableLayoutPanel1.Controls.Add(this.subtitleLabel, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.progressBar, 0, 1); + this.tableLayoutPanel1.Controls.Add(this.progressLabel, 0, 2); + this.tableLayoutPanel1.Controls.Add(this.progressBarSub, 0, 4); + this.tableLayoutPanel1.Controls.Add(this.bottomPanel, 0, 7); + this.tableLayoutPanel1.Controls.Add(this.logBox, 0, 6); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 8; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 50F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.Size = new System.Drawing.Size(444, 318); + this.tableLayoutPanel1.TabIndex = 0; + // + // progressSubLabel + // + this.progressSubLabel.Dock = System.Windows.Forms.DockStyle.Fill; + this.progressSubLabel.Location = new System.Drawing.Point(10, 128); + this.progressSubLabel.Margin = new System.Windows.Forms.Padding(10, 0, 3, 0); + this.progressSubLabel.Name = "progressSubLabel"; + this.progressSubLabel.Size = new System.Drawing.Size(431, 26); + this.progressSubLabel.TabIndex = 6; + this.progressSubLabel.Text = "しばらくお待ちください..."; + this.progressSubLabel.Visible = false; + // + // subtitleLabel + // + this.subtitleLabel.Dock = System.Windows.Forms.DockStyle.Bottom; + this.subtitleLabel.Location = new System.Drawing.Point(3, 27); + this.subtitleLabel.Name = "subtitleLabel"; + this.subtitleLabel.Size = new System.Drawing.Size(438, 23); + this.subtitleLabel.TabIndex = 0; + this.subtitleLabel.Text = "しばらくお待ちください..."; + // + // progressBar + // + this.progressBar.Dock = System.Windows.Forms.DockStyle.Top; + this.progressBar.Location = new System.Drawing.Point(10, 53); + this.progressBar.Margin = new System.Windows.Forms.Padding(10, 3, 10, 3); + this.progressBar.Name = "progressBar"; + this.progressBar.Size = new System.Drawing.Size(424, 20); + this.progressBar.Style = System.Windows.Forms.ProgressBarStyle.Marquee; + this.progressBar.TabIndex = 2; + // + // progressLabel + // + this.progressLabel.Dock = System.Windows.Forms.DockStyle.Fill; + this.progressLabel.Location = new System.Drawing.Point(10, 76); + this.progressLabel.Margin = new System.Windows.Forms.Padding(10, 0, 3, 0); + this.progressLabel.Name = "progressLabel"; + this.progressLabel.Size = new System.Drawing.Size(431, 26); + this.progressLabel.TabIndex = 3; + this.progressLabel.Text = "しばらくお待ちください..."; + // + // progressBarSub + // + this.progressBarSub.Dock = System.Windows.Forms.DockStyle.Top; + this.progressBarSub.Location = new System.Drawing.Point(10, 105); + this.progressBarSub.Margin = new System.Windows.Forms.Padding(10, 3, 10, 3); + this.progressBarSub.Name = "progressBarSub"; + this.progressBarSub.Size = new System.Drawing.Size(424, 20); + this.progressBarSub.Style = System.Windows.Forms.ProgressBarStyle.Continuous; + this.progressBarSub.TabIndex = 5; + this.progressBarSub.Visible = false; + // + // bottomPanel + // + this.bottomPanel.AutoSize = true; + this.bottomPanel.Controls.Add(this.okButton); + this.bottomPanel.Controls.Add(this.cancelButton); + this.bottomPanel.Dock = System.Windows.Forms.DockStyle.Right; + this.bottomPanel.Location = new System.Drawing.Point(279, 286); + this.bottomPanel.Name = "bottomPanel"; + this.bottomPanel.Size = new System.Drawing.Size(162, 29); + this.bottomPanel.TabIndex = 4; + // + // okButton + // + this.okButton.Enabled = false; + this.okButton.Location = new System.Drawing.Point(3, 3); + this.okButton.Name = "okButton"; + this.okButton.Size = new System.Drawing.Size(75, 23); + this.okButton.TabIndex = 0; + this.okButton.Text = "OK"; + this.okButton.UseVisualStyleBackColor = true; + this.okButton.Click += new System.EventHandler(this.OkButtonClick); + // + // cancelButton + // + this.cancelButton.Enabled = false; + this.cancelButton.Location = new System.Drawing.Point(84, 3); + this.cancelButton.Name = "cancelButton"; + this.cancelButton.Size = new System.Drawing.Size(75, 23); + this.cancelButton.TabIndex = 1; + this.cancelButton.Text = "キャンセル"; + this.cancelButton.UseVisualStyleBackColor = true; + this.cancelButton.Click += new System.EventHandler(this.CancelButtonClick); + // + // logBox + // + this.logBox.BackColor = System.Drawing.SystemColors.Control; + this.logBox.DetectUrls = false; + this.logBox.Dock = System.Windows.Forms.DockStyle.Fill; + this.logBox.ForeColor = System.Drawing.SystemColors.ControlText; + this.logBox.Location = new System.Drawing.Point(10, 157); + this.logBox.Margin = new System.Windows.Forms.Padding(10, 3, 3, 3); + this.logBox.Name = "logBox"; + this.logBox.ReadOnly = true; + this.logBox.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.ForcedVertical; + this.logBox.Size = new System.Drawing.Size(431, 123); + this.logBox.TabIndex = 8; + this.logBox.Text = ""; + // + // ExecutionProgressViewer + // + this.AcceptButton = this.okButton; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(444, 318); + this.Controls.Add(this.tableLayoutPanel1); + this.MaximizeBox = false; + this.Name = "ExecutionProgressViewer"; + this.ShowIcon = false; + this.Text = "AppliStation"; + this.Shown += new System.EventHandler(this.ExecutionProgressViewerShown); + this.tableLayoutPanel1.ResumeLayout(false); + this.tableLayoutPanel1.PerformLayout(); + this.bottomPanel.ResumeLayout(false); + this.ResumeLayout(false); + } + private System.Windows.Forms.Button cancelButton; + private System.Windows.Forms.Button okButton; + private System.Windows.Forms.RichTextBox logBox; + private System.Windows.Forms.Label progressSubLabel; + private System.Windows.Forms.ProgressBar progressBarSub; + private System.Windows.Forms.FlowLayoutPanel bottomPanel; + private System.Windows.Forms.Label progressLabel; + private System.Windows.Forms.ProgressBar progressBar; + private System.Windows.Forms.Label subtitleLabel; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + } +} diff --git a/AppliStation/AppliStation.Util/ExecutionProgressViewer.cs b/AppliStation/AppliStation.Util/ExecutionProgressViewer.cs new file mode 100644 index 0000000..2b99bfb --- /dev/null +++ b/AppliStation/AppliStation.Util/ExecutionProgressViewer.cs @@ -0,0 +1,206 @@ +using System; +using System.Drawing; +using System.Windows.Forms; +using System.Threading; +using NaGet.SubCommands; +using NaGet.Net; + +namespace AppliStation.Util +{ + /// + /// Description of ExecutionProgressViewer. + /// + public partial class ExecutionProgressViewer : Form + { + private NaGetTaskSet taskSet; + + private Downloader downloader; + + private Thread tasksetRunningThread = null; + + public Downloader Downloader { + get { return downloader; } + } + + public ExecutionProgressViewer() + { + // + // The InitializeComponent() call is required for Windows Forms designer support. + // + InitializeComponent(); + + downloader = new Downloader(); + downloader.DownloadEventRaised += delegate(object sender, DownloadEventArgs e) { + if (InvokeRequired) { + Invoke(new EventHandler(onDownloadEvent), sender, e); + } else { + onDownloadEvent(sender, e); + } + }; + } + + private void onDownloadEvent(object sender, DownloadEventArgs a) + { + if (a.TaskProgressPercent >= 0) { + progressBarSub.Value = (int) a.TaskProgressPercent; + progressBarSub.Style = ProgressBarStyle.Continuous; + } else { + progressBarSub.Style = ProgressBarStyle.Marquee; + } + + switch (a.Type) { + case DownloadEventType.INITED: + case DownloadEventType.CONNECTED: + progressSubLabel.Text = a.TaskMessage; + + progressBarSub.Visible = true; + progressSubLabel.Visible = true; + break; + case DownloadEventType.DOWNLOADING: + progressSubLabel.Text = a.TaskMessage; + break; + case DownloadEventType.COMPLETED: + progressBarSub.Visible = false; + progressSubLabel.Visible = false; + break; + case DownloadEventType.ERROR: + progressBarSub.Visible = false; + progressSubLabel.Visible = false; + + logBox.SelectionColor = System.Drawing.Color.Red; + logBox.AppendText(" [ƒGƒ‰[] " + a.TaskMessage + System.Environment.NewLine); + logBox.SelectionColor = logBox.ForeColor; + break; + } + } + + #region NaGetTaskSetŠÖ˜A + + private void onTaskSetRaised(object sender, NaGetTaskSetEventArgs e) + { + NaGetTaskSet taskSet = (NaGetTaskSet) sender; + + if (e.TaskProgressPercent >= 0) { + progressBar.Value = (int) e.TaskProgressPercent; + progressBar.Style = ProgressBarStyle.Continuous; + } else { + progressBar.Style = ProgressBarStyle.Marquee; + } + progressLabel.Text = e.TaskMessage ?? string.Empty; + + cancelButton.Enabled = taskSet.Running && taskSet.Cancelable; + + switch (e.Type) { + case NaGetTaskSetEventType.COMPLETED: + logBox.AppendText("Š®—¹." + System.Environment.NewLine); + if (taskSet.Done) { + okButton.Enabled = true; + cancelButton.Enabled = false; + } + break; + case NaGetTaskSetEventType.STARTED_TASKSET: + subtitleLabel.Text = taskSet.TaskSetNames[taskSet.CurrentTaskSetIndex]; + logBox.AppendText(" " + e.TaskMessage + System.Environment.NewLine); + break; + case NaGetTaskSetEventType.COMPLETED_TASKSET: + if (progressBarSub.Visible) progressBarSub.Hide(); + if (progressSubLabel.Visible) progressSubLabel.Hide(); + + NativeMethods.ProgressBar_SetState(progressBar, 1); // VistaProgressFFƒm[ƒ}ƒ‹ + + logBox.AppendText(string.Format(" ... Š®—¹. [{0}%]", (int) e.TaskProgressPercent)); + logBox.AppendText(System.Environment.NewLine); + break; + case NaGetTaskSetEventType.INFO: + logBox.AppendText(" " + e.TaskMessage + System.Environment.NewLine); + break; + case NaGetTaskSetEventType.ERROR: + logBox.SelectionColor = System.Drawing.Color.Red; + logBox.AppendText(" [ƒGƒ‰[] " + e.TaskMessage + System.Environment.NewLine); + logBox.SelectionColor = logBox.ForeColor; + + NativeMethods.ProgressBar_SetState(progressBar, 2); // VistaProgressFFƒGƒ‰[ + + okButton.Enabled = true; + cancelButton.Enabled = false; + break; + case NaGetTaskSetEventType.CANCELED: + logBox.SelectionColor = System.Drawing.Color.Red; + logBox.AppendText(e.TaskMessage + System.Environment.NewLine); + logBox.SelectionColor = logBox.ForeColor; + + NativeMethods.ProgressBar_SetState(progressBar, 1); // VistaProgressFF’†’f + + okButton.Enabled = true; + cancelButton.Enabled = false; + break; + case NaGetTaskSetEventType.WARNING: + logBox.SelectionColor = System.Drawing.Color.Red; + logBox.AppendText(" [ƒGƒ‰[] " + e.TaskMessage + System.Environment.NewLine); + logBox.SelectionColor = logBox.ForeColor; + + break; + } + + if (taskSet.Done) { + NativeMethods.Form_FlashWindow(this, + NativeMethods.FlashFlag.All | NativeMethods.FlashFlag.TimerNoFG, + uint.MaxValue, 0); + } + } + + public void SetTaskSet(NaGetTaskSet taskSet) + { + this.taskSet = taskSet; + + taskSet.TaskSetRaised += delegate(object sender, NaGetTaskSetEventArgs e) { + if (InvokeRequired) { + Invoke(new EventHandler(onTaskSetRaised), taskSet, e); + } else { + onTaskSetRaised(taskSet, e); + } + }; + } + + public void StartTaskSet() + { + tasksetRunningThread = new Thread(taskSet.Run); + tasksetRunningThread.Start(); + } + + #endregion + + void OkButtonClick(object sender, EventArgs e) + { + if (taskSet == null || taskSet.Done) { + this.Close(); + this.Dispose(); + } + } + + void CancelButtonClick(object sender, EventArgs e) + { + if (InvokeRequired) { + Invoke(new EventHandler(CancelButtonClickConcrete), sender, e); + } else { + CancelButtonClickConcrete(sender,e); + } + } + + void CancelButtonClickConcrete(object sender, EventArgs e) + { + if (taskSet != null && taskSet.Running && taskSet.Cancelable) { + cancelButton.Enabled = false; + + NativeMethods.ProgressBar_SetState(progressBar, 3); // VistaProgressFF’†’f + + taskSet.Cancel(); + } + } + + void ExecutionProgressViewerShown(object sender, EventArgs e) + { + this.BringToFront(); + } + } +} diff --git a/AppliStation/AppliStation.Util/ExecutionProgressViewer.resx b/AppliStation/AppliStation.Util/ExecutionProgressViewer.resx new file mode 100644 index 0000000..5ea0895 --- /dev/null +++ b/AppliStation/AppliStation.Util/ExecutionProgressViewer.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/AppliStation/AppliStation.Util/ListViewItemSortComparer.cs b/AppliStation/AppliStation.Util/ListViewItemSortComparer.cs new file mode 100644 index 0000000..11a5f61 --- /dev/null +++ b/AppliStation/AppliStation.Util/ListViewItemSortComparer.cs @@ -0,0 +1,43 @@ +using System; +using System.Drawing; +using System.Windows.Forms; +using NaGet.Packages; +using NaGet.Packages.Install; +using System.IO; +using System.Collections.Generic; + +namespace AppliStation.Util +{ + class ListViewItemSortComparer : System.Collections.IComparer + { + public SortOrder Order = SortOrder.Ascending; + + public int Column = -1; + + public ListViewItemSortComparer(int index, SortOrder order) + { + this.Column = index; + this.Order = order; + } + + public int Compare(object x, object y) + { + ListViewItem itemx = (ListViewItem) x; + ListViewItem itemy = (ListViewItem) y; + + int result = -1; + result = string.Compare(itemx.SubItems[Column].Text, + itemy.SubItems[Column].Text); + + switch (Order) { + case SortOrder.Descending: + result = -result; + break; + case SortOrder.None: + result = 0; + break; + } + return result; + } + } +} diff --git a/AppliStation/AppliStation.Util/NativeMethods.cs b/AppliStation/AppliStation.Util/NativeMethods.cs new file mode 100644 index 0000000..f739712 --- /dev/null +++ b/AppliStation/AppliStation.Util/NativeMethods.cs @@ -0,0 +1,166 @@ +using System; +using System.Runtime.InteropServices; +using System.Windows.Forms; + +namespace AppliStation.Util +{ + public sealed class NativeMethods + { + private NativeMethods() + { + } + + + /// + /// WindowsVistaŒü‚¯AƒvƒƒOƒŒƒXƒo[ƒXƒe[ƒ^ƒX(F)‚ðÝ’è‚·‚é + /// + /// ‘Ώۂ̃vƒƒOƒŒƒXƒo[ + /// ó‘ԁB(1:Normal,2:Error,3:Paused) + public static void ProgressBar_SetState(ProgressBar progBar, uint state) + { + try { + // status := (PBST_NORMAL | PBST_ERROR | PBST_PAUSED) + // SendMessage(progressBar.Handle, PBM_SETSTATE, state, 0); + SendMessage(progBar.Handle, 0x410, state, 0); + } catch (Exception) { + } + } + + #region ƒ^ƒXƒNƒo[‚¨‚æ‚у^ƒCƒgƒ‹ƒo[‚̃tƒ‰ƒbƒVƒ… + + /// + /// ƒ^ƒXƒNƒo[‚¨‚æ‚у^ƒCƒgƒ‹ƒo[ƒ{ƒ^ƒ“‚̃tƒ‰ƒbƒVƒ…‚̐ݒèƒtƒ‰ƒO + /// + public enum FlashFlag : uint { + /// + /// “_–ł̒âŽ~ + /// + Stop = 0, + /// + /// ƒ^ƒCƒgƒ‹ƒo[‚ð“_–Å + /// + Caption = 1, + /// + /// ƒ^ƒXƒNƒo[ƒ{ƒ^ƒ“‚ð“_–Å + /// + Tray = 2, + /// + /// ƒ^ƒCƒgƒ‹ƒo[‚ƃ^ƒXƒNƒo[ƒ{ƒ^ƒ“‚ð“_–Å + /// + All = 3, + /// + /// Stop‚ªÝ’肳‚ê‚é‚܂œ_–Å‚·‚é + /// + Timer = 4, + /// + /// ƒtƒHƒAƒOƒ‰ƒEƒ“ƒh‚̏ó‘ԂɂȂé‚܂œ_–Å + /// + TimerNoFG = 12, + } + + [StructLayout(LayoutKind.Sequential)] + struct FLASHWINFO + { + public int cbSize; + public IntPtr hWnd; + public FlashFlag dwFlags; + public uint uCount; + public uint dwTimeout; + } + + /// + /// ƒ^ƒXƒNƒo[‚¨‚æ‚у^ƒCƒgƒ‹ƒo[ƒ{ƒ^ƒ“‚ð“_–Å‚³‚¹‚é + /// + /// ‘ΏۃtƒH[ƒ€ + /// “_–Ńpƒ‰ƒ[ƒ^ƒtƒ‰ƒO + /// “_–ʼnñ” + /// “_–ł̊Ԋu(ƒ~ƒŠ•b) + /// + public static bool Form_FlashWindow(Form form, FlashFlag flag, uint count, uint timeout) + { + try { + FLASHWINFO info = new FLASHWINFO(); + info.cbSize = Marshal.SizeOf(typeof(FLASHWINFO)); + info.hWnd = form.Handle; + info.dwFlags = flag; + info.uCount = count; + info.dwTimeout = timeout; + + return FlashWindowEx(ref info) == 0; + } catch (Exception) { + return false; + } + } + + [DllImport("user32.dll")] + static extern Int32 FlashWindowEx(ref FLASHWINFO pwfi); + + #endregion + + #region ColumnHeader‚̃\[ƒg‚ÌŽOŠpˆó—p + + [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] + internal struct HD_ITEM + { + public uint mask; + public int cxy; + [MarshalAs(UnmanagedType.LPTStr)]public string pszText; + public IntPtr hbm; + public int cchTextMax; + public int fmt; + [MarshalAs(UnmanagedType.LPTStr)]public string lParam; + public int iImage; // index of bitmap in ImageList + public int iOrder; + } + + internal static IntPtr ListView_GetHeader(ListView listview) + { + // SendMessage(hWnd, LVM_GETHEADER, 0, NULL); + return SendMessage(listview.Handle, 0x101E, 0, 0); + } + + /// + /// WinXPˆÈ~Aƒ\[ƒg‚Ì–îˆó‚ð•\ަ + /// + /// ‘ΏۂÌListView + /// •\ަ‚·‚é–îˆó‚̃wƒbƒ_ + /// ƒ\[ƒg‚̏¸‡E~‡ + public static void ColumnHeader_SetSortState(ListView listView, int column, SortOrder order) + { + try { + // SendMessage(hWnd, LVM_GETHEADER, NULL, NULL); + IntPtr hWnd = SendMessage(listView.Handle, 0x101F, 0, 0); + + HD_ITEM hdi = new HD_ITEM(); + hdi.mask = 0x0004; // HDI_FORMAT; + for (int i = 0; i < listView.Columns.Count; i++) { + // SendMessage(hWnd, HDM_GETITEMW, i, &hdi); + SendMessage(hWnd, 0x120b, i, ref hdi); + + const int HDF_SORTUP = 0x400; + const int HDF_SORTDOWN = 0x200; + + if (i != column || order == SortOrder.None) { + hdi.fmt = hdi.fmt & ~(HDF_SORTUP | HDF_SORTDOWN); + } else if (order == SortOrder.Ascending) { // ¸‡ + hdi.fmt = hdi.fmt & ~HDF_SORTDOWN | HDF_SORTUP; + } else if (order == SortOrder.Descending) { // ~‡ + hdi.fmt = hdi.fmt & ~HDF_SORTUP | HDF_SORTDOWN; + } + + // SendMessage(hWnd, HDM_SETITEMW, i, &hdi); + SendMessage(hWnd, 0x120c, i, ref hdi); + } + } catch (Exception) { + } + } + + #endregion + + [DllImport("user32.dll", CharSet=CharSet.Auto)] + internal static extern IntPtr SendMessage( IntPtr hWnd, UInt32 Msg, UInt32 wParam, UInt32 lParam); + + [DllImport("user32.dll", CharSet=CharSet.Auto)] + internal static extern IntPtr SendMessage( IntPtr hWnd, UInt32 Msg, int wParam, ref HD_ITEM lParam); + } +} diff --git a/AppliStation/AppliStation.csproj b/AppliStation/AppliStation.csproj new file mode 100644 index 0000000..908fae6 --- /dev/null +++ b/AppliStation/AppliStation.csproj @@ -0,0 +1,110 @@ + + + {0FC9CFF6-95CE-4C2D-833D-F6D697CD57EB} + Debug + AnyCPU + WinExe + AppliStation + AppliStation + bin\ + False + False + 4 + false + v2.0 + + + bin\Debug\ + true + Full + false + true + DEBUG;TRACE + WinExe + AppliStation + AppliStation + false + 4 + + + bin\Release\ + false + None + true + false + TRACE + WinExe + AppliStation + AppliStation + false + 4 + + + False + Auto + 4194304 + AnyCPU + 4096 + + + + + + + + + + + + + + ExceptionDialogForm.cs + + + + ExecutionProgressViewer.cs + + + + + + + + PackageListViewForm.cs + + + + PackagesInstallConfirmForm.cs + + + + PackageUninstallConfirmForm.cs + + + + ExceptionDialogForm.Designer.cs + + + ExecutionProgressViewer.cs + + + PackageListViewForm.cs + + + PackagesInstallConfirmForm.cs + + + PackageUninstallConfirmForm.cs + + + Always + + + + + + {058E953D-3986-4F74-8516-5A50D267D36A} + na-get-lib + + + \ No newline at end of file diff --git a/AppliStation/ArgParse.cs b/AppliStation/ArgParse.cs new file mode 100644 index 0000000..5754ffa --- /dev/null +++ b/AppliStation/ArgParse.cs @@ -0,0 +1,118 @@ +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; + +namespace AppliStation +{ + /// + /// ’á‹@”\‚Ȉø”‰ðÍ‚ð‚·‚éB + /// + public class ArgParse + { + /// + /// ‰ðÍŒ‹‰Ê + /// + private Dictionary opts; + + /// + /// ‰ðÍŒ‹‰Ê‚ðƒnƒbƒVƒ…Ž«‘‚Æ‚µ‚Ď擾 + /// + public Dictionary Opts { + get { + lock (opts) { + return opts; + } + } + } + + public ArgParse() + : this(new Dictionary()) + { + } + + /// + /// ‰Šú‰» + /// + /// ‰Šú‚ÌŽ«‘ + public ArgParse(Dictionary hashDefault) + { + opts = hashDefault; + } + + /// + /// ƒnƒbƒVƒ…‚Ì’†g‚ðÝ’è‚ ‚é‚¢‚͎擾‚·‚éB + /// + public object this[string key] { + set { + lock(opts) { + opts[key] = value; + } + } + get { + lock(opts) { + return opts[key]; + } + } + } + + /// + /// ˆø”‚ð‰ðÍ‚·‚é + /// + /// ‘Ώۈø” + /// Žc‚Á‚½(ƒIƒvƒVƒ‡ƒ“‚ł͂Ȃ¢)ˆø” + public string[] Parse(string[] args) + { + List rest = new List(); + lock (opts) { + bool disableOptionParse = false; + for (int i = 0; i < args.Length; i++) { + if (disableOptionParse || !args[i].StartsWith("-")) { + rest.Add(args[i]); + } else { + if (args[i].StartsWith("-")) { + if (args[i] == "--") { + // ƒIƒvƒVƒ‡ƒ“‰ðÍ’†’f + disableOptionParse = true; + } else { + parseOption(args[i]); + } + } + } + } + } + + return rest.ToArray(); + } + + /// + /// ƒIƒvƒVƒ‡ƒ“ƒg[ƒNƒ“‚̉ðÍ + /// + /// + private void parseOption(string option) + { + Match match = Regex.Match(option, "^--?([^=]+)(=\"?(.+)\"?)?$"); + if (match.Success) { + string key = match.Groups[1].Value; + string val = match.Groups[3].Value; + + if (opts.ContainsKey(key)) { // “o˜^Œ‹‰Ê‚É“ü‚Á‚Ä‚¢‚邱‚Æ + object origVal = opts[key]; + + try { + if (origVal is bool) { + opts[key] = val.ToLower() != "no"; + } else if (origVal is int) { + opts[key] = int.Parse(val); + } else /* if (origVal is string) */ { + opts[key] = val; + } + } catch (FormatException) { + throw new ApplicationException(string.Format("Illegal Format For {0}", key)); + } + } else { + throw new ApplicationException(string.Format("Undefined option: {0}", key)); + } + } + } + } +} diff --git a/AppliStation/AssemblyInfo.cs b/AppliStation/AssemblyInfo.cs new file mode 100644 index 0000000..2f28673 --- /dev/null +++ b/AppliStation/AssemblyInfo.cs @@ -0,0 +1,31 @@ +#region Using directives + +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +#endregion + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("AppliStation")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("AppliStation")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// This sets the default COM visibility of types in the assembly to invisible. +// If you need to expose a type to COM, use [ComVisible(true)] on that type. +[assembly: ComVisible(false)] + +// The assembly version has following format : +// +// Major.Minor.Build.Revision +// +// You can specify all the values or you can use the default the Revision and +// Build Numbers by using the '*' as shown below: +[assembly: AssemblyVersion("0.9.8.*")] diff --git a/AppliStation/PackageListViewForm.Designer.cs b/AppliStation/PackageListViewForm.Designer.cs new file mode 100644 index 0000000..0a0abfa --- /dev/null +++ b/AppliStation/PackageListViewForm.Designer.cs @@ -0,0 +1,406 @@ +namespace AppliStation +{ + partial class PackageListViewForm + { + /// + /// Designer variable used to keep track of non-visual components. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Disposes resources used by the form. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing) { + if (components != null) { + components.Dispose(); + } + } + base.Dispose(disposing); + } + + /// + /// This method is required for Windows Forms designer support. + /// Do not change the method contents inside the source code editor. The Forms designer might + /// not be able to load this method if it was changed manually. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PackageListViewForm)); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.toolStripContainer = new System.Windows.Forms.ToolStripPanel(); + this.packageListFilterToolStrip = new System.Windows.Forms.ToolStrip(); + this.packageFilterToolStripDropDownButton = new System.Windows.Forms.ToolStripDropDownButton(); + this.allPackageFilterToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.notInstalledPackageFilterToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.installedASPackageFilterToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.installedSysPackageFilterToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.searchTextBox = new System.Windows.Forms.ToolStripTextBox(); + this.packageCommandsToolStrip = new System.Windows.Forms.ToolStrip(); + this.updateToolStripButton = new System.Windows.Forms.ToolStripSplitButton(); + this.localUpdateToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.upgradeToolStripButton = new System.Windows.Forms.ToolStripButton(); + this.installToolStripButton = new System.Windows.Forms.ToolStripButton(); + this.uninstallToolStripButton = new System.Windows.Forms.ToolStripButton(); + this.splitContainer = new System.Windows.Forms.SplitContainer(); + this.packageListView = new System.Windows.Forms.ListView(); + this.nameHeader = new System.Windows.Forms.ColumnHeader(); + this.versionHeader = new System.Windows.Forms.ColumnHeader(); + this.summaryHeader = new System.Windows.Forms.ColumnHeader(); + this.packageListContextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components); + this.installToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.uninstallToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.webResourcesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.webOfficialToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.webGoogleSearchToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.openInstalledDirectoryStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.detailBox = new System.Windows.Forms.RichTextBox(); + this.tableLayoutPanel1.SuspendLayout(); + this.toolStripContainer.SuspendLayout(); + this.packageListFilterToolStrip.SuspendLayout(); + this.packageCommandsToolStrip.SuspendLayout(); + this.splitContainer.Panel1.SuspendLayout(); + this.splitContainer.Panel2.SuspendLayout(); + this.splitContainer.SuspendLayout(); + this.packageListContextMenuStrip.SuspendLayout(); + this.SuspendLayout(); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(222, 6); + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.ColumnCount = 1; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.Controls.Add(this.toolStripContainer, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.splitContainer, 0, 1); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 2; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.Size = new System.Drawing.Size(492, 366); + this.tableLayoutPanel1.TabIndex = 0; + // + // toolStripContainer + // + this.toolStripContainer.Controls.Add(this.packageListFilterToolStrip); + this.toolStripContainer.Controls.Add(this.packageCommandsToolStrip); + this.toolStripContainer.Dock = System.Windows.Forms.DockStyle.Top; + this.toolStripContainer.Location = new System.Drawing.Point(0, 0); + this.toolStripContainer.Name = "toolStripContainer"; + this.toolStripContainer.Orientation = System.Windows.Forms.Orientation.Horizontal; + this.toolStripContainer.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0); + this.toolStripContainer.Size = new System.Drawing.Size(492, 50); + // + // packageListFilterToolStrip + // + this.packageListFilterToolStrip.Dock = System.Windows.Forms.DockStyle.None; + this.packageListFilterToolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.packageFilterToolStripDropDownButton, + this.searchTextBox}); + this.packageListFilterToolStrip.Location = new System.Drawing.Point(3, 0); + this.packageListFilterToolStrip.Name = "packageListFilterToolStrip"; + this.packageListFilterToolStrip.Size = new System.Drawing.Size(177, 25); + this.packageListFilterToolStrip.TabIndex = 1; + // + // packageFilterToolStripDropDownButton + // + this.packageFilterToolStripDropDownButton.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.allPackageFilterToolStripMenuItem, + this.notInstalledPackageFilterToolStripMenuItem, + this.installedASPackageFilterToolStripMenuItem, + this.installedSysPackageFilterToolStripMenuItem}); + this.packageFilterToolStripDropDownButton.Name = "packageFilterToolStripDropDownButton"; + this.packageFilterToolStripDropDownButton.Size = new System.Drawing.Size(13, 22); + // + // allPackageFilterToolStripMenuItem + // + this.allPackageFilterToolStripMenuItem.Name = "allPackageFilterToolStripMenuItem"; + this.allPackageFilterToolStripMenuItem.Size = new System.Drawing.Size(144, 22); + this.allPackageFilterToolStripMenuItem.Text = "全て"; + this.allPackageFilterToolStripMenuItem.ToolTipText = "全てのソフトを表示"; + this.allPackageFilterToolStripMenuItem.Click += new System.EventHandler(this.AnyPackageFilterToolStripMenuItemClicked); + // + // notInstalledPackageFilterToolStripMenuItem + // + this.notInstalledPackageFilterToolStripMenuItem.Name = "notInstalledPackageFilterToolStripMenuItem"; + this.notInstalledPackageFilterToolStripMenuItem.Size = new System.Drawing.Size(144, 22); + this.notInstalledPackageFilterToolStripMenuItem.Text = "未インストール"; + this.notInstalledPackageFilterToolStripMenuItem.ToolTipText = "インストールされていないソフトを表示"; + this.notInstalledPackageFilterToolStripMenuItem.Click += new System.EventHandler(this.AnyPackageFilterToolStripMenuItemClicked); + // + // installedASPackageFilterToolStripMenuItem + // + this.installedASPackageFilterToolStripMenuItem.Name = "installedASPackageFilterToolStripMenuItem"; + this.installedASPackageFilterToolStripMenuItem.Size = new System.Drawing.Size(144, 22); + this.installedASPackageFilterToolStripMenuItem.Text = "AppliStation内"; + this.installedASPackageFilterToolStripMenuItem.ToolTipText = "AppliStationにインストールされているソフトを表示"; + this.installedASPackageFilterToolStripMenuItem.Click += new System.EventHandler(this.AnyPackageFilterToolStripMenuItemClicked); + // + // installedSysPackageFilterToolStripMenuItem + // + this.installedSysPackageFilterToolStripMenuItem.Name = "installedSysPackageFilterToolStripMenuItem"; + this.installedSysPackageFilterToolStripMenuItem.Size = new System.Drawing.Size(144, 22); + this.installedSysPackageFilterToolStripMenuItem.Text = "コンピュータ内"; + this.installedSysPackageFilterToolStripMenuItem.ToolTipText = "コンピュータにインストールされているソフトを表示"; + this.installedSysPackageFilterToolStripMenuItem.Click += new System.EventHandler(this.AnyPackageFilterToolStripMenuItemClicked); + // + // searchTextBox + // + this.searchTextBox.ForeColor = System.Drawing.SystemColors.GrayText; + this.searchTextBox.Name = "searchTextBox"; + this.searchTextBox.Overflow = System.Windows.Forms.ToolStripItemOverflow.Never; + this.searchTextBox.Size = new System.Drawing.Size(150, 25); + this.searchTextBox.Text = "検索"; + this.searchTextBox.ToolTipText = "検索する語を入力"; + this.searchTextBox.Enter += new System.EventHandler(this.SearchTextBoxEnter); + this.searchTextBox.Leave += new System.EventHandler(this.SearchTextBoxLeave); + this.searchTextBox.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.SearchTextBoxKeyPress); + // + // packageCommandsToolStrip + // + this.packageCommandsToolStrip.Dock = System.Windows.Forms.DockStyle.None; + this.packageCommandsToolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.updateToolStripButton, + this.upgradeToolStripButton, + this.installToolStripButton, + this.uninstallToolStripButton}); + this.packageCommandsToolStrip.Location = new System.Drawing.Point(3, 25); + this.packageCommandsToolStrip.Name = "packageCommandsToolStrip"; + this.packageCommandsToolStrip.Size = new System.Drawing.Size(223, 25); + this.packageCommandsToolStrip.TabIndex = 2; + // + // updateToolStripButton + // + this.updateToolStripButton.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.localUpdateToolStripMenuItem}); + this.updateToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("updateToolStripButton.Image"))); + this.updateToolStripButton.Name = "updateToolStripButton"; + this.updateToolStripButton.Size = new System.Drawing.Size(111, 22); + this.updateToolStripButton.Text = "リストの更新(&U)"; + this.updateToolStripButton.ToolTipText = "ソフトリスト更新(U)"; + this.updateToolStripButton.ButtonClick += new System.EventHandler(this.UpdateToolStripButtonClick); + // + // localUpdateToolStripMenuItem + // + this.localUpdateToolStripMenuItem.Name = "localUpdateToolStripMenuItem"; + this.localUpdateToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F5; + this.localUpdateToolStripMenuItem.Size = new System.Drawing.Size(250, 22); + this.localUpdateToolStripMenuItem.Text = "インストール済ソフトの読み直し(&R)"; + this.localUpdateToolStripMenuItem.Click += new System.EventHandler(this.LocalupdateToolStripMenuItemClick); + // + // upgradeToolStripButton + // + this.upgradeToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("upgradeToolStripButton.Image"))); + this.upgradeToolStripButton.Name = "upgradeToolStripButton"; + this.upgradeToolStripButton.Size = new System.Drawing.Size(100, 22); + this.upgradeToolStripButton.Text = "ソフトの更新(&G)"; + this.upgradeToolStripButton.Click += new System.EventHandler(this.UpgradeToolStripButtonClick); + // + // installToolStripButton + // + this.installToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("installToolStripButton.Image"))); + this.installToolStripButton.Name = "installToolStripButton"; + this.installToolStripButton.Size = new System.Drawing.Size(80, 22); + this.installToolStripButton.Text = "インストール"; + this.installToolStripButton.ToolTipText = "選択されているアプリケーションをインストール"; + this.installToolStripButton.Visible = false; + this.installToolStripButton.Click += new System.EventHandler(this.InstallToolStripButtonClick); + // + // uninstallToolStripButton + // + this.uninstallToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("uninstallToolStripButton.Image"))); + this.uninstallToolStripButton.Name = "uninstallToolStripButton"; + this.uninstallToolStripButton.Size = new System.Drawing.Size(98, 22); + this.uninstallToolStripButton.Text = "アンインストール"; + this.uninstallToolStripButton.ToolTipText = "選択されているアプリケーションをアンインストール"; + this.uninstallToolStripButton.Visible = false; + this.uninstallToolStripButton.Click += new System.EventHandler(this.UninstallToolStripButtonClick); + // + // splitContainer + // + this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel2; + this.splitContainer.Location = new System.Drawing.Point(3, 53); + this.splitContainer.Name = "splitContainer"; + this.splitContainer.Orientation = System.Windows.Forms.Orientation.Horizontal; + // + // splitContainer.Panel1 + // + this.splitContainer.Panel1.Controls.Add(this.packageListView); + // + // splitContainer.Panel2 + // + this.splitContainer.Panel2.Controls.Add(this.detailBox); + this.splitContainer.Size = new System.Drawing.Size(486, 310); + this.splitContainer.SplitterDistance = 225; + this.splitContainer.TabIndex = 1; + // + // packageListView + // + this.packageListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.nameHeader, + this.versionHeader, + this.summaryHeader}); + this.packageListView.ContextMenuStrip = this.packageListContextMenuStrip; + this.packageListView.Dock = System.Windows.Forms.DockStyle.Fill; + this.packageListView.FullRowSelect = true; + this.packageListView.GridLines = true; + this.packageListView.Location = new System.Drawing.Point(0, 0); + this.packageListView.MultiSelect = false; + this.packageListView.Name = "packageListView"; + this.packageListView.Size = new System.Drawing.Size(486, 225); + this.packageListView.TabIndex = 0; + this.packageListView.UseCompatibleStateImageBehavior = false; + this.packageListView.View = System.Windows.Forms.View.Details; + this.packageListView.ItemActivate += new System.EventHandler(this.PackageListViewItemActivate); + this.packageListView.SelectedIndexChanged += new System.EventHandler(this.PackageListViewSelectedIndexChanged); + this.packageListView.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.PackageListViewColumnClick); + // + // nameHeader + // + this.nameHeader.Text = "名前"; + this.nameHeader.Width = 100; + // + // versionHeader + // + this.versionHeader.Text = "バージョン"; + // + // summaryHeader + // + this.summaryHeader.Text = "概要"; + this.summaryHeader.Width = 300; + // + // packageListContextMenuStrip + // + this.packageListContextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.installToolStripMenuItem, + this.uninstallToolStripMenuItem, + this.toolStripSeparator1, + this.webResourcesToolStripMenuItem, + this.openInstalledDirectoryStripMenuItem}); + this.packageListContextMenuStrip.Name = "packageListContextMenuStrip"; + this.packageListContextMenuStrip.Size = new System.Drawing.Size(226, 98); + this.packageListContextMenuStrip.Opening += new System.ComponentModel.CancelEventHandler(this.PackageListContextMenuStripOpening); + // + // installToolStripMenuItem + // + this.installToolStripMenuItem.Name = "installToolStripMenuItem"; + this.installToolStripMenuItem.Size = new System.Drawing.Size(225, 22); + this.installToolStripMenuItem.Text = "インストール(&I)..."; + this.installToolStripMenuItem.Click += new System.EventHandler(this.InstallToolStripButtonClick); + // + // uninstallToolStripMenuItem + // + this.uninstallToolStripMenuItem.Name = "uninstallToolStripMenuItem"; + this.uninstallToolStripMenuItem.Size = new System.Drawing.Size(225, 22); + this.uninstallToolStripMenuItem.Text = "アンインストール(&U)..."; + this.uninstallToolStripMenuItem.Click += new System.EventHandler(this.UninstallToolStripButtonClick); + // + // webResourcesToolStripMenuItem + // + this.webResourcesToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.webOfficialToolStripMenuItem, + this.webGoogleSearchToolStripMenuItem}); + this.webResourcesToolStripMenuItem.Name = "webResourcesToolStripMenuItem"; + this.webResourcesToolStripMenuItem.Size = new System.Drawing.Size(225, 22); + this.webResourcesToolStripMenuItem.Tag = "\"{0}\"に関するWebページ(&W)"; + // + // webOfficialToolStripMenuItem + // + this.webOfficialToolStripMenuItem.Name = "webOfficialToolStripMenuItem"; + this.webOfficialToolStripMenuItem.Size = new System.Drawing.Size(145, 22); + this.webOfficialToolStripMenuItem.Text = "公式サイト(&O)"; + this.webOfficialToolStripMenuItem.Click += new System.EventHandler(this.WebOfficialToolStripMenuItemClick); + // + // webGoogleSearchToolStripMenuItem + // + this.webGoogleSearchToolStripMenuItem.Name = "webGoogleSearchToolStripMenuItem"; + this.webGoogleSearchToolStripMenuItem.Size = new System.Drawing.Size(145, 22); + this.webGoogleSearchToolStripMenuItem.Text = "Google検索(&G)"; + this.webGoogleSearchToolStripMenuItem.Click += new System.EventHandler(this.WebGoogleSearchToolStripMenuItemClick); + // + // openInstalledDirectoryStripMenuItem + // + this.openInstalledDirectoryStripMenuItem.Name = "openInstalledDirectoryStripMenuItem"; + this.openInstalledDirectoryStripMenuItem.Size = new System.Drawing.Size(225, 22); + this.openInstalledDirectoryStripMenuItem.Text = "インストール先のフォルダを開く(&O)"; + this.openInstalledDirectoryStripMenuItem.Click += new System.EventHandler(this.OpenInstalledDirectoryStripMenuItemClick); + // + // detailBox + // + this.detailBox.BackColor = System.Drawing.SystemColors.Control; + this.detailBox.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.detailBox.Dock = System.Windows.Forms.DockStyle.Fill; + this.detailBox.ForeColor = System.Drawing.SystemColors.ControlText; + this.detailBox.Location = new System.Drawing.Point(0, 0); + this.detailBox.Name = "detailBox"; + this.detailBox.ReadOnly = true; + this.detailBox.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.Vertical; + this.detailBox.Size = new System.Drawing.Size(486, 81); + this.detailBox.TabIndex = 0; + this.detailBox.Text = ""; + this.detailBox.LinkClicked += new System.Windows.Forms.LinkClickedEventHandler(this.PackageDetailBoxLinkClicked); + // + // PackageListViewForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(492, 366); + this.Controls.Add(this.tableLayoutPanel1); + this.Name = "PackageListViewForm"; + this.Text = "AppliStation"; + this.Load += new System.EventHandler(this.Form_OnLoad); + this.tableLayoutPanel1.ResumeLayout(false); + this.tableLayoutPanel1.PerformLayout(); + this.toolStripContainer.ResumeLayout(false); + this.toolStripContainer.PerformLayout(); + this.packageListFilterToolStrip.ResumeLayout(false); + this.packageListFilterToolStrip.PerformLayout(); + this.packageCommandsToolStrip.ResumeLayout(false); + this.packageCommandsToolStrip.PerformLayout(); + this.splitContainer.Panel1.ResumeLayout(false); + this.splitContainer.Panel2.ResumeLayout(false); + this.splitContainer.ResumeLayout(false); + this.packageListContextMenuStrip.ResumeLayout(false); + this.ResumeLayout(false); + } + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripMenuItem openInstalledDirectoryStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem webGoogleSearchToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem webOfficialToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem webResourcesToolStripMenuItem; + private System.Windows.Forms.RichTextBox detailBox; + private System.Windows.Forms.SplitContainer splitContainer; + private System.Windows.Forms.ToolStripPanel toolStripContainer; + private System.Windows.Forms.ToolStripMenuItem installedSysPackageFilterToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem installedASPackageFilterToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem notInstalledPackageFilterToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem allPackageFilterToolStripMenuItem; + private System.Windows.Forms.ToolStripDropDownButton packageFilterToolStripDropDownButton; + private System.Windows.Forms.ToolStripButton upgradeToolStripButton; + private System.Windows.Forms.ToolStripMenuItem localUpdateToolStripMenuItem; + private System.Windows.Forms.ToolStripSplitButton updateToolStripButton; + private System.Windows.Forms.ToolStripMenuItem uninstallToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem installToolStripMenuItem; + private System.Windows.Forms.ContextMenuStrip packageListContextMenuStrip; + private System.Windows.Forms.ToolStripButton uninstallToolStripButton; + private System.Windows.Forms.ToolStripButton installToolStripButton; + private System.Windows.Forms.ToolStrip packageCommandsToolStrip; + private System.Windows.Forms.ToolStrip packageListFilterToolStrip; + private System.Windows.Forms.ToolStripTextBox searchTextBox; + private System.Windows.Forms.ColumnHeader versionHeader; + private System.Windows.Forms.ListView packageListView; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + private System.Windows.Forms.ColumnHeader summaryHeader; + private System.Windows.Forms.ColumnHeader nameHeader; + } +} diff --git a/AppliStation/PackageListViewForm.cs b/AppliStation/PackageListViewForm.cs new file mode 100644 index 0000000..66e5c56 --- /dev/null +++ b/AppliStation/PackageListViewForm.cs @@ -0,0 +1,634 @@ +using System; +using System.Drawing; +using System.Windows.Forms; +using NaGet.Packages; +using NaGet.Packages.Install; +using System.IO; +using System.Collections.Generic; + +namespace AppliStation +{ + /// + /// Description of PackageListViewForm. + /// + public partial class PackageListViewForm : Form + { + protected PackageListsManager pkgListsMan = null; + + public PackageListViewForm() + { + // + // The InitializeComponent() call is required for Windows Forms designer support. + // + InitializeComponent(); + + installToolStripMenuItem.Font = new Font(installToolStripMenuItem.Font, FontStyle.Bold); + uninstallToolStripMenuItem.Font = new Font(uninstallToolStripMenuItem.Font, FontStyle.Bold); + + pkgListsMan = new PackageListsManager(); + } + + void PackageListViewSelectedIndexChanged(object sender, EventArgs e) + { + bool installBtnEnabled = false; + bool uninstallBtnEnabled = false; + + detailBox.Clear(); + foreach (ListViewItem item in packageListView.SelectedItems) { + Package pkg = (Package) item.Tag; + + bool isInstalledPackage = pkg is InstalledPackage; + uninstallBtnEnabled = isInstalledPackage; + installBtnEnabled = ! isInstalledPackage; + + detailBox.SelectionFont = new Font(detailBox.Font.FontFamily, 12); + detailBox.SelectedText += string.Format("{0} ({1})\r\n", pkg.Name, pkg.Version); + if (! string.IsNullOrEmpty(pkg.Tags) ) { + detailBox.SelectionFont = new Font(detailBox.Font.FontFamily, 8); + detailBox.SelectedText += string.Format("ƒ^ƒO: {0}\r\n", pkg.Tags); + } + if (isInstalledPackage) { + InstalledPackage iPkg = (InstalledPackage) pkg; + System.Text.StringBuilder sb = new System.Text.StringBuilder(); + if (iPkg.UninstallInfo.InstallDate != null) { + sb.AppendFormat("ƒCƒ“ƒXƒg[ƒ‹‚µ‚½“ú: {0:d} ", iPkg.UninstallInfo.InstallDate.Value); + } + if (iPkg.UninstallInfo.EstimatedSize > 0) { + sb.AppendFormat("ƒTƒCƒY: {0} ", NaGet.Utils.FormatSize(iPkg.UninstallInfo.EstimatedSize*1024)); + } + + if (sb.Length > 0) { + detailBox.SelectionFont = new Font(detailBox.Font.FontFamily, 8); + detailBox.SelectedText += sb.ToString(); + detailBox.SelectedText += "\r\n"; + } + } + detailBox.SelectionFont = detailBox.Font; + if (pkg.Url != null && pkg.Url.Href != null) { + detailBox.SelectedText += "ŒöŽ®ƒTƒCƒg: " + pkg.Url.Href + "\r\n"; + } + detailBox.SelectedText += pkg.Summary; + + break; + } + + uninstallToolStripButton.Visible = uninstallBtnEnabled; + installToolStripButton.Visible = installBtnEnabled; + + if (packageListView.SelectedItems.Count <= 0) { + detailBox.SelectionFont = detailBox.Font; + int count = packageListView.Items.Count; + detailBox.Text = (count > 0) ? string.Format("{0}ŒÂ‚̃\ƒtƒg‚ª‚ ‚è‚Ü‚·B", count) + : "ŠY“–‚·‚éƒ\ƒtƒg‚ª‚ ‚è‚Ü‚¹‚ñB"; + } + + detailBox.SelectionStart = 0; + detailBox.ScrollToCaret(); + } + + void PackageListViewItemActivate(object sender, EventArgs e) + { + if (packageListView.SelectedItems.Count <= 0) { + return; // exit + } + + foreach (ListViewItem item in packageListView.SelectedItems) { + Package pkg = (Package) item.Tag; + + if (pkg is InstalledPackage) { + UninstallToolStripButtonClick(sender, e); + } else { + InstallToolStripButtonClick(sender, e); + } + + break; + } + } + + AppliStation.Util.ListViewItemSortComparer packageListViewSortComparer; + + void PackageListViewColumnClick(object sender, ColumnClickEventArgs e) + { + SortOrder order = SortOrder.None; + + if (packageListViewSortComparer == null) { + order = SortOrder.Ascending; + packageListViewSortComparer = new AppliStation.Util.ListViewItemSortComparer(e.Column, order); + packageListView.ListViewItemSorter = packageListViewSortComparer; + } else { + if (packageListViewSortComparer.Column == e.Column) { + order = (packageListViewSortComparer.Order == SortOrder.Ascending)? SortOrder.Descending : SortOrder.Ascending; + + packageListViewSortComparer.Order = order; + } else { + order = packageListViewSortComparer.Order; + packageListViewSortComparer.Column = e.Column; + } + + packageListView.Sort(); + } + AppliStation.Util.NativeMethods.ColumnHeader_SetSortState(packageListView, e.Column, order); + + // ƒ\[ƒg‘Ώۗñ‚̐F•t‚¯ + try { + // SendMessage(hWnd, LVM_SETSELECTEDCOLUMN, column, NULL); + AppliStation.Util.NativeMethods.SendMessage(packageListView.Handle, 0x1000+140, (uint) e.Column, 0); + } catch (Exception) { + } + } + + void Form_OnLoad(object sender, EventArgs e) + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PackageListViewForm)); + ImageList imageList = new ImageList(); + imageList.Images.Add("installed", this.Icon); + imageList.Images.Add("sys", (Icon)(resources.GetObject("sysinstalled.Icon"))); + packageListView.SmallImageList = imageList; + + updatePackageFilterToolStripMenuItemCheckState(); + installedASPackageFilterToolStripMenuItem.Image = this.Icon.ToBitmap(); + installedSysPackageFilterToolStripMenuItem.Image = ((Icon)(resources.GetObject("sysinstalled.Icon"))).ToBitmap(); + } + + #region PackageFilterŠÖ˜A + + private enum PackageFilterIndex : int + { + All = 0, + NotInstalled = 1, + InstalledAS = 2, + InstalledSys = 3, + } + + private PackageFilterIndex currentPackageFilter = PackageFilterIndex.All; + + private PackageFilterIndex CurrentPackageFilter { + get { + return currentPackageFilter; + } + set { + currentPackageFilter = value; + + updatePackageFilterToolStripMenuItemCheckState(); + } + } + + private void updatePackageFilterToolStripMenuItemCheckState() + { + ToolStripMenuItem selected = getCheckedPackageFilterToolStripItem(); + + foreach (ToolStripMenuItem item in packageFilterToolStripDropDownButton.DropDown.Items) { + item.Checked = selected == item; + } + + packageFilterToolStripDropDownButton.Text = selected.Text; + packageFilterToolStripDropDownButton.Image = selected.Image; + packageFilterToolStripDropDownButton.ToolTipText = selected.ToolTipText; + } + + private ToolStripMenuItem getCheckedPackageFilterToolStripItem() + { + switch (currentPackageFilter) { + case PackageFilterIndex.NotInstalled: + return notInstalledPackageFilterToolStripMenuItem; + case PackageFilterIndex.InstalledAS: + return installedASPackageFilterToolStripMenuItem; + case PackageFilterIndex.InstalledSys: + return installedSysPackageFilterToolStripMenuItem; + default: + return allPackageFilterToolStripMenuItem; + } + } + + void AnyPackageFilterToolStripMenuItemClicked(object sender, EventArgs e) + { + if (sender == notInstalledPackageFilterToolStripMenuItem) { + currentPackageFilter = PackageFilterIndex.NotInstalled; + } else if (sender == installedASPackageFilterToolStripMenuItem) { + currentPackageFilter = PackageFilterIndex.InstalledAS; + } else if (sender == installedSysPackageFilterToolStripMenuItem) { + currentPackageFilter = PackageFilterIndex.InstalledSys; + } else { + currentPackageFilter = PackageFilterIndex.All; + } + + updatePackageFilterToolStripMenuItemCheckState(); + searchTextBoxUpdate(false); + } + + #endregion + + void PackageListViewUpdate() + { + this.packageListView.Items.Clear(); + + if (currentPackageFilter == PackageFilterIndex.All || currentPackageFilter == PackageFilterIndex.NotInstalled) { + foreach (Package pkg in pkgListsMan.AvailablePkgList.Search(this.SearchKeyword)) { + if (Installation.GetPreferInstallerIndex(pkg) >= 0) { // ƒCƒ“ƒXƒg[ƒ‹‰Â”\ + if (currentPackageFilter == PackageFilterIndex.NotInstalled && + (pkgListsMan.InstalledPkgList.GetPackageForName(pkg.Name) != null|| + pkgListsMan.SystemInstalledPkgList.GetPackageForName(pkg.Name) != null) ) { + continue; // ƒCƒ“ƒXƒg[ƒ‹Ï‚݂͎Ÿ‚̃‹[ƒv‚Ö(–¢ƒCƒ“ƒXƒg[ƒ‹ƒ\ƒtƒg’ŠoŽž) + } + + ListViewItem item = new ListViewItem(new string[]{pkg.Name, pkg.Version, pkg.Summary}); + item.Tag = pkg; + item.ToolTipText = pkg.Summary; + + this.packageListView.Items.Add(item); + } + } + } + + if (currentPackageFilter == PackageFilterIndex.All || currentPackageFilter == PackageFilterIndex.InstalledAS) { + foreach (Package pkg in pkgListsMan.InstalledPkgList.Search(this.SearchKeyword)) { + ListViewItem item = new ListViewItem(new string[]{pkg.Name, pkg.Version, pkg.Summary}); + item.Tag = pkg; + item.ToolTipText = pkg.Summary; + item.ImageKey = "installed"; + + this.packageListView.Items.Add(item); + } + } + + if (currentPackageFilter == PackageFilterIndex.All || currentPackageFilter == PackageFilterIndex.InstalledSys) { + foreach (Package pkg in pkgListsMan.SystemInstalledPkgList.Search(this.SearchKeyword)) { + ListViewItem item = new ListViewItem(new string[]{pkg.Name, pkg.Version, pkg.Summary}); + item.Tag = pkg; + item.ToolTipText = pkg.Summary; + item.ImageKey = "sys"; + + this.packageListView.Items.Add(item); + } + } + + PackageListViewSelectedIndexChanged(packageListView, null); + detailBox.Refresh(); + + //this.packageListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent); + } + + void PackageDetailBoxLinkClicked(object sender, LinkClickedEventArgs e) + { + System.Diagnostics.Process.Start(e.LinkText); + } + + internal void updateActionInvoke(bool downloadPackageListsFlag) + { + AppliStation.Util.ExecutionProgressViewer prog = new AppliStation.Util.ExecutionProgressViewer(); + prog.Shown += delegate(object sender2, EventArgs e2) { + NaGet.SubCommands.NaGetUpdate tasks = new NaGet.SubCommands.NaGetUpdate(pkgListsMan, downloadPackageListsFlag); + tasks.Downloader = prog.Downloader; + prog.SetTaskSet(tasks); + prog.Refresh(); + prog.StartTaskSet(); + }; + prog.Text = "ƒŠƒXƒg‚̍XV"; + prog.ShowDialog(this); + } + + void UpdateToolStripButtonClick(object sender, EventArgs e) + { + updateActionInvoke(true); + + UpdatePackageList(); + } + + void LocalupdateToolStripMenuItemClick(object sender, EventArgs e) + { + updateActionInvoke(false); + + UpdatePackageList(); + } + + #region searchTextBox‚Ü‚í‚è + + private bool searchTextBoxIsEmpty = true; + + private Timer searchUpdateTimer = null; + + string SearchKeyword { + get { + return searchTextBoxIsEmpty? string.Empty : searchTextBox.Text; + } + } + + void SearchTextBoxEnter(object sender, EventArgs e) + { + if (searchTextBoxIsEmpty) { + searchTextBox.Text = string.Empty; + searchTextBox.ForeColor = DefaultForeColor; + searchTextBoxIsEmpty = false; + } + } + + void SearchTextBoxLeave(object sender, EventArgs e) + { + if (string.IsNullOrEmpty(searchTextBox.Text)) { + searchTextBox.Text = "ŒŸõ"; + searchTextBox.ForeColor = SystemColors.GrayText; + searchTextBoxIsEmpty = true; + } + } + + void SearchTextBoxKeyPress(object sender, KeyPressEventArgs e) + { + switch (e.KeyChar) { + case (char)Keys.Enter: + searchTextBoxUpdate(true); + break; + case (char)Keys.Escape: + searchTextBox.Text = ""; + searchTextBoxUpdate(false); + break; + default: + searchTextBoxUpdate(false); + break; + } + } + + private void searchTextBoxUpdate(bool force) + { + if (! this.Created) return; + + if (searchUpdateTimer != null) { + searchUpdateTimer.Stop(); + } else { + searchUpdateTimer = new Timer(); + searchUpdateTimer.Tick += searchUpdateTimerTick; + } + searchUpdateTimer.Interval = (force)? 10 : 500; + searchUpdateTimer.Start(); + } + + private void searchUpdateTimerTick(object sender, EventArgs e) + { + searchUpdateTimer.Stop(); + + PackageListViewUpdate(); + } + + #endregion + + internal void installActionInvoke(Package[] pkgs) + { + AppliStation.Util.ExecutionProgressViewer prog = new AppliStation.Util.ExecutionProgressViewer(); + prog.Shown += delegate(object sender2, EventArgs e2) { + NaGet.SubCommands.NaGetInstall tasks = new NaGet.SubCommands.NaGetInstall(pkgListsMan, pkgs); + tasks.Downloader = prog.Downloader; + prog.SetTaskSet(tasks); + prog.Refresh(); + prog.StartTaskSet(); + }; + prog.Text = string.Format("ƒ\ƒtƒgƒEƒFƒA‚̃Cƒ“ƒXƒg[ƒ‹"); + prog.ShowDialog(this); + } + + void InstallToolStripButtonClick(object sender, EventArgs e) + { + PackagesInstallConfirmForm confirm = new PackagesInstallConfirmForm(); + confirm.PkgListsManager = pkgListsMan; + confirm.Packages = SelectedPackages(); + confirm.UseRunas = confirm.GetShouldUseRunas(); + DialogResult result = confirm.ShowDialog(this); + + if (result == DialogResult.OK) { + Package[] instPkgs = confirm.CheckedPackages; + + if (confirm.UseRunas) { + this.Enabled = false; + installRunasActionInvoke(instPkgs); + this.Enabled = true; + this.Focus(); + } else { + installActionInvoke(instPkgs); + } + + UpdatePackageList(); + } + } + + public void installRunasActionInvoke(Package[] pkgs) + { + string tmpfileName = System.IO.Path.GetTempFileName(); + try { + NaGet.Utils.PutSerializeObject(tmpfileName, pkgs); + + System.Diagnostics.ProcessStartInfo procInfo = new System.Diagnostics.ProcessStartInfo(); + procInfo.FileName = Application.ExecutablePath; + procInfo.Arguments = string.Format("--noupdate --cmd=install \"--pkgsref={0}\"", tmpfileName); + procInfo.Verb = "runas"; + procInfo.WorkingDirectory = Environment.CurrentDirectory; + + using (System.Diagnostics.Process hProc = System.Diagnostics.Process.Start(procInfo)) { + hProc.WaitForExit(); + } + + pkgListsMan.LoadPackageLists(); + } catch (System.ComponentModel.Win32Exception ex) { + MessageBox.Show(ex.Message, "ƒCƒ“ƒXƒg[ƒ‹", MessageBoxButtons.OK, MessageBoxIcon.Error); + } finally { + if (File.Exists(tmpfileName)) { + File.Delete(tmpfileName); + } + } + } + + internal void uninstallActionInvoke(InstalledPackage[] pkgs) + { + AppliStation.Util.ExecutionProgressViewer prog = new AppliStation.Util.ExecutionProgressViewer(); + prog.Shown += delegate(object sender2, EventArgs e2) { + NaGet.SubCommands.NaGetUninstall tasks = new NaGet.SubCommands.NaGetUninstall(pkgListsMan, pkgs); + prog.SetTaskSet(tasks); + prog.Refresh(); + prog.StartTaskSet(); + }; + prog.Text = string.Format("ƒ\ƒtƒgƒEƒFƒA‚̃Aƒ“ƒCƒ“ƒXƒg[ƒ‹"); + prog.ShowDialog(this); + } + + internal void uninstallRunasActionInvoke(InstalledPackage[] pkgs) + { + string tmpfileName = System.IO.Path.GetTempFileName(); + try { + NaGet.Utils.PutSerializeObject(tmpfileName, pkgs); + + System.Diagnostics.ProcessStartInfo procInfo = new System.Diagnostics.ProcessStartInfo(); + procInfo.FileName = Application.ExecutablePath; + procInfo.Arguments = string.Format("--noupdate --cmd=uninstall \"--pkgsref={0}\"", tmpfileName); + procInfo.Verb = "runas"; + procInfo.WorkingDirectory = Environment.CurrentDirectory; + + using (System.Diagnostics.Process hProc = System.Diagnostics.Process.Start(procInfo)) { + hProc.WaitForExit(); + } + + pkgListsMan.LoadPackageLists(); + } catch (System.ComponentModel.Win32Exception ex) { + MessageBox.Show(ex.Message, "ƒAƒ“ƒCƒ“ƒXƒg[ƒ‹", MessageBoxButtons.OK, MessageBoxIcon.Error); + } finally { + if (File.Exists(tmpfileName)) { + File.Delete(tmpfileName); + } + } + } + + void UninstallToolStripButtonClick(object sender, EventArgs e) + { + PackageUninstallConfirmForm confirm = new PackageUninstallConfirmForm(); + foreach (InstalledPackage pkg in SelectedPackages()) { + confirm.UninstallPackage = pkg; + break; + } + confirm.UseRunas = confirm.GetShouldUseRunas(); + DialogResult result = confirm.ShowDialog(this); + + if (result == DialogResult.OK) { + InstalledPackage[] instPkgs = new InstalledPackage[]{confirm.UninstallPackage}; + + if (confirm.UseRunas) { + this.Enabled = false; + uninstallRunasActionInvoke(instPkgs); + this.Enabled = true; + this.Focus(); + } else { + uninstallActionInvoke(instPkgs); + } + + UpdatePackageList(); + } + } + + + void WebOfficialToolStripMenuItemClick(object sender, EventArgs e) + { + foreach (Package pkg in SelectedPackages()) { + string linkURL = pkg.Url.Href; + + if (! (pkg == null || string.IsNullOrEmpty(linkURL))) { + System.Diagnostics.Process.Start(linkURL); + } + break; + } + } + + void WebGoogleSearchToolStripMenuItemClick(object sender, EventArgs e) + { + foreach (Package pkg in SelectedPackages()) { + string q = System.Web.HttpUtility.UrlEncode(pkg.Name, System.Text.Encoding.UTF8); + string googleURL = @"http://www.google.co.jp/search?q="+q; + + System.Diagnostics.Process.Start(googleURL); + + break; + } + } + + void OpenInstalledDirectoryStripMenuItemClick(object sender, EventArgs e) + { + foreach (InstalledPackage pkg in SelectedPackages()) { + if (pkg.Type == InstallerType.ARCHIVE) { + System.Diagnostics.Process.Start(Path.Combine(NaGet.Env.ArchiveProgramFiles, pkg.Name)); + } else if (Directory.Exists(pkg.UninstallInfo.InstallLocation)) { + System.Diagnostics.Process.Start(pkg.UninstallInfo.InstallLocation); + } + + break; + } + } + + void PackageListContextMenuStripOpening(object sender, System.ComponentModel.CancelEventArgs e) + { + // ‘I‘ð‚³‚ê‚Ä‚¢‚È‚¢‚È‚çŠJ‚©‚È‚¢ + if (packageListView.SelectedItems.Count <= 0) { + e.Cancel = true; + return; + } + + foreach (Package pkg in SelectedPackages()) { + bool isInstalledPackage = pkg is InstalledPackage; + + installToolStripMenuItem.Visible = ! isInstalledPackage; + uninstallToolStripMenuItem.Visible = isInstalledPackage; + + webResourcesToolStripMenuItem.Text = string.Format(webResourcesToolStripMenuItem.Tag.ToString(), pkg.Name); + webOfficialToolStripMenuItem.Enabled = ! (pkg.Url == null || string.IsNullOrEmpty(pkg.Url.Href)); + // webGoogleSearchToolStripMenuItem always active. + + openInstalledDirectoryStripMenuItem.Visible = isInstalledPackage && + ( (pkg.Type == InstallerType.ARCHIVE) || Directory.Exists(((InstalledPackage) pkg).UninstallInfo.InstallLocation) ); + + break; + } + } + + private IEnumerable getUpdatedPackages(PackageList installedPkgList, PackageList avaiablePkgList, IComparer verComp) + { + foreach (InstalledPackage pkg in installedPkgList.Packages) { + Package avaiablePkg = avaiablePkgList.GetPackageForName(pkg.Name); + + if (avaiablePkgList != null) { + if (verComp.Compare(pkg.Version, avaiablePkg.Version) < 0 && + installedPkgList.GetPackageForPackage(pkg.Name, avaiablePkg.Version) == null) { + + yield return avaiablePkg; + } + } + } + } + + void UpgradeToolStripButtonClick(object sender, EventArgs e) + { + List pkgs = new List(); + VersionComparetor verComp = new VersionComparetor(); + PackageList avaiablePackageList = pkgListsMan.AvailablePkgList; + + pkgs.AddRange(getUpdatedPackages(pkgListsMan.InstalledPkgList, avaiablePackageList, verComp)); + pkgs.AddRange(getUpdatedPackages(pkgListsMan.SystemInstalledPkgList, avaiablePackageList, verComp)); + + if (pkgs.Count <= 0) { + MessageBox.Show(this, "XV‚³‚ꂽƒ\ƒtƒg‚Í‚ ‚è‚Ü‚¹‚ñ", "ƒ\ƒtƒg‚̍XV"); + return; + } + + PackagesInstallConfirmForm confirm = new PackagesInstallConfirmForm(); + confirm.PkgListsManager = pkgListsMan; + confirm.Packages = pkgs.ToArray(); + DialogResult result = confirm.ShowDialog(this); + + if (result == DialogResult.OK) { + Package[] instPkgs = confirm.CheckedPackages; + + if (confirm.UseRunas) { + this.Enabled = false; + installRunasActionInvoke(instPkgs); + this.Enabled = true; + } else { + installActionInvoke(instPkgs); + } + + UpdatePackageList(); + } + } + + public void UpdatePackageList() + { + pkgListsMan.LoadPackageLists(); + this.PackageListViewUpdate(); + } + + /// + /// ƒCƒ“ƒXƒg[ƒ‹‚·‚邿‚¤‘I‘ð‚³‚ê‚½ƒpƒbƒP[ƒW‚Ì”z—ñ + /// + public TPackage[] SelectedPackages() where TPackage : Package + { + List pkgs = new List(); + foreach (ListViewItem item in packageListView.SelectedItems) { + pkgs.Add((TPackage) item.Tag); + } + + return pkgs.ToArray(); + } + } + +} diff --git a/AppliStation/PackageListViewForm.resx b/AppliStation/PackageListViewForm.resx new file mode 100644 index 0000000..adca5e9 --- /dev/null +++ b/AppliStation/PackageListViewForm.resx @@ -0,0 +1,358 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 127, 17 + + + 314, 17 + + + + + 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 + P90Qa56ijxDNAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAA49JREFUOE89k39M + GwUUx28KUTfnnGE1JF23dZuJxhmN4h8aXTJN8D91W2JnHGIQbaQVyCaoc5M4IyWOxbDE6LSUUmiFrQLp + gEFt11HaUo5B18FGx4/R0sLalVqu0Bb64+trnb7kk0vu7vu5d+/ebaiVyTbnbNyyN2dT3jYmlXyCSa5t + 3bhp25ZHHt7My0Vyx/TUcDef/2RuXl7eYz6fb1ar1Zr0en2YYZgkwTAq9R8/NQxF4mdtibRyJI22UaCL + 0DsA2zjQrrUHpm4H0+k0YDKZ3Hw+/w2KbSU2ZAXNSmVViFvBuWtJ/GhJQT4YR5OBg6o3iNbORZgGgwgE + gFAojYMHD12hyKeEgHggKygvLy+YnZpcvzw4ieM13ag5rUN9vR6KRgvaNSwcIy7ElwPwez2QSiUuHo8n + oVj+/x1IJJI9N5zO2B3fEmyOeYTv+uH3B+H2+eHyLODS+CJq+tyo6JpD8ceVMwKBsJrC24kHsx1UV1fv + Nv7VF7Ven0SlDfiOTeDLwXWIryTxTmcMR3+dwC89Hlw0LqKhoZ8rKqq1C4UFhRR9NNvFya++EH6vsURl + vfOoGgCK+gCxiehJorbFiYD3HqIcMDMFjNJwe+h8RcWfnp07n38zKzlZVSn8RDUWffcCB7UT+M0ehWpg + Bo1qFiH/EjIVDgNOFrikA5pVgEKRpIGeyAz0Oab8c6mw38JGdbej6HCuYlX7ERI/vwKzUgNuFUgkyBAB + po0c2KspNCoAHYlkMlOMBB8yZWUSITtkiQYCIeimI+ieO4ph9cu43GrFtTFgdga4M+HFeVU/RtglsDSj + YXYdra2jmUU6zYjFYqF5YCDq8QZhdEdQtnAIz3YJINcOYcQODBPXbQvo6LTBO7eMldU4uJU4WtSmBAnO + MqWlpUKDwRB1e+7C7lvGAfMLeKiJwXG5AoZeoEkJ9HcBDn0SMXqV/6q4+Ot5EtQyJSUluzs7OtbGxsZx + 414Ye7W7sKv9aZSc/x0tchI0ARe1gMGI7EZmymyeSOXnP6UngZgRiUTbm5uVy+MTt8ClgJucB+7IGuRX + Qzj1gzV9oS0GqxVwuYBgME3hm6l9+w44KFxPvJbZpdzCwsL36+rqpjWatr9PffOtTyQ6cuvFlwosgh17 + eva//sGQWHxm9tixc97Dh6UuPv+ZzJPPEG8TvIwg81c9TuwnpMQJoiL7if696S3iPeKz+9eL6Pjq/XDO + P90Qa56ijxDNAAAAAElFTkSuQmCC + + + + + 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 + Sf+QAAD/pBMA/6oVAP+0GAD/whwA/8kaAP/FHw7/1cbD//39/f+oj4v/8rGj//27rP/+va3//7+u///D + tv//spr/8MK1/8DU2v+QjYu5AAAAAAAAAABogXbYAHs5/2J4af/YxND/19zb/8rKyv/Nzc7/vM7R/5M0 + Mf++cGj/oisg/5sBAP+uGAD/vhkA/8odAP/WJAD/4BYA//AsBP/VraP/4N3c/+Dg4P+nioL//867///M + vP//z73//9XF///Jsf/0w63/xdTc/5GPj+CXl5cLAAAAAHRqceRHJi3/el9n/8DGx//X2Nj/w8PD/9DQ + 0f++0NP/lUI9/7dhVP+cCQD/qg8A/7cZAP/EHAD/0CAA/9smAP/nDgD/9Eoo//7g2P/Erqf/3t7e/767 + uv+9oZb//9jI///Zyf//287//9jD//nCqf/L19v/k5aX9paWlRgAAAAAjouNnnp0d/+trKz/9fb5//// + ///h4eH/19fX/8HS1/+bWFP/oSgZ/58EAP+vFwD/uxoA/8cdAP/TIAD/3yYA/+sJAP/7d13///Hv//jV + yP/As6//1NTU/6ejof/Js6j//N/S///k2///49X//8qz/9re3v+bnaD/k5KQIQAAAAAAAAAJsbSyUaao + qbi2t7f/2NjY//z8/P//////0N7j/5xbU/+MAAD/phAA/7IXAP+/GwD/yx4A/9ckAP/jIAD/8A4A//+w + nf//+Pb//9/Z//DXz/+zrKr/vb29/62jn//55+L///Ls///z7v//2Mb/6eXk/6asrv+QkI8sAAAAAAAA + AAAAAAAAAAAABZ+goBeQkZFimZqauLO0tPPDz9L/nnJt/40AAP+oEwD/tRwA/8EeAP/PIAD/2yYA/+YY + AP/4JAD//+LX////////7en///Dr/+7i2v/p3tb/7NvS//3m2///5dX//9zJ//u7nv/z6eT/sbq8/42L + ilAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlpaWDK62uaymnZz/kQUC/60IAP+6DQD/xgoA/9QK + AP/jCAD/7wAA//8rAv//29D//dnP///Gtf/6xLH/9MKw//jBr//0u6T/5rSh/+C6rP/jxbn/48zE//X2 + 9f/Exsn/nZybOwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsri8bbG6vf+FAAD/oQAA/7MI + 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 + vv+2v8D/tsnJ/7a/wP+2v8D/tr/A/7a/wP+2v8D/tr/A/7a/wP+2v8D/tr/A/7a/wP+2v8D/tr/A/7a/ + wP/Bw8L/t7i41QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///8ADgAfAA4AHwAPAB8AD4B/AA/g/wAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAA + AQAAAAEA8AABAPAAAQDwAAEA8AABAPAAAQD///8A////AP///wAoAAAAEAAAACAAAAABACAAAAAAAEAE + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJGQkP97eXn/kZCQ/wAAAAAAAAAAAAAAALu8vP+7vLz/tLW1/5uc + nP+bnJz/n6Cg/6CgoP8AAAAAAAAAAAAAAAC0tLTTlJSU/56ens0AAAAAAAAAAAAAAADS0tKCyMnJ/8TG + xv+5urr/qqur/6CgoP+goKBhAAAAAAAAAAAAAAAAq6ur97+/v/+lpaX/AAAAAAAAAAAAAAAAAAAAAN7e + 3ja5urr/ioqK/5eXl+ygoKA2AAAAAAAAAAAAAAAAAAAAAK6urvfR0dH/q6ur/8PExIbAwcH/vr+//7u8 + vP+4ubn/tba2/6qqqv+oqKj/pqam/6SkpP+ioqL/oKCg/6CgoJWtra330dHR/6urq//Nz8//zc/P/83O + z//Mzs7/y83N/8rMzP/Hycn/xsnJ/8bJyf/FyMj/xcjI/8THx/+goKD/ra2t99HR0f+rq6v/ztDQ/62u + rv+nDw//qxMN/6gODv+pICD/tD8v/9QbAf/UHQH/2B0A/8slA//FyMj/oaGh/66urvfR0dH/rKys/8/R + 0f+rrKz/siwj/7MxIv+5HQz/ycXE/8xxY//XRyz/3kAl/+NEJ//dOxD/xMfH/6Ojo/+WvaP3APJI/2LC + gv/P0dH/qamp/7RANf+0LyL/19bV/+7u7v/4+Pj/s42H/9tYO//dXEH/3k8t/8XIyP+lpaX/q6ur90hE + Q/97eXn/0dLS/6Ojo/+4Qzr/wEE0/9zKyf/YGgD/1IJ1///////WalP/1WxZ/9piSP/Hysr/q6ur/76+ + vpS+vr7/vr6+wNDS0v+ioqL/vC8k/8UcCf/aHgD/5hsA//9ZNv/zpJD/2dnZ//9qPP//ZTH/x8rK/62u + rv8AAAAAAAAAAAAAAADR0tP/oKCg/8UYB//UGAH/4yYA/+0aAP//cEv//2tI/+Hh4f/Aurj//2s//8jK + y/+wsbH/AAAAAAAAAAAAAAAA0dLT/6CgoP/KBAT/3A8A/+gSAP/3FgD//388/9aCXP/Xg1n/2oFR/99z + Q//Jy8v/srOz/wAAAAAAAAAAAAAAANHS0/+goKD/oKCg/6CgoP+ioqL/pKSk/62urv+wsLD/srOz/7W2 + tv+4ubn/ycvM/7W2tv8AAAAAAAAAAAAAAADR0tN40dLT/9HS0//R0tP/0NLS/9DR0v/O0ND/zc/P/83P + z//Mzs7/y83N/8rMzP+4ubmVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAAcBwAAHAcAAB4PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA4AAAAOAAAADgAAAA4AAAAP//AAA= + + + + 127, 17 + + + 314, 17 + + + 511, 17 + + + 53 + + diff --git a/AppliStation/PackageUninstallConfirmForm.Designer.cs b/AppliStation/PackageUninstallConfirmForm.Designer.cs new file mode 100644 index 0000000..bd1d03d --- /dev/null +++ b/AppliStation/PackageUninstallConfirmForm.Designer.cs @@ -0,0 +1,180 @@ + +namespace AppliStation +{ + partial class PackageUninstallConfirmForm + { + /// + /// Designer variable used to keep track of non-visual components. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Disposes resources used by the form. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing) { + if (components != null) { + components.Dispose(); + } + } + base.Dispose(disposing); + } + + /// + /// This method is required for Windows Forms designer support. + /// Do not change the method contents inside the source code editor. The Forms designer might + /// not be able to load this method if it was changed manually. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PackageUninstallConfirmForm)); + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.label = new System.Windows.Forms.Label(); + this.btnPanel = new System.Windows.Forms.FlowLayoutPanel(); + this.runasCheckBox = new System.Windows.Forms.CheckBox(); + this.okButton = new System.Windows.Forms.Button(); + this.cancelButton = new System.Windows.Forms.Button(); + this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); + this.iconLabel = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.tableLayoutPanel1.SuspendLayout(); + this.btnPanel.SuspendLayout(); + this.flowLayoutPanel1.SuspendLayout(); + this.SuspendLayout(); + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.ColumnCount = 1; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + this.tableLayoutPanel1.Controls.Add(this.label, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.btnPanel, 0, 2); + this.tableLayoutPanel1.Controls.Add(this.flowLayoutPanel1, 0, 1); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 3; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.Size = new System.Drawing.Size(392, 216); + this.tableLayoutPanel1.TabIndex = 1; + // + // label + // + this.label.Dock = System.Windows.Forms.DockStyle.Fill; + this.label.Location = new System.Drawing.Point(10, 10); + this.label.Margin = new System.Windows.Forms.Padding(10, 10, 10, 0); + this.label.Name = "label"; + this.label.Size = new System.Drawing.Size(372, 23); + this.label.TabIndex = 1; + this.label.Text = "以下のソフトをアンインストールしようとしています。よろしいですか?"; + // + // btnPanel + // + this.btnPanel.AutoSize = true; + this.btnPanel.Controls.Add(this.runasCheckBox); + this.btnPanel.Controls.Add(this.okButton); + this.btnPanel.Controls.Add(this.cancelButton); + this.btnPanel.Dock = System.Windows.Forms.DockStyle.Right; + this.btnPanel.Location = new System.Drawing.Point(66, 184); + this.btnPanel.Name = "btnPanel"; + this.btnPanel.Size = new System.Drawing.Size(323, 29); + this.btnPanel.TabIndex = 0; + // + // runasCheckBox + // + this.runasCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); + this.runasCheckBox.AutoSize = true; + this.runasCheckBox.Checked = true; + this.runasCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; + this.runasCheckBox.Location = new System.Drawing.Point(3, 6); + this.runasCheckBox.Name = "runasCheckBox"; + this.runasCheckBox.Size = new System.Drawing.Size(126, 16); + this.runasCheckBox.TabIndex = 2; + this.runasCheckBox.Text = "管理者として実行(&A)"; + this.runasCheckBox.UseVisualStyleBackColor = true; + this.runasCheckBox.CheckedChanged += new System.EventHandler(this.RunasCheckBoxCheckedChanged); + // + // okButton + // + this.okButton.AutoSize = true; + this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK; + this.okButton.Image = ((System.Drawing.Image)(resources.GetObject("okButton.Image"))); + this.okButton.Location = new System.Drawing.Point(135, 3); + this.okButton.Name = "okButton"; + this.okButton.Size = new System.Drawing.Size(104, 23); + this.okButton.TabIndex = 0; + this.okButton.Text = "アンインストール"; + this.okButton.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; + // + // cancelButton + // + this.cancelButton.AutoSize = true; + this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.cancelButton.Location = new System.Drawing.Point(245, 3); + this.cancelButton.Name = "cancelButton"; + this.cancelButton.Size = new System.Drawing.Size(75, 23); + this.cancelButton.TabIndex = 1; + this.cancelButton.Text = "キャンセル"; + // + // flowLayoutPanel1 + // + this.flowLayoutPanel1.Controls.Add(this.iconLabel); + this.flowLayoutPanel1.Controls.Add(this.label2); + this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.flowLayoutPanel1.Location = new System.Drawing.Point(10, 43); + this.flowLayoutPanel1.Margin = new System.Windows.Forms.Padding(10); + this.flowLayoutPanel1.Name = "flowLayoutPanel1"; + this.flowLayoutPanel1.Size = new System.Drawing.Size(372, 128); + this.flowLayoutPanel1.TabIndex = 2; + // + // iconLabel + // + this.iconLabel.Location = new System.Drawing.Point(3, 0); + this.iconLabel.Name = "iconLabel"; + this.iconLabel.Size = new System.Drawing.Size(1, 1); + this.iconLabel.TabIndex = 0; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(10, 0); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(0, 12); + this.label2.TabIndex = 1; + // + // PackageUninstallConfirmForm + // + this.AcceptButton = this.okButton; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.cancelButton; + this.ClientSize = new System.Drawing.Size(392, 216); + this.Controls.Add(this.tableLayoutPanel1); + this.MaximizeBox = false; + this.Name = "PackageUninstallConfirmForm"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.Text = "ソフトのアンインストール"; + this.tableLayoutPanel1.ResumeLayout(false); + this.tableLayoutPanel1.PerformLayout(); + this.btnPanel.ResumeLayout(false); + this.btnPanel.PerformLayout(); + this.flowLayoutPanel1.ResumeLayout(false); + this.flowLayoutPanel1.PerformLayout(); + this.ResumeLayout(false); + } + private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; + private System.Windows.Forms.Label iconLabel; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label; + private System.Windows.Forms.Button cancelButton; + private System.Windows.Forms.Button okButton; + private System.Windows.Forms.CheckBox runasCheckBox; + private System.Windows.Forms.FlowLayoutPanel btnPanel; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + } +} diff --git a/AppliStation/PackageUninstallConfirmForm.cs b/AppliStation/PackageUninstallConfirmForm.cs new file mode 100644 index 0000000..b922f24 --- /dev/null +++ b/AppliStation/PackageUninstallConfirmForm.cs @@ -0,0 +1,98 @@ +using System; +using System.Drawing; +using System.Windows.Forms; +using NaGet.Packages; +using NaGet.Packages.Install; + +namespace AppliStation +{ + /// + /// Description of PackageUninstallConfirmForm. + /// + public partial class PackageUninstallConfirmForm : Form + { + private InstalledPackage uninstallPackage; + + public InstalledPackage UninstallPackage { + get { return uninstallPackage; } + set { + uninstallPackage = value; + + label2.Text = string.Format("{0}({1})", uninstallPackage.Name, uninstallPackage.Version); + label2.Font = new Font(SystemFonts.DefaultFont.FontFamily, SystemFonts.DefaultFont.Size*1.5f); + + string iconPath = uninstallPackage.UninstallInfo.IconPath; + if (!string.IsNullOrEmpty(iconPath)) { + if (iconPath.EndsWith(",0")) { + iconPath = iconPath.Substring(0, iconPath.Length-2); + } + if (System.IO.File.Exists(iconPath)) { + iconLabel.Image = Icon.ExtractAssociatedIcon(iconPath).ToBitmap(); + iconLabel.Size = iconLabel.Image.Size; + } + } + } + } + + public PackageUninstallConfirmForm() + { + // + // The InitializeComponent() call is required for Windows Forms designer support. + // + InitializeComponent(); + + // ŠÇ—ŽÒŒ ŒÀ‚Å“®‚¢‚Ä‚¢‚é‚È‚ç‚Îrunas‚ª•K—v‚ɂ͂Ȃç‚È‚¢‚̂ŕ\ަ‚µ‚È‚¢ + if (NaGet.Utils.IsAdministrators()) { + runasCheckBox.Checked = false; + runasCheckBox.Visible = false; + } + } + + #region runasŠÖ˜A + + /// + /// runas‚ÅŽÀs‚·‚é‚©”Û‚© + /// + public bool UseRunas { + set { + runasCheckBox.Checked = (! NaGet.Utils.IsAdministrators()) && value; + + updateUseRunas(); + } + get { + return runasCheckBox.Checked; + } + } + + /// + /// ‘I‘ð‚³‚ê‚½ƒpƒbƒP[ƒW‚𒲍¸‚µ‚āARunas‚ðŽg‚¤‚ׂ«‚©‚¢‚È‚©‚ð•Ô‚· + /// + public bool GetShouldUseRunas() + { + if (NaGet.Utils.IsAdministrators()) { + // ŠÇ—ŽÒŒ ŒÀ‚Å“®‚¢‚Ä‚¢‚éê‡‚Í•s—v + return false; + } + + return (uninstallPackage.Type != InstallerType.ARCHIVE); + } + + void RunasCheckBoxCheckedChanged(object sender, EventArgs e) + { + updateUseRunas(); + } + + private void updateUseRunas() + { + if (UseRunas) { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PackagesInstallConfirmForm)); + okButton.Image = ((System.Drawing.Bitmap)(resources.GetObject("okButton.Image"))); + } else { + okButton.Image = null; + } + } + + #endregion + + } +} diff --git a/AppliStation/PackageUninstallConfirmForm.resx b/AppliStation/PackageUninstallConfirmForm.resx new file mode 100644 index 0000000..6c99de1 --- /dev/null +++ b/AppliStation/PackageUninstallConfirmForm.resx @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAApdJREFUOE+Fk21I + k1EUx61vgRX0wYqc4mi+JOqoD4WV9oJKpC5fM6m1QKdJEpVCTZFCmpl92FaNEicJlWUffGtEy2eS5sbQ + 9mIlFRWIIk60TZuYpPt37mgy6QEf+MPl3P/53XPPc+66IJ5PqVRGBwcHv/B6vSLaXk/fiMfjSVMoFE4+ + /0qMEqNaWlpadTrdvNFohM1m84mtGxsbPbTXRp7I/yAULFSr1d9UKpXHZDKBafnDEJaeNaPpkQzlHfmw + WCy+OHnmNRqNneUEnjxhtVq97DT342YsDvRg8XU7FjQ3Uf8wAyVdWSh6KkGe5qivIvKCAO5AwIzdbseP + qmuYuV2Dn1olZq9XwC3Nw+VbeyF5nozM5v1IvbMb+xRRPggB5lYBWHD0ghyTFcWYKMrBZOIeOAUCyKp3 + IuZBBBJUYRDf2AFh+WZewDSrYKr0NGZl6ZiKDYUrKAi/SKcUEdhyPxzRd0VIaBAhrHIbL2DM4XDgo7QQ + X9KOwBqyHcMbt+JzaCTOV+3CwdZ4HH8ihkSXgCRlmB8wFniFDqrAmyVrQsGZe8jMrcehjAak5KvRbZDD + 8TURw58OY3goGe9fRsFsNi9TD14FAmoMBsOfpKscQuRGhF7isKGkB5vK3qCvrxxwpwLOE8BoOtAXC71e + P0OA2hVAXV1djFarHWeNFEk7ESfvRPi5TgiLu2B5R4CpY8B4LjBC16NfSN7vBBCuGigK2FgjcyrbIDrb + jQhpF4RFepj6CeDMBsYkcA0c8M+AgW8aBQRxsSqyq/SIL+MgvshhoP8K4CrF3EiBv3nT5BPwvgnaOEn6 + zSBsbFNqzRgcrPat/w3PIvOs9aAYZKG3t3flMXEcxyZvYc1kP5mMcSQzaYnEkt+SYvhO/gusfu3mrz6d + pwAAAABJRU5ErkJggg== + + + \ No newline at end of file diff --git a/AppliStation/PackagesInstallConfirmForm.Designer.cs b/AppliStation/PackagesInstallConfirmForm.Designer.cs new file mode 100644 index 0000000..9a7ac7c --- /dev/null +++ b/AppliStation/PackagesInstallConfirmForm.Designer.cs @@ -0,0 +1,221 @@ + +namespace AppliStation +{ + partial class PackagesInstallConfirmForm + { + /// + /// Designer variable used to keep track of non-visual components. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Disposes resources used by the form. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing) { + if (components != null) { + components.Dispose(); + } + } + base.Dispose(disposing); + } + + /// + /// This method is required for Windows Forms designer support. + /// Do not change the method contents inside the source code editor. The Forms designer might + /// not be able to load this method if it was changed manually. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PackagesInstallConfirmForm)); + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.btnPanel = new System.Windows.Forms.FlowLayoutPanel(); + this.runasCheckBox = new System.Windows.Forms.CheckBox(); + this.okButton = new System.Windows.Forms.Button(); + this.cancelButton = new System.Windows.Forms.Button(); + this.label = new System.Windows.Forms.Label(); + this.packageListView = new System.Windows.Forms.ListView(); + this.nameColumnHeader = new System.Windows.Forms.ColumnHeader(); + this.versionColumnHeader = new System.Windows.Forms.ColumnHeader(); + this.currentVersionColumnHeader = new System.Windows.Forms.ColumnHeader(); + this.packageListViewContextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components); + this.selectAllPackagesStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.unselectAllPackagesStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.tableLayoutPanel1.SuspendLayout(); + this.btnPanel.SuspendLayout(); + this.packageListViewContextMenuStrip.SuspendLayout(); + this.SuspendLayout(); + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.ColumnCount = 1; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel1.Controls.Add(this.btnPanel, 0, 2); + this.tableLayoutPanel1.Controls.Add(this.label, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.packageListView, 0, 1); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 3; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 50F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.Size = new System.Drawing.Size(392, 266); + this.tableLayoutPanel1.TabIndex = 0; + // + // btnPanel + // + this.btnPanel.AutoSize = true; + this.btnPanel.Controls.Add(this.runasCheckBox); + this.btnPanel.Controls.Add(this.okButton); + this.btnPanel.Controls.Add(this.cancelButton); + this.btnPanel.Dock = System.Windows.Forms.DockStyle.Right; + this.btnPanel.Location = new System.Drawing.Point(84, 234); + this.btnPanel.Name = "btnPanel"; + this.btnPanel.Size = new System.Drawing.Size(305, 29); + this.btnPanel.TabIndex = 0; + // + // runasCheckBox + // + this.runasCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); + this.runasCheckBox.AutoSize = true; + this.runasCheckBox.Checked = true; + this.runasCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; + this.runasCheckBox.Location = new System.Drawing.Point(3, 6); + this.runasCheckBox.Name = "runasCheckBox"; + this.runasCheckBox.Size = new System.Drawing.Size(126, 16); + this.runasCheckBox.TabIndex = 2; + this.runasCheckBox.Text = "管理者として実行(&A)"; + this.runasCheckBox.UseVisualStyleBackColor = true; + this.runasCheckBox.CheckedChanged += new System.EventHandler(this.RunasCheckBoxCheckedChanged); + // + // okButton + // + this.okButton.AutoSize = true; + this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK; + this.okButton.Image = ((System.Drawing.Image)(resources.GetObject("okButton.Image"))); + this.okButton.Location = new System.Drawing.Point(135, 3); + this.okButton.Name = "okButton"; + this.okButton.Size = new System.Drawing.Size(86, 23); + this.okButton.TabIndex = 0; + this.okButton.Text = "インストール"; + this.okButton.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; + // + // cancelButton + // + this.cancelButton.AutoSize = true; + this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.cancelButton.Location = new System.Drawing.Point(227, 3); + this.cancelButton.Name = "cancelButton"; + this.cancelButton.Size = new System.Drawing.Size(75, 23); + this.cancelButton.TabIndex = 1; + this.cancelButton.Text = "キャンセル"; + // + // label + // + this.label.Dock = System.Windows.Forms.DockStyle.Fill; + this.label.Location = new System.Drawing.Point(10, 10); + this.label.Margin = new System.Windows.Forms.Padding(10); + this.label.Name = "label"; + this.label.Size = new System.Drawing.Size(372, 30); + this.label.TabIndex = 1; + this.label.Text = "以下のソフトをインストールしようとしています。インストールするソフトをチェックしてください"; + // + // packageListView + // + this.packageListView.CheckBoxes = true; + this.packageListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.nameColumnHeader, + this.versionColumnHeader, + this.currentVersionColumnHeader}); + this.packageListView.ContextMenuStrip = this.packageListViewContextMenuStrip; + this.packageListView.Dock = System.Windows.Forms.DockStyle.Fill; + this.packageListView.GridLines = true; + this.packageListView.Location = new System.Drawing.Point(5, 53); + this.packageListView.Margin = new System.Windows.Forms.Padding(5, 3, 5, 5); + this.packageListView.Name = "packageListView"; + this.packageListView.ShowItemToolTips = true; + this.packageListView.Size = new System.Drawing.Size(382, 173); + this.packageListView.TabIndex = 2; + this.packageListView.UseCompatibleStateImageBehavior = false; + this.packageListView.View = System.Windows.Forms.View.Details; + this.packageListView.ItemChecked += new System.Windows.Forms.ItemCheckedEventHandler(this.PackageListViewItemChecked); + this.packageListView.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.PackageListViewColumnClick); + // + // nameColumnHeader + // + this.nameColumnHeader.Text = "名前"; + this.nameColumnHeader.Width = 146; + // + // versionColumnHeader + // + this.versionColumnHeader.Text = "バージョン"; + this.versionColumnHeader.Width = 82; + // + // currentVersionColumnHeader + // + this.currentVersionColumnHeader.Text = "現バージョン"; + this.currentVersionColumnHeader.Width = 89; + // + // packageListViewContextMenuStrip + // + this.packageListViewContextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.selectAllPackagesStripMenuItem, + this.unselectAllPackagesStripMenuItem}); + this.packageListViewContextMenuStrip.Name = "packageListViewContextMenuStrip"; + this.packageListViewContextMenuStrip.Size = new System.Drawing.Size(175, 48); + this.packageListViewContextMenuStrip.Opening += new System.ComponentModel.CancelEventHandler(this.PackageListViewContextMenuStripOpening); + // + // selectAllPackagesStripMenuItem + // + this.selectAllPackagesStripMenuItem.Name = "selectAllPackagesStripMenuItem"; + this.selectAllPackagesStripMenuItem.Size = new System.Drawing.Size(174, 22); + this.selectAllPackagesStripMenuItem.Text = "全て選択(&A)"; + this.selectAllPackagesStripMenuItem.Click += new System.EventHandler(this.SelectAllPackagesStripMenuItemClick); + // + // unselectAllPackagesStripMenuItem + // + this.unselectAllPackagesStripMenuItem.Name = "unselectAllPackagesStripMenuItem"; + this.unselectAllPackagesStripMenuItem.Size = new System.Drawing.Size(174, 22); + this.unselectAllPackagesStripMenuItem.Text = "全ての選択を解除(&U)"; + this.unselectAllPackagesStripMenuItem.Click += new System.EventHandler(this.UnselectAllPackagesStripMenuItemClick); + // + // PackagesInstallConfirmForm + // + this.AcceptButton = this.okButton; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.cancelButton; + this.ClientSize = new System.Drawing.Size(392, 266); + this.Controls.Add(this.tableLayoutPanel1); + this.MaximizeBox = false; + this.Name = "PackagesInstallConfirmForm"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "ソフトのインストール"; + this.tableLayoutPanel1.ResumeLayout(false); + this.tableLayoutPanel1.PerformLayout(); + this.btnPanel.ResumeLayout(false); + this.btnPanel.PerformLayout(); + this.packageListViewContextMenuStrip.ResumeLayout(false); + this.ResumeLayout(false); + } + private System.Windows.Forms.ToolStripMenuItem unselectAllPackagesStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem selectAllPackagesStripMenuItem; + private System.Windows.Forms.ContextMenuStrip packageListViewContextMenuStrip; + private System.Windows.Forms.CheckBox runasCheckBox; + private System.Windows.Forms.ColumnHeader currentVersionColumnHeader; + private System.Windows.Forms.ColumnHeader versionColumnHeader; + private System.Windows.Forms.ColumnHeader nameColumnHeader; + private System.Windows.Forms.ListView packageListView; + private System.Windows.Forms.Label label; + private System.Windows.Forms.Button cancelButton; + private System.Windows.Forms.Button okButton; + private System.Windows.Forms.FlowLayoutPanel btnPanel; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + } +} diff --git a/AppliStation/PackagesInstallConfirmForm.cs b/AppliStation/PackagesInstallConfirmForm.cs new file mode 100644 index 0000000..351089c --- /dev/null +++ b/AppliStation/PackagesInstallConfirmForm.cs @@ -0,0 +1,212 @@ +using System; +using System.Drawing; +using System.Windows.Forms; +using NaGet.Packages; + +namespace AppliStation +{ + /// + /// Description of PackagesInstallConfirmForm. + /// + public partial class PackagesInstallConfirmForm : Form + { + private Package[] packages; + + private PackageListsManager pkgListMan; + + /// + /// ƒpƒbƒP[ƒW‚̏W‡ + /// + public Package[] Packages { + get { return packages; } + set { + packages = value; + + updatePackagesListView(); + } + } + + public PackageListsManager PkgListsManager { + get { return pkgListMan; } + set { + pkgListMan = value; + + updatePackagesListView(); + } + } + + public PackagesInstallConfirmForm() + { + // + // The InitializeComponent() call is required for Windows Forms designer support. + // + InitializeComponent(); + + // ŠÇ—ŽÒŒ ŒÀ‚Å“®‚¢‚Ä‚¢‚é‚È‚ç‚Îrunas‚ª•K—v‚ɂ͂Ȃç‚È‚¢‚̂ŕ\ަ‚µ‚È‚¢ + if (NaGet.Utils.IsAdministrators()) { + runasCheckBox.Checked = false; + runasCheckBox.Visible = false; + } + } + + private void updatePackagesListView() + { + packageListView.Items.Clear(); + + if (packages != null && packages.Length > 0) { + foreach (Package pkg in packages) { + Package curPkg = null; + if (pkgListMan != null) { + curPkg = pkgListMan.InstalledPkgList.GetPackageForName(pkg.Name); + if (curPkg == null) curPkg = pkgListMan.SystemInstalledPkgList.GetPackageForName(pkg.Name); + } + string curVersion = (curPkg == null)? "-" : curPkg.Version; + + ListViewItem item = new ListViewItem(new string[]{pkg.Name, pkg.Version, curVersion}); + item.Tag = pkg; + item.ToolTipText = pkg.Summary; + item.Checked = true; + + packageListView.Items.Add(item); + } + } + + PackageListViewItemChecked(packageListView, null); + packageListView.Refresh(); + } + + void PackageListViewItemChecked(object sender, ItemCheckedEventArgs e) + { + System.Windows.Forms.ListView.CheckedListViewItemCollection checkeds = packageListView.CheckedItems; + + okButton.Enabled = checkeds != null && checkeds.Count > 0; + } + + AppliStation.Util.ListViewItemSortComparer packageListViewSortComparer; + + void PackageListViewColumnClick(object sender, ColumnClickEventArgs e) + { + SortOrder order = SortOrder.None; + + if (packageListViewSortComparer == null) { + order = SortOrder.Ascending; + packageListViewSortComparer = new AppliStation.Util.ListViewItemSortComparer(e.Column, order); + packageListView.ListViewItemSorter = packageListViewSortComparer; + } else { + if (packageListViewSortComparer.Column == e.Column) { + order = (packageListViewSortComparer.Order == SortOrder.Ascending)? SortOrder.Descending : SortOrder.Ascending; + + packageListViewSortComparer.Order = order; + } else { + order = packageListViewSortComparer.Order; + packageListViewSortComparer.Column = e.Column; + } + + packageListView.Sort(); + } + AppliStation.Util.NativeMethods.ColumnHeader_SetSortState(packageListView, e.Column, order); + + // ƒ\[ƒg‘Ώۗñ‚̐F•t‚¯ + try { + // SendMessage(hWnd, LVM_SETSELECTEDCOLUMN, column, NULL); + AppliStation.Util.NativeMethods.SendMessage(packageListView.Handle, 0x1000+140, (uint) e.Column, 0); + } catch (Exception) { + } + } + + + void PackageListViewContextMenuStripOpening(object sender, System.ComponentModel.CancelEventArgs e) + { + System.Windows.Forms.ListView.CheckedIndexCollection coll = packageListView.CheckedIndices; + selectAllPackagesStripMenuItem.Enabled = coll.Count < packages.Length; + unselectAllPackagesStripMenuItem.Enabled = coll.Count > 0; + } + + void SelectAllPackagesStripMenuItemClick(object sender, EventArgs e) + { + foreach (ListViewItem item in packageListView.Items) { + item.Checked = true; + } + packageListView.Refresh(); + } + + void UnselectAllPackagesStripMenuItemClick(object sender, EventArgs e) + { + foreach (ListViewItem item in packageListView.CheckedItems) { + item.Checked = false; + } + packageListView.Refresh(); + } + + /// + /// ƒCƒ“ƒXƒg[ƒ‹‚·‚邿‚¤‘I‘ð‚³‚ê‚½ƒpƒbƒP[ƒW‚Ì”z—ñ + /// + public Package[] CheckedPackages { + get { + System.Collections.Generic.List pkgs = new System.Collections.Generic.List(); + foreach (ListViewItem item in packageListView.CheckedItems) { + pkgs.Add((Package) item.Tag); + } + return pkgs.ToArray(); + } + } + + #region runasŠÖ˜A + + /// + /// runas‚ÅŽÀs‚·‚é‚©”Û‚© + /// + public bool UseRunas { + set { + runasCheckBox.Checked = (! NaGet.Utils.IsAdministrators()) && value; + + updateUseRunas(); + } + get { + return runasCheckBox.Checked; + } + } + + /// + /// ‘I‘ð‚³‚ê‚½ƒpƒbƒP[ƒW‚𒲍¸‚µ‚āARunas‚ðŽg‚¤‚ׂ«‚©‚¢‚È‚©‚ð•Ô‚· + /// + public bool GetShouldUseRunas() + { + if (NaGet.Utils.IsAdministrators()) { + // ŠÇ—ŽÒŒ ŒÀ‚Å“®‚¢‚Ä‚¢‚éê‡‚Í•s—v + return false; + } else if (NaGet.Utils.IsUACEnabled()) { + // UAC‚ª“K—p‚³‚ê‚Ä‚¢‚éê‡‚Í•W€‚ł͕s—v‚Æ‚·‚é + return false; + } + + bool useRunas = false; + foreach (Package pkg in CheckedPackages) { + if (pkg.Type != InstallerType.ARCHIVE) { + useRunas = true; + break; + } + } + return useRunas; + } + + void RunasCheckBoxCheckedChanged(object sender, EventArgs e) + { + updateUseRunas(); + } + + private void updateUseRunas() + { + if (UseRunas) { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PackagesInstallConfirmForm)); + okButton.Image = ((System.Drawing.Bitmap)(resources.GetObject("okButton.Image"))); + } else { + okButton.Image = null; + } + } + + #endregion + + + } +} diff --git a/AppliStation/PackagesInstallConfirmForm.resx b/AppliStation/PackagesInstallConfirmForm.resx new file mode 100644 index 0000000..00b8979 --- /dev/null +++ b/AppliStation/PackagesInstallConfirmForm.resx @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAApdJREFUOE+Fk21I + k1EUx61vgRX0wYqc4mi+JOqoD4WV9oJKpC5fM6m1QKdJEpVCTZFCmpl92FaNEicJlWUffGtEy2eS5sbQ + 9mIlFRWIIk60TZuYpPt37mgy6QEf+MPl3P/53XPPc+66IJ5PqVRGBwcHv/B6vSLaXk/fiMfjSVMoFE4+ + /0qMEqNaWlpadTrdvNFohM1m84mtGxsbPbTXRp7I/yAULFSr1d9UKpXHZDKBafnDEJaeNaPpkQzlHfmw + WCy+OHnmNRqNneUEnjxhtVq97DT342YsDvRg8XU7FjQ3Uf8wAyVdWSh6KkGe5qivIvKCAO5AwIzdbseP + qmuYuV2Dn1olZq9XwC3Nw+VbeyF5nozM5v1IvbMb+xRRPggB5lYBWHD0ghyTFcWYKMrBZOIeOAUCyKp3 + IuZBBBJUYRDf2AFh+WZewDSrYKr0NGZl6ZiKDYUrKAi/SKcUEdhyPxzRd0VIaBAhrHIbL2DM4XDgo7QQ + X9KOwBqyHcMbt+JzaCTOV+3CwdZ4HH8ihkSXgCRlmB8wFniFDqrAmyVrQsGZe8jMrcehjAak5KvRbZDD + 8TURw58OY3goGe9fRsFsNi9TD14FAmoMBsOfpKscQuRGhF7isKGkB5vK3qCvrxxwpwLOE8BoOtAXC71e + P0OA2hVAXV1djFarHWeNFEk7ESfvRPi5TgiLu2B5R4CpY8B4LjBC16NfSN7vBBCuGigK2FgjcyrbIDrb + jQhpF4RFepj6CeDMBsYkcA0c8M+AgW8aBQRxsSqyq/SIL+MgvshhoP8K4CrF3EiBv3nT5BPwvgnaOEn6 + zSBsbFNqzRgcrPat/w3PIvOs9aAYZKG3t3flMXEcxyZvYc1kP5mMcSQzaYnEkt+SYvhO/gusfu3mrz6d + pwAAAABJRU5ErkJggg== + + + + 17, 17 + + \ No newline at end of file diff --git a/AppliStation/Program.cs b/AppliStation/Program.cs new file mode 100644 index 0000000..9b16164 --- /dev/null +++ b/AppliStation/Program.cs @@ -0,0 +1,140 @@ +using System; +using System.Collections.Generic; +using System.Windows.Forms; +using System.IO; + +namespace AppliStation +{ + class Program + { + Form splashScreen; + + PackageListViewForm form; + + /// + /// ƒAƒvƒŠƒP[ƒVƒ‡ƒ“‚̃IƒvƒVƒ‡ƒ“ + /// + Dictionary appArgs; + + string[] restAppArgs; + + public Program() + { + appArgs = new Dictionary(); + appArgs["noupdate"] = false; + appArgs["cmd"] = string.Empty; + appArgs["pkgsref"] = string.Empty; + + form = new PackageListViewForm(); + } + + void RunNormal() + { + form.Load += delegate(object sender, EventArgs e) { + hideSplashScreen(); + form.updateActionInvoke(((bool)appArgs["noupdate"]) != true); + + form.UpdatePackageList(); + }; + Application.Run(form); + } + + void RunInstall() + { + try { + NaGet.Packages.Package[] pkgs = NaGet.Utils.GetDeserializedObject((string) appArgs["pkgsref"]); + + hideSplashScreen(); + form.installActionInvoke(pkgs); + } catch (UnauthorizedAccessException e) { + MessageBox.Show(string.Format("ŠÇ—ŽÒŒ ŒÀ‚ɏ¸Ši‚µ‚Ä‚¢‚È‚¢‚©AŽÀsŒ ŒÀ‚É–â‘肪‚ ‚è‚Ü‚·B\n(Ú×:{0})", e.Message), + Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); + } catch (FileNotFoundException e) { + MessageBox.Show(string.Format("ƒ\ƒtƒgŽw’èƒtƒ@ƒCƒ‹{0}‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ", e.FileName), + Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + void RunUninstall() + { + try { + NaGet.Packages.Install.InstalledPackage[] pkgs = NaGet.Utils.GetDeserializedObject((string) appArgs["pkgsref"]); + + hideSplashScreen(); + form.uninstallActionInvoke(pkgs); + } catch (UnauthorizedAccessException e) { + MessageBox.Show(string.Format("ŠÇ—ŽÒŒ ŒÀ‚ɏ¸Ši‚µ‚Ä‚¢‚È‚¢‚©AŽÀsŒ ŒÀ‚É–â‘肪‚ ‚è‚Ü‚·B\n(Ú×:{0})", e.Message), + Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); + } catch (FileNotFoundException e) { + MessageBox.Show(string.Format("ƒ\ƒtƒgŽw’èƒtƒ@ƒCƒ‹{0}‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ", e.FileName), + Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void hideSplashScreen() + { + if (splashScreen != null && splashScreen.Visible) { + splashScreen.Hide(); + splashScreen.Dispose(); + } + } + + public void Run(string[] args) + { + parseArgs(args); + + switch ((string) appArgs["cmd"]) { + case "install": + RunInstall(); + break; + case "uninstall": + RunUninstall(); + break; + default: + RunNormal(); + break; + } + } + + private void parseArgs(string[] args) + { + ArgParse parser = new ArgParse(appArgs); + restAppArgs = parser.Parse(args); + } + + [STAThread] + public static void Main(string[] args) + { + Form splashScreen = null; + + try { + if (args.Length <= 0) { // HACK ˆø”ƒp[ƒX‚ÌŽžŠÔ‚³‚¦‘҂ĂȂ¢‚̂ňø”‚Ì—L–³‚Å•\ަ‚ð”»’f + splashScreen = new Form(); + splashScreen.FormBorderStyle = FormBorderStyle.None; + splashScreen.BackgroundImage = System.Drawing.Bitmap.FromFile(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "SplashScreen.png")); + splashScreen.Size = splashScreen.BackgroundImage.Size; + splashScreen.ShowIcon = false; + splashScreen.ShowInTaskbar = false; + splashScreen.StartPosition = FormStartPosition.CenterScreen; + splashScreen.Show(); + } + + ToolStripManager.VisualStylesEnabled = false; // ToolStrip‚ªLuna‚Ղ­‚È‚ç‚È‚¢‚悤‚É + Application.EnableVisualStyles(); // Luna‚âVista‚̃fƒUƒCƒ“‚ð—LŒø‚É + + Application.ThreadException += AppliStation.Util.ExceptionDialogForm.Application_ThrowException; + System.Threading.Thread.GetDomain().UnhandledException += AppliStation.Util.ExceptionDialogForm.Application_ThrowException; + + Program prog = new Program(); + prog.splashScreen = splashScreen; + prog.Run(args); + } catch (Exception e) { + AppliStation.Util.ExceptionDialogForm.Application_ThrowException(null, new System.Threading.ThreadExceptionEventArgs(e)); + } finally { + if (splashScreen != null) { + splashScreen.Dispose(); + } + } + } + } +} diff --git a/AppliStation/SplashScreen.png b/AppliStation/SplashScreen.png new file mode 100644 index 0000000000000000000000000000000000000000..95283d7e1a25e6dc552795e85d5441904451927c GIT binary patch literal 7884 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 O$i&Fva@FrHfBYK+W^I`O literal 0 HcmV?d00001 diff --git a/all-get/AssemblyInfo.cs b/all-get/AssemblyInfo.cs new file mode 100644 index 0000000..25fad42 --- /dev/null +++ b/all-get/AssemblyInfo.cs @@ -0,0 +1,31 @@ +#region Using directives + +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +#endregion + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("all-get")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("all-get")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// This sets the default COM visibility of types in the assembly to invisible. +// If you need to expose a type to COM, use [ComVisible(true)] on that type. +[assembly: ComVisible(false)] + +// The assembly version has following format : +// +// Major.Minor.Build.Revision +// +// You can specify all the values or you can use the default the Revision and +// Build Numbers by using the '*' as shown below: +[assembly: AssemblyVersion("0.9.*")] diff --git a/all-get/Main.cs b/all-get/Main.cs new file mode 100644 index 0000000..6afb569 --- /dev/null +++ b/all-get/Main.cs @@ -0,0 +1,527 @@ +// project created on 2007/09/08 at 20:20 +using System; +using System.IO; +using System.Collections.Generic; +using NaGet.Net; +using NaGet.Packages; +using NaGet.Packages.Install; +using NaGet.SubCommands; + +namespace AllGet +{ + + class DownloadListener + { + private string line = null; + + /// + /// lineのコンソール上における長さ + /// + private int lineWidth = 0; + + public void OnDownload(object sender, DownloadEventArgs a) { + if (line != null) { + lock (line) { + int newpos = (lineWidth <= 0)? 0 : Console.CursorLeft - lineWidth; + if (newpos < 0) newpos = 0; + + // 空白で埋める + Console.CursorLeft = newpos; + for (int i = 0; i < lineWidth && Console.CursorLeft < Console.BufferWidth; i++) { + Console.Write(' '); + } + Console.CursorLeft = newpos; + + line = null; lineWidth = 0; + } + } + + switch (a.Type) { + case DownloadEventType.INITED: + line = "starting..."; + break; + case DownloadEventType.CONNECTED: + case DownloadEventType.DOWNLOADING: + line = a.TaskMessage; + break; + case DownloadEventType.COMPLETED: + // + line = null; + break; + case DownloadEventType.ERROR: + Console.Write("interrupted! ERROR!"); + line = null; + break; + } + + if (line != null) { + int posOld = Console.CursorLeft; + Console.Write(line); + lineWidth = Console.CursorLeft - posOld; + } + } + } + + class MainClass + { + private Downloader downloader; + + private PackageListsManager pkgListMan; + + public MainClass() + { + downloader = new Downloader(); + DownloadListener dl = new DownloadListener(); + downloader.DownloadEventRaised += new EventHandler(dl.OnDownload); + + pkgListMan = new PackageListsManager(); + } + + public void Update() + { + update(true); + } + + public void LocalUpdate() + { + update(false); + } + + public void update(bool downloadPackageListFlag) + { + NaGet.SubCommands.NaGetUpdate tasks = new NaGet.SubCommands.NaGetUpdate(pkgListMan, downloadPackageListFlag); + tasks.Downloader = this.downloader; + tasks.TaskSetRaised += delegate(object sender, NaGetTaskSetEventArgs e) { + switch (e.Type) { +// case NaGetTaskSetEventType.COMPLETED_TASKSET +// break; + case NaGetTaskSetEventType.COMPLETED: + Console.WriteLine("Done."); + break; + case NaGetTaskSetEventType.STARTED_TASKSET: + Console.Write(" " + e.TaskMessage); + break; + case NaGetTaskSetEventType.COMPLETED_TASKSET: + Console.WriteLine(" ... Done. [{0}%]", (int) e.TaskProgressPercent); + break; + case NaGetTaskSetEventType.INFO: + Console.WriteLine(" " + e.TaskMessage); + break; + case NaGetTaskSetEventType.ERROR: + case NaGetTaskSetEventType.WARNING: + Console.WriteLine(" [Error]" + e.TaskMessage); + break; + } + }; + + tasks.Run(); + } + + public void Upgrade() + { + PackageList packageList = pkgListMan.AvailablePkgList; + + VersionComparetor verComp = new VersionComparetor(); + + foreach (InstalledPackage pkg in pkgListMan.InstalledPkgList.Packages) { + Package avaiablePkg = packageList.GetPackageForName(pkg.Name); + + if (avaiablePkg != null) { + if (verComp.Compare(pkg.Version, avaiablePkg.Version) < 0 && + pkgListMan.InstalledPkgList.GetPackageForPackage(pkg.Name, avaiablePkg.Version) == null) { + Console.ForegroundColor = ConsoleColor.Green; + } + + Console.WriteLine("{0} ({1}) => ({2})", pkg.Name, pkg.Version, avaiablePkg.Version); + Console.ResetColor(); + } + } + foreach (InstalledPackage pkg in pkgListMan.SystemInstalledPkgList.Packages) { + Package avaiablePkg = packageList.GetPackageForName(pkg.Name); + + if (avaiablePkg != null) { + if (verComp.Compare(pkg.Version, avaiablePkg.Version) < 0 && + pkgListMan.SystemInstalledPkgList.GetPackageForPackage(pkg.Name, avaiablePkg.Version) == null) { + Console.ForegroundColor = ConsoleColor.Green; + } + + Console.WriteLine("{0} ({1})@sys => ({2})", pkg.Name, pkg.Version, avaiablePkg.Version); + Console.ResetColor(); + } + } + } + + public void Search(string keys) + { + foreach(Package package in pkgListMan.AvailablePkgList.Search(keys)) { + Console.WriteLine("{0} ({1}) - {2}", package.Name, package.Version, package.Summary); + } + + foreach(InstalledPackage package in pkgListMan.InstalledPkgList.Search(keys)) { + Console.WriteLine("{0} ({1})[@install] - {2}", package.Name, package.Version, package.Summary); + } + + foreach(InstalledPackage package in pkgListMan.SystemInstalledPkgList.Search(keys)) { + Console.WriteLine("{0} ({1})[@sys] - {2}", package.Name, package.Version, package.Summary); + } + } + + public void Show(string packagename) + { + PackageList allPkgs = new PackageList(); + allPkgs.AddPackages(pkgListMan.GetAllPackages()); + + foreach (Package pkg in allPkgs.GetPackagesForName(packagename)) { + Console.WriteLine("Package: {0}", pkg.Name); + Console.WriteLine("Version: {0}", pkg.Version); + if (pkg.Url != null) Console.WriteLine("Website: {0}", pkg.Url.Href); + if (pkg.Tags != null) Console.WriteLine("Tag: {0}", pkg.Tags.ToLower()); + Console.WriteLine("Type: {0}", pkg.Type); + if (pkg.License != null) Console.WriteLine("License: {0}", pkg.License); + if (pkg is InstalledPackage) Console.WriteLine("State: Installed"); + + if (pkg.Description != null) { + Console.WriteLine("Description:"); + Console.WriteLine(pkg.Description); + } + Console.WriteLine(); + } + } + + public void Download(string[] packagenames) + { + Installation[] installations = null; + { + List downloadList = new List(); + + foreach(string packagename in packagenames) { + Package foundPackage = pkgListMan.AvailablePkgList.GetPackageForName(packagename); + if (foundPackage == null) { + Console.WriteLine("E: Couldn't find package "+packagename); + Environment.Exit(1); + } + if (! downloadList.Contains(foundPackage)) { + downloadList.Add(foundPackage); + } + } + + installations = new Installation[downloadList.Count]; + for (int i = 0; i < installations.Length; i++) { + installations[i] = new Installation((Package) downloadList[i]); + } + } + + Console.WriteLine("The following packages will be downloaded:"); + Console.WriteLine(" {0}", Installation.ToString(installations)); + if (AllGet.Util.Confirm("Do you want to continue [Y/n]?", true) == false) { + Console.WriteLine("Abort."); + Environment.Exit(0); + } + + { + int i = 0; + foreach (Installation inst in installations) { + i++; + + if (! inst.IsInstallablePackage()) { + Console.WriteLine("E:{0} {1} can not be installed.", i, inst.ToString()); + continue; + } + + try { + Console.Write("Get:{0} {1}", i, inst.ToString()); + inst.Download(downloader); + Console.WriteLine(" ...Done"); + } catch (Exception e) { + Console.WriteLine("E: "+e.Message); + throw new ApplicationException(string.Format("Failed to download {0}", inst.ToString()), e); + } + } + + i = 0; + foreach (Installation inst in installations) { + i++; + + if (inst.IsInstallablePackage() && inst.VerifyHashValues() == false) { + Console.WriteLine("Verify:{0} {1} does not match hash value!", i, inst.ToString()); + } + } + } + } + + public void Install(string[] packagenames) + { + if (! NaGet.Utils.IsAdministrators()) { + Console.WriteLine("W: you are not administrators!"); + } + + Installation[] installations = null; + { + List downloadList = new List(); + + foreach(string packagename in packagenames) { + Package foundPackage = pkgListMan.AvailablePkgList.GetPackageForName(packagename); + if (foundPackage == null) { + Console.WriteLine("E: Couldn't find package "+packagename); + Environment.Exit(1); + } + if (! downloadList.Contains(foundPackage)) { + downloadList.Add(foundPackage); + } + } + + installations = new Installation[downloadList.Count]; + for (int i = 0; i < installations.Length; i++) { + installations[i] = new Installation((Package) downloadList[i]); + + if (! installations[i].IsInstallablePackage()) { + Console.WriteLine("E: Can not install package {0} to your PC.", installations[i].ToString()); + Environment.Exit(1); + } + } + } + + Console.WriteLine("The following packages will be downloaded:"); + Console.WriteLine(" {0}", Installation.ToString(installations)); + if (AllGet.Util.Confirm("Do you want to continue [Y/n]?", true) == false) { + Console.WriteLine("Abort."); + Environment.Exit(0); + } + + NaGet.SubCommands.NaGetInstall tasks = new NaGet.SubCommands.NaGetInstall(pkgListMan, installations); + tasks.Downloader = this.downloader; + tasks.TaskSetRaised += delegate(object sender, NaGetTaskSetEventArgs e) { + switch (e.Type) { +// case NaGetTaskSetEventType.COMPLETED_TASKSET +// break; + case NaGetTaskSetEventType.COMPLETED: + Console.WriteLine("Done."); + break; + case NaGetTaskSetEventType.STARTED_TASKSET: + Console.Write(" " + e.TaskMessage); + break; + case NaGetTaskSetEventType.COMPLETED_TASKSET: + Console.WriteLine(" ... Done. [{0}%]", (int) e.TaskProgressPercent); + break; + case NaGetTaskSetEventType.INFO: + Console.WriteLine(" " + e.TaskMessage); + break; + case NaGetTaskSetEventType.ERROR: + case NaGetTaskSetEventType.WARNING: + Console.WriteLine(" [Error] " + e.TaskMessage); + break; + } + }; + + tasks.Run(); + } + + public void Remove(string[] packagenames) + { + if (! NaGet.Utils.IsAdministrators()) { + Console.WriteLine("W: you are not administrators!"); + } + + this.LocalUpdate(); + + PackageList installedPkgList = new PackageList(); + installedPkgList.AddPackages(pkgListMan.GetAllInstalledPackages()); + + Uninstallation[] uninstallations = new Uninstallation[packagenames.Length]; + for (int i = 0; i < packagenames.Length; i++) { + InstalledPackage pkg = installedPkgList.GetPackageForName(packagenames[i]); + + if (pkg == null) { + Console.WriteLine("E: could not found package " + packagenames[i]); + Environment.Exit(1); + } + + uninstallations[i] = new Uninstallation(pkg); + } + +// if (AllGet.Util.Confirm("Do you want to continue [Y/n]?", true) == false) { +// Console.WriteLine("Abort."); +// Environment.Exit(0); +// } + + NaGet.SubCommands.NaGetUninstall tasks = new NaGet.SubCommands.NaGetUninstall(pkgListMan, uninstallations); + tasks.TaskSetRaised += delegate(object sender, NaGetTaskSetEventArgs e) { + switch (e.Type) { +// case NaGetTaskSetEventType.COMPLETED_TASKSET +// break; + case NaGetTaskSetEventType.COMPLETED: + Console.WriteLine("Done."); + break; + case NaGetTaskSetEventType.STARTED_TASKSET: + Console.Write(" " + e.TaskMessage); + break; + case NaGetTaskSetEventType.COMPLETED_TASKSET: + Console.WriteLine(" ... Done. [{0}%]", (int) e.TaskProgressPercent); + break; + case NaGetTaskSetEventType.INFO: + Console.WriteLine(" " + e.TaskMessage); + break; + case NaGetTaskSetEventType.ERROR: + case NaGetTaskSetEventType.WARNING: + Console.WriteLine(" [Error] " + e.TaskMessage); + break; + } + }; + + tasks.Run(); + } + + public void CleanCache(string[] packages) + { + if (! Directory.Exists(NaGet.Env.ArchiveFolderPath)) { + return; + } + + int i = 0; + if (packages.Length == 0) { + foreach (string folder in Directory.GetDirectories(NaGet.Env.ArchiveFolderPath)) { + Directory.Delete(folder, true); + i ++; + } + } else { + foreach (string package in packages) { + foreach (string folder in Directory.GetDirectories(NaGet.Env.ArchiveFolderPath, package+"*", SearchOption.TopDirectoryOnly)) { + Directory.Delete(folder, true); + i ++; + } + } + } + if (i > 0) { + Console.WriteLine("... Done."); + } + } + + public void Help() + { + string executeFileName = System.AppDomain.CurrentDomain.FriendlyName; + Console.Write("Usage:"); + + Console.WriteLine("\t{0} update|localupdate", executeFileName); + Console.WriteLine("\t{0} search|show pkg1 [pkg2 ...]", executeFileName); + Console.WriteLine("\t{0} cleancache [pkg ...]", executeFileName); + Console.WriteLine("\t{0} download pkg1 [pkg2 ...]", executeFileName); + Console.WriteLine("\t{0} install|uninstall pkg1 [pkg2 ...]", executeFileName); + Console.WriteLine(); + Console.WriteLine("{0} is a simple command line interface for downloading and "+ + "installing packages. The most frequently used commands are update "+ + "and install.", executeFileName); + Console.WriteLine(); + Console.WriteLine("Commands:"); + Console.WriteLine(" update - Retrieve new lists of packages"); + Console.WriteLine(" localupdate - Update installed-soft-list only"); + Console.WriteLine(" search - Search the package list for not a regex pattern"); + Console.WriteLine(" show - Show package detail"); + Console.WriteLine(" cleancache - Clear cached archived file(s)"); + Console.WriteLine(" download - Download only - do NOT install or unpack archives"); + Console.WriteLine(" install - Install new packages"); + Console.WriteLine(" remove - Uninstall packages"); + Console.WriteLine(); + } + + public void FooBar() + { + foreach (InstalledPackage pkg in pkgListMan.SystemInstalledPkgList.Packages) { + Console.WriteLine("{0} : {1}", pkg.Name, pkg.UninstallInfo.UninstallString); + } + } + + public void Hoge() + { + foreach (UninstallInformation uInfo in RegistriedUninstallers.Uninstallers) { + if (! uInfo.IsOSPatch && ! uInfo.IsSystemComponent) { + Console.WriteLine("{0}", uInfo.DisplayName); + } + } + } + + public static void Main(string[] args) + { + // アーカイブSYSTEM32をパスに足す + NaGet.Utils.AddDirectoryToPath(NaGet.Env.ArchiveSystem32); + + MainClass mc = new MainClass(); + + if (args.Length == 0) { + mc.Help(); + } else if (args[0] == "update") { + if (args.Length != 1) { + Console.WriteLine("E: The update command takes no arguments"); + Environment.Exit(1); + } + mc.Update(); + } else if (args[0] == "localupdate") { + if (args.Length != 1) { + Console.WriteLine("E: The update command takes no arguments"); + Environment.Exit(1); + } + mc.LocalUpdate(); + } else if (args[0] == "search") { + if (args.Length <= 1) { + Console.WriteLine("E: You must give exactly one pattern"); + Environment.Exit(1); + } + + mc.Search(string.Join(" ", args, 1, args.Length - 1)); + } else if (args[0] == "show") { + if (args.Length <= 1) { + Console.WriteLine("E: You must give exactly one pattern"); + Environment.Exit(1); + } + + for (int i = 1; i < args.Length; i++) { + mc.Show(args[i]); + } + } else if (args[0] == "download") { + if (args.Length <= 1) { + Console.WriteLine("E: Invalid operation download"); + Environment.Exit(1); + } + + string[] packages = new string[args.Length - 1]; + Array.Copy(args, 1, packages, 0, packages.Length); + + mc.Download(packages); + } else if (args[0] == "install") { + if (args.Length <= 1) { + Console.WriteLine("E: Invalid operation install"); + Environment.Exit(1); + } + + string[] packages = new string[args.Length - 1]; + Array.Copy(args, 1, packages, 0, packages.Length); + + mc.Install(packages); + } else if (args[0] == "upgrade") { + mc.Upgrade(); + } else if (args[0] == "remove") { + if (args.Length <= 1) { + Console.WriteLine("E: Invalid operation remove"); + Environment.Exit(1); + } + + string[] packages = new string[args.Length - 1]; + Array.Copy(args, 1, packages, 0, packages.Length); + + mc.Remove(packages); + } else if (args[0] == "cleancache") { + string[] packages = new string[args.Length - 1]; + Array.Copy(args, 1, packages, 0, packages.Length); + + mc.CleanCache(packages); + } else if (args[0] == "foobar") { + mc.FooBar(); + } else if (args[0] == "hoge") { + mc.Hoge(); + } else { + mc.Help(); + + Environment.Exit(1); + } + } + } +} diff --git a/all-get/Util.cs b/all-get/Util.cs new file mode 100644 index 0000000..de82784 --- /dev/null +++ b/all-get/Util.cs @@ -0,0 +1,24 @@ +using System; + +namespace AllGet +{ + + sealed class Util + { + public static bool Confirm(string msg, bool defaultSelection) + { + Console.Write(msg); + string response = Console.ReadLine(); + + switch (response.ToLower()) + { + case "y": + return true; + case "n": + return false; + default: + return defaultSelection; + } + } + } +} diff --git a/all-get/all-get.csproj b/all-get/all-get.csproj new file mode 100644 index 0000000..7972ea6 --- /dev/null +++ b/all-get/all-get.csproj @@ -0,0 +1,54 @@ + + + {F212C7FF-0FC5-4319-BD72-87DB3A4CC55F} + Debug + AnyCPU + Exe + AllGet + all-get + bin/ + False + False + 4 + false + + + bin\Debug\ + true + Full + False + True + DEBUG;TRACE + + + bin\Release\ + False + None + True + False + TRACE + + + False + Auto + 4194304 + AnyCPU + 4096 + + + + + + + + + + + + + + {058E953D-3986-4F74-8516-5A50D267D36A} + na-get-lib + + + \ No newline at end of file diff --git a/archive-inst/AssemblyInfo.cs b/archive-inst/AssemblyInfo.cs new file mode 100644 index 0000000..5122001 --- /dev/null +++ b/archive-inst/AssemblyInfo.cs @@ -0,0 +1,31 @@ +#region Using directives + +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +#endregion + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("archive-inst")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("archive-inst")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// This sets the default COM visibility of types in the assembly to invisible. +// If you need to expose a type to COM, use [ComVisible(true)] on that type. +[assembly: ComVisible(false)] + +// The assembly version has following format : +// +// Major.Minor.Build.Revision +// +// You can specify all the values or you can use the default the Revision and +// Build Numbers by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.*")] diff --git a/archive-inst/InstalledFileList.cs b/archive-inst/InstalledFileList.cs new file mode 100644 index 0000000..b991a7c --- /dev/null +++ b/archive-inst/InstalledFileList.cs @@ -0,0 +1,70 @@ +using System; +using System.Xml.Serialization; +using System.Collections.Generic; +using System.IO; +using NaGet.Packages; + +namespace ArchiveInstall +{ + public class InstalledFileList + { + [XmlElement("Entry")] + public List Entries; + + public InstalledFileList() + { + Entries = new List(); + } + + /// + /// ƒnƒbƒVƒ…ŒŸØ‚ðs‚¢A•ύX‚³‚ꂽ‚ÆŠm”F‚µ‚½(‘Ó–‚łȂ¢)ƒtƒ@ƒCƒ‹‚ð•Ô‚· + /// + /// ŒŸ¸‚·‚éƒtƒ@ƒCƒ‹‚̃‹[ƒgƒfƒBƒŒƒNƒgƒŠ + /// •ύX‚³‚ꂽ‚ÆŒŸo‚µ‚½ƒtƒ@ƒCƒ‹() + public IEnumerable Verify(string rootDirectory) + { + foreach (InstalledFile file in Entries) { + if (! file.Hash.Validate(Path.Combine(rootDirectory, file.Path)) ) { + yield return file; + } + } + } + + public static InstalledFileList CreateFromFiles(string rootDirectory) + { + InstalledFileList list = new InstalledFileList(); + foreach (string filepath in Directory.GetFiles(rootDirectory, "*", SearchOption.AllDirectories)) { + string relativePath = NaGet.Utils.GetRelativePath(rootDirectory, filepath); + if (relativePath.StartsWith(".applistation.")) { + continue; + } + + InstalledFile file = new InstalledFile(); + file.Path = relativePath; + file.Hash = new HashValue(); + file.Hash.Type = HashValueType.SHA1SUM; + file.Hash.Value = HashValue.HashValueFor(filepath, file.Hash.Type); + + list.Entries.Add(file); + } + return list; + } + } + + public class InstalledFile + { + /// + /// ƒtƒ@ƒCƒ‹‚̃pƒX + /// + public string Path; + + /// + /// ƒnƒbƒVƒ…’l + /// + public HashValue Hash; + + public InstalledFile() + { + } + } +} diff --git a/archive-inst/MSBuild.cs b/archive-inst/MSBuild.cs new file mode 100644 index 0000000..edb0b66 --- /dev/null +++ b/archive-inst/MSBuild.cs @@ -0,0 +1,26 @@ +using System; +using Microsoft.Build.BuildEngine; + +namespace ArchiveInstall +{ + public static class MSBuild + { + public static Engine Engine { + get { + string binPath = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory(); + return new Engine(binPath); + } + } + } + + /// + /// WriteHandler‚ðŽæ‚èo‚·‚½‚߂̃Nƒ‰ƒX + /// + public class MSBuildLogger : ConsoleLogger + { + public void AddHandler(WriteHandler writehandler) + { + this.WriteHandler += writehandler; + } + } +} diff --git a/archive-inst/Program.cs b/archive-inst/Program.cs new file mode 100644 index 0000000..1a44c1c --- /dev/null +++ b/archive-inst/Program.cs @@ -0,0 +1,329 @@ +using System; +using System.Text; +using System.IO; +using Microsoft.Build.BuildEngine; +using NaGet.Packages; +using NaGet.Packages.Install; + +namespace ArchiveInstall +{ + class Program + { + public const string InstalledFileListName = ".applistation.installedfiles.xml"; + + public const string InstalledPackageFileName = ".applistation.package.xml"; + + private static void extract(string arcFile, string extractDestDir) + { + StringBuilder output = new StringBuilder(1024); + int res = NaGet.InteropServices.CommonArchiverExtracter.ExtractArchive(arcFile, extractDestDir, output, IntPtr.Zero); + if (res != 0) { + Environment.Exit(res); + } + } + + private static void install(string fakeTargetDir, string targetDir) + { + string installSrc = fakeTargetDir; + + if (Directory.GetFiles(installSrc).Length == 0 && + Directory.GetDirectories(installSrc).Length == 1) { + installSrc = Directory.GetDirectories(installSrc)[0]; + } + + // ハッシュ比較 + if (Directory.Exists(targetDir)) { + InstalledFileList list = null; + try { + list = NaGet.Utils.GetDeserializedObject(Path.Combine(targetDir, InstalledFileListName)); + } catch { + } + if (list != null) { + foreach (InstalledFile changedFile in list.Verify(targetDir)) { // 変更されたファイルたちを。。。 + string changedFilePath = Path.Combine(targetDir, changedFile.Path); + string toBeChangedFilePath = Path.Combine(installSrc, changedFile.Path); + + if (File.Exists(toBeChangedFilePath)) { + File.Move(toBeChangedFilePath, toBeChangedFilePath + ".newfile"); // 新規を退避させて + } + File.Copy(changedFilePath, toBeChangedFilePath); // installSrcの方に反映させておく + } + } + } else { + Directory.CreateDirectory(targetDir); + } + + // まずはフォルダツリーを作成 + foreach (string dir in Directory.GetDirectories(installSrc, "*", SearchOption.AllDirectories)) { + string dirPath = NaGet.Utils.GetRelativePath(installSrc, dir); + string targetDirPath = Path.Combine(targetDir, dirPath); + if (! Directory.Exists(targetDirPath)) { + Directory.CreateDirectory(targetDirPath); + } + } + + // ファイルをインストール(高速化のため移動) + foreach (string file in Directory.GetFiles(installSrc, "*", SearchOption.AllDirectories)) { + string filePath = NaGet.Utils.GetRelativePath(installSrc, file); + string targetFilePath = Path.Combine(targetDir, filePath); + if (File.Exists(targetFilePath)) { + File.Delete(targetFilePath); + } + File.Move(file, targetFilePath); + } + } + + private static void postInstall(string targetDir, Package package) + { + // SYSTEM32へのコピーの実行 + if (!string.IsNullOrEmpty(package.System32CopyFiles)) { + if (! Directory.Exists(NaGet.Env.ArchiveSystem32)) { + Directory.CreateDirectory(NaGet.Env.ArchiveSystem32); + } + + string logfile = Path.Combine(NaGet.Env.ArchiveSystem32, ".applistation.install."+package.Name+".log"); + if (File.Exists(logfile)) { + File.SetAttributes(logfile, FileAttributes.Normal); + } + using (FileStream fs = new FileStream(logfile, FileMode.Create)) + using (StreamWriter sw = new StreamWriter(fs)){ + foreach (string pathpat in package.System32CopyFiles.Split(';')) { + foreach (string path in NaGet.Utils.ExtendWildcardFile(targetDir, pathpat)) { + if ((File.GetAttributes(path) & FileAttributes.Directory) == 0) { // もしファイルならば + string destPath = Path.Combine(NaGet.Env.ArchiveSystem32, Path.GetFileName(path)); + File.Copy(path, destPath, true); + + sw.WriteLine(Path.GetFileName(destPath)); + } + } + } + } + File.SetAttributes(logfile, FileAttributes.Hidden); + } + + // インストールスクリプトの実行 + if (! string.IsNullOrEmpty(package.InstallScript) ) { + Engine engine = MSBuild.Engine; + Project proj = new Project(engine); + try { + proj.LoadXml(package.InstallScript); + } catch (InvalidProjectFileException e) { + throw new ApplicationException("InstallScript is invalid", e); + } + + engine.BuildProject(proj, "Install"); + } + + // 直下のファイルで*.exeがGUIプログラムならプログラムフォルダに登録 + foreach (string exeFile in Directory.GetFiles(targetDir, "*.exe")) { + if (NaGet.InteropServices.PEFileInfoUtils.GetPEFileType(exeFile) == NaGet.InteropServices.PEFileInfoUtils.PEFileType.WinGUI) { + string progGrpPath = Path.Combine(NaGet.Env.ArchiveProgramGroup, package.Name); + if (! Directory.Exists(progGrpPath)) Directory.CreateDirectory(progGrpPath); + + using (NaGet.InteropServices.ShellLink lnk = new NaGet.InteropServices.ShellLink() ) { + //string path = NaGet.Utils.GetRelativePath(progGrpPath, exeFile);// lnkファイルに相対パス指定不能 + string path = exeFile; + + lnk.Path = path; + //lnk.SetIconLocation(path, 0); + + // .lnk ファイル名 + string lnkFileName; + System.Diagnostics.FileVersionInfo vInfo = System.Diagnostics.FileVersionInfo.GetVersionInfo(exeFile); + if (vInfo.ProductName != null && vInfo.ProductName != string.Empty + && (!File.Exists(Path.Combine(progGrpPath, vInfo.ProductName+".lnk")))) { + // 原則、lnkファイル名に製品名を採用 + lnkFileName = vInfo.ProductName; + } else { + // そのほかの場合は、*.exeファイルの名前をそのまま使用 + lnkFileName = Path.GetFileNameWithoutExtension(exeFile); + } + + // 保存 + lnk.ToPersistFile().Save(Path.Combine(progGrpPath, lnkFileName+".lnk"), true); + } + } + } + } + + private static void storeInstalledFileList(string targetDir) + { + string installedFileListPath = Path.Combine(targetDir, InstalledFileListName); + if (File.Exists(installedFileListPath)) { + File.SetAttributes(installedFileListPath, FileAttributes.Normal); + } + InstalledFileList installedFileList = InstalledFileList.CreateFromFiles(targetDir); + NaGet.Utils.PutSerializeObject(installedFileListPath, installedFileList); + + File.SetAttributes(installedFileListPath, FileAttributes.Hidden | FileAttributes.ReadOnly); + } + + private static void storePackageXml(Package package, string destDir) + { + if (package == null) { + return; + } + + InstalledPackage pkg = InstalledPackage.PackageConverter(package); + UninstallInformation uninfo = pkg.UninstallInfo; + uninfo.InstallLocation = destDir; + uninfo.UninstallString = string.Format("archive-inst -x \"{0}\"", package.Name); + uninfo.EstimatedSize = (int) (NaGet.Utils.GetFileSize(destDir) >> 10); + uninfo.InstallDateString = DateTime.Now.ToString("yyyyMMdd"); + pkg.UninstallInfo = uninfo; + + string packageXmlFilePath = Path.Combine(destDir, InstalledPackageFileName); + if (File.Exists(packageXmlFilePath)) { + File.SetAttributes(packageXmlFilePath, FileAttributes.Normal); + } + NaGet.Utils.PutSerializeObject(packageXmlFilePath, pkg); + File.SetAttributes(packageXmlFilePath, FileAttributes.Hidden | FileAttributes.ReadOnly); + } + + private static void removePackage(InstalledPackage package, string targetDir) + { + // アンインストールスクリプトの実行 + if (! string.IsNullOrEmpty(package.InstallScript)) { + Engine engine = MSBuild.Engine; + Project proj = new Project(engine); + try { + proj.LoadXml(package.InstallScript); + } catch (InvalidProjectFileException e) { + throw new ApplicationException("InstallScript is invalid", e); + } + + engine.BuildProject(proj, "Uninstall"); + } + + // GUIプログラムでプログラムフォルダに登録しているのを解除 + string progGrpPath = Path.Combine(NaGet.Env.ArchiveProgramGroup, package.Name); + if (Directory.Exists(progGrpPath)) { + NaGet.Utils.SetAttributeRecursive(progGrpPath, FileAttributes.Normal); + Directory.Delete(progGrpPath, true); + } + + // SYSTEM32からの削除の実行 + if (! string.IsNullOrEmpty(package.System32CopyFiles) ) { + string logfile = Path.Combine(NaGet.Env.ArchiveSystem32, ".applistation.install."+package.Name+".log"); + + if (File.Exists(logfile)) { + using (FileStream fs = new FileStream(logfile, FileMode.Open)) + using (StreamReader sr = new StreamReader(fs)){ + string fileName = sr.ReadLine().Trim(); + string filePath = Path.Combine(NaGet.Env.ArchiveSystem32, fileName); + + if (File.Exists(filePath)) { + File.SetAttributes(filePath, FileAttributes.Normal); + File.Delete(filePath); + } + } + File.SetAttributes(logfile, FileAttributes.Normal); + File.Delete(logfile); + } + } + + NaGet.Utils.SetAttributeRecursive(targetDir, FileAttributes.Normal); + Directory.Delete(targetDir, true); + } + + private static void parseMainArguments(string[] args, out string arcFile, out string targetDir, out Package package) + { + if (args.Length < 1) { + throw new ArgumentException(); + } + + switch (args[0].ToLower()) { + case "-t": + if (args.Length != 3) { + throw new ArgumentException(); + } + + arcFile = args[1]; + targetDir = args[2]; + package = null; + break; + case "-i": + if (args.Length != 3) { + throw new ArgumentException(); + } + + arcFile = args[1]; + PackageList pkgList = NaGet.Utils.GetDeserializedObject>(NaGet.Env.PackageListFile); + package = pkgList.GetPackageForName(args[2]); + targetDir = Path.Combine(NaGet.Env.ArchiveProgramFiles, package.Name); + break; + case "-x": + if (args.Length != 2) { + throw new ArgumentException(); + } + + arcFile = null; + targetDir = Path.Combine(NaGet.Env.ArchiveProgramFiles, args[1]); + package = null; + + string filepath = Path.Combine(targetDir, InstalledPackageFileName); + if (File.Exists(filepath)) { + package = NaGet.Utils.GetDeserializedObject(filepath); + } else { + Console.Error.WriteLine("Not found or already removed package : {0}", args[1]); + Environment.Exit(100); + } + break; + default: + arcFile = null; + targetDir = null; + package = null; + Console.Error.WriteLine("Unreconized command \"{0}\".", args[0]); + Environment.Exit(100); + break; + } + } + + [STAThread] + public static void Main(string[] args) + { + // アーカイブSYSTEM32をパスに足す + NaGet.Utils.AddDirectoryToPath(NaGet.Env.ArchiveSystem32); + + string arcFile = null; + string targetDir = null; + Package package = null; + + try { + parseMainArguments(args, out arcFile, out targetDir, out package); + } catch (ArgumentException) { + string executeFileName = System.AppDomain.CurrentDomain.FriendlyName; + Console.Write("Usage:"); + Console.WriteLine("\t{0} -t archive.zip target_dir\tExtraction", executeFileName); + Console.WriteLine("\t{0} -i archive.zip PackageName\tInstall", executeFileName); + Console.WriteLine("\t{0} -x PackageName\t\tUninstall", executeFileName); + Console.WriteLine(); + } + + if (arcFile != null) { // install or extract + string tempExtractDir = targetDir + "___temp___"; // HACK + Directory.CreateDirectory(tempExtractDir); + + try { + extract(arcFile, tempExtractDir); + + install(tempExtractDir, targetDir); + + if (package != null) { + postInstall(targetDir, package); + + storeInstalledFileList(targetDir); + storePackageXml(package, targetDir); + } + } catch (DllNotFoundException) { + Console.Error.WriteLine("E: Does not exist archive dll for {0}", arcFile); // TODO + Environment.Exit(10); + } finally { + Directory.Delete(tempExtractDir, true); + } + } else if (package is InstalledPackage) { + removePackage((InstalledPackage) package, targetDir); + } + } + } +} diff --git a/archive-inst/archive-inst.csproj b/archive-inst/archive-inst.csproj new file mode 100644 index 0000000..e52e86a --- /dev/null +++ b/archive-inst/archive-inst.csproj @@ -0,0 +1,58 @@ + + + {9D7ADB99-6E53-4E3E-A13B-6D82412B3671} + Debug + AnyCPU + Exe + ArchiveInstall + archive-inst + bin/ + False + False + 4 + false + + + bin\Debug\ + true + Full + False + True + DEBUG;TRACE + + + bin\Release\ + False + None + True + False + TRACE + + + False + Auto + 4194304 + x86 + 4096 + + + + + + + + + + + + + + + + + + {058E953D-3986-4F74-8516-5A50D267D36A} + na-get-lib + + + \ No newline at end of file diff --git a/build.bat b/build.bat new file mode 100644 index 0000000..4321829 --- /dev/null +++ b/build.bat @@ -0,0 +1,3 @@ +@set path=%windir%\Microsoft.NET\Framework\v2.0.50727;%path% +msbuild AppliStation.proj /t:Build +msbuild AppliStation.proj /t:Dist /p:IncludePdb=Yes \ No newline at end of file diff --git a/na-get-lib/AssemblyInfo.cs b/na-get-lib/AssemblyInfo.cs new file mode 100644 index 0000000..3d4acb6 --- /dev/null +++ b/na-get-lib/AssemblyInfo.cs @@ -0,0 +1,32 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following +// attributes. +// +// change them to the information which is associated with the assembly +// you compile. + +[assembly: AssemblyTitle("NaGet Library")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// The assembly version has following format : +// +// Major.Minor.Build.Revision +// +// You can specify all values by your own or you can build default build and revision +// numbers with the '*' character (the default): + +[assembly: AssemblyVersion("0.9.8.*")] + +// The following attributes specify the key for the sign of your assembly. See the +// .NET Framework documentation for more information about signing. +// This is not required, if you don't want signing let these attributes like they're. +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] diff --git a/na-get-lib/NaGet.InteropServices/CommonArchiverExtracter.cs b/na-get-lib/NaGet.InteropServices/CommonArchiverExtracter.cs new file mode 100644 index 0000000..1126d15 --- /dev/null +++ b/na-get-lib/NaGet.InteropServices/CommonArchiverExtracter.cs @@ -0,0 +1,186 @@ +using System; +using System.Runtime.InteropServices; +using System.IO; + +namespace NaGet.InteropServices +{ + /// + /// CommonArchiverDllの設定 + /// + public struct CommonArchiverDllConfig + { + public CommonArchiverDllConfig(string dllName, string cmdName, string cmdLineFmt, int versionreq) + { + DllName = dllName; + CmdName = cmdName; + CmdLineFmt = cmdLineFmt; + VersionMoreThan = versionreq; + } + + /// + /// DLLの名称。LoadLibraryに渡される + /// + public string DllName; + /// + /// コマンド名称。 + /// + public string CmdName; + /// + /// コマンドライン形式"{0}"がアーカイブ名、"{1}"が展開先 + /// + public string CmdLineFmt; + /// + /// 最低バージョン要求 + /// + public int VersionMoreThan; + } + + /// + /// アーカイバDLLを使った書庫展開器 + /// + public class CommonArchiverExtracter + { + + #region DLL関数のdelegate + + /// + /// DLL の版の取得 + /// + private delegate ushort ArcGetVersion(); + + /// + /// DLL の実行状況の取得 + /// + private delegate bool ArcGetRunning(); + + /// + /// 書庫のチェック + /// + private delegate bool ArcCheckArchive(string szFileName, ArchCheckFlag iMode); + + /// + /// 書庫のチェックの精度 + /// + private enum ArchCheckFlag { + /// + /// 簡易モード。先頭の数個のヘッダのみ確認 + /// + RAPID = 0, + /// + /// 通常モード。すべてのヘッダを確認 + /// + BASIC = 1, + /// + /// 厳密モード。CRCも含めすべて確認 + /// + FULLCRC = 2, + //RECOVERY = 4, + //SFX = 8, + //ALL = 16, + } + + /// + /// 格納ファイル数の取得 + /// + private delegate int ArcGetFileCount(string szFileName); + + /// + /// 書庫操作一般 + /// + private delegate int ArcMain(IntPtr hWnd, + [MarshalAs(UnmanagedType.LPStr)] string szCmdLine, + [MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder szOutput, uint dwSize); + + #endregion + + /// + /// アーカイバDLLの設定 + /// + public static readonly CommonArchiverDllConfig[] Configs = { + new CommonArchiverDllConfig("UNZIP32", "UnZip", "-x -o \"{0}\" \"{1}\" *", 541), + new CommonArchiverDllConfig("7-ZIP32", "SevenZip", "x -y \"{0}\" \"-o{1}\"", 423), + new CommonArchiverDllConfig("UNLHA32", "Unlha", "x \"{0}\" \"{1}\" *", 240), + new CommonArchiverDllConfig("CAB32", "Cab", "-x \"{0}\" \"{1}\" *", 98), + new CommonArchiverDllConfig("TAR32", "Tar", "-x \"{0}\" -o \"{1}\"", 218), + new CommonArchiverDllConfig("UNGCA32", "UnGCA", "e \"{0}\" \"{1}\"", 10), // いるかな? + + //new CommonArchiverDllConfig("UNRAR32", "Unrar", "x -y \"{0}\" \"{1}\" *", -1), + }; + + /// + /// アーカイブを展開する。適切なDLLで自動的に展開する。 + /// + /// アーカイブのパス + /// 展開先ディレクトリ + /// アーカイバDLLの展開時の標準出力を格納する + /// 親フレーム + /// アーカイバDLLの展開時のエラーコード(0なら正常終了) + public static int ExtractArchive(string arcFile, string targetDir, System.Text.StringBuilder output, IntPtr hWnd) + { + foreach (CommonArchiverDllConfig config in Configs) { + try { + return ExtractArchiveWith(arcFile, targetDir, config, output, hWnd); + } catch (DllNotFoundException) { + } catch (ApplicationException) { + } + } + throw new DllNotFoundException("Not found dll matched for " + arcFile); + } + + /// + /// 指定したDLLの設定を使ってアーカイブを展開する + /// + /// アーカイブのパス + /// 展開先ディレクトリ + /// 使用するアーカイバDLLの設定 + /// アーカイバDLLの展開時の標準出力を格納する + /// 親フレーム + /// アーカイバDLLの展開時のエラーコード(0なら正常終了) + public static int ExtractArchiveWith(string arcFile, string targetDir, CommonArchiverDllConfig config, System.Text.StringBuilder output, IntPtr hWnd) + { + if (! File.Exists(arcFile) ) { + throw new FileNotFoundException("File not found: ", arcFile); + } + if (! Directory.Exists(targetDir)) { + throw new DirectoryNotFoundException("Directory not found: " + targetDir); + } + + // 統合アーカイバDLLの解凍先ディレクトリは\で終わらないといけない(重要) + if (! targetDir.EndsWith("\\")) { + targetDir += "\\"; + } + + // DLLバージョンチェック + using (DllAccess dll = new DllAccess(config.DllName)) { + ArcGetVersion GetVersion = (ArcGetVersion) dll.GetFunction(config.CmdName+"GetVersion", typeof(ArcGetVersion)); + ushort version = GetVersion(); + if (version < config.VersionMoreThan) { + throw new DllNotFoundException("Dll version is too old."); + } + } + + string cmdLine = string.Format(config.CmdLineFmt, arcFile, targetDir); + return ExtractArchiveWith(config.DllName, config.CmdName, cmdLine, arcFile, output, hWnd); + } + + protected static int ExtractArchiveWith(string dllName, string cmdName, string cmdLine, string arcFile, System.Text.StringBuilder output, IntPtr hWnd) + { + using (DllAccess dll = new DllAccess(dllName)) { + ArcGetRunning GetRunning = (ArcGetRunning) dll.GetFunction(cmdName+"GetRunning", typeof(ArcGetRunning)); + if ( GetRunning() ) { // マルチスレッド対応でないのでビジー時には例外 + throw new SystemException(dllName + " is busy"); + } + + ArcCheckArchive CheckArchive = (ArcCheckArchive) dll.GetFunction(cmdName+"CheckArchive", typeof(ArcCheckArchive)); + if (! CheckArchive(arcFile, ArchCheckFlag.BASIC)) { + throw new ApplicationException(dllName + " could not treat the archive file"); + } + + ArcMain Exec = (ArcMain) dll.GetFunction(cmdName, typeof(ArcMain)); + int retVal = Exec(hWnd, cmdLine, output, (uint)((output != null)? output.Capacity : 0) ); + + return retVal; + } + } + } +} diff --git a/na-get-lib/NaGet.InteropServices/CreateProcessCaller.cs b/na-get-lib/NaGet.InteropServices/CreateProcessCaller.cs new file mode 100644 index 0000000..cfb1d5c --- /dev/null +++ b/na-get-lib/NaGet.InteropServices/CreateProcessCaller.cs @@ -0,0 +1,131 @@ +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace NaGet.InteropServices +{ + public class CreateProcessCaller : IDisposable + { + #region Win32API + + /* + [StructLayout(LayoutKind.Sequential)] + internal struct SECURITY_ATTRIBUTES + { + public int nLength; + public IntPtr lpSecurityDescriptor; + public int bInheritHandle; + } + */ + + [StructLayout(LayoutKind.Sequential)] + internal struct PROCESS_INFORMATION + { + public IntPtr hProcess; + public IntPtr hThread; + public int dwProcessId; + public int dwThreadId; + } + + [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] + struct STARTUPINFO + { + public Int32 cb; + string lpReserved; + string lpDesktop; + string lpTitle; + Int32 dwX; + Int32 dwY; + Int32 dwXSize; + Int32 dwYSize; + Int32 dwXCountChars; + Int32 dwYCountChars; + Int32 dwFillAttribute; + Int32 dwFlags; + Int16 wShowWindow; + Int16 cbReserved2; + IntPtr lpReserved2; + IntPtr hStdInput; + IntPtr hStdOutput; + IntPtr hStdError; + } + + [DllImport("kernel32.dll", CharSet= CharSet.Auto, SetLastError=true)] + static extern bool CreateProcess(string lpApplicationName, + string lpCommandLine, + /* ref SECURITY_ATTRIBUTES lpProcessAttributes, */ + IntPtr lpProcessAttributes, + /* ref SECURITY_ATTRIBUTES lpThreadAttributes, */ + IntPtr lpThreadAttributes, + bool bInheritHandles, + uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, + [In] ref STARTUPINFO lpStartupInfo, + out PROCESS_INFORMATION lpProcessInformation); + + [DllImport("kernel32", SetLastError=true, ExactSpelling=true)] + static extern UInt32 WaitForSingleObject(IntPtr handle, UInt32 milliseconds); + + [DllImport("kernel32.dll", SetLastError=true)] + [return: MarshalAs(UnmanagedType.Bool)] + static extern bool CloseHandle(IntPtr hObject); + + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + static extern bool GetExitCodeProcess(IntPtr hProcess, out int lpExitCode); + + #endregion + + STARTUPINFO si; + PROCESS_INFORMATION pi; + + public CreateProcessCaller(ProcessStartInfo procInfo) + { + if (procInfo.UseShellExecute) { + throw new ArgumentException("UseShellExecute must be false"); + } + si.cb = Marshal.SizeOf(si); + + string lpFileName = (string.IsNullOrEmpty(procInfo.FileName))? null : procInfo.FileName; + + uint dwCreationFlags = 0x0020; // NORMAL_PRIORITY_CLASS + if (procInfo.CreateNoWindow) dwCreationFlags |= 0x08000000; // CREATE_NO_WINDOW + string lpCurrentDirectory = (System.IO.Directory.Exists(procInfo.WorkingDirectory))? procInfo.WorkingDirectory : null; + + bool retValue = CreateProcess(lpFileName, procInfo.Arguments, + IntPtr.Zero, IntPtr.Zero, + false, dwCreationFlags, + IntPtr.Zero, lpCurrentDirectory, ref si, out pi); + if (! retValue) { + throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()); + } + CloseHandle(pi.hThread); + } + + public uint WaitForExit(uint timeout) + { + return WaitForSingleObject(pi.hProcess, timeout); + } + + public uint WaitForExit() + { + // return WaitForExit(INFINITE) + return WaitForExit(0xFFFFFFFF); + } + + public int ExitCode { + get { + int lpExitCode; + if (! GetExitCodeProcess(pi.hProcess, out lpExitCode) ) { + throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()); + } + return lpExitCode; + } + } + + public void Dispose() + { + CloseHandle(pi.hProcess); + } + + } +} diff --git a/na-get-lib/NaGet.InteropServices/DllAccess.cs b/na-get-lib/NaGet.InteropServices/DllAccess.cs new file mode 100644 index 0000000..bd008bb --- /dev/null +++ b/na-get-lib/NaGet.InteropServices/DllAccess.cs @@ -0,0 +1,80 @@ +using System; +using System.Reflection; +using System.Runtime.InteropServices; + +namespace NaGet.InteropServices +{ + /// + /// DLLへの動的アクセスを行うクラス + /// + public class DllAccess : IDisposable + { + #region Win32 API + + [DllImport("kernel32.dll", CharSet=CharSet.Auto)] + private extern static IntPtr LoadLibrary(string lpFileName); + + [DllImport("kernel32.dll")] + private extern static bool FreeLibrary(IntPtr hModule); + + [DllImport("kernel32.dll", CharSet=CharSet.Ansi)] + private extern static IntPtr GetProcAddress(IntPtr hModule, string lpProcName); + + #endregion + + private IntPtr hModule = IntPtr.Zero; + + /// + /// コンストラクタ。DLLを読み込む + /// + /// + /// DLLの名称。直接Win32APIのLoadLibraryにわたされる + /// + public DllAccess(string dllName) + { + hModule = LoadLibrary(dllName); + if (hModule == IntPtr.Zero) { + Exception innerEx = null; + try { + innerEx = Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()); + } catch { + } + throw new DllNotFoundException("Failed to LoadLibrary " + dllName, innerEx); + } + } + + /// + /// 関数をdelegateに変換して得る + /// + /// + /// 関数名 + /// + /// + /// 関数の型。戻り値のdelegateのタイプ + /// + /// + /// delegateに変換された関数 + /// + public Delegate GetFunction(string strProcName, Type type) + { + IntPtr pFunc = GetProcAddress(hModule, strProcName); + if (pFunc == IntPtr.Zero) { + int result = Marshal.GetHRForLastWin32Error(); + throw Marshal.GetExceptionForHR(result); + } + + return Marshal.GetDelegateForFunctionPointer(pFunc, type); + } + + /// + /// DLLの読み込みを閉じる + /// + public void Dispose() + { + if (hModule != IntPtr.Zero) { + FreeLibrary(hModule); + hModule = IntPtr.Zero; + } + } + } +} diff --git a/na-get-lib/NaGet.InteropServices/PEFileInfoUtils.cs b/na-get-lib/NaGet.InteropServices/PEFileInfoUtils.cs new file mode 100644 index 0000000..489bcc9 --- /dev/null +++ b/na-get-lib/NaGet.InteropServices/PEFileInfoUtils.cs @@ -0,0 +1,142 @@ +using System; +using System.IO; +using System.Runtime.InteropServices; + +namespace NaGet.InteropServices +{ + public sealed class PEFileInfoUtils + { + // ŒÄ‚яo‚µ‹ÖŽ~ + private PEFileInfoUtils() + { + } + + /// + /// PEƒtƒ@ƒCƒ‹‚ÌŽí—Þ + /// + public enum PEFileType : uint + { + /// + /// •s–¾‚ÈŒ`Ž®A‚ ‚é‚¢‚ÍPEƒtƒ@ƒCƒ‹ƒwƒbƒ_‚ðŽ‚½‚È‚¢ + /// + Unknown = 0, + /// + /// WindowsƒRƒ“ƒ\[ƒ‹ƒAƒvƒŠƒP[ƒVƒ‡ƒ“ + /// + WinConsole = 1, + /// + /// Windows GUIƒAƒvƒŠƒP[ƒVƒ‡ƒ“ + /// + WinGUI = 2, + /// + /// MS-DOS(‹y‚уRƒ}ƒ“ƒhƒvƒƒ“ƒvƒg)‚Å‚ÌCOMƒtƒ@ƒCƒ‹ + /// + MSDosCom = 3, + } + + /// + /// “n‚³‚ꂽŽÀsƒtƒ@ƒCƒ‹‚ÌŽí—Þ‚ð•Ô‚·B“à•”‚ÅSHGetFileInfo‚ðŽg—pB + /// + /// ŽÀsƒtƒ@ƒCƒ‹(*.exe,*.dll)‚ւ̃pƒX + /// ŽÀsƒtƒ@ƒCƒ‹‚ÌŽí—Þ + public static PEFileType GetPEFileType(string path) + { + PEFileType fileType; + + try { + SHFILEINFO info = new SHFILEINFO(); + int type = (int) shGetFileInfo(path, 0, ref info, SHGFI.ExeType); + + const int MZ = 0x5a4d; + const int NE = 0x504e; + const int PE = 0x4550; + switch (type) + { + case MZ: + fileType = PEFileType.MSDosCom; + break; + case PE: + fileType = PEFileType.WinConsole; + break; + default: + int loWord = type & 0xffff; + int hiWord = (type >> 16) & 0xffff; + + if (((loWord == PE) || (loWord == NE)) && + ((hiWord == 0x0300) || (hiWord == 0x0350) || (hiWord == 0x0400))) + { + fileType = PEFileType.WinGUI; + } else { + fileType = PEFileType.Unknown; + } + break; + } + } catch (FileNotFoundException e) { + throw new FileNotFoundException(e.Message, e); + } catch (IOException) { + fileType = PEFileType.Unknown; + } + + return fileType; + } + + #region SHGetFileInfo + + [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] + private struct SHFILEINFO + { + public IntPtr hIcon; + public IntPtr iIcon; + public uint dwAttributes; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst=260)] + public string szDisplayName; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst=80)] + public string szTypeName; + } + + private enum SHGFI : uint + { + Icon = 256, + DisplayName = 512, + TypeName = 1024, + Attributes = 2048, + IconLocation = 4096, + ExeType = 8192, + SysIconIndex = 16384, + LinkOverlay = 32768, + Selected = 65536, + AttrSpecified = 131072, + LargeIcon = 0, + SmallIcon = 1, + OpenIcon = 2, + PIDL = 8, + UseFileAttributes = 16 + } + + [DllImport("shell32.dll", CharSet=CharSet.Auto)] + private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbFileInfo, uint uFlags); + + /// + /// SHGetFileInfo‚ðŒÄ‚яo‚·•Ö—˜ƒƒ\ƒbƒhBƒtƒ@ƒCƒ‹“ǂݍž‚݂ȂǂɎ¸”s‚µ‚½‚èA + /// ŽÀsƒtƒ@ƒCƒ‹‚łȂ¢ê‡‚ÍIOException‚𓊂°‚Ü‚·B + /// + /// ƒtƒ@ƒCƒ‹ƒpƒX + /// ƒtƒ@ƒCƒ‹‘®« + /// ƒtƒ@ƒCƒ‹î•ñ + /// ƒtƒ‰ƒO + private static IntPtr shGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, SHGFI uFlags) + { + if (! File.Exists(pszPath)) { + throw new FileNotFoundException(null, pszPath); + } + + IntPtr hSuccess = SHGetFileInfo(pszPath, 0, ref psfi, (uint)Marshal.SizeOf(psfi), (uint) uFlags); + if (hSuccess == IntPtr.Zero) { + throw new IOException(string.Format("Maybe {0} is not a executable file.", pszPath)); + } + return hSuccess; + } + + #endregion + } +} diff --git a/na-get-lib/NaGet.InteropServices/ShellLink.cs b/na-get-lib/NaGet.InteropServices/ShellLink.cs new file mode 100644 index 0000000..1188d92 --- /dev/null +++ b/na-get-lib/NaGet.InteropServices/ShellLink.cs @@ -0,0 +1,280 @@ +using System; +using System.Text; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.ComTypes; +using System.Diagnostics; + +namespace NaGet.InteropServices +{ + /// + /// ShellLink‚̍XVƒtƒ‰ƒO + /// + [Flags] + public enum ShellLinkResolve : uint + { + // AnyMatch = 0x02, // winMe,win2kˆÈ~–³Œø + + /// + /// MSI‚ðŒÄ‚Ô + /// + InvokeMSI = 0x80, + /// + /// ’ǐՋ֎~ + /// + NoLinkInfo = 0x40, + /// + /// ƒŠƒ“ƒNæ‚Ì‰ðŒˆ‚ª‚Å‚«‚È‚¢‚Æ‚«ƒ_ƒCƒAƒƒO‚ð•\ަ‚µ‚È‚¢ + /// + NoUi = 0x01, + NoUiWithMsgPump = 0x101, + /// + /// ƒŠƒ“ƒNæ‚̃f[ƒ^XV‚ðs‚í‚È‚¢ + /// + NoUpdate = 0x07, + /// + /// ŒŸõ‚ð‚µ‚È‚¢ + /// + NoSearch = 0x10, + NoTrack = 0x20, + /// + /// ƒŠƒ“ƒNæ‚ðXV‚·‚é + /// + Update = 0x04, + } + + [ComImport()] + [Guid("000214F9-0000-0000-C000-000000000046")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IShellLinkW + { + void GetPath([MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, + int cchMaxPath, IntPtr pfd, uint fFlags); + + void GetIDList(out IntPtr ppidl); + void SetIDList(IntPtr pidl); + + void GetDescription([MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDesc, + int cchMaxPath); + void SetDescription(string pszDesc); + + void GetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, + int cchMaxPath); + void SetWorkingDirectory(string pszDir); + + void GetArguments([MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, + int cchMaxPath); + void SetArguments(string pszArgs); + + void GetHotkey(out short pwHotkey); + void SetHotkey(short pwHotkey); + + void GetShowCmd(out uint piShowCmd); + void SetShowCmd(uint piShowCmd); + + void GetIconLocation([MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath, + int cchMaxPath, out int piIcon); + void SetIconLocation(string pszIconPath, int iIcon); + + void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszPath, + int cchMaxPath, uint dwReserved); + + void Resolve(IntPtr hWnd, ShellLinkResolve fFlag); + + void SetPath(string pszFile); + } + + /// + /// ƒVƒFƒ‹ƒŠƒ“ƒN(ƒVƒ‡[ƒgƒJƒbƒg)‚̃JƒvƒZƒ‹ƒNƒ‰ƒX + /// + public class ShellLink : IDisposable + { + /// + /// ƒVƒFƒ‹ƒŠƒ“ƒN‚ÌCOMƒIƒuƒWƒFƒNƒg + /// + protected IShellLinkW shellLink; + + /// + /// ƒVƒFƒ‹ƒŠƒ“ƒN‚ÌGUID + /// + public const string ShellLinkGuid = "00021401-0000-0000-C000-000000000046"; + + protected const int MAX_PATH = 260; + + public ShellLink() + { + Type shellLinkType = Type.GetTypeFromCLSID(new Guid(ShellLinkGuid)); + shellLink = (IShellLinkW) Activator.CreateInstance(shellLinkType); + } + + public ShellLink(string path) : this() + { + if (! System.IO.File.Exists(path)) { + throw new System.IO.FileNotFoundException("File does not found", path); + } + + ToPersistFile().Load(path, 0); + Resolve(IntPtr.Zero, ShellLinkResolve.NoUpdate | ShellLinkResolve.NoUi); + } + + /// + /// ƒVƒFƒ‹ƒŠƒ“ƒN‚̉ðÍ‰ðŒˆ + /// + /// eƒtƒŒ[ƒ€‚̃nƒ“ƒhƒ‹ + /// •û–@ + public void Resolve(IntPtr? hWnd, ShellLinkResolve fFlags) + { + shellLink.Resolve(hWnd ?? IntPtr.Zero, fFlags); + } + + /// + /// IPersistFile‚Æ‚µ‚ÄŽæ‚èo‚· + /// + /// IPersistFile‚ɃLƒƒƒXƒg‚³‚ꂽCOMƒIƒuƒWƒFƒNƒg + public IPersistFile ToPersistFile() + { + return (IPersistFile) shellLink; + } + + /// + /// ƒŠƒ“ƒNæƒpƒX‚𓾂éBƒRƒ}ƒ“ƒhƒ‰ƒCƒ“‚𓾂邽‚߂ɂà + /// + /// ƒpƒX‚̃^ƒCƒv(1:8.3Œ`Ž®; 2:UNCƒpƒX; 4:ŠÂ‹«•ϐ”•ÏŠ·‚È‚µ) + /// ƒpƒX + public string GetPath(uint fFlags) + { + StringBuilder sb = new StringBuilder(MAX_PATH); + shellLink.GetPath(sb, sb.Capacity, IntPtr.Zero, fFlags); + return sb.ToString(); + } + + /// + /// ƒŠƒ“ƒNæƒpƒX(Žæ“¾Žž‚ɂ͊‹«•ϐ”‚Í“WŠJ‚³‚ê‚Ü‚¹‚ñ) + /// + public string Path { + get { return GetPath(0x04); } + set { shellLink.SetPath(value); } + } + + /// + /// ƒŠƒ“ƒNæ(ˆø”) + /// + public string Arguments { + get { + StringBuilder sb = new StringBuilder(MAX_PATH); + shellLink.GetArguments(sb, sb.Capacity); + return sb.ToString(); + } + set { shellLink.SetArguments(value); } + } + + /// + /// ì‹ÆƒtƒHƒ‹ƒ_ + /// + public string WorkingDirectory { + get { + StringBuilder sb = new StringBuilder(MAX_PATH); + shellLink.GetWorkingDirectory(sb, sb.Capacity); + return sb.ToString(); + } + set { shellLink.SetWorkingDirectory(value); } + } + + /// + /// ƒEƒBƒ“ƒhƒEƒXƒ^ƒCƒ‹(ShowCmd‚̃ƒbƒp) + /// + public ProcessWindowStyle WindowStyle + { + get { + uint showcmd; + shellLink.GetShowCmd(out showcmd); + switch (showcmd) { + case 3: + return ProcessWindowStyle.Maximized; + case 7: + return ProcessWindowStyle.Minimized; + case 1: + default: + return ProcessWindowStyle.Normal; + } + } + set { + switch (value) { + case ProcessWindowStyle.Normal: + shellLink.SetShowCmd(1); + break; + case ProcessWindowStyle.Maximized: + shellLink.SetShowCmd(3); + break; + case ProcessWindowStyle.Minimized: + case ProcessWindowStyle.Hidden: + shellLink.SetShowCmd(7); + break; + } + } + } + + /// + /// ƒAƒCƒRƒ“‚̏ꏊ‚𓾂é + /// + /// ƒAƒCƒRƒ“‚ðŠÜ‚Þƒtƒ@ƒCƒ‹ƒpƒX + /// ƒAƒCƒRƒ“‚̃Cƒ“ƒfƒbƒNƒX + public void GetIconLocation(out string iconPath, out int iconIndex) + { + StringBuilder sb = new StringBuilder(MAX_PATH); + shellLink.GetIconLocation(sb, sb.Capacity, out iconIndex); + iconPath = sb.ToString(); + } + + /// + /// ƒAƒCƒRƒ“‚̏ꏊ‚ðÝ’è‚·‚é + /// + /// ƒAƒCƒRƒ“‚ðŠÜ‚Þƒtƒ@ƒCƒ‹ƒpƒX + /// ƒAƒCƒRƒ“‚̃Cƒ“ƒfƒbƒNƒX + public void SetIconLocation(string iconPath, int iconIndex) + { + shellLink.SetIconLocation(iconPath, iconIndex); + } + + /// + /// COMƒIƒuƒWƒFƒNƒg‚ÌŠJ•ú + /// + public void Dispose() + { + if (shellLink != null) { + Marshal.ReleaseComObject(shellLink); + shellLink = null; + } + } + + /// + /// ƒVƒFƒ‹ƒŠƒ“ƒN‚Ì’†g‚ðƒvƒƒZƒXî•ñ‚Æ‚µ‚Ď擾‚·‚éB‹N“®‚̍ۂɗ˜—p + /// + /// ƒvƒƒZƒX‹N“®î•ñ‰»‚³‚ꂽƒVƒFƒ‹ƒŠƒ“ƒN‚̏î•ñ + public ProcessStartInfo ToProcessStartInfo() + { + ProcessStartInfo procInfo = new ProcessStartInfo(); + procInfo.FileName = GetPath(0); + procInfo.Arguments = Arguments; + procInfo.WorkingDirectory = WorkingDirectory; + procInfo.WindowStyle = WindowStyle; + + return procInfo; + } + + /// + /// ƒvƒƒZƒXî•ñ‚©‚çƒVƒFƒ‹ƒŠƒ“ƒNƒIƒuƒWƒFƒNƒg‚𐶐¬ + /// + /// ƒvƒƒZƒXî•ñ + /// ¶¬‚³‚ꂽƒVƒFƒ‹ƒŠƒ“ƒNƒIƒuƒWƒFƒNƒg + public static ShellLink CreateFromProcessStartInfo(ProcessStartInfo procInfo) + { + ShellLink shelllink = new ShellLink(); + shelllink.Path = procInfo.FileName; + shelllink.Arguments = procInfo.Arguments; + shelllink.WorkingDirectory = procInfo.WorkingDirectory; + shelllink.WindowStyle = procInfo.WindowStyle; + + return shelllink; + } + } +} diff --git a/na-get-lib/NaGet.Net/Downloader.cs b/na-get-lib/NaGet.Net/Downloader.cs new file mode 100644 index 0000000..a38f76b --- /dev/null +++ b/na-get-lib/NaGet.Net/Downloader.cs @@ -0,0 +1,323 @@ +using System; +using System.Net; +using System.IO; +using System.Collections; +using System.Threading; +using NaGet.SubCommands; + +namespace NaGet.Net +{ + +/// +/// ダウンロードイベントオブジェクト +/// +public class DownloadEventArgs : NaGetEventArgs +{ + /// + /// イベントの種類 + /// + public DownloadEventType Type; + + /// + /// ダウンロード済みのバイト数 + /// + public long DownloadSize; + + /// + /// ダウンロードする総バイト数 + /// + public long MaxSize; + + /// + /// コンストラクタ + /// + /// イベントの種類 + /// イベントメッセージ + /// ダウンロード済みのバイト数 + /// ダウンロードする総バイト数 + public DownloadEventArgs(DownloadEventType type, string msg, long pos, long max) + { + Type = type; + DownloadSize = pos; + MaxSize = max; + + TaskMessage = msg; + TaskProgressPercent = (max > 0)? (100.0f * pos / max) : -1; + } +} + +/// +/// DownloadEventArgsでのイベントの種類 +/// +public enum DownloadEventType { + INITED, + CONNECTED, + STARTED, + DOWNLOADING, + ERROR, + COMPLETED +} + +/// +/// ダウンロード処理を行うクラス +/// +public class Downloader : NaGetTask +{ + /// + /// デフォルトで使うプロキシ + /// + public static IWebProxy DefaultProxy = WebRequest.GetSystemWebProxy(); + + /// + /// 通信に使うプロキシ + /// + public IWebProxy Proxy; + + /// + /// イベントハンドラ + /// + public event EventHandler DownloadEventRaised; + + protected string url; + + protected string filepath; + + protected WebRequest request; + + protected WebResponse response; + + private bool cancelCalled = false; + + private bool done = false; + + /// + /// ダウンロード時にHTTPヘッダなどから取得した本来のファイル名 + /// + private string downloadedFileName = null; + + /// + /// ダウンロード時にHTTPヘッダなどから取得した本来のファイル名 + /// + public string DownloadedFileName { + get { return downloadedFileName; } + } + + /* ダウンロードの処理時間計測器 */ + private System.Diagnostics.Stopwatch stopwatch; + + /// + /// ダウンロードを行う + /// + /// ダウンロードするリソースのURL + /// 保存先ファイルパス + public void Download(string url, string filepath) + { + this.url = url; + this.filepath = filepath; + + try { + Run(); + } catch (NotSupportedException e) { + throw new NotSupportedException("Not supported download location for downloader.", e); + } + } + + public override bool Done { + get { return done; } + } + + public override bool Running { + get { return request != null && (!done); } + } + + public override void Run() + { + RaiseDownloadEvent(DownloadEventType.INITED, 0, -1); + + try { + request = WebRequest.Create(url); + request.Proxy = (Proxy == null)? DefaultProxy : Proxy; + if (request is HttpWebRequest) { + request.CachePolicy = new System.Net.Cache.HttpRequestCachePolicy( + System.Net.Cache.HttpRequestCacheLevel.NoCacheNoStore); + } + + if (cancelCalled) { + throw new NaGetTaskCanceledException(string.Empty); + } + + try { + response = request.GetResponse(); + } catch (WebException e) { + if (cancelCalled) { // キャンセル時 + throw new NaGetTaskCanceledException(string.Empty, e); + } else { + throw new WebException(e.Message, e); + } + } + + if (cancelCalled) { + throw new NaGetTaskCanceledException(string.Empty); + } + + try { + downloadedFileName = getFileNameFromWebResponse(response); + } catch (Exception) { + } + + if (File.Exists(filepath)) { // ファイルが存在するとき削除 + File.Delete(filepath); + } + + RaiseDownloadEvent(DownloadEventType.CONNECTED, 0, -1); + + using (Stream stream = response.GetResponseStream() ) + using (FileStream fs = new FileStream(filepath, + FileMode.Create, + FileAccess.Write) ) { + try { + File.SetAttributes(filepath, FileAttributes.Hidden); + long contentLength = response.ContentLength; + + RaiseDownloadEvent(DownloadEventType.STARTED, 0, contentLength); + + stopwatch = new System.Diagnostics.Stopwatch(); + stopwatch.Start(); + + Timer timer = new Timer(new TimerCallback( + delegate(object obj) { + try { + RaiseDownloadEvent(DownloadEventType.DOWNLOADING, fs.Position, contentLength); + } catch (ObjectDisposedException) { + } + }), null, 0, 1000); + + try { + byte[] data = new byte[4096]; + int size = 0; + while ((size = stream.Read(data,0,data.Length)) > 0) { + fs.Write(data, 0, size); + + bool hoge = cancelCalled; + + if (cancelCalled) { + throw new NaGetTaskCanceledException(string.Empty); + } + } + } finally { + timer.Dispose(); + } + + File.SetAttributes(filepath, FileAttributes.Normal); + + RaiseDownloadEvent(DownloadEventType.COMPLETED, fs.Position, contentLength); + } catch (IOException ex) { + if (cancelCalled) { + throw new NaGetTaskCanceledException(string.Empty); + } else { + RaiseDownloadEvent(DownloadEventType.ERROR, 0, 0); + throw new IOException(ex.Message, ex); + } + } finally { + if (stopwatch != null) { + stopwatch.Stop(); + stopwatch = null; + } + } + } + } finally { + if (response != null) { + response.Close(); + } + + request = null; + done = true; + } + } + + protected void RaiseDownloadEvent(DownloadEventType type, long pos, long max) + { + if (DownloadEventRaised != null) { + DownloadEventArgs e = new DownloadEventArgs(type, string.Empty, pos, max); + + switch (e.Type) { + case DownloadEventType.CONNECTED: + e.TaskMessage = "接続しました"; + break; + case DownloadEventType.STARTED: + case DownloadEventType.DOWNLOADING: + case DownloadEventType.COMPLETED: + try { + e.TaskMessage = string.Format("{0} bytes ({1} %)", e.DownloadSize, (int) e.TaskProgressPercent); + } catch (DivideByZeroException) { + e.TaskMessage = string.Format("{0} bytes", e.DownloadSize); + } + + + if (stopwatch != null && stopwatch.IsRunning && stopwatch.ElapsedMilliseconds > 3000) { + long bpers = e.DownloadSize * 1000 / stopwatch.ElapsedMilliseconds; + try { + TimeSpan rest = TimeSpan.FromSeconds((max - e.DownloadSize) / bpers); + e.TaskMessage += string.Format(" 推定残り時間:{0} ({1}/s)", rest, NaGet.Utils.FormatSize(bpers)); + } catch { + e.TaskMessage += string.Format(" ({0}/s)", NaGet.Utils.FormatSize(bpers)); + } + } + + break; + } + + DownloadEventRaised(this, e); + } + } + + public override bool Cancelable { + get { return !(this.Done || cancelCalled); } + } + + public override bool Cancel() + { + if (this.Done || cancelCalled) { + return false; + } + + cancelCalled = true; + if (request != null) { + try { + request.Abort(); + } catch (WebException) { + } + } + return true; + } + + /// + /// Webレスポンスからダウンロードしたファイルの名前を取得 + /// + /// + /// + private string getFileNameFromWebResponse(WebResponse response) + { + if (response is HttpWebResponse) { + string contentDisposition = ((HttpWebResponse) response).Headers["Content-Disposition"]; + + // TODO check license for http://www.atmarkit.co.jp/fdotnet/dotnettips/618downnoname/downnoname.html + if (! string.IsNullOrEmpty(contentDisposition)) { + System.Text.RegularExpressions.Regex re = new System.Text.RegularExpressions.Regex( + @"filename\s*=\s*(?:""(?[^""]*)""|(?[^;]*))", + System.Text.RegularExpressions.RegexOptions.IgnoreCase); + + System.Text.RegularExpressions.Match m = re.Match(contentDisposition); + if (m.Success) { + return m.Groups["filename"].Value; + } + } + } + + return NaGet.Utils.Url2filename(response.ResponseUri.ToString()); + } +} + +} + + diff --git a/na-get-lib/NaGet.Packages.Install/Installation.cs b/na-get-lib/NaGet.Packages.Install/Installation.cs new file mode 100644 index 0000000..359146b --- /dev/null +++ b/na-get-lib/NaGet.Packages.Install/Installation.cs @@ -0,0 +1,410 @@ +using System; +using System.IO; +using System.Diagnostics; +using NaGet.Net; +using NaGet.SubCommands; + +namespace NaGet.Packages.Install +{ + + /// + /// ダウンロード・インストール処理をカプセル化するクラス + /// + public class Installation + { + /// + /// インストールするパッケージ + /// + public Package InstalledPackage; + + /// + /// (保存される)インストーラのファイルのパス + /// + public string InstallerFile; + + /// + /// インストールが完了されたか否かのフラグ + /// + private bool installed = false; + + /// + /// 起動するインストーラのインデックス番号 + /// + protected int installerIndex = 0; + + /// + /// 外部アプリのエラー出力の受信ハンドラ + /// + public event EventHandler> ErrorDataReceived; + + /// + /// 外部アプリの標準出力の受信ハンドラ + /// + public event EventHandler> OutputDataReceived; + + /// + /// コンストラクタ + /// + /// インストールするパッケージ + public Installation(Package package) + { + InstalledPackage = package; + InstallerFile = getArchiveFilePath(); + installerIndex = GetPreferInstallerIndex(package); + } + + /// + /// コンストラクタ + /// + /// インストールするパッケージ + /// (保存される)インストーラのファイルのパス + protected Installation(Package package, string installerfile) + { + InstalledPackage = package; + InstallerFile = installerfile; + installerIndex = GetPreferInstallerIndex(package); + } + + /// + /// インストール可能か否か + /// + public bool IsInstallablePackage() + { + return installerIndex >= 0; + } + + /// + /// すでにインストールされているパッケージを取得する + /// + /// + /// インストールドリスト + /// + /// + /// インストールされているパッケージの情報。インストールされたパッケージが見つからないならばnullを返す + /// + public InstalledPackage GetInstalledPackage(PackageList installedPkgs) + { + return installedPkgs.GetPackageForName(InstalledPackage.Name); + } + + /// + /// ダウンロードを行う。 + /// + /// ダウンローダオブジェクト + public void Download(Downloader downloader) + { + if (! Installed) { + string url = InstalledPackage.Installer[installerIndex].Url.Href; + downloader.Download(url, InstallerFile); + + // サーバ指定のファイル名に変更する + if (! string.IsNullOrEmpty(downloader.DownloadedFileName)) { + string newFile = Path.Combine(Path.GetDirectoryName(InstallerFile), downloader.DownloadedFileName); + File.Move(InstallerFile, newFile); + InstallerFile = newFile; + } + } + } + + /// + /// ハッシュ検証のためのハッシュの種類の数を返す + /// + /// ハッシュの個数 + public int GetRegisteredHashCount() + { + HashValue[] hashValues = InstalledPackage.Installer[installerIndex].Hash; + return (hashValues == null)? 0 : hashValues.Length; + } + + /// + /// ハッシュ検証を行う + /// + /// 検証にパスしたらtrue、パスしなかったらfalse + public bool VerifyHashValues() + { + HashValue[] hashValues = InstalledPackage.Installer[installerIndex].Hash; + if (hashValues != null) { + foreach (HashValue hash in hashValues) { + if (! hash.Validate(InstallerFile)) { + return false; + } + } + } + + return true; + } + + private int invokeInstaller(string installerfile, InstallerType type) + { + if (! File.Exists(installerfile)) { + throw new FileNotFoundException(string.Format("{0} is not found, perhaps failed to download.", installerfile), installerfile); + } + + Process hProcess = null; + try { + switch (type) { + case InstallerType.EXEC_INSTALLER: + hProcess = Process.Start(installerfile); + hProcess.WaitForExit(); + + break; + case InstallerType.MSI_PACKAGE: + hProcess = Process.Start("msiexec", string.Format("/i \"{0}\"", installerfile)); + hProcess.WaitForExit(); + break; + case InstallerType.ARCHIVE: + // TODO ハックな実装? + if (File.Exists("archive-inst.exe")) { + string argument = string.Format("-i \"{0}\" \"{1}\"", installerfile, this.InstalledPackage.Name); + ProcessStartInfo procInfo = new ProcessStartInfo(Path.GetFullPath("archive-inst.exe"), argument); + procInfo.UseShellExecute = false; + procInfo.CreateNoWindow = true; + procInfo.WorkingDirectory = Environment.CurrentDirectory; + + hProcess = NaGet.Utils.ProcessStartWithOutputCapture(procInfo, this.OutputDataReceived, this.ErrorDataReceived); + hProcess.WaitForExit(); + break; + } + throw new NotImplementedException("Not implemented archive installation yet"); + //break; + default: + throw new NotImplementedException("Not implemented archive installation yet"); + } + + return hProcess.ExitCode; + } finally { + if (hProcess != null) { + hProcess.Close(); + } + } + } + + /// + /// インストーラ等を起動してインストール作業を行う + /// + /// インストーラの終了コード + public int Install() + { + string installerFile = this.InstallerFile; + string tempDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + + // アーカイブされているなら一旦展開 + if (InstalledPackage.ArchivedInstaller) { + Directory.CreateDirectory(tempDir); + + // 64bit対策で展開も別プロセスで + // TODO エラーとかの出力を取得できたりとかできるように + if (File.Exists("archive-inst.exe")) { + string argument = string.Format("-t \"{0}\" \"{1}\"", installerFile, tempDir); + ProcessStartInfo info = new ProcessStartInfo(Path.GetFullPath("archive-inst.exe"), argument); + info.UseShellExecute = false; + info.WorkingDirectory = Environment.CurrentDirectory; + + using (Process hProcess = Process.Start(info)) { + hProcess.WaitForExit(); + + if (hProcess.ExitCode != 0) { + throw new ApplicationException("Extract error " + installerFile + " to " + tempDir); + } + } + } else { + throw new ApplicationException(string.Format("archive-inst.exe not found in {0}!", Environment.CurrentDirectory)); + } + +// System.Text.StringBuilder output = new System.Text.StringBuilder(1024); +// int res = NaGet.InteropServices.CommonArchiverExtracter.ExtractArchive(installerFile, tempDir, output, IntPtr.Zero); +// if (res != 0) { +// throw new ApplicationException("Extract error\n" + output.ToString()); +// } + + installerFile = seekInstallerFile(tempDir, InstalledPackage.Type); + if (installerFile == null && Directory.GetDirectories(tempDir).Length == 1) { + installerFile = seekInstallerFile(Path.Combine(tempDir, Directory.GetDirectories(tempDir)[0]), InstalledPackage.Type); + } + } + + + int exitCode = invokeInstaller(installerFile, InstalledPackage.Type); + + installed = true; + + return exitCode; + } + + /// + /// ダウンロード済みであるか否か + /// + public bool Downloaded { + get { + return File.Exists(InstallerFile) && ((File.GetAttributes(InstallerFile) & FileAttributes.Hidden) != FileAttributes.Hidden); + } + } + + /// + /// インストール作業済みであるか否か。実際にインストールされたかどうかではありません。 + /// + public bool Installed { + get { return installed; } + } + + /// + /// インストーラの処理が成功してインストールされたプログラムが確認できるか否か。 + /// + public bool InstallSuccessed { + get { + switch (Type) { + case InstallerType.ARCHIVE: // アーカイブインストーラはフォルダの確認 + return Directory.Exists(Path.Combine(NaGet.Env.ArchiveProgramFiles, InstalledPackage.Name)); + case InstallerType.EXEC_INSTALLER: + case InstallerType.MSI_PACKAGE: + return RegistriedUninstallers.GetInstalledPackageFor(InstalledPackage) != null; + default: + return false; + } + } + } + + /// + /// インストーラの種類を返す + /// + public InstallerType Type { + get { + return InstalledPackage.Type; + } + } + + /// + /// もっともふさわしいインストーラ番号を返す + /// + /// + public static int GetPreferInstallerIndex(Package InstalledPackage) + { + if (InstalledPackage.Type == InstallerType.CANNOT_INSTALL) { // インストール不能パッケージ + return -1; + } + + int best = -1; + int bestVal = 0; + + for (int i = 0; i < InstalledPackage.Installer.Length; i++) { + Platform platform = InstalledPackage.Installer[i].Platform; + + int pts = 0; + if (platform != null) { + pts = (platform.IsRunnable())? 10 : 0; + pts += (platform.IsRunnableArchOnWow64() && platform.IsRunnableOS())? 1 : 0; + } else { // if (platform == null) { + pts = 1; // null の場合は動作プラットホーム扱い + } + if (pts > bestVal) { + bestVal = pts; + best = i; + } + } + + return best; + } + + /// + /// インストーラの一時保存先パスを生成 + /// + private string getArchiveFilePath() + { + Package package = this.InstalledPackage; + + string folderName = string.Format("{0}({1})", package.Name, package.Version); + string fileName = NaGet.Utils.Url2filename(package.Installer[0].Url.Href); + + string folder = Path.Combine(NaGet.Env.ArchiveFolderPath, folderName); + + if (! File.Exists(Path.Combine(folder, fileName))) { + if (Directory.Exists(folder)) { + if (! File.Exists(Path.Combine(folder, fileName))) { + fileName = seekInstallerFile(folder, package.Type) ?? fileName; + } + } else { + Directory.CreateDirectory(folder); + } + } + + return Path.Combine(folder, fileName); + } + + /// + /// インストーラファイルを探す + /// + /// 探すフォルダ + /// インストーラの種類 + /// 探し出されたインストーラファイルのフルパス。存在しないならばnull + private static string seekInstallerFile(string basedir, InstallerType type) + { + if (! Directory.Exists(basedir)) { + return null; + } + + System.Collections.Generic.List list = new System.Collections.Generic.List(); + switch (type) { + case InstallerType.MSI_PACKAGE: + list.AddRange(Directory.GetFiles(basedir, "*.msi")); + break; + case InstallerType.EXEC_INSTALLER: + list.AddRange(Directory.GetFiles(basedir, "*.exe")); + break; + case InstallerType.ARCHIVE: + list.AddRange(Directory.GetFiles(basedir, "*.zip")); + list.AddRange(Directory.GetFiles(basedir, "*.lzh")); + list.AddRange(Directory.GetFiles(basedir, "*.cab")); + list.AddRange(Directory.GetFiles(basedir, "*.7z")); + list.AddRange(Directory.GetFiles(basedir, "*.tar*")); + break; + default: + return null; + } + + // 存在しないファイルを削除 + list.RemoveAll( + delegate(string file) { + return ! File.Exists(file); + } + ); + + // "setup"の語が入ったファイルはインストーラとみなし、優先選択 + foreach (string path in list) { + if (Path.GetFileName(path).ToLower().IndexOf("setup") >= 0) { + return path; + } + } + + // それ以外なら一つ目を返す + return (list.Count > 0)? list[0] : null; + } + + public override string ToString() + { + return string.Format("{0}({1})", InstalledPackage.Name, InstalledPackage.Version); + } + + public static string ToString(Installation[] installations) + { + string[] strs = new string[installations.Length]; + for (int i = 0; i < installations.Length; i++) { + strs[i] = installations[i].ToString(); + } + return string.Join(" ", strs); + } + + /// + /// パッケージ配列をインストール処理配列に変換する便利メソッド + /// + /// パッケージ配列 + /// 変換されたインストール処理配列 + public static Installation[] ConvertInstallations(Package[] pkgs) + { + Installation[] insts = new Installation[pkgs.Length]; + for (int i = 0; i < pkgs.Length; i++) { + insts[i] = new Installation(pkgs[i]); + } + return insts; + } + } +} diff --git a/na-get-lib/NaGet.Packages.Install/InstallationLog.cs b/na-get-lib/NaGet.Packages.Install/InstallationLog.cs new file mode 100644 index 0000000..ea967e6 --- /dev/null +++ b/na-get-lib/NaGet.Packages.Install/InstallationLog.cs @@ -0,0 +1,10 @@ +using System; + +namespace NaGet.Packages.Install +{ + public class InstallationLog + { + public DateTime Date; + public Package Package; + } +} diff --git a/na-get-lib/NaGet.Packages.Install/InstalledPackage.cs b/na-get-lib/NaGet.Packages.Install/InstalledPackage.cs new file mode 100644 index 0000000..857d43b --- /dev/null +++ b/na-get-lib/NaGet.Packages.Install/InstalledPackage.cs @@ -0,0 +1,48 @@ +using System; +using System.IO; +using System.Collections.Generic; +using System.Xml.Serialization; +using System.Text.RegularExpressions; +using NaGet.Packages; + +namespace NaGet.Packages.Install +{ + public class InstalledPackage : Package + { + /// + /// アンインストール情報 + /// + public UninstallInformation UninstallInfo; + + public static InstalledPackage PackageConverter(Package basePkg) + { + InstalledPackage pkg = new InstalledPackage(); + + NaGet.Utils.FieldCopy(basePkg, ref pkg); + pkg.UninstallInfo = UninstallInformation.NewInstance(basePkg); + + return pkg; + } + + public static InstalledPackage PackageConverter(Package basePkg, UninstallInformation info) + { + InstalledPackage instPkg = new InstalledPackage(); + + NaGet.Utils.FieldCopy(basePkg, ref instPkg); + instPkg.UninstallInfo = info; + + Match match = Regex.Match(info.DisplayName, basePkg.UninstallerKey); + if (! match.Success) { + throw new ArgumentException(string.Format("{0}({1}) does not matched for {2}.", basePkg.Name, basePkg.Version, info.DisplayName)); + } else if (match.Groups[1].Success) { // DisplayNameの方のバージョン表記を優先 + instPkg.Version = match.Groups[1].Value; + } else if (! string.IsNullOrEmpty(info.DisplayVersion) ) { + instPkg.Version = info.DisplayVersion; + } else { + instPkg.Version = string.Empty; + } + + return instPkg; + } + } +} diff --git a/na-get-lib/NaGet.Packages.Install/RegistriedUninstallers.cs b/na-get-lib/NaGet.Packages.Install/RegistriedUninstallers.cs new file mode 100644 index 0000000..4ef65b7 --- /dev/null +++ b/na-get-lib/NaGet.Packages.Install/RegistriedUninstallers.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using Microsoft.Win32; + +namespace NaGet.Packages.Install +{ + /// + /// レジストリ登録されているアンインストーラに関するユーティリティ + /// + public sealed class RegistriedUninstallers + { + /// + /// アンインストーラのレジストリの格納されているルートキーの文字列表現 + /// + public const string UninstallersKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"; + + /// + /// アンインストーラのレジストリの格納されているルートキーの文字列表現 + /// + public const string UninstallersKeyWow6432 = @"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"; + + /// + /// アンインストーラのレジストリのキーを返す。 + /// + public static IEnumerable RegistryKeies { + get { + RegistryKey key = null; + + // UninstallersKey + try { + key = Registry.LocalMachine.OpenSubKey(UninstallersKey, false); + } catch (System.Security.SecurityException) { + } + if (key != null) { + yield return key; + key.Close(); + } + + // UninstallersKeyWow6432 + try { + key = Registry.LocalMachine.OpenSubKey(UninstallersKeyWow6432, false); + } catch (System.Security.SecurityException) { + } + if (key != null) { + yield return key; + key.Close(); + } + } + } + + + /// + /// アンインストーラをイテレートする + /// + public static IEnumerable Uninstallers { + get { + foreach (RegistryKey regkey in RegistryKeies) { + foreach (string key in regkey.GetSubKeyNames()) { + UninstallInformation info; + using (RegistryKey subregkey = regkey.OpenSubKey(key, false)) { + info = UninstallInformation.NewInstance(subregkey); + } + + if (info.IsOSPatch || info.IsSystemComponent || string.IsNullOrEmpty(info.DisplayName) ) { + continue; + } + + yield return info; + } + } + } + } + + /// + /// レジストリを走査してインストール済みのソフトを検出する + /// + /// + /// 参照するパッケージリスト + /// + /// + /// インストール済みのパッケージを返すイテレータ + /// + public static IEnumerable DetectInstalledPackages(PackageList list) + { + foreach (UninstallInformation info in RegistriedUninstallers.Uninstallers) { + foreach (Package pkg in list.Packages) { + if (pkg.Type != InstallerType.ARCHIVE && pkg.UninstallerKey != null) { + Match match = Regex.Match(info.DisplayName, pkg.UninstallerKey); + + if (match.Success) { + yield return InstalledPackage.PackageConverter(pkg, info); + + break; + } + }// else continue; + } + } + } + + /// + /// パッケージに対応するインストールパッケージを返す。 + /// インストール終了確認などに使用。 + /// + /// 対応するパッケージ + /// インストール情報 + public static InstalledPackage GetInstalledPackageFor(Package pkg) + { + if (pkg.Type == InstallerType.ARCHIVE || pkg.Type == InstallerType.CANNOT_INSTALL) { + return null; + } + + foreach (UninstallInformation info in RegistriedUninstallers.Uninstallers) { + Match match = Regex.Match(info.DisplayName, pkg.UninstallerKey); + + if (match.Success) { + return InstalledPackage.PackageConverter(pkg, info); + } + } + return null; + } + } +} diff --git a/na-get-lib/NaGet.Packages.Install/UninstallInformation.cs b/na-get-lib/NaGet.Packages.Install/UninstallInformation.cs new file mode 100644 index 0000000..49e00fb --- /dev/null +++ b/na-get-lib/NaGet.Packages.Install/UninstallInformation.cs @@ -0,0 +1,227 @@ +using System; +using System.Xml.Serialization; +using Microsoft.Win32; + +namespace NaGet.Packages.Install +{ + /// + /// アンインストール情報の抽象化クラス + /// + public class UninstallInformation + { + /// + /// 名称。DisplayName + /// + public string DisplayName; + + /// + /// バージョン。DisplayVersion + /// + public string DisplayVersion; + + /// + /// 作者。Publisher + /// + public string Publisher; + + /// + /// アイコンのパス。DisplayIcon + /// + public string IconPath; + + /// + /// 「変更」・「修復」のコマンド文字列。ModifyPath + /// + public string ModifyPath; + + /// + /// 「アンインストール」のコマンド文字列。UninstallString + /// + public string UninstallString; + + /// + /// サイレントアンインストールのコマンド文字列。QuietUninstallString + /// + public string QuietUninstallString; + + /// + /// 発行元のURL + /// + public string URLInfoAbout; + + /// + /// 「変更」ができるか否かのフラグ。NoModifyの逆(きちんと動かない??) + /// + public bool CanModify; + + /// + /// 「修復」ができるか否かのフラグ。NoRepairの逆(きちんと動かない??) + /// + public bool CanRepair; + + /// + /// 「アンインストール」ができるか否かのフラグ。NoRemoveの逆 + /// + public bool CanRemove = true; + + /// + /// システムコンポーネントか否か + /// + public bool IsSystemComponent; + + /// + /// OSの更新パッチか否か。 + /// + public bool IsOSPatch; + + /// + /// ソフトをインストールした日付 + /// + [XmlIgnore] + public DateTime? InstallDate = null; + + /// + /// ソフトをインストールした日付、のレジストリ登録文字列表現 + /// + [XmlElement("InstallDate")] + public string InstallDateString { + get { return (InstallDate != null)? InstallDate.Value.ToString("yyyyMMdd") : null; } + set { + if (value == null) { + InstallDate = null; + } else if (System.Text.RegularExpressions.Regex.IsMatch(value, @"^[0-9]{8}$")) { + InstallDate = new DateTime(int.Parse(value.Substring(0,4)), + int.Parse(value.Substring(4,2)), + int.Parse(value.Substring(6,2))); + } else throw new ArgumentException("Does not match date format (YYYYMMDD)"); + } + } + + /// + /// インストール先のフォルダ + /// + public string InstallLocation; + + /// + /// (推定の)アプリケーションの占有する容量(キロバイト単位) + /// + public int EstimatedSize = 0; + + #region 変換メソッド + + /// + /// レジストリのキーからアンインストール情報を取得する + /// + /// アンインストール情報を示す + /// 生成されたアンインストール + public static UninstallInformation NewInstance(RegistryKey regKey) + { + UninstallInformation uninstInfo = new UninstallInformation(); + + uninstInfo.DisplayName = (string) regKey.GetValue("DisplayName"); + uninstInfo.DisplayVersion = (string) regKey.GetValue("DisplayVersion", null); + uninstInfo.Publisher = (string) regKey.GetValue("Publisher", null); + uninstInfo.URLInfoAbout = (string) regKey.GetValue("URLInfoAbout", null); + uninstInfo.IconPath = (string) regKey.GetValue("DisplayIcon", null); + uninstInfo.ModifyPath = (string) regKey.GetValue("ModifyPath", null); + uninstInfo.UninstallString = (string) regKey.GetValue("UninstallString", null); + uninstInfo.QuietUninstallString = (string) regKey.GetValue("QuietUninstallString", null); + uninstInfo.CanModify = ((int) regKey.GetValue("NoModify", 1)) != 1; + uninstInfo.CanRepair = ((int) regKey.GetValue("NoRepair", 1)) != 1; + uninstInfo.CanRemove = ((int) regKey.GetValue("NoRemove", 1)) != 1; + uninstInfo.IsSystemComponent = ((int) regKey.GetValue("SystemComponent", 0)) > 0; + uninstInfo.IsOSPatch = ((string) regKey.GetValue("ParentKeyName", null)) == "OperatingSystem"; + try { + uninstInfo.InstallDateString = (string) regKey.GetValue("InstallDate", null); + } catch (ArgumentException) {} + uninstInfo.InstallLocation = (string) regKey.GetValue("InstallLocation", null); + uninstInfo.EstimatedSize = (int) regKey.GetValue("EstimatedSize", 0); + + PrefixWithSlowInfoCache(ref uninstInfo, regKey); + + return uninstInfo; + } + + /// + /// SlowInfoCacheを読み込んで情報を補完 + /// + /// アンインストール情報 + /// 元のレジストリキー + private static void PrefixWithSlowInfoCache(ref UninstallInformation uninstInfo, RegistryKey regKey) + { + try { + byte[] slowInfoCache; + + string arpCacheKey = string.Format(@"{0}\..\..\App Management\ARPCache\{1}", regKey.Name, System.IO.Path.GetFileName(regKey.Name)); + arpCacheKey = NaGet.Utils.GetDotsRemovedPath(arpCacheKey); + slowInfoCache = (byte[]) Registry.GetValue(arpCacheKey, "SlowInfoCache", null); + + if (slowInfoCache == null || slowInfoCache.Length <= 0) { + arpCacheKey = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\App Management\ARPCache\"+System.IO.Path.GetFileName(regKey.Name); + slowInfoCache = (byte[]) Registry.GetValue(arpCacheKey, "SlowInfoCache", null); + } + + if (slowInfoCache != null && slowInfoCache.Length > 0) { + Int32 size = BitConverter.ToInt32(slowInfoCache, 0); + Int32 hasName = BitConverter.ToInt32(slowInfoCache, 4); + Int64 installSize = BitConverter.ToInt64(slowInfoCache, 8); + //Int64 lastUsed = BitConverter.ToInt64(slowInfoCache, 16); + //Int32 freq = BitConverter.ToInt32(slowInfoCache, 24); + + if (installSize > 0) { + uninstInfo.EstimatedSize = (int)(installSize >> 10); + } + + string filename = null; + if (hasName != 0) { + int offset = 28; + int pos = offset; + while (pos < slowInfoCache.Length) { + if (slowInfoCache[pos] == 0) { + break; + } + pos += 2; + } + + filename = System.Text.Encoding.Unicode.GetString(slowInfoCache, offset, pos-offset); + + if (string.IsNullOrEmpty(uninstInfo.IconPath) && System.IO.File.Exists(filename)) { + uninstInfo.IconPath = filename; + } + } + } + } catch (Exception) { + } + } + + /// + /// パッケージ情報からアンインストーラ情報を生成する + /// + /// パッケージ + /// 生成されたアンインストール + public static UninstallInformation NewInstance(Package pkg) + { + UninstallInformation uninstInfo = new UninstallInformation(); + + uninstInfo.DisplayName = pkg.Name; + uninstInfo.DisplayVersion = pkg.Version; + uninstInfo.Publisher = pkg.Author; + uninstInfo.URLInfoAbout = pkg.Url.Href; + uninstInfo.IconPath = null; // TODO + uninstInfo.ModifyPath = null; + uninstInfo.UninstallString = null; // TODO + uninstInfo.CanModify = false; + uninstInfo.CanRepair = false; + uninstInfo.CanRemove = true; + uninstInfo.IsSystemComponent = false; + uninstInfo.IsOSPatch = false; + uninstInfo.InstallLocation = null; + uninstInfo.InstallDate = null; + uninstInfo.EstimatedSize = 0; + + return uninstInfo; + } + + #endregion + } +} diff --git a/na-get-lib/NaGet.Packages.Install/Uninstallation.cs b/na-get-lib/NaGet.Packages.Install/Uninstallation.cs new file mode 100644 index 0000000..930bfb7 --- /dev/null +++ b/na-get-lib/NaGet.Packages.Install/Uninstallation.cs @@ -0,0 +1,113 @@ +using System; +using System.Diagnostics; +using System.Text.RegularExpressions; +using System.Collections; +using System.CodeDom.Compiler; +using System.IO; + +namespace NaGet.Packages.Install +{ + /// + /// Description of Uninstallation. + /// + public class Uninstallation + { + /// + /// アンインストールするパッケージ + /// + public InstalledPackage UninstalledPackage; + + /// + /// 外部アプリのエラー出力の受信ハンドラ + /// + public event EventHandler> ErrorDataReceived; + + /// + /// 外部アプリの標準出力の受信ハンドラ + /// + public event EventHandler> OutputDataReceived; + + /// + /// サイレントアンインストールするか否か + /// + public bool Silent = false; + + /// + /// コンストラクタ + /// + /// アンインストールするパッケージ + public Uninstallation(InstalledPackage package) + { + UninstalledPackage = package; + } + + /// + /// インストールされた状態か否か + /// + public bool Installed + { + get { + if (Directory.Exists(UninstalledPackage.UninstallInfo.InstallLocation)) { + return true; + } else if (UninstalledPackage.Type == InstallerType.ARCHIVE) { + return false; + } + + foreach (UninstallInformation info in RegistriedUninstallers.Uninstallers) { + Match match = Regex.Match(info.DisplayName, UninstalledPackage.UninstallerKey); + + if (match.Success) { + return true; + } + } + return false; + } + } + + /// + /// アンインストーラ等を起動してアンインストール作業を行う + /// + /// アンインストーラの終了コード + public int Uninstall() + { + if (! Installed) { + throw new ApplicationException("Program not found, may be already uninstalled"); + } + + int exitValue = 0; + string uninstallString = Silent? UninstalledPackage.UninstallInfo.QuietUninstallString : UninstalledPackage.UninstallInfo.UninstallString; + if (string.IsNullOrEmpty(uninstallString)) { + throw new ApplicationException(string.Format("Could not found {0}install script", Silent? "silent " : "")); + } + + if (File.Exists(uninstallString)) { + // 単独のファイルの場合 + using (Process hProcess = NaGet.Utils.ProcessStartWithOutputCapture(new ProcessStartInfo(uninstallString), + NaGet.Utils.ConvertToDataReceivedEventHandler(OutputDataReceived), + NaGet.Utils.ConvertToDataReceivedEventHandler(ErrorDataReceived)) ) { + hProcess.WaitForExit(); + + exitValue = hProcess.ExitCode; + } + } else { + ProcessStartInfo procInfo = new ProcessStartInfo(null, uninstallString); + procInfo.UseShellExecute = false; + if (UninstalledPackage.Type == InstallerType.ARCHIVE) { + procInfo.CreateNoWindow = true; + } + using (NaGet.InteropServices.CreateProcessCaller p = new NaGet.InteropServices.CreateProcessCaller(procInfo)) { + p.WaitForExit(); + + exitValue = p.ExitCode; + } + } + + return exitValue; + } + + public override string ToString() + { + return string.Format("{0}({1})", UninstalledPackage.Name, UninstalledPackage.Version); + } + } +} diff --git a/na-get-lib/NaGet.Packages/HashValue.cs b/na-get-lib/NaGet.Packages/HashValue.cs new file mode 100644 index 0000000..20651d6 --- /dev/null +++ b/na-get-lib/NaGet.Packages/HashValue.cs @@ -0,0 +1,96 @@ +using System; +using System.IO; +using System.Xml.Serialization; +using System.Security.Cryptography; + +namespace NaGet.Packages +{ + /// + /// ハッシュ値の種類(計算法)を表す。 + /// + public enum HashValueType + { + [XmlEnum(Name="size")] + SIZE, + [XmlEnum(Name="md5")] + MD5SUM, + [XmlEnum(Name="sha1")] + SHA1SUM, + [XmlEnum(Name="sha256")] + SHA256SUM + } + + public class HashValue + { + /// + /// ハッシュ値の種類(計算法) + /// + [XmlAttribute] + public HashValueType Type; + + /// + /// ハッシュ値そのものをあらわす + /// + [XmlText] + public string Value; + + /// + /// コンストラクタ + /// + public HashValue() + { + } + + /// + /// 与えられたファイルのハッシュ値が同一であるか検証する + /// + /// ハッシュ計算を行う対象のファイル + /// ファイルのハッシュ値が妥当な場合true。 + public bool Validate(string path) + { + return string.Compare(this.Value, HashValueFor(path, this.Type), true) == 0; + } + + /// + /// ファイルのハッシュを計算する + /// + /// 計算対象のファイル + /// ハッシュの種類(計算法) + /// + public static string HashValueFor(string file, HashValueType type) + { + using (FileStream fs = new FileStream(file, FileMode.Open)) { + return HashValue.HashValueFor(fs, type); + } + } + + /// + /// ストリーム入力からハッシュを計算する + /// + /// ストリーム入力 + /// ハッシュの種類(計算法) + /// + public static string HashValueFor(Stream stream, HashValueType type) + { + byte[] hash; + + switch (type) { + case HashValueType.SIZE: + return stream.Length.ToString(); + case HashValueType.MD5SUM: + hash = MD5.Create().ComputeHash(stream); + break; + case HashValueType.SHA1SUM: + hash = SHA1.Create().ComputeHash(stream); + break; + case HashValueType.SHA256SUM: + hash = SHA256.Create().ComputeHash(stream); + break; + default: + throw new NotSupportedException(string.Format("Hash type {0} does not supported", type)); + } + + return BitConverter.ToString(hash).Replace("-",string.Empty); + } + } +} diff --git a/na-get-lib/NaGet.Packages/Package.cs b/na-get-lib/NaGet.Packages/Package.cs new file mode 100644 index 0000000..ee12ee3 --- /dev/null +++ b/na-get-lib/NaGet.Packages/Package.cs @@ -0,0 +1,199 @@ +using System.Xml.Serialization; + +namespace NaGet.Packages +{ + /// + /// インストーラの種類を表す。 + /// + public enum InstallerType + { + /// + /// インストーラ + /// + [XmlEnum(Name="installer")] + EXEC_INSTALLER, + /// + /// Microsoft Software Installer + /// + [XmlEnum(Name="msi")] + MSI_PACKAGE, + /// + /// 自己解凍書庫を含む書庫一般 + /// + [XmlEnum(Name="archive")] + ARCHIVE, + /// + /// インストールできない単なるデータ(BIOSなど) + /// + [XmlEnum(Name="cannotinstall")] + CANNOT_INSTALL, + } + + /// + /// パッケージ情報を格納するクラス + /// + public class Package + { + /// + /// パッケージ名 + /// + public string Name; + + /// + /// バージョン文字列 + /// + public string Version; + + /// + /// パッケージの概要 + /// + public string Summary; + + /// + /// パッケージの解説 + /// + public string Description; + + /// + /// 公式サイトのURL + /// + public LocationEntry Url; + + /// + /// 製作者の名前 + /// + public string Author; + + /// + /// インストーラのタイプ + /// + public InstallerType Type; + + /// + /// インストーラが書庫内に入っているかのフラグ + /// + public bool ArchivedInstaller = false; + + /// + /// アンインストーラのレジストリのキー + /// + public string UninstallerKey; + + /// + /// インストールスクリプト(MSBuildドキュメント) + /// + public string InstallScript; + + /// + /// アーカイブインストーラのときのSystem32のコピー + /// + public string System32CopyFiles; + + /// + /// インストーラのリソースの配列 + /// + [XmlElement] + public Installer[] Installer; + + /// + /// 必要とされるパッケージの配列 + /// + [XmlArray(IsNullable=true),XmlArrayItem("Entry")] + public Entry[] Requires; + + /// + /// 競合するパッケージの配列 + /// + [XmlArray(IsNullable=true),XmlArrayItem("Entry")] + public Entry[] Conflicts; + + /// + /// タグ + /// + public string Tags; + + /// + /// ライセンス + /// + public string License; + + /// + /// 所属するパッケージリスト名称 + /// + public string PackageListName; + } + + /// + /// パッケージ参照を示すクラス + /// + public class Entry + { + /// + /// パッケージ名 + /// + [XmlAttribute] + public string Name; + /// + /// パッケージのバージョン比較の式 + /// + [XmlAttribute] + public string Flags; + /// + /// パッケージのバージョン + /// + public string Version; + } + + public class Installer + { + /// + /// コンストラクタ + /// + public Installer() + { + } + + public Platform Platform; + + /// + /// ダウンロードリソースURLの配列 + /// + public LocationEntry Url; + + /// + /// ファイル検証用ハッシュ + /// + [XmlElement] + public HashValue[] Hash; + } + + /// + /// リソースの位置を示すクラス + /// + public class LocationEntry + { + // TODO LocationEntryは果たして必要なのかの、考察 + + /// + /// コンストラクタ + /// + public LocationEntry() + { + } + + /// + /// コンストラクタ + /// + /// リソースのURL + public LocationEntry(string sHref) + { + Href = sHref; + } + + /// + /// リソースのURL + /// + [XmlAttribute] + public string Href; + } +} diff --git a/na-get-lib/NaGet.Packages/PackageList.cs b/na-get-lib/NaGet.Packages/PackageList.cs new file mode 100644 index 0000000..d4e69d9 --- /dev/null +++ b/na-get-lib/NaGet.Packages/PackageList.cs @@ -0,0 +1,162 @@ +using System; +using System.IO; +using System.Collections.Generic; +using System.Xml.Serialization; + +namespace NaGet.Packages +{ + /// + /// パッケージのリストの情報を示すクラス + /// + [XmlRoot("PackageList", Namespace="http://diffshare.tv/xmlns/2007/na-get/PackageList/")] + public class PackageList where TPackage : Package + { + /// + /// パッケージリスト自体の識別名 + /// + public string Name; + + /// + /// パッケージの配列のリスト + /// + private List packageArrayList; + + /// + /// コンストラクタ + /// + public PackageList() + { + packageArrayList = new List(); + } + + /// + /// 本リストが格納しているパッケージの配列 + /// + [XmlElement("Package", Namespace="http://diffshare.tv/xmlns/2007/na-get/PackageList/")] + public TPackage[] Packages + { + get + { + return packageArrayList.ToArray(); + } + set + { + packageArrayList = new List(); + if (value != null) { + foreach (TPackage package in value) { + packageArrayList.Add(package); + } + } + } + } + + /// + /// パッケージをリストに追加する + /// + /// 追加するパッケージ + public void AddPackages(IEnumerable package) + { + packageArrayList.AddRange(package); + } + + /// + /// パッケージをリストにマージ(追加)する + /// + /// 追加するパッケージ + public void AddPackages(PackageList pkgList) + { + packageArrayList.AddRange(pkgList.packageArrayList); + } + + /// + /// パッケージをリストに追加する + /// + /// 追加するパッケージ + public void AddPackage(TPackage package) + { + packageArrayList.Add(package); + } + + /// + /// パッケージをリストから削除 + /// + /// 削除するパッケージ + public void RemovePackage(TPackage package) + { + packageArrayList.Remove(package); + } + + /// + /// パッケージを検索をする際のPredicateを返す + /// + /// 検索キー + protected static Predicate GetPredicateForSearch(string key) + { + string lowerKey = key.ToLower(); + return delegate(TPackage package) { + return package.Name.ToLower().IndexOf(lowerKey) >= 0 || + package.Summary.ToLower().IndexOf(lowerKey) >= 0 || + ((package.Tags ?? string.Empty).ToLower().IndexOf(lowerKey) >= 0); + }; + } + + /// + /// パッケージを検索して、それにマッチしたパッケージをイテレータとして返す。 + /// + /// 検索キー + public IEnumerable Search(string key) + { + return packageArrayList.FindAll(GetPredicateForSearch(key)); + } + + /// + /// パッケージ名で検索をする際のPredicateを返す + /// + /// + /// パッケージ名 + /// + /// + /// Predicate + /// + protected static Predicate GetPredicateForPackageName(string name) + { + return delegate(TPackage package) { + return package.Name == name; + }; + } + + /// + /// 指定した名前に対応するパッケージを返す + /// + /// 検索にかけるパッケージ名 + public TPackage GetPackageForName(string name) + { + return packageArrayList.Find(GetPredicateForPackageName(name)); + } + + /// + /// 指定した名前に対応するパッケージを返す + /// + /// 検索にかけるパッケージ名 + public TPackage[] GetPackagesForName(string name) + { + return packageArrayList.FindAll(GetPredicateForPackageName(name)).ToArray(); + } + + /// + /// 名前・バージョンが対応するパッケージを返す + /// + /// 検索にかけるパッケージ名 + /// 検索にかけるパッケージのバージョン + public TPackage GetPackageForPackage(string name, string version) + { + TPackage[] pkgs = GetPackagesForName(name); + foreach (TPackage tpkg in pkgs) { + if (tpkg.Version == version) { + return tpkg; + } + } + return null; + } + } +} diff --git a/na-get-lib/NaGet.Packages/PackageListsManager.cs b/na-get-lib/NaGet.Packages/PackageListsManager.cs new file mode 100644 index 0000000..fa60078 --- /dev/null +++ b/na-get-lib/NaGet.Packages/PackageListsManager.cs @@ -0,0 +1,187 @@ +using System; +using System.IO; +using System.Collections.Generic; +using NaGet.Packages; +using NaGet.Packages.Install; + +namespace NaGet.Packages +{ + public class PackageListsManager + { + internal PackageList availablePkgList; + internal PackageList installedPkgList; + internal PackageList systemInstalledPkgList; + + public PackageList AvailablePkgList { + get { return availablePkgList; } + } + + public PackageList InstalledPkgList { + get { return installedPkgList; } + } + + public PackageList SystemInstalledPkgList { + get { return systemInstalledPkgList; } + } + + private List systemInstalledLogList; + + public PackageListsManager() + { + LoadPackageLists(); + } + + #region ƒtƒ@ƒCƒ‹“ǂݏ‘‚« + + /// + /// ƒtƒ@ƒCƒ‹‚ð“ǂݍž‚ñ‚ōXV‚·‚é + /// + public void LoadPackageLists() + { + try { + availablePkgList = NaGet.Utils.GetDeserializedObject>(NaGet.Env.PackageListFile); + } catch (FileNotFoundException) { + availablePkgList = new PackageList(); + } + + try { + installedPkgList = NaGet.Utils.GetDeserializedObject>(NaGet.Env.ArchiveInstalledPackageListFile); + } catch (FileNotFoundException) { + installedPkgList = new PackageList(); + } + + try { + systemInstalledPkgList = NaGet.Utils.GetDeserializedObject>(NaGet.Env.SystemInstalledPackageListFile); + } catch (FileNotFoundException) { + systemInstalledPkgList = new PackageList(); + } + + + systemInstalledLogList = new List(); + try { + systemInstalledLogList.AddRange( + NaGet.Utils.GetDeserializedObject(NaGet.Env.SystemInstalledPackageLogFile) + ); + } catch (Exception) { + // do nothing + } + } + + public void SaveAvailablePackageList() + { + NaGet.Utils.PutSerializeObject(NaGet.Env.PackageListFile, availablePkgList); + } + public void SaveInstalledPackageList() + { + NaGet.Utils.PutSerializeObject(NaGet.Env.ArchiveInstalledPackageListFile, installedPkgList); + } + public void SaveSystemInstalledPackageList() + { + NaGet.Utils.PutSerializeObject(NaGet.Env.SystemInstalledPackageListFile, systemInstalledPkgList); + } + public void SaveSystemInstalledLogList() + { + NaGet.Utils.PutSerializeObject(NaGet.Env.SystemInstalledPackageLogFile, systemInstalledLogList); + } + + public void CommitToFile() + { + SaveAvailablePackageList(); + SaveInstalledPackageList(); + SaveSystemInstalledPackageList(); + + SaveSystemInstalledLogList(); + } + + #endregion + + #region ƒpƒbƒP[ƒWƒCƒ“ƒXƒg[ƒ‹ŒŸ’mŠÖ˜A + + public void DetectInstalledPkgs() + { + PackageList pkgList = new PackageList(); + if (Directory.Exists(NaGet.Env.ArchiveProgramFiles)) { + foreach (string path in NaGet.Utils.ExtendWildcardFile(NaGet.Env.ArchiveProgramFiles, Path.Combine("*", ".applistation.package.xml"))) { + pkgList.AddPackage(NaGet.Utils.GetDeserializedObject(path)); + } + this.installedPkgList = pkgList; + } + } + + public void DetectSystemInstalledPkgs() + { + PackageList installedPkgList = new PackageList(); + foreach (InstalledPackage pkg in RegistriedUninstallers.DetectInstalledPackages(availablePkgList)) { + InstallationLog log = this.GetLogFor(pkg); + if (log != null) { + InstalledPackage pkg2 = new InstalledPackage(); + NaGet.Utils.FieldCopy((Package) log.Package, ref pkg2); + pkg2.UninstallInfo = pkg.UninstallInfo; + + installedPkgList.AddPackage(pkg2); + } else { + installedPkgList.AddPackage(pkg); + } + } + this.systemInstalledPkgList = installedPkgList; + } + + #endregion + + #region ƒpƒbƒP[ƒW•Ö—˜ƒƒ\ƒbƒh + + public IEnumerable GetAllInstalledPackages() + { + foreach (InstalledPackage pkg in installedPkgList.Packages) { + yield return pkg; + } + foreach (InstalledPackage pkg in systemInstalledPkgList.Packages) { + yield return pkg; + } + } + + /// + /// ‘S‚ẴpƒbƒP[ƒW‚ðƒCƒeƒŒ[ƒ^‚ŕԂ·•Ö—˜ƒƒ\ƒbƒhB + /// + /// ƒpƒbƒP[ƒW‚̃CƒeƒŒ[ƒ^ + public IEnumerable GetAllPackages() + { + foreach (Package pkg in availablePkgList.Packages) { + yield return pkg; + } + foreach (Package pkg in GetAllInstalledPackages()) { + yield return pkg; + } + } + + #endregion + + #region ƒCƒ“ƒXƒg[ƒ‹ƒƒOŠÖ˜A + + private Predicate createPackageNamePredicator(Package pkg) + { + return delegate(InstallationLog log) { + return log.Package.Name == pkg.Name; + }; + } + + public InstallationLog GetLogFor(Package pkg) + { + return systemInstalledLogList.Find(createPackageNamePredicator(pkg)); + } + + public void WriteInstallationLog(Installation inst) + { + // d•¡‚͍폜 + systemInstalledLogList.RemoveAll(createPackageNamePredicator(inst.InstalledPackage)); + + InstallationLog newLog = new InstallationLog(); + newLog.Date = DateTime.Now; + newLog.Package = inst.InstalledPackage; + + systemInstalledLogList.Add(newLog); + } + + #endregion + } +} diff --git a/na-get-lib/NaGet.Packages/Platform.cs b/na-get-lib/NaGet.Packages/Platform.cs new file mode 100644 index 0000000..ff77eda --- /dev/null +++ b/na-get-lib/NaGet.Packages/Platform.cs @@ -0,0 +1,183 @@ +using System; +using System.Reflection; +using System.Xml.Serialization; + +namespace NaGet.Packages +{ + /// + /// PlatformのOSの種類をあらわす + /// + public enum PlatformOSType + { + WIN95, + WIN98, + WINME, + + WINNT4, + WIN2K, + WINXP, + WIN2003, + VISTA, + } + + public class Platform + { + /// + /// ソフトの動作するアーキテクチャ + /// + [XmlAttribute] + public ProcessorArchitecture Arch = ProcessorArchitecture.X86; + + /// + /// 動作するOSの種類の配列 + /// + [XmlIgnore] + public PlatformOSType[] OsType; + + /// + /// OsTypeの文字列表現 + /// + [XmlAttribute] + public string Os { + get { + if (OsType == null) return null; + string[] strs = new string[OsType.Length]; + for (int i = 0; i < OsType.Length; i++) { + strs[i] = OsType[i].ToString("G"); + } + return string.Join(",", strs); + } + set { + string[] strs = (value ?? "").Split(','); + System.Collections.Generic.List list = new System.Collections.Generic.List(); + for (int i = 0; i < strs.Length; i++) { + try { + list.Add((PlatformOSType) Enum.Parse(typeof(PlatformOSType), strs[i], true)); + } catch (ArgumentException) { + } + } + OsType = list.ToArray(); + } + } + + /// + /// 現在のプラットホームで動くか否か? + /// + /// 動く場合はtrue + public bool IsRunnable() + { + return IsRunnableArch() && IsRunnableOS(); + } + + /// + /// 現在のマシンのアーキテクチャで動くか否か? + /// + /// 動く場合はtrue + public bool IsRunnableArch() + { + return Arch == GetArch() || + Arch == ProcessorArchitecture.None || + Arch == ProcessorArchitecture.MSIL; + } + + /// + /// 現在のマシンのアーキテクチャで動かないが、Wow64で動くか否か? + /// 64ビット環境でない場合は常にfalse + /// + /// + public bool IsRunnableArchOnWow64() + { + if (IntPtr.Size == 8) { + return Arch == ProcessorArchitecture.X86; + } else { + return false; + } + } + + /// + /// 現在のマシンのアーキテクチャを得る + /// + /// 現在のマシンのアーキテクチャ + public static ProcessorArchitecture GetArch() + { + Module[] moduleArray = Assembly.GetExecutingAssembly().GetModules(); + Module md = moduleArray[0]; + + PortableExecutableKinds pekinds; + ImageFileMachine ifm; + md.GetPEKind(out pekinds, out ifm); + + switch (ifm) { + case ImageFileMachine.AMD64: + return ProcessorArchitecture.Amd64; + case ImageFileMachine.I386: + return (IntPtr.Size == 4)? ProcessorArchitecture.X86 : ProcessorArchitecture.Amd64; + case ImageFileMachine.IA64: + return ProcessorArchitecture.IA64; + default: + return ProcessorArchitecture.None; + } + } + + /// + /// 現在のマシンのアーキテクチャを得る + /// + /// 現在のマシンのアーキテクチャ + public bool IsRunnableOS() + { + if (OsType == null || OsType.Length <= 0) { + return true; // 記述なしはOS全部で動く扱い + } + + PlatformOSType? thisOs = GetOSType(); + return thisOs != null && Array.BinarySearch(OsType, (PlatformOSType) thisOs) >= 0; + } + + /// + /// 現在のマシンのOSを得る + /// + /// 現在のマシンのOS + public static PlatformOSType? GetOSType() + { + OperatingSystem os = Environment.OSVersion; + Version osVer = os.Version; + + switch (os.Platform) { + case PlatformID.Win32Windows: + if (osVer.Major == 4) { + switch (osVer.Minor) { + case 4: + return PlatformOSType.WIN95; + case 10: + return PlatformOSType.WIN98; + case 99: + return PlatformOSType.WINME; + } + } + break; + case PlatformID.Win32NT: + if (osVer.Major == 4) { + return PlatformOSType.WINNT4; + } else if (osVer.Major == 5) { + switch (osVer.Minor) { + case 0: + return PlatformOSType.WIN2K; + case 1: + return PlatformOSType.WINXP; + case 2: + return PlatformOSType.WIN2003; + } + } else if (osVer.Major == 6) { + return PlatformOSType.VISTA; + } + break; +// case PlatformID.WinCE: +// return null; +// case PlatformID.Unix: +// return null; + } + + return null; + } + } +} diff --git a/na-get-lib/NaGet.Packages/ProviderList.cs b/na-get-lib/NaGet.Packages/ProviderList.cs new file mode 100644 index 0000000..37054cc --- /dev/null +++ b/na-get-lib/NaGet.Packages/ProviderList.cs @@ -0,0 +1,41 @@ +using System; +using System.IO; +using System.Collections.Generic; + +namespace NaGet.Packages +{ + /// + /// パッケージリストを提供するプロバイダのリストを示すクラス + /// + public class ProviderList + { + /// + /// パッケージリストのリソースURLの配列 + /// + public string[] Urls; + + /// + /// コンストラクタ + /// + public ProviderList() + { + } + + /// + /// コンストラクタ + /// + /// プロバイダリストのファイルのパス + public ProviderList(string path) + { + List providerList = new List(); + using(StreamReader reader = new StreamReader(path)) { + string line; + while ((line = reader.ReadLine()) != null) { + providerList.Add(line); + } + } + + Urls = providerList.ToArray(); + } + } +} diff --git a/na-get-lib/NaGet.Packages/VersionComparetor.cs b/na-get-lib/NaGet.Packages/VersionComparetor.cs new file mode 100644 index 0000000..60aa78d --- /dev/null +++ b/na-get-lib/NaGet.Packages/VersionComparetor.cs @@ -0,0 +1,85 @@ +using System; +using System.Text.RegularExpressions; + +namespace NaGet.Packages +{ + // TODO Debian-apt‚̃R[ƒh‚ð—˜—p‚µ‚Ä‚¢‚é‚Ì‚ÅGPL‚ɂȂé‚̂ɒˆÓ + + + public class VersionComparetor : System.Collections.Generic.IComparer + { + public VersionComparetor() + { + } + + private static int order(char x) + { + return (char.IsDigit(x) ? 0 + : (x==0) ? 0 + : char.IsLetter(x) ? (x) + : (x) + 256); + } + + public int Compare(string a, string b) + { + // ‘Oˆ— + a = a.ToLower(); + b = b.ToLower(); + if (Regex.IsMatch(a, @"\.0*$")) + Regex.Replace(a, @"\.0*$", string.Empty); + if (Regex.IsMatch(b, @"\.0*$")) + Regex.Replace(b, @"\.0*$", string.Empty); + + if (a == b) { + return 0; + } + + + int apos = 0, bpos = 0; + int alen = a.Length, blen = b.Length; + + while ((apos < alen) && (bpos < blen)) { + int first_diff = 0; + + while ((apos < alen) && (bpos < blen) && + (!char.IsDigit(a[apos]) || !char.IsDigit(b[bpos])) ) { + int vc = order(a[apos]); + int rc = order(b[bpos]); + if (vc != rc) + return vc - rc; + apos ++; bpos ++; + } + + if (a[apos] == '0') apos ++; + if (b[bpos] == '0') bpos ++; + + while ((apos < alen) && (bpos < blen) && + char.IsDigit(a[apos]) && char.IsDigit(b[bpos])) { + if (first_diff == 0) + first_diff = a[apos] - b[bpos]; + apos ++; bpos ++; + } + + if (apos < alen && char.IsDigit(a[apos])) { + return 1; + } else if (bpos < blen && char.IsDigit(b[bpos])) { + return -1; + } else if (first_diff != 0) { + return first_diff; + } + } + + if (apos == alen && bpos == blen) { + return 0; + } else if (apos == alen) { + return -1; + } else if (bpos == blen) { + return 1; + } else { + return 1; // Shouldnt happen + } + } + + + } +} diff --git a/na-get-lib/NaGet.SubCommands/NaGetInstall.cs b/na-get-lib/NaGet.SubCommands/NaGetInstall.cs new file mode 100644 index 0000000..3d01139 --- /dev/null +++ b/na-get-lib/NaGet.SubCommands/NaGetInstall.cs @@ -0,0 +1,214 @@ +using System; +using NaGet.Packages.Install; +using NaGet.Packages; +using NaGet.Net; + +namespace NaGet.SubCommands +{ + public class NaGetInstall : NaGetTaskSet + { + private bool done = false; + + private int currentTaskSetIndex = -1; + + private PackageListsManager pkgListMan; + + public Downloader Downloader; // TODO ŽQÆ‚ð‚µ‚ÄƒZƒbƒg‚·‚邿‚¤‚É + + private bool packageInstallerDownloaded = false; + + public override bool Cancelable { + get { return ! done; } + } + + /// + /// ƒCƒ“ƒXƒg[ƒ‹‚·‚éƒpƒbƒP[ƒW + /// + public Installation[] Installations; + + /// + /// ƒRƒ“ƒXƒgƒ‰ƒNƒ^ + /// + /// ƒCƒ“ƒXƒg[ƒ‹‚·‚éƒpƒbƒP[ƒW + public NaGetInstall(PackageListsManager pkgListMan, Package[] pkgs) + : this(pkgListMan, Installation.ConvertInstallations(pkgs)) + { + } + + /// + /// ƒRƒ“ƒXƒgƒ‰ƒNƒ^ + /// + /// ƒCƒ“ƒXƒg[ƒ‹ˆ—‚Ì”z—ñ + public NaGetInstall(PackageListsManager pkgMan, Installation[] installations) + { + pkgListMan = pkgMan; + + Installations = installations; + initializeMainTaskSetNames(); + } + + private void initializeMainTaskSetNames() + { + System.Collections.Generic.List taskSetNames = new System.Collections.Generic.List(); + + for (int i =0; i < Installations.Length; i++) { + taskSetNames.Add(string.Format("Žæ“¾: {0}", Installations[i].ToString())); + } + taskSetNames.Add("ƒCƒ“ƒXƒg[ƒ‰‚ÌŒŸØ"); + for (int i =0; i < Installations.Length; i++) { + taskSetNames.Add(string.Format("ƒCƒ“ƒXƒg[ƒ‹: {0}", Installations[i].ToString())); + } + taskSetNames.Add(string.Format("ƒŠƒXƒgXV: {0}", NaGet.Env.ArchiveInstalledPackageListFile)); + taskSetNames.Add(string.Format("ƒŠƒXƒgXV: {0}", NaGet.Env.SystemInstalledPackageListFile)); + + TaskSetNames = taskSetNames.ToArray(); + } + + public override void Run() + { + currentTaskSetIndex ++; + RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED, "ƒCƒ“ƒXƒg[ƒ‹ˆ—ŠJŽn"); + + foreach (Installation inst in Installations) { + if (! inst.IsInstallablePackage()) { + string msg = string.Format("{0}‚̓Cƒ“ƒXƒg[ƒ‹‚·‚邱‚Æ‚ª‚Å‚«‚Ü‚¹‚ñ", inst.ToString()); + + RaiseTaskSetEvent(NaGetTaskSetEventType.ERROR, msg); + done = true; + return; + } + + RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED_TASKSET, inst.ToString()); + + if (! inst.Downloaded) { + try { + inst.Download(Downloader); + } catch (NaGetTaskCanceledException) { + RaiseTaskSetEvent(NaGetTaskSetEventType.CANCELED, "ƒCƒ“ƒXƒg[ƒ‰‚̃_ƒEƒ“ƒ[ƒhˆ—‚ªƒLƒƒƒ“ƒZƒ‹‚³‚ê‚Ü‚µ‚½"); + done = true; + return; + } catch (System.Net.WebException e) { + RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING, e.Message); + if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()) { + RaiseTaskSetEvent(NaGetTaskSetEventType.ERROR, "ƒlƒbƒgƒ[ƒN‚ɐڑ±‚³‚ê‚Ä‚¢‚Ü‚¹‚ñB"); + } else { + RaiseTaskSetEvent(NaGetTaskSetEventType.ERROR, "ƒlƒbƒgƒ[ƒN‚ɐڑ±‚Å‚«‚Ü‚¹‚ñ‚Å‚µ‚½Bƒlƒbƒgƒ[ƒN‚ªØ’f‚³‚ê‚Ä‚¢‚é‚©Aƒtƒ@ƒCƒAƒEƒH[ƒ‹‚É‚æ‚Á‚ÄŽÕ’f‚³‚ꂽ‰Â”\«‚ª‚ ‚è‚Ü‚·B"); + } + done = true; + return; + } catch (Exception e) { + RaiseTaskSetEvent(NaGetTaskSetEventType.ERROR, e.Message); + done = true; + return; + } + } + currentTaskSetIndex ++; + + if (inst.Downloaded) { // ³íI—¹ + RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED_TASKSET, inst.ToString()); + } else { // ƒCƒ“ƒXƒg[ƒ‹‚ªŠ®—¹‚¹‚¸‚ɏI‚í‚Á‚½=ޏ”s=ƒGƒ‰[ + RaiseTaskSetEvent(NaGetTaskSetEventType.ERROR, string.Format("{0}‚̃Cƒ“ƒXƒg[ƒ‰‚𐳏í‚Ƀ_ƒEƒ“ƒ[ƒh‚Å‚«‚Ü‚¹‚ñ‚Å‚µ‚½", inst.ToString())); + } + } + + packageInstallerDownloaded = true; + + { + bool invalid = false; + int i = 0; + foreach (Installation inst in Installations) { + float percent = (CurrentTaskSetIndex+((float)i / Installations.Length))*100f/TaskSetNames.Length; + + if (inst.GetRegisteredHashCount() > 0) { + RaiseTaskSetEvent(NaGetTaskSetEventType.INFO, "ŒŸØ: "+inst.ToString(), percent); + + if (inst.IsInstallablePackage() && inst.VerifyHashValues() == false) { + invalid = true; + RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING, "ŒŸØ: "+inst.ToString() + " ”ñ®‡", percent); + } else { + RaiseTaskSetEvent(NaGetTaskSetEventType.INFO, "ŒŸØ: "+inst.ToString() + " OK", percent); + } + } + i++; + } + + // TODO ƒnƒbƒVƒ…‚ª‰ó‚ê‚Ä‚¢‚邯‚«‚̑΍ô +// if (invalid && (! AllGet.Util.Confirm("Some packages do not match hash value. Are you really sure to install them [yN]?", false) )) { +// Console.WriteLine("Abort."); +// Environment.Exit(0); +// } + currentTaskSetIndex ++; + } + + foreach (Installation inst in Installations) { + RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED_TASKSET, inst.ToString()); + + try { + inst.ErrorDataReceived += this.ReceivedErrorData; + inst.OutputDataReceived += this.ReceivedOutputData; + int exitCode = inst.Install(); + if (exitCode != 0) { + RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING, "ƒCƒ“ƒXƒg[ƒ‹‚ª³í‚ɏI‚¦‚Ä‚¢‚È‚¢‰Â”\«‚ª‚ ‚è‚Ü‚·BƒCƒ“ƒXƒg[ƒ‰‚̏I—¹ƒR[ƒh:"+exitCode); + } + + pkgListMan.WriteInstallationLog(inst); + } catch (Exception e) { + RaiseTaskSetEvent(NaGetTaskSetEventType.ERROR, e.Message); + done = true; + return; + } + currentTaskSetIndex ++; + + RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED_TASKSET, inst.ToString()); + + if (cancelCalled) { + RaiseTaskSetEvent(NaGetTaskSetEventType.CANCELED, "ƒpƒbƒP[ƒW‚̃Cƒ“ƒXƒg[ƒ‹ˆ—‚ªƒLƒƒƒ“ƒZƒ‹‚³‚ê‚Ü‚µ‚½"); + done = true; + return; + } + } + pkgListMan.SaveSystemInstalledLogList(); // ƒƒO‚̃Rƒ~ƒbƒg + + runLocalUpdate(); + + done = true; + + RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED, "I—¹", 100); + } + + private void runLocalUpdate() + { + // ƒCƒ“ƒXƒg[ƒ‹ƒgƒŠƒXƒg‚̍XV + RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED_TASKSET, TaskSetNames[currentTaskSetIndex]); + pkgListMan.DetectInstalledPkgs(); + pkgListMan.SaveInstalledPackageList(); + currentTaskSetIndex++; + RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED_TASKSET, TaskSetNames[currentTaskSetIndex-1]); + + // ƒVƒXƒeƒ€‚ɃCƒ“ƒXƒg[ƒ‹‚³‚ê‚Ä‚¢‚郊ƒXƒg‚̍XV + RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED_TASKSET, TaskSetNames[currentTaskSetIndex]); + pkgListMan.DetectSystemInstalledPkgs(); + pkgListMan.SaveSystemInstalledPackageList(); + currentTaskSetIndex++; + RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED_TASKSET, TaskSetNames[currentTaskSetIndex-1]); + } + + public override bool Done { + get { return done; } + } + + public override int CurrentTaskSetIndex { + get { return currentTaskSetIndex; } + } + + private bool cancelCalled = false; + + public override bool Cancel() + { + cancelCalled = true; + if (! packageInstallerDownloaded) { + return Downloader.Cancel(); + } else return true; + } + } +} diff --git a/na-get-lib/NaGet.SubCommands/NaGetTask.cs b/na-get-lib/NaGet.SubCommands/NaGetTask.cs new file mode 100644 index 0000000..10a75b9 --- /dev/null +++ b/na-get-lib/NaGet.SubCommands/NaGetTask.cs @@ -0,0 +1,71 @@ +using System; + +namespace NaGet.SubCommands +{ + public class NaGetEventArgs : EventArgs + { + /// + /// ƒ^ƒXƒN‚̐i’»ó‹µ‚Ì•S•ª—¦•\ަ + /// + public float TaskProgressPercent = -1; + + /// + /// ƒ^ƒXƒN‚ÌŒ»‹µ‚̃ƒbƒZ[ƒW + /// + public string TaskMessage; + } + + public class NaGetTaskCanceledException : Exception + { + public NaGetTaskCanceledException(string msg) + : base(msg) + { + } + + public NaGetTaskCanceledException(string msg, Exception e) + : base(msg, e) + { + } + } + + /// + /// NaGet‚̃Rƒ}ƒ“ƒhƒ^ƒXƒN‚̍ŏ¬’PˆÊ‚̐eƒNƒ‰ƒX + /// + public abstract class NaGetTask + { + /// + /// ŽÀs‚·‚é + /// + public abstract void Run(); + + /// + /// ŽÀsó‘Ô‚©”Û‚©‚𓾂é + /// + public abstract bool Running { + get; + } + + /// + /// I—¹‚µ‚Ä‚¢‚é‚©”Û‚©B + /// + public abstract bool Done { + get; + } + + /// + /// ƒLƒƒƒ“ƒZƒ‹‰Â”\‚©”Û‚©‚ð•Ô‚· + /// + public virtual bool Cancelable { + get { return false; } + } + + /// + /// ’†’f‚³‚¹‚é + /// + /// ¬Œ÷‚µ‚½‚©‚¢‚È‚© + public virtual bool Cancel() + { + return false; + } + } +} diff --git a/na-get-lib/NaGet.SubCommands/NaGetTaskSet.cs b/na-get-lib/NaGet.SubCommands/NaGetTaskSet.cs new file mode 100644 index 0000000..83beaf8 --- /dev/null +++ b/na-get-lib/NaGet.SubCommands/NaGetTaskSet.cs @@ -0,0 +1,114 @@ +using System; + +namespace NaGet.SubCommands +{ + public class NaGetTaskSetEventArgs : NaGetEventArgs + { + public NaGetTaskSetEventType Type; + + public NaGetTaskSetEventArgs(NaGetTaskSetEventType type, string message, float processPercent) + { + this.Type = type; + this.TaskMessage = message; + this.TaskProgressPercent = processPercent; + } + } + + /// + /// ƒ^ƒXƒN‚ÌŽí—Þ + /// + public enum NaGetTaskSetEventType + { + /// + /// ŠJŽn + /// + STARTED, + /// + /// Š®—¹‚µ‚½(‚·‚×‚Ä‚ðŠ®—¹) + /// + COMPLETED, + /// + /// ì‹Æ‚ªƒLƒƒƒ“ƒZƒ‹‚³‚ꂽ + /// + CANCELED, + /// + /// ƒGƒ‰[‚𔭐¶‚µ(’†’f‚µ‚½) + /// + ERROR, + /// + /// ƒGƒ‰[‚ª”­¶‚µ‚½‚ªŒp‘± + /// + WARNING, + /// + /// ‚»‚̂ق©‚̏î•ñ + /// + INFO, + /// + /// ì‹Æ‚ðŠJŽn + /// + STARTED_TASKSET, + /// + /// ì‹Æ‚ðI—¹ + /// + COMPLETED_TASKSET + } + + /// + /// NaGetƒ^ƒXƒNˆ—‚̃pƒbƒN + /// + public abstract class NaGetTaskSet : NaGetTask + { + /// + /// ƒ^ƒXƒNˆ—‚̃Cƒxƒ“ƒgƒnƒ“ƒhƒ‰ + /// + public event EventHandler TaskSetRaised; + + /// + /// •¶Žš—ñ‚Å•\Œ»‚µ‚½ì‹Æˆê——ƒŠƒXƒg + /// + public string[] TaskSetNames; + + /// + /// Œ»ÝŽÀs’†‚Ìì‹Æ”ԍ† + /// + public abstract int CurrentTaskSetIndex { + get; + } + + protected virtual void RaiseTaskSetEvent(NaGetTaskSetEventType type, string message) + { + float percent = (CurrentTaskSetIndex >= 0)? CurrentTaskSetIndex * 100 / TaskSetNames.Length : -1; + RaiseTaskSetEvent(type, message, percent); + } + + protected virtual void RaiseTaskSetEvent(NaGetTaskSetEventType type, string message, float percent) + { + RaiseTaskSetEvent(new NaGetTaskSetEventArgs(type, message, percent)); + } + + protected virtual void RaiseTaskSetEvent(NaGetTaskSetEventArgs e) + { + if (TaskSetRaised != null) { + TaskSetRaised(this, e); + } + } + + protected virtual void ReceivedErrorData(object sender, NaGet.Utils.AnyDataEventArgs e) + { + if (! string.IsNullOrEmpty(e.Data)) { + RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING, e.Data); + } + } + + protected virtual void ReceivedOutputData(object sender, NaGet.Utils.AnyDataEventArgs e) + { + if (! string.IsNullOrEmpty(e.Data)) { + RaiseTaskSetEvent(NaGetTaskSetEventType.INFO, e.Data); + } + } + + public override bool Running { + get { return CurrentTaskSetIndex >= 0 && !Done; } + } + } +} diff --git a/na-get-lib/NaGet.SubCommands/NaGetUninstall.cs b/na-get-lib/NaGet.SubCommands/NaGetUninstall.cs new file mode 100644 index 0000000..11818c9 --- /dev/null +++ b/na-get-lib/NaGet.SubCommands/NaGetUninstall.cs @@ -0,0 +1,122 @@ +using System; +using NaGet.Packages.Install; +using NaGet.Packages; +using NaGet.Net; + +namespace NaGet.SubCommands +{ + public class NaGetUninstall : NaGetTaskSet + { + private bool done = false; + + private int currentTaskSetIndex = -1; + + private PackageListsManager pkgListMan; + + /// + /// ƒAƒ“ƒCƒ“ƒXƒg[ƒ‹‚·‚éƒpƒbƒP[ƒW + /// + public Uninstallation[] Uninstallations; + + /// + /// ƒRƒ“ƒXƒgƒ‰ƒNƒ^ + /// + /// ƒAƒ“ƒCƒ“ƒXƒg[ƒ‹‚·‚éƒpƒbƒP[ƒW + public NaGetUninstall(PackageListsManager pkgMan, InstalledPackage[] pkgs) + { + pkgListMan = pkgMan; + + Uninstallations = new Uninstallation[pkgs.Length]; + for (int i = 0; i < pkgs.Length; i++) { + Uninstallations[i] = new Uninstallation(pkgs[i]); + } + + initializeMainTaskSetNames(); + } + + /// + /// ƒRƒ“ƒXƒgƒ‰ƒNƒ^ + /// + /// ƒAƒ“ƒCƒ“ƒXƒg[ƒ‹ˆ—‚Ì”z—ñ + public NaGetUninstall(PackageListsManager pkgMan, Uninstallation[] uninstallations) + { + pkgListMan = pkgMan; + + Uninstallations = uninstallations; + initializeMainTaskSetNames(); + } + + private void initializeMainTaskSetNames() + { + System.Collections.Generic.List taskSetNames = new System.Collections.Generic.List(); + + for (int i =0; i < Uninstallations.Length; i++) { + taskSetNames.Add(string.Format("ƒAƒ“ƒCƒ“ƒXƒg[ƒ‹: {0}", Uninstallations[i].ToString())); + } + taskSetNames.Add(string.Format("ƒŠƒXƒgXV: {0}", NaGet.Env.ArchiveInstalledPackageListFile)); + taskSetNames.Add(string.Format("ƒŠƒXƒgXV: {0}", NaGet.Env.SystemInstalledPackageListFile)); + + TaskSetNames = taskSetNames.ToArray(); + } + + public override void Run() + { + currentTaskSetIndex ++; + RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED, "ƒAƒ“ƒCƒ“ƒXƒg[ƒ‹ˆ—ŠJŽn"); + + foreach (Uninstallation uninst in Uninstallations) { + RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED_TASKSET, uninst.ToString()); + + if (uninst.Installed) { + try { + uninst.OutputDataReceived += this.ReceivedOutputData; + uninst.ErrorDataReceived += this.ReceivedErrorData; + int exitCode = uninst.Uninstall(); + if (exitCode != 0) { + RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING, "ƒAƒ“ƒCƒ“ƒXƒg[ƒ‹‚ª³í‚ɏI‚¦‚Ä‚¢‚È‚¢‰Â”\«‚ª‚ ‚è‚Ü‚·BƒAƒ“ƒCƒ“ƒXƒg[ƒ‰‚̏I—¹ƒR[ƒh:"+exitCode); + } + } catch (Exception e) { + RaiseTaskSetEvent(NaGetTaskSetEventType.ERROR, e.Message); + done = true; + return; + } + } else { + RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING, string.Format("{0}‚ÍŠù‚ɃAƒ“ƒCƒ“ƒXƒg[ƒ‹‚³‚ê‚Ä‚¢‚é‚©Aƒ\ƒtƒg‚Ì‘¶Ý‚ðŠm”F‚Å‚«‚Ü‚¹‚ñ‚Å‚µ‚½", uninst)); + } + + RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED_TASKSET, uninst.ToString()); + } + + runLocalUpdate(); + + done = true; + + RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED, "I—¹", 100); + } + + private void runLocalUpdate() + { + // ƒCƒ“ƒXƒg[ƒ‹ƒgƒŠƒXƒg‚̍XV + RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED_TASKSET, TaskSetNames[currentTaskSetIndex]); + pkgListMan.DetectInstalledPkgs(); + pkgListMan.SaveInstalledPackageList(); + currentTaskSetIndex++; + RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED_TASKSET, TaskSetNames[currentTaskSetIndex-1]); + + // ƒVƒXƒeƒ€‚ɃCƒ“ƒXƒg[ƒ‹‚³‚ê‚Ä‚¢‚郊ƒXƒg‚̍XV + RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED_TASKSET, TaskSetNames[currentTaskSetIndex]); + pkgListMan.DetectSystemInstalledPkgs(); + pkgListMan.SaveSystemInstalledPackageList(); + currentTaskSetIndex++; + RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED_TASKSET, TaskSetNames[currentTaskSetIndex-1]); + } + + public override bool Done { + get { return done; } + } + + public override int CurrentTaskSetIndex { + get { return currentTaskSetIndex; } + } + } +} diff --git a/na-get-lib/NaGet.SubCommands/NaGetUpdate.cs b/na-get-lib/NaGet.SubCommands/NaGetUpdate.cs new file mode 100644 index 0000000..0524292 --- /dev/null +++ b/na-get-lib/NaGet.SubCommands/NaGetUpdate.cs @@ -0,0 +1,147 @@ +using System; +using System.IO; +using NaGet.Packages; +using NaGet.Packages.Install; +using NaGet.Net; +using NaGet.SubCommands; + +namespace NaGet.SubCommands +{ + public class NaGetUpdate : NaGetTaskSet + { + private ProviderList providerList; + + private PackageListsManager pkgListMan; + + private bool downloadPackageLists = false; + + private bool packageListsDownloaded = true; + + public Downloader Downloader; // TODO 参照をしてセットするように + + private int currentTaskSetIndex = -1; + + private bool done = false; + + public override int CurrentTaskSetIndex { + get { return currentTaskSetIndex; } + } + + public override bool Cancelable { + get { return ! packageListsDownloaded; } + } + + public NaGetUpdate(PackageListsManager pkgListMan) + : this(pkgListMan, true) + { + } + + public NaGetUpdate(PackageListsManager pkgMan, bool downloadPackageListsFlag) + { + pkgListMan = pkgMan; + downloadPackageLists = downloadPackageListsFlag; + + System.Collections.Generic.List taskSetNames = new System.Collections.Generic.List(); + if (downloadPackageLists) { + providerList = new ProviderList(NaGet.Env.ProviderListFile); + + foreach (string url in providerList.Urls) { + taskSetNames.Add(string.Format("リスト取得: {0}", url)); + } + taskSetNames.Add(string.Format("リスト更新: {0}", NaGet.Env.PackageListFile)); + } + taskSetNames.Add(string.Format("リスト更新: {0}", NaGet.Env.ArchiveInstalledPackageListFile)); + taskSetNames.Add(string.Format("リスト更新: {0}", NaGet.Env.SystemInstalledPackageListFile)); + + TaskSetNames = taskSetNames.ToArray(); + } + + public override void Run() + { + currentTaskSetIndex ++; + RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED, "リスト更新処理開始"); + + try { + // リストのダウンロード + if (downloadPackageLists) { + packageListsDownloaded = false; + try { + runDownloadPackages(); + } catch (NaGetTaskCanceledException) { + RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING, "リストのダウンロード処理がキャンセルされました"); + } catch (System.Net.WebException e) { + RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING, e.Message); + if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()) { + RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING, "ネットワークに接続されていません。"); + } else { + RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING, "ネットワークに接続できませんでした。ネットワークが切断されているか、ファイアウォールによって遮断された可能性があります。"); + } + } finally { + currentTaskSetIndex = providerList.Urls.Length + 1; + } + packageListsDownloaded = true; + } + + runLocalUpdate(); + } finally { + done = true; + } + + RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED, "終了", 100); + } + + private void runDownloadPackages() + { + PackageList avaiablePackageList = new PackageList(); + foreach(string provider in providerList.Urls) { + RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED_TASKSET, TaskSetNames[currentTaskSetIndex]); + + string tmpfileName = Path.GetTempFileName(); + try { + Downloader.Download(provider, tmpfileName); + + avaiablePackageList.AddPackages(NaGet.Utils.GetDeserializedObject>(tmpfileName).Packages); + } finally { + if (File.Exists(tmpfileName)) { + File.Delete(tmpfileName); + } + } + + currentTaskSetIndex ++; + RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED_TASKSET, TaskSetNames[currentTaskSetIndex-1]); + } + + RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED_TASKSET, TaskSetNames[currentTaskSetIndex]); + pkgListMan.availablePkgList = avaiablePackageList; // Mediatorのリストを更新 + pkgListMan.SaveAvailablePackageList(); + currentTaskSetIndex ++; + RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED_TASKSET, TaskSetNames[currentTaskSetIndex-1]); + } + + private void runLocalUpdate() + { + // インストールトリストの更新 + RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED_TASKSET, TaskSetNames[currentTaskSetIndex]); + pkgListMan.DetectInstalledPkgs(); + pkgListMan.SaveInstalledPackageList(); + currentTaskSetIndex++; + RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED_TASKSET, TaskSetNames[currentTaskSetIndex-1]); + + // システムにインストールされているリストの更新 + RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED_TASKSET, TaskSetNames[currentTaskSetIndex]); + pkgListMan.DetectSystemInstalledPkgs(); + pkgListMan.SaveSystemInstalledPackageList(); + currentTaskSetIndex++; + RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED_TASKSET, TaskSetNames[currentTaskSetIndex-1]); + } + + public override bool Cancel() + { + return Downloader.Cancel(); + } + + public override bool Done { + get { return done; } + } + } +} diff --git a/na-get-lib/NaGet/Env.cs b/na-get-lib/NaGet/Env.cs new file mode 100644 index 0000000..17a98c3 --- /dev/null +++ b/na-get-lib/NaGet/Env.cs @@ -0,0 +1,102 @@ +using System; +using System.IO; + +namespace NaGet +{ + /// + /// 環境変数などを取り扱うクラス + /// + public sealed class Env + { + /// + /// 呼び出し禁止 + /// + private Env() + { + } + + + /// + /// ファイルリスト提供サーバのリストファイル + /// + public static readonly string ProviderListFile = "provider.list.txt"; + + /// + /// パッケージリスト(キャッシュ)置き場のパス + /// + public static readonly string PackageListFile = "packages.list.xml"; + + /// + /// 本ソフトウェアを介してインストールされたパッケージのリストファイル + /// + public static readonly string ArchiveInstalledPackageListFile = "packages.envinstalled.xml"; + + /// + /// システムから検出されたパッケージのリストファイル + /// + public static readonly string SystemInstalledPackageListFile = "packages.sysinstalled.xml"; + + /// + /// インストールログファイル + /// + public static readonly string SystemInstalledPackageLogFile = "packages.sysinstalled.log.xml"; + + private static string appDataFolderPath = null; + + /// + /// アプリケーションデータを保存するフォルダのパス + /// + public static string AppDataFolderPath + { + get { + if (appDataFolderPath == null) { +// string progFiles = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles); +// if (Path.GetDirectoryName(Environment.CurrentDirectory) == progFiles) { +// string appData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); +// return Path.Combine(appData, "AppliStation"); +// } else { + return Environment.CurrentDirectory; +// } + } else { + return appDataFolderPath; + } + } + set { appDataFolderPath = value; } + } + + /// + /// インストーラの一時置き場の親ディレクトリ + /// + public static string ArchiveFolderPath + { + get { return Path.Combine(AppDataFolderPath, "Cache"); } + } + + /// + /// アーカイバ方式のパッケージのインストール先フォルダ + /// + public static string ArchiveProgramFiles { + get { + return Path.Combine(AppDataFolderPath, "progs"); + } + } + + /// + /// アーカイバ方式のパッケージのプログラムグループフォルダ + /// + public static string ArchiveProgramGroup { + get { + return Path.Combine(AppDataFolderPath, "programs"); + } + } + + /// + /// アーカイバ方式のパッケージのSystem32のフォルダ + /// + public static string ArchiveSystem32 { + get { + return Path.Combine(ArchiveProgramFiles, ".system32"); + } + } + } +} diff --git a/na-get-lib/NaGet/Utils.cs b/na-get-lib/NaGet/Utils.cs new file mode 100644 index 0000000..8bd2e09 --- /dev/null +++ b/na-get-lib/NaGet/Utils.cs @@ -0,0 +1,481 @@ +using System; +using System.IO; +using System.Text; +using System.Globalization; +using System.Security.Principal; +using System.Reflection; +using System.Diagnostics; +using Microsoft.Win32; + +namespace NaGet +{ + + /// + /// 雑多な便利メソッドを集めたクラス + /// + public sealed class Utils + { + /// + /// 呼び出し禁止 + /// + private Utils() + { + } + + /// + /// オブジェクトのフィールドをコピーしてクローン化する + /// + /// コピー元 + /// コピー先。コピー元のクラスと同一か継承している型でなければならない + public static void FieldCopy(T from, ref U target) where U : T + { + foreach(FieldInfo member in typeof(T).GetFields()) { + try { + member.SetValue(target, member.GetValue(from)); + } catch (FieldAccessException) {} // アクセス不能は無視 + } + } + + /// + /// パス変数に指定のフォルダを追加する + /// + /// 追加するフォルダ + public static void AddDirectoryToPath(string dir) + { + string path = Environment.GetEnvironmentVariable("PATH"); + + if (path.IndexOf(dir) < 0) { + path = dir + Path.PathSeparator + path; + Environment.SetEnvironmentVariable("PATH", path); + } + } + + /// + /// バイト単位で表現された容量を接尾語を活用して適切な文字列に変換 + /// + /// バイト単位の容量 + /// 読みやすい形に直された容量文字列 + public static string FormatSize(double bytes) + { + string[] units = new string[] {"B", "KB", "MB", "GB", "TB"}; + + double size = bytes; + int i; + for (i = 0; size >= 1024 && i < units.Length-1 ; i++) { + size /= 1024.0; + } + + return string.Format("{0:F2}{1}", size, units[i]); + } + + public static string FormatSize(long bytes) + { + return FormatSize((double) bytes); + } + + #region ファイル操作関数群 + + /// + /// URLからそのファイル名を生成する + /// + /// 対象のurl + public static string Url2filename(string url) + { + string filename = Path.GetFileName(UrlDecode(url, Encoding.UTF8)); + + int pos; + if ((pos = filename.IndexOfAny(Path.GetInvalidFileNameChars())) >= 0) { + // 不正な文字が含まれているならば、それ以降を削除 + filename = filename.Substring(0, pos); + // そうしてしまったら文字の内容がまったくなくなってしまったら、ランダムな名に + if (filename.Length == 0) { + filename = Path.GetFileName(Path.GetTempFileName()); + } + } + return filename; + //return UrlDecode(Path.GetFileName(url), Encoding.UTF8); + } + + /// + /// URLのデコードを行う + /// + /// 対象のurl文字列 + /// デコードの処理に使う文字コード + public static string UrlDecode(string s, Encoding e) + { + // mono の System.Net.HttpUtility より作成 + + if (null == s) + return null; + + if (s.IndexOf ('%') == -1 && s.IndexOf ('+') == -1) + return s; + + if (e == null) + e = Encoding.GetEncoding (28591); + + StringBuilder output = new StringBuilder (); + long len = s.Length; + NumberStyles hexa = NumberStyles.HexNumber; + MemoryStream bytes = new MemoryStream (); + + for (int i = 0; i < len; i++) { + if (s [i] == '%' && i + 2 < len) { + if (s [i + 1] == 'u' && i + 5 < len) { + if (bytes.Length > 0) { + //output.Append (GetChars (bytes, e)); + output.Append(e.GetChars(bytes.GetBuffer(), 0, (int) bytes.Length)); + bytes.SetLength (0); + } + + output.Append ((char) int.Parse(s.Substring (i + 2, 4), hexa)); + i += 5; + } else { + bytes.WriteByte ((byte) int.Parse(s.Substring (i + 1, 2), hexa)); + i += 2; + } + continue; + } + + if (bytes.Length > 0) { + //output.Append (GetChars (bytes, e)); + output.Append(e.GetChars(bytes.GetBuffer(), 0, (int) bytes.Length)); + bytes.SetLength (0); + } + + if (s [i] == '+') { + output.Append (' '); + } else { + output.Append (s [i]); + } + } + + if (bytes.Length > 0) { + //output.Append (GetChars (bytes, e)); + output.Append(e.GetChars(bytes.GetBuffer(), 0, (int) bytes.Length)); + } + + bytes = null; + return output.ToString (); + } + + /// + /// ファイルパスから、指定のパスセパレータの意味でファイル名を取り出す。 + /// + /// ファイルパス(またはURLパス) + /// パスセパレータ + public static string Basedir(string filepath, char separator) + { + int dirSep = filepath.LastIndexOf(separator); + if (dirSep < 0) return ""; + + return filepath.Substring(0, dirSep); + } + + /// + /// 再帰的にファイルの属性を指定します。強制的にフォルダの再帰削除の前に読み込み専用属性を消すのに使います。 + /// + /// 設定するフォルダ + /// 設定する属性値 + public static void SetAttributeRecursive(string path, FileAttributes attr) + { + // 自分自身の属性を変更 + File.SetAttributes(path, attr); + + // 子ファイルの属性変更 + foreach (string file in Directory.GetFiles(path)) { + File.SetAttributes(file, attr); + } + + // 子フォルダを再帰的に属性変更 + foreach (string file in Directory.GetDirectories(path)) { + SetAttributeRecursive(file, attr); + } + } + + /// + /// ファイルまたはフォルダの容量を算出して返す + /// + /// + /// 対象ファイル及びフォルダのパス + /// + /// + /// 計算された容量(バイト単位) + /// + public static ulong GetFileSize(string path) + { + return ((File.GetAttributes(path) & FileAttributes.Directory) != 0)? + GetDirectoryFileSize(new DirectoryInfo(path)) : ((ulong) (new FileInfo(path)).Length); + } + + /// + /// フォルダの容量を算出して返す + /// + /// + /// 対象フォルダ + /// + /// + /// 計算された容量(バイト単位) + /// + public static ulong GetDirectoryFileSize(DirectoryInfo dirInfo) + { + ulong size = 0; + foreach (FileInfo child in dirInfo.GetFiles("*", SearchOption.AllDirectories)) { + size += (ulong) child.Length; + } + return size; + } + + /// + /// ワイルドカードを展開したファイルパス文字列を作り出す。 + /// 戻り値のそれぞれの文字列はフルパスとなる。 + /// + /// ベース(基点)のディレクトリ + /// ワイルドカードパターン + /// 展開したファイルパス + public static string[] ExtendWildcardFile(string baseDir, string pattern) + { + if (pattern.IndexOfAny(new char[]{'*','?'}) < 0) { + return new string[]{Path.Combine(baseDir, pattern)}; // ワイルドカードがなければそのまま返す + } + + string[] pathArray = pattern.Split(Path.DirectorySeparatorChar); + System.Collections.Generic.List extended = new System.Collections.Generic.List(); + try { + if (pathArray.Length == 1) { + extended.AddRange(Directory.GetFiles(baseDir, pathArray[0], SearchOption.TopDirectoryOnly)); + extended.AddRange(Directory.GetDirectories(baseDir, pathArray[0], SearchOption.TopDirectoryOnly)); + } else { // pathArray.Length > 1 + string subPattern = string.Join(Path.DirectorySeparatorChar.ToString(), pathArray, 1, pathArray.Length-1); + + foreach (string subDir in Directory.GetDirectories(baseDir, pathArray[0], SearchOption.TopDirectoryOnly)) { + // 再帰的に追加してゆく + extended.AddRange(ExtendWildcardFile(subDir, subPattern)); + } + } + } catch (UnauthorizedAccessException) { + } + + // 存在しないパスは消去する + extended.RemoveAll( + delegate(string path) { + return ! File.Exists(path); + } + ); + + return extended.ToArray(); + } + + /// + /// パスをパス区切り文字列ごとに分割した配列を返す + /// + /// パス文字列。相対・絶対は区別しない + /// フォルダ名ごとに分けられた文字列配列 + private static string[] splitPath(string path) + { + return path.Split(new char[]{Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar}); + } + + /// + /// Converts a given absolute path and a given base path to a path that leads + /// from the base path to the absoulte path. (as a relative path) + /// + public static string GetRelativePath(string baseDirectoryPath, string absPath) + { + // TODO SharpDevelopのICSharpCode.Core.FileUtilityからのコピペ(GPL) + + string[] bPath = splitPath(baseDirectoryPath); + string[] aPath = splitPath(absPath); + int indx = 0; + for(; indx < Math.Min(bPath.Length, aPath.Length); ++indx){ + if(!bPath[indx].Equals(aPath[indx], StringComparison.OrdinalIgnoreCase)) + break; + } + + if (indx == 0) { + return absPath; + } + + StringBuilder erg = new StringBuilder(); + + if(indx == bPath.Length) { +// erg.Append('.'); +// erg.Append(Path.DirectorySeparatorChar); + } else { + for (int i = indx; i < bPath.Length; ++i) { + erg.Append(".."); + erg.Append(Path.DirectorySeparatorChar); + } + } + erg.Append(String.Join(Path.DirectorySeparatorChar.ToString(), aPath, indx, aPath.Length-indx)); + return erg.ToString(); + } + + /// + /// 相対パスに含まれている".."などを消去する + /// + /// + /// + public static string GetDotsRemovedPath(string aPath) + { + string[] folders = splitPath(aPath); + System.Collections.Generic.List newFolders = new System.Collections.Generic.List(); + + foreach (string fol in folders) { + if (fol == ".") { + // 無視 + } else if (fol == "..") { + // 一つ前のフォルダを消す + newFolders.RemoveAt(newFolders.Count-1); + } else { + newFolders.Add(fol); + } + } + + return string.Join(Path.DirectorySeparatorChar.ToString(), newFolders.ToArray()); + } + + #endregion + + #region XmlSerializer便利メソッド群 + + public static T GetDeserializedObject(string path) + { + T retVal = default(T); + using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read)) { + System.Xml.Serialization.XmlSerializer sr = new System.Xml.Serialization.XmlSerializer(typeof(T)); + retVal = (T) sr.Deserialize(fs); + } + return retVal; + } + + public static void PutSerializeObject(string path, T obj) + { + using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write)) { + System.Xml.Serialization.XmlSerializer sr = new System.Xml.Serialization.XmlSerializer(typeof(T)); + sr.Serialize(fs, obj); + } + } + + #endregion + + #region 権限関連関数群 + + /// + /// 現在のユーザがAdministrators権限を持っているか否かを返す + /// + public static bool IsAdministrators() + { + // TODO UAC はどうするんだ!!!! + + // 現在の Windows ユーザーを現在のスレッドのプリンシパルに反映する + AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal ); + IPrincipal prin = System.Threading.Thread.CurrentPrincipal; + return prin.IsInRole(@"BUILTIN\Administrators"); + } + + /// + /// 現在のPCがUACが有効になっているか否かを返す。 + /// レジストリのHKLM\SOFTWAREÂ¥MicrosoftÂ¥WindowsÂ¥CurrentVersionÂ¥PoliciesÂ¥System\EnableLUAの値を見る。 + /// + /// UACが有効ならばtrue + public static bool IsUACEnabled() + { + try { + using(RegistryKey key = Registry.LocalMachine.CreateSubKey(@"SOFTWAREÂ¥MicrosoftÂ¥WindowsÂ¥CurrentVersionÂ¥PoliciesÂ¥System")) { + return ((int) key.GetValue("EnableLUA", 0)) == 1; + } + } catch (Exception) { + return false; + } + } + + #endregion + + #region プロセス関連便利メソッド群 + + /// + /// プロセスに出力をリダイレクトした上で実行 + /// + /// プロセス起動情報 + /// 標準出力用リスナ(null可) + /// エラー出力用リスナ(null可) + /// 実行プロセス + public static Process ProcessStartWithOutputCapture(ProcessStartInfo procInfo, + DataReceivedEventHandler outputReceived, + DataReceivedEventHandler errorReceived) + { + if (outputReceived != null) { + procInfo.RedirectStandardOutput = true; + } + if (errorReceived != null) { + procInfo.RedirectStandardError = true; + } + procInfo.UseShellExecute = false; + + Process hProcess = Process.Start(procInfo); + if (outputReceived != null) { + hProcess.OutputDataReceived += outputReceived; + hProcess.BeginOutputReadLine(); + } + if (errorReceived != null) { + hProcess.ErrorDataReceived += errorReceived; + hProcess.BeginErrorReadLine(); + } + + return hProcess; + } + + + /// + /// プロセスに出力をリダイレクトした上で実行 + /// + /// プロセス起動情報 + /// 標準出力用リスナ(null可) + /// エラー出力用リスナ(null可) + /// 実行プロセス + public static Process ProcessStartWithOutputCapture(ProcessStartInfo procInfo, + EventHandler> outputReceived, + EventHandler> errorReceived) + { + return ProcessStartWithOutputCapture(procInfo, + ConvertToDataReceivedEventHandler(outputReceived), + ConvertToDataReceivedEventHandler(errorReceived)); + } + + public static DataReceivedEventHandler ConvertToDataReceivedEventHandler(EventHandler> handler) + { + if (handler == null) return null; + return delegate (object sender, DataReceivedEventArgs e) { + AnyDataEventArgs args = new AnyDataEventArgs(e.Data); + handler.Invoke(sender, args); + }; + } + + #endregion + + + /// + /// 任意データのイベント情報を表現するクラス + /// + public class AnyDataEventArgs : EventArgs + { + /// + /// データ + /// + T data; + + public AnyDataEventArgs(T data) + { + this.data = data; + } + + /// + /// データを返す + /// + public T Data { + get { return data; } + } + } + } +} diff --git a/na-get-lib/na-get-lib.csproj b/na-get-lib/na-get-lib.csproj new file mode 100644 index 0000000..7369c9e --- /dev/null +++ b/na-get-lib/na-get-lib.csproj @@ -0,0 +1,86 @@ + + + {058E953D-3986-4F74-8516-5A50D267D36A} + Debug + AnyCPU + Library + na_get_lib + na-get-lib + bin/ + False + False + 4 + false + + + bin\Debug\ + true + Full + false + true + DEBUG;TRACE + Library + na-get-lib + na_get_lib + false + 4 + + + bin\Release\ + false + None + true + false + TRACE + Library + na-get-lib + na_get_lib + false + 4 + + + False + Auto + 4194304 + AnyCPU + 4096 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/provider.list.txt b/provider.list.txt new file mode 100644 index 0000000..d0509b4 --- /dev/null +++ b/provider.list.txt @@ -0,0 +1 @@ +http://diffshare.tv/AppliStationNetwork/softlist.xml -- 2.11.0