2 using System.Collections.Generic;
\r
3 using System.Drawing;
\r
4 using System.Windows.Forms;
\r
5 using NaGet.Packages;
\r
6 using NaGet.Packages.Install;
\r
8 namespace AppliStation
\r
11 /// Description of PackagesInstallConfirmForm.
\r
13 public partial class InstallationConfirmForm : Form
\r
15 private Installation[] selectedInstallations = null;
\r
17 private Installation[] updateInstallations = null;
\r
19 private Installation[] requiredInstallations = null;
\r
21 private PackageListsManager pkgListMan;
\r
23 public IEnumerable<Installation> Installations {
\r
25 return NaGet.Utils.MergeEnumerable<Installation>(requiredInstallations, selectedInstallations);
\r
28 List<Installation> selectedInstList = new List<Installation>();
\r
29 List<Installation> updateInstList = new List<Installation>();
\r
31 requiredInstallations = null;
\r
32 foreach (Installation inst in value) {
\r
33 Package instPkg = pkgListMan.InstalledPkgList.GetPackageForName(inst.InstalledPackage.Name) ??
\r
34 pkgListMan.SystemInstalledPkgList.GetPackageForName(inst.InstalledPackage.Name);
\r
36 if (instPkg != null) {
\r
37 updateInstList.Add(inst);
\r
39 selectedInstList.Add(inst);
\r
42 selectedInstallations = selectedInstList.ToArray();
\r
43 updateInstallations = updateInstList.ToArray();
\r
45 updateInstsListView();
\r
49 public PackageListsManager PkgListsManager {
\r
50 get { return pkgListMan; }
\r
54 updateInstsListView();
\r
58 public InstallationConfirmForm()
\r
61 // The InitializeComponent() call is required for Windows Forms designer support.
\r
63 InitializeComponent();
\r
65 // 管理者権限で動いているならばrunasが必要にはならないので表示しない
\r
66 if (NaGet.Utils.IsAdministrators()) {
\r
67 runasCheckBox.Checked = false;
\r
68 runasCheckBox.Visible = false;
\r
72 AppliStation.Util.NativeMethods.ListView_EnableVistaExplorerTheme(instsListView);
\r
73 AppliStation.Util.NativeMethods.ListView_SetDoubleBuffer(instsListView, true);
\r
76 #region インストールリスト表示処理部
\r
78 #region インストールリストの反映
\r
81 /// インストールリストを更新したなどで、リストの表示を更新する
\r
83 private void updateInstsListView()
\r
85 if (instsListView.Items.Count > 0) {
\r
86 instsListView.Items.Clear();
\r
89 addInstsListItemPerGroup(requiredInstallations, instsListView.Groups["requires"], true);
\r
90 addInstsListItemPerGroup(selectedInstallations, instsListView.Groups["install"], false);
\r
91 addInstsListItemPerGroup(updateInstallations, instsListView.Groups["update"], false);
\r
93 InstsListViewItemChecked(instsListView, null);
\r
94 instsListView.Refresh();
\r
98 /// 指定したグループのリストの表示を更新する。
\r
100 /// <param name="insts">インストールリスト</param>
\r
101 /// <param name="group">対象のグループ</param>
\r
102 /// <param name="firstAppend">先頭に追加するか</param>
\r
103 private void addInstsListItemPerGroup(IEnumerable<Installation> insts, ListViewGroup group, bool firstAppend)
\r
105 // まず所属グループのアイテムをすべて削除する
\r
106 if (insts == null) return;
\r
108 List<ListViewItem> itemsToAdd = new List<ListViewItem>();
\r
109 foreach (Installation inst in insts) {
\r
110 Package pkg = inst.InstalledPackage;
\r
112 string[] itemData = new string[instsListView.Columns.Count];
\r
113 itemData[nameColumnHeader.Index] = pkg.Name;
\r
115 inst.Silent = true; // silent install as possible!
\r
117 Package curPkg = null;
\r
118 if (pkgListMan != null) {
\r
119 curPkg = pkgListMan.InstalledPkgList.GetPackageForName(pkg.Name) ??
\r
120 pkgListMan.SystemInstalledPkgList.GetPackageForName(pkg.Name);
\r
122 itemData[versionColumnHeader.Index] = pkg.Version;
\r
123 itemData[currentVersionColumnHeader.Index] = (curPkg != null)? curPkg.Version : "-";
\r
124 // itemData[silentInstColumnHeader.Index] の設定は instViewUpdateSilentInstallView で
\r
125 itemData[pkgListNameColumnHeader.Index] = pkg.PackageListName;
\r
127 ListViewItem item = new ListViewItem(itemData);
\r
129 item.ToolTipText = pkg.Summary;
\r
130 item.Checked = true;
\r
131 item.Group = group;
\r
132 instViewUpdateSilentInstallView(item);
\r
134 itemsToAdd.Add(item);
\r
138 for (int i = 0; i < itemsToAdd.Count; i++) {
\r
139 instsListView.Items.Insert(i, itemsToAdd[i]);
\r
142 instsListView.Items.AddRange(itemsToAdd.ToArray());
\r
149 /// アイテムのサイレントインストール部分の表示の更新を行う。
\r
151 /// <param name="item">対象のインストーラのリストアイテム</param>
\r
152 private void instViewUpdateSilentInstallView(ListViewItem item)
\r
154 Installation inst = (Installation) item.Tag;
\r
155 item.SubItems[silentInstColumnHeader.Index].Text =
\r
156 (inst.SupportsSilentOnly)? "サイレントインストールのみサポート" :
\r
157 (inst.Silent)? "サイレントインストール" :
\r
158 (inst.IsSupportsSilent)? "手動でインストール" :
\r
159 "サイレントインストールできませんので、手動でインストールします";
\r
162 #region instsListViewのオーナードドロー関連
\r
164 void InstsListViewDrawSubItem(object sender, DrawListViewSubItemEventArgs e)
\r
166 if (e.Header == silentInstColumnHeader) {
\r
167 Installation inst = ((Installation) e.Item.Tag);
\r
169 //e.DrawBackground();
\r
170 e.Graphics.Clip.Intersect(e.Bounds);
\r
173 AppliStation.Util.GUIUtils.Graphics_DrawCenterImage(
\r
175 instListViewSilentInstallImageList.Images[0],
\r
177 } else if (inst.IsSupportsSilent) {
\r
178 AppliStation.Util.GUIUtils.Graphics_DrawCenterImage(
\r
180 instListViewSilentInstallImageList.Images[0],
\r
182 AppliStation.Util.GUIUtils.GetImageAttributeToGrayOut(0.5f));
\r
185 e.DrawDefault = true;
\r
189 void InstsListViewDrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
\r
191 if (e.Header == silentInstColumnHeader) {
\r
192 e.DrawBackground();
\r
193 e.Graphics.Clip.Intersect(e.Bounds);
\r
194 AppliStation.Util.GUIUtils.Graphics_DrawCenterImage(
\r
196 instListViewSilentInstallImageList.Images[0],
\r
199 e.DrawDefault = true;
\r
207 void InstsListViewItemChecked(object sender, ItemCheckedEventArgs e)
\r
209 System.Windows.Forms.ListView.CheckedListViewItemCollection checkeds = instsListView.CheckedItems;
\r
211 runasCheckBox.Checked = GetShouldUseRunas();
\r
214 okButton.Enabled = (checkeds != null) && (checkeds.Count > 0);
\r
216 checkUnselectedDependencies();
\r
219 void InstsListViewContextMenuStripOpening(object sender, System.ComponentModel.CancelEventArgs e)
\r
221 System.Windows.Forms.ListView.CheckedIndexCollection chkIdxes = instsListView.CheckedIndices;
\r
222 System.Windows.Forms.ListView.SelectedIndexCollection selIdxes = instsListView.SelectedIndices;
\r
224 silentInstallStripMenuItem.Visible = selIdxes.Count > 0;
\r
225 if (selIdxes.Count > 0) {
\r
226 Installation inst0th = ((Installation) instsListView.Items[selIdxes[0]].Tag);
\r
227 bool bChecked = inst0th.Silent;
\r
228 bool bEnabled = (inst0th.IsSupportsSilent && (!inst0th.SupportsSilentOnly));
\r
229 silentInstallStripMenuItem.Checked = bChecked;
\r
230 silentInstallStripMenuItem.Enabled = bEnabled;
\r
232 for (int i = 1; i < selIdxes.Count; i++) {
\r
233 Installation inst = ((Installation) instsListView.Items[selIdxes[i]].Tag);
\r
235 if ( (bChecked != inst.Silent) ||
\r
236 (bEnabled != (inst.IsSupportsSilent && (!inst.SupportsSilentOnly))) ) {
\r
237 silentInstallStripMenuItem.CheckState = CheckState.Indeterminate;
\r
238 silentInstallStripMenuItem.Enabled = false;
\r
243 instListToolStripSeparator.Visible = selIdxes.Count > 0;
\r
246 selectAllInstsStripMenuItem.Enabled = chkIdxes.Count < instsListView.Items.Count;
\r
247 unselectAllInstsStripMenuItem.Enabled = chkIdxes.Count > 0;
\r
250 void SilentInstallStripMenuItemClick(object sender, EventArgs e)
\r
252 bool silent = ! silentInstallStripMenuItem.Checked;
\r
253 foreach (ListViewItem item in instsListView.SelectedItems) {
\r
254 ((Installation) item.Tag).Silent = silent;
\r
255 instViewUpdateSilentInstallView(item);
\r
259 void SelectAllInstsStripMenuItemClick(object sender, EventArgs e)
\r
261 foreach (ListViewItem item in instsListView.Items) {
\r
262 item.Checked = true;
\r
264 instsListView.Refresh();
\r
267 void UnselectAllInstsStripMenuItemClick(object sender, EventArgs e)
\r
269 foreach (ListViewItem item in instsListView.CheckedItems) {
\r
270 item.Checked = false;
\r
272 instsListView.Refresh();
\r
275 void InstallationConfirmFormShown(object sender, EventArgs e)
\r
277 if (InvokeRequired) {
\r
278 Invoke(new MethodInvoker(resolveDependecies));
\r
280 resolveDependecies();
\r
287 private void resolveDependecies()
\r
289 if (requiredInstallations == null) {
\r
290 Installation[] resolved, dependencies;
\r
292 DependeciesResolver.ResolveInstallations(
\r
293 selectedInstallations,
\r
298 requiredInstallations = dependencies;
\r
300 addInstsListItemPerGroup(requiredInstallations, instsListView.Groups["requires"], true);
\r
302 InstsListViewItemChecked(instsListView, null);
\r
303 instsListView.Refresh();
\r
308 /// 依存関係を確認してGUIに反映させる。
\r
309 /// 選択されていないが依存関係上必要なソフトを探し出す。
\r
311 /// <returns>選択されていないが依存関係上必要なソフトの個数(何もない場合はゼロ)</returns>
\r
312 private uint checkUnselectedDependencies()
\r
316 List<Package> instPkgs = new List<Package>();
\r
317 foreach (Installation inst in Installations) {
\r
318 instPkgs.Add(inst.InstalledPackage);
\r
321 List<Package> pkg = new List<Package>();
\r
322 foreach (Installation inst in DependeciesResolver.CreateRequiresInstallations(CheckedInstallations, pkgListMan, instPkgs)) {
\r
323 pkg.Add(inst.InstalledPackage);
\r
326 foreach (ListViewItem item in instsListView.Items) {
\r
327 if ((pkg.IndexOf(((Installation) item.Tag).InstalledPackage) >= 0) && !item.Checked) {
\r
328 item.ForeColor = Color.Red;
\r
331 item.ForeColor = Color.Empty;
\r
339 /// インストールするよう選択されたパッケージの配列
\r
341 public Installation[] CheckedInstallations {
\r
343 List<Installation> insts = new List<Installation>();
\r
344 foreach (ListViewItem item in instsListView.CheckedItems) {
\r
345 insts.Add((Installation) item.Tag);
\r
347 return insts.ToArray();
\r
356 public bool UseRunas {
\r
358 runasCheckBox.Checked = (! NaGet.Utils.IsAdministrators()) && value;
\r
363 return runasCheckBox.Checked;
\r
368 /// 選択されたパッケージを調査して、Runasを使うべきかいなかを返す
\r
370 public bool GetShouldUseRunas()
\r
372 if (NaGet.Utils.IsAdministrators()) {
\r
373 // 管理者権限で動いている場合は不要
\r
375 } else if (NaGet.Utils.IsUACEnabled()) {
\r
376 // UACが適用されている場合は標準では不要とする
\r
380 // ひとつでもPCターゲットなインストーラがあれば必要とする
\r
381 foreach (Installation inst in CheckedInstallations) {
\r
382 if (inst.TargetPC) return true;
\r
388 void RunasCheckBoxCheckedChanged(object sender, EventArgs e)
\r
393 private void updateUseRunas()
\r
395 AppliStation.Util.NativeMethods.Button_SetElevationRequiredState(okButton, UseRunas);
\r