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 private ushort instslistviewitemcheckedguardcounter = 0;
\r
25 public IEnumerable<Installation> Installations {
\r
27 return NaGet.Utils.MergeEnumerable<Installation>(requiredInstallations, selectedInstallations);
\r
30 List<Installation> selectedInstList = new List<Installation>();
\r
31 List<Installation> updateInstList = new List<Installation>();
\r
33 requiredInstallations = null;
\r
34 foreach (Installation inst in value) {
\r
35 Package instPkg = pkgListMan.InstalledPkgList.GetPackageForName(inst.InstalledPackage.Name) ??
\r
36 pkgListMan.SystemInstalledPkgList.GetPackageForName(inst.InstalledPackage.Name);
\r
38 if (instPkg != null) {
\r
39 updateInstList.Add(inst);
\r
41 selectedInstList.Add(inst);
\r
44 selectedInstallations = selectedInstList.ToArray();
\r
45 updateInstallations = updateInstList.ToArray();
\r
47 updateInstsListView();
\r
51 public PackageListsManager PkgListsManager {
\r
52 get { return pkgListMan; }
\r
56 updateInstsListView();
\r
60 public InstallationConfirmForm()
\r
63 // The InitializeComponent() call is required for Windows Forms designer support.
\r
65 InitializeComponent();
\r
67 // 管理者権限で動いているならばrunasが必要にはならないので表示しない
\r
68 if (NaGet.Utils.IsAdministrators()) {
\r
69 runasCheckBox.Checked = false;
\r
70 runasCheckBox.Visible = false;
\r
74 AppliStation.Util.NativeMethods.ListView_EnableVistaExplorerTheme(instsListView);
\r
75 AppliStation.Util.NativeMethods.ListView_SetDoubleBuffer(instsListView, true);
\r
78 #region インストールリスト表示処理部
\r
80 #region インストールリストの反映
\r
83 /// インストールリストを更新したなどで、リストの表示を更新する
\r
85 private void updateInstsListView()
\r
87 instsListView.BeginUpdate();
\r
89 if (instsListView.Items.Count > 0) {
\r
90 instsListView.Items.Clear();
\r
93 addInstsListItemPerGroup(requiredInstallations, instsListView.Groups["requires"], true);
\r
94 addInstsListItemPerGroup(selectedInstallations, instsListView.Groups["install"], false);
\r
95 addInstsListItemPerGroup(updateInstallations, instsListView.Groups["update"], false);
\r
97 updateCheckBoxStatuses();
\r
98 updateSilentInstallAsPossibleCheckBox();
\r
100 instsListView.EndUpdate();
\r
104 /// 指定したグループのリストの表示を更新する。
\r
106 /// <param name="insts">インストールリスト</param>
\r
107 /// <param name="group">対象のグループ</param>
\r
108 /// <param name="firstAppend">先頭に追加するか</param>
\r
109 private void addInstsListItemPerGroup(IEnumerable<Installation> insts, ListViewGroup group, bool firstAppend)
\r
111 // まず所属グループのアイテムをすべて削除する
\r
112 if (insts == null) return;
\r
114 instsListView.BeginUpdate();
\r
116 List<ListViewItem> itemsToAdd = new List<ListViewItem>();
\r
117 foreach (Installation inst in insts) {
\r
118 Package pkg = inst.InstalledPackage;
\r
120 string[] itemData = new string[instsListView.Columns.Count];
\r
121 itemData[nameColumnHeader.Index] = pkg.Name;
\r
123 inst.Silent = true; // silent install as possible!
\r
125 Package curPkg = null;
\r
126 if (pkgListMan != null) {
\r
127 curPkg = pkgListMan.InstalledPkgList.GetPackageForName(pkg.Name) ??
\r
128 pkgListMan.SystemInstalledPkgList.GetPackageForName(pkg.Name);
\r
130 itemData[versionColumnHeader.Index] = pkg.Version;
\r
131 itemData[currentVersionColumnHeader.Index] = (curPkg != null)? curPkg.Version : "-";
\r
132 // itemData[silentInstColumnHeader.Index] の設定は instViewUpdateSilentInstallView で
\r
133 itemData[pkgListNameColumnHeader.Index] = pkg.PackageListName;
\r
135 ListViewItem item = new ListViewItem(itemData);
\r
137 item.ToolTipText = pkg.Summary;
\r
138 item.Checked = true;
\r
139 item.Group = group;
\r
140 instViewUpdateSilentInstallView(item);
\r
142 itemsToAdd.Add(item);
\r
146 for (int i = 0; i < itemsToAdd.Count; i++) {
\r
147 instsListView.Items.Insert(i, itemsToAdd[i]);
\r
150 instsListView.Items.AddRange(itemsToAdd.ToArray());
\r
153 instsListView.EndUpdate();
\r
159 /// アイテムのサイレントインストール部分の表示の更新を行う。
\r
161 /// <param name="item">対象のインストーラーのリストアイテム</param>
\r
162 private void instViewUpdateSilentInstallView(ListViewItem item)
\r
164 Installation inst = (Installation) item.Tag;
\r
165 item.SubItems[silentInstColumnHeader.Index].Text =
\r
166 (inst.SupportsSilentOnly)? "サイレントインストールのみサポート" :
\r
167 (inst.Silent)? "サイレントインストール" :
\r
168 (inst.IsSupportsSilent)? "手動でインストール" :
\r
169 "サイレントインストールできませんので、手動でインストールします";
\r
172 #region instsListViewのオーナードドロー関連
\r
174 void InstsListViewDrawSubItem(object sender, DrawListViewSubItemEventArgs e)
\r
176 if (e.Header == silentInstColumnHeader) {
\r
177 Installation inst = ((Installation) e.Item.Tag);
\r
179 //e.DrawBackground();
\r
180 e.Graphics.Clip.Intersect(e.Bounds);
\r
183 AppliStation.Util.GUIUtils.Graphics_DrawCenterImage(
\r
185 instListViewSilentInstallImageList.Images[0],
\r
187 } else if (inst.IsSupportsSilent) {
\r
188 AppliStation.Util.GUIUtils.Graphics_DrawCenterImage(
\r
190 instListViewSilentInstallImageList.Images[0],
\r
192 AppliStation.Util.GUIUtils.GetImageAttributeToGrayOut(0.5f));
\r
195 e.DrawDefault = true;
\r
199 void InstsListViewDrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
\r
201 if (e.Header == silentInstColumnHeader) {
\r
202 e.DrawBackground();
\r
203 e.Graphics.Clip.Intersect(e.Bounds);
\r
204 AppliStation.Util.GUIUtils.Graphics_DrawCenterImage(
\r
206 instListViewSilentInstallImageList.Images[0],
\r
209 e.DrawDefault = true;
\r
217 private void updateCheckBoxStatuses()
\r
219 System.Windows.Forms.ListView.ListViewItemCollection items = instsListView.Items;
\r
220 System.Windows.Forms.ListView.CheckedListViewItemCollection checkeds = instsListView.CheckedItems;
\r
222 instslistviewitemcheckedguardcounter ++;
\r
225 selectAllCheckBox.CheckState =
\r
226 (checkeds == null || checkeds.Count == 0)? CheckState.Unchecked :
\r
227 (checkeds.Count == items.Count)? CheckState.Checked :
\r
228 CheckState.Indeterminate;
\r
231 runasCheckBox.Checked = GetShouldUseRunas();
\r
235 okButton.Enabled = (checkeds != null) && (checkeds.Count > 0);
\r
237 checkUnselectedDependencies();
\r
239 instslistviewitemcheckedguardcounter --;
\r
242 void InstsListViewItemChecked(object sender, ItemCheckedEventArgs e)
\r
244 if (instslistviewitemcheckedguardcounter == 0) {
\r
245 updateCheckBoxStatuses();
\r
249 void InstsListViewContextMenuStripOpening(object sender, System.ComponentModel.CancelEventArgs e)
\r
251 System.Windows.Forms.ListView.CheckedIndexCollection chkIdxes = instsListView.CheckedIndices;
\r
252 System.Windows.Forms.ListView.SelectedIndexCollection selIdxes = instsListView.SelectedIndices;
\r
254 silentInstallStripMenuItem.Visible = selIdxes.Count > 0;
\r
255 if (selIdxes.Count > 0) {
\r
256 Installation inst0th = ((Installation) instsListView.Items[selIdxes[0]].Tag);
\r
257 bool bChecked = inst0th.Silent;
\r
258 bool bEnabled = (inst0th.IsSupportsSilent && (!inst0th.SupportsSilentOnly));
\r
259 silentInstallStripMenuItem.Checked = bChecked;
\r
260 silentInstallStripMenuItem.Enabled = bEnabled;
\r
262 for (int i = 1; i < selIdxes.Count; i++) {
\r
263 Installation inst = ((Installation) instsListView.Items[selIdxes[i]].Tag);
\r
265 if ( (bChecked != inst.Silent) ||
\r
266 (bEnabled != (inst.IsSupportsSilent && (!inst.SupportsSilentOnly))) ) {
\r
267 silentInstallStripMenuItem.CheckState = CheckState.Indeterminate;
\r
268 silentInstallStripMenuItem.Enabled = false;
\r
277 void SilentInstallStripMenuItemClick(object sender, EventArgs e)
\r
279 instsListView.BeginUpdate();
\r
280 bool silent = ! silentInstallStripMenuItem.Checked;
\r
281 foreach (ListViewItem item in instsListView.SelectedItems) {
\r
282 ((Installation) item.Tag).Silent = silent;
\r
283 instViewUpdateSilentInstallView(item);
\r
285 updateSilentInstallAsPossibleCheckBox();
\r
286 instsListView.EndUpdate();
\r
289 void SelectAllCheckBoxCheckedChanged(object sender, EventArgs e)
\r
291 instsListView.BeginUpdate();
\r
293 instslistviewitemcheckedguardcounter ++;
\r
295 if (selectAllCheckBox.CheckState == CheckState.Checked) {
\r
296 foreach (ListViewItem item in instsListView.Items) {
\r
297 item.Checked = true;
\r
300 if (selectAllCheckBox.CheckState == CheckState.Unchecked) {
\r
301 foreach (ListViewItem item in instsListView.Items) {
\r
302 item.Checked = false;
\r
306 instslistviewitemcheckedguardcounter --;
\r
308 updateCheckBoxStatuses();
\r
310 instsListView.EndUpdate();
\r
313 void updateSilentInstallAsPossibleCheckBox()
\r
315 bool isAllSilentAsPossible = true;
\r
316 bool isAllNotSilentAsPossible = true;
\r
317 bool canChangeSilent = false;
\r
319 foreach (ListViewItem item in instsListView.Items) {
\r
320 Installation inst = item.Tag as Installation;
\r
321 if (inst != null) {
\r
323 if (! inst.SupportsSilentOnly) {
\r
324 isAllNotSilentAsPossible = false;
\r
325 canChangeSilent = true;
\r
328 if (inst.IsSupportsSilent) {
\r
329 isAllSilentAsPossible = false;
\r
330 canChangeSilent = true;
\r
336 silentInstallAsPossibleCheckBox.Enabled = canChangeSilent;
\r
337 silentInstallAsPossibleCheckBox.CheckState =
\r
338 (isAllSilentAsPossible)? CheckState.Checked :
\r
339 (isAllNotSilentAsPossible)? CheckState.Unchecked :
\r
340 CheckState.Indeterminate;
\r
343 void SilentInstallAsPossibleCheckBoxCheckedChanged(object sender, EventArgs e)
\r
345 instsListView.BeginUpdate();
\r
346 if (silentInstallAsPossibleCheckBox.CheckState == CheckState.Checked) {
\r
347 foreach (ListViewItem item in instsListView.Items) {
\r
348 Installation inst = item.Tag as Installation;
\r
349 if (inst != null) {
\r
350 if (inst.IsSupportsSilent && inst.Silent == false) {
\r
351 inst.Silent = true;
\r
352 instViewUpdateSilentInstallView(item);
\r
357 if (silentInstallAsPossibleCheckBox.CheckState == CheckState.Unchecked) {
\r
358 foreach (ListViewItem item in instsListView.Items) {
\r
359 Installation inst = item.Tag as Installation;
\r
360 if (inst != null) {
\r
361 if ((!inst.SupportsSilentOnly) && inst.Silent == true) {
\r
362 inst.Silent = false;
\r
363 instViewUpdateSilentInstallView(item);
\r
368 instsListView.EndUpdate();
\r
371 void InstallationConfirmFormShown(object sender, EventArgs e)
\r
373 if (InvokeRequired) {
\r
374 Invoke(new MethodInvoker(resolveDependecies));
\r
376 resolveDependecies();
\r
383 private void resolveDependecies()
\r
385 if (requiredInstallations == null) {
\r
386 Installation[] resolved, dependencies;
\r
388 instsListView.BeginUpdate();
\r
390 DependeciesResolver.ResolveInstallations(
\r
391 selectedInstallations,
\r
396 requiredInstallations = dependencies;
\r
398 addInstsListItemPerGroup(requiredInstallations, instsListView.Groups["requires"], true);
\r
400 updateCheckBoxStatuses();
\r
401 updateSilentInstallAsPossibleCheckBox();
\r
402 instsListView.EndUpdate();
\r
407 /// 依存関係を確認してGUIに反映させる。
\r
408 /// 選択されていないが依存関係上必要なソフトを探し出す。
\r
410 /// <returns>選択されていないが依存関係上必要なソフトの個数(何もない場合はゼロ)</returns>
\r
411 private uint checkUnselectedDependencies()
\r
415 List<Package> instPkgs = new List<Package>();
\r
416 foreach (Installation inst in Installations) {
\r
417 instPkgs.Add(inst.InstalledPackage);
\r
420 List<Package> pkg = new List<Package>();
\r
421 foreach (Installation inst in DependeciesResolver.CreateRequiresInstallations(CheckedInstallations, pkgListMan, instPkgs)) {
\r
422 pkg.Add(inst.InstalledPackage);
\r
425 foreach (ListViewItem item in instsListView.Items) {
\r
426 if ((pkg.IndexOf(((Installation) item.Tag).InstalledPackage) >= 0) && !item.Checked) {
\r
427 item.ForeColor = Color.Red;
\r
430 item.ForeColor = Color.Empty;
\r
438 /// インストールするよう選択されたパッケージの配列
\r
440 public Installation[] CheckedInstallations {
\r
442 List<Installation> insts = new List<Installation>();
\r
443 foreach (ListViewItem item in instsListView.CheckedItems) {
\r
444 insts.Add((Installation) item.Tag);
\r
446 return insts.ToArray();
\r
455 public bool UseRunas {
\r
457 runasCheckBox.Checked = (! NaGet.Utils.IsAdministrators()) && value;
\r
462 return runasCheckBox.Checked;
\r
467 /// 選択されたパッケージを調査して、Runasを使うべきかいなかを返す
\r
469 public bool GetShouldUseRunas()
\r
471 if (NaGet.Utils.IsAdministrators()) {
\r
472 // 管理者権限で動いている場合は不要
\r
474 } else if (NaGet.Utils.IsUACEnabled()) {
\r
475 // UACが適用されている場合は標準では不要とする
\r
479 // ひとつでもPCターゲットなインストーラーがあれば必要とする
\r
480 foreach (Installation inst in CheckedInstallations) {
\r
481 if (inst.TargetPC) return true;
\r
487 void RunasCheckBoxCheckedChanged(object sender, EventArgs e)
\r
492 private void updateUseRunas()
\r
494 AppliStation.Util.NativeMethods.Button_SetElevationRequiredState(okButton, UseRunas);
\r