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(); this.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath); } 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("タグ: {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("インストールした日: {0:d} ", iPkg.UninstallInfo.InstallDate.Value); } if (iPkg.UninstallInfo.EstimatedSize > 0) { sb.AppendFormat("サイズ: {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 += "公式サイト: " + pkg.Url.Href + "\r\n"; } detailBox.SelectedText += pkg.Summary; break; } uninstallToolStripButton.Visible = uninstallBtnEnabled; installToolStripButton.Visible = installBtnEnabled; packageCommandsToolStripSeparator.Visible = uninstallBtnEnabled || installBtnEnabled; if (packageListView.SelectedItems.Count <= 0) { detailBox.SelectionFont = detailBox.Font; int count = packageListView.Items.Count; detailBox.Text = (count > 0) ? string.Format("{0}個のソフトがあります。", count) : "該当するソフトがありません。"; } 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); // ソート対象列の色付け 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関連 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(); searchTextBox.FireTextChangedTrigger(); PackageListViewUpdate(); } #endregion void PackageListViewUpdate() { this.packageListView.Items.Clear(); if (currentPackageFilter == PackageFilterIndex.All || currentPackageFilter == PackageFilterIndex.NotInstalled) { foreach (Package pkg in pkgListsMan.AvailablePkgList.Search(searchTextBox.Text)) { if (Installation.GetPreferInstallerIndex(pkg) >= 0) { // インストール可能 if (currentPackageFilter == PackageFilterIndex.NotInstalled && (pkgListsMan.InstalledPkgList.GetPackageForName(pkg.Name) != null|| pkgListsMan.SystemInstalledPkgList.GetPackageForName(pkg.Name) != null) ) { continue; // インストール済みは次のループへ(未インストールソフト抽出時) } 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(searchTextBox.Text)) { 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(searchTextBox.Text)) { 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); prog.SetTaskSet(tasks); prog.Refresh(); prog.StartTaskSet(); }; prog.Text = "リストの更新"; prog.ShowDialog(this); } void UpdateToolStripButtonClick(object sender, EventArgs e) { updateActionInvoke(true); UpdatePackageList(); } void LocalupdateToolStripMenuItemClick(object sender, EventArgs e) { updateActionInvoke(false); UpdatePackageList(); } #region searchTextBoxまわり void SearchTextBoxKeyPress(object sender, KeyPressEventArgs e) { switch (e.KeyChar) { case (char)Keys.Enter: searchTextBox.FireTextChangedTrigger(); break; case (char)Keys.Escape: searchTextBox.Text = string.Empty; break; } } void SearchTextBoxTextChangedTriggerFired(object sender, EventArgs e) { PackageListViewUpdate(); } #endregion internal void installActionInvoke(Installation[] insts) { AppliStation.Util.ExecutionProgressViewer prog = new AppliStation.Util.ExecutionProgressViewer(); prog.Shown += delegate(object sender2, EventArgs e2) { NaGet.SubCommands.NaGetInstall tasks = new NaGet.SubCommands.NaGetInstall(pkgListsMan, insts); prog.SetTaskSet(tasks); prog.Refresh(); prog.StartTaskSet(); }; prog.Text = string.Format("ソフトウェアのインストール"); prog.ShowDialog(this); } void InstallToolStripButtonClick(object sender, EventArgs e) { InstallationConfirmForm confirm = new InstallationConfirmForm(); confirm.PkgListsManager = pkgListsMan; confirm.Installations = Installation.ConvertInstallations(SelectedPackages()); confirm.UseRunas = confirm.GetShouldUseRunas(); DialogResult result = confirm.ShowDialog(this); if (result == DialogResult.OK) { Installation[] insts = confirm.CheckedInstallations; if (confirm.UseRunas) { installRunasActionInvoke(insts); } else { installActionInvoke(insts); } UpdatePackageList(); } } public void installRunasActionInvoke(Installation[] insts) { this.setWindowEnabled(false); string tmpfileName = Path.GetTempFileName(); try { NaGet.Utils.PutSerializeObject(tmpfileName, insts); System.Diagnostics.ProcessStartInfo procInfo = new System.Diagnostics.ProcessStartInfo(); procInfo.FileName = Application.ExecutablePath; procInfo.Arguments = string.Format("--noupdate --cmd=install \"--instsref={0}\"", tmpfileName); procInfo.Verb = "runas"; procInfo.WorkingDirectory = Environment.CurrentDirectory; System.Diagnostics.Process hProc = System.Diagnostics.Process.Start(procInfo); hProc.EnableRaisingEvents = true; hProc.SynchronizingObject = this; hProc.Exited += delegate(object sender, EventArgs e) { pkgListsMan.LoadPackageLists(); this.setWindowEnabled(true); this.BringToFront(); if (File.Exists(tmpfileName)) { File.Delete(tmpfileName); } }; } catch (System.ComponentModel.Win32Exception ex) { MessageBox.Show(ex.Message, "インストール", MessageBoxButtons.OK, MessageBoxIcon.Error); if (File.Exists(tmpfileName)) { File.Delete(tmpfileName); } this.setWindowEnabled(true); } } 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("ソフトウェアのアンインストール"); prog.ShowDialog(this); } internal void uninstallRunasActionInvoke(InstalledPackage[] pkgs) { this.setWindowEnabled(false); string tmpfileName = 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; System.Diagnostics.Process hProc = System.Diagnostics.Process.Start(procInfo); hProc.EnableRaisingEvents = true; hProc.SynchronizingObject = this; hProc.Exited += delegate(object sender, EventArgs e) { pkgListsMan.LoadPackageLists(); this.setWindowEnabled(true); this.BringToFront(); if (File.Exists(tmpfileName)) { File.Delete(tmpfileName); } }; } catch (System.ComponentModel.Win32Exception ex) { MessageBox.Show(ex.Message, "アンインストール", MessageBoxButtons.OK, MessageBoxIcon.Error); this.setWindowEnabled(true); 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) { uninstallRunasActionInvoke(instPkgs); } 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 PropertiesToolStripMenuItemClick(object sender, EventArgs e) { foreach (Package pkg in SelectedPackages()) { PackageInfoForm form = new PackageInfoForm(); form.SelectedObject = pkg; form.Text = string.Format("{0}({1})のプロパティ", pkg.Name, pkg.Version); form.ShowDialog(this); break; } } void PackageListContextMenuStripOpening(object sender, System.ComponentModel.CancelEventArgs e) { // 選択されていないなら開かない 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.Replace("&", "&&")); // 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) { 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, "更新されたソフトはありません", "ソフトの更新"); return; } InstallationConfirmForm confirm = new InstallationConfirmForm(); confirm.PkgListsManager = pkgListsMan; confirm.Installations = Installation.ConvertInstallations(pkgs.ToArray()); DialogResult result = confirm.ShowDialog(this); if (result == DialogResult.OK) { Installation[] insts = confirm.CheckedInstallations; if (confirm.UseRunas) { installRunasActionInvoke(insts); } else { installActionInvoke(insts); } UpdatePackageList(); } } public void UpdatePackageList() { pkgListsMan.LoadPackageLists(); this.PackageListViewUpdate(); } /// /// インストールするよう選択されたパッケージの配列 /// public TPackage[] SelectedPackages() where TPackage : Package { List pkgs = new List(); foreach (ListViewItem item in packageListView.SelectedItems) { pkgs.Add((TPackage) item.Tag); } return pkgs.ToArray(); } /// /// 自ウィンドウの有効無効(Enabled)を(必要あればInvokeして)実行する /// /// 有効か否か。Enabledの値に入れられる private void setWindowEnabled(bool enabled) { MethodInvoker process = (MethodInvoker) delegate() { this.Enabled = enabled; }; if (InvokeRequired) { Invoke(process); } else { process.Invoke(); } } } }