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("タグ: {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;
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();
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) { // インストール可能
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(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 = "リストの更新";
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 SearchTextBoxTextChanged(object sender, EventArgs e)
{
if (searchTextBox.Focused) {
searchTextBoxUpdate(false);
}
}
void SearchTextBoxKeyPress(object sender, KeyPressEventArgs e)
{
switch (e.KeyChar) {
case (char)Keys.Enter:
searchTextBoxUpdate(true);
break;
case (char)Keys.Escape:
searchTextBox.Text = "";
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();
searchUpdateTimer = null;
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("ソフトウェアのインストール");
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, "インストール", 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("ソフトウェアのアンインストール");
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, "アンインストール", 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)
{
// 選択されていないなら開かない
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, "更新されたソフトはありません", "ソフトの更新");
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();
}
///
/// インストールするよう選択されたパッケージの配列
///
public TPackage[] SelectedPackages() where TPackage : Package
{
List pkgs = new List();
foreach (ListViewItem item in packageListView.SelectedItems) {
pkgs.Add((TPackage) item.Tag);
}
return pkgs.ToArray();
}
}
}