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 instsListView.BeginUpdate();
\r
87 if (instsListView.Items.Count > 0) {
\r
88 instsListView.Items.Clear();
\r
91 addInstsListItemPerGroup(requiredInstallations, instsListView.Groups["requires"], true);
\r
92 addInstsListItemPerGroup(selectedInstallations, instsListView.Groups["install"], false);
\r
93 addInstsListItemPerGroup(updateInstallations, instsListView.Groups["update"], false);
\r
95 InstsListViewItemChecked(instsListView, null);
\r
96 updateSilentInstallAsPossibleCheckBox();
\r
98 instsListView.EndUpdate();
\r
102 /// 指定したグループのリストの表示を更新する。
\r
104 /// <param name="insts">インストールリスト</param>
\r
105 /// <param name="group">対象のグループ</param>
\r
106 /// <param name="firstAppend">先頭に追加するか</param>
\r
107 private void addInstsListItemPerGroup(IEnumerable<Installation> insts, ListViewGroup group, bool firstAppend)
\r
109 // まず所属グループのアイテムをすべて削除する
\r
110 if (insts == null) return;
\r
112 List<ListViewItem> itemsToAdd = new List<ListViewItem>();
\r
113 foreach (Installation inst in insts) {
\r
114 Package pkg = inst.InstalledPackage;
\r
116 string[] itemData = new string[instsListView.Columns.Count];
\r
117 itemData[nameColumnHeader.Index] = pkg.Name;
\r
119 inst.Silent = true; // silent install as possible!
\r
121 Package curPkg = null;
\r
122 if (pkgListMan != null) {
\r
123 curPkg = pkgListMan.InstalledPkgList.GetPackageForName(pkg.Name) ??
\r
124 pkgListMan.SystemInstalledPkgList.GetPackageForName(pkg.Name);
\r
126 itemData[versionColumnHeader.Index] = pkg.Version;
\r
127 itemData[currentVersionColumnHeader.Index] = (curPkg != null)? curPkg.Version : "-";
\r
128 // itemData[silentInstColumnHeader.Index] の設定は instViewUpdateSilentInstallView で
\r
129 itemData[pkgListNameColumnHeader.Index] = pkg.PackageListName;
\r
131 ListViewItem item = new ListViewItem(itemData);
\r
133 item.ToolTipText = pkg.Summary;
\r
134 item.Checked = true;
\r
135 item.Group = group;
\r
136 instViewUpdateSilentInstallView(item);
\r
138 itemsToAdd.Add(item);
\r
142 for (int i = 0; i < itemsToAdd.Count; i++) {
\r
143 instsListView.Items.Insert(i, itemsToAdd[i]);
\r
146 instsListView.Items.AddRange(itemsToAdd.ToArray());
\r
153 /// アイテムのサイレントインストール部分の表示の更新を行う。
\r
155 /// <param name="item">対象のインストーラーのリストアイテム</param>
\r
156 private void instViewUpdateSilentInstallView(ListViewItem item)
\r
158 Installation inst = (Installation) item.Tag;
\r
159 item.SubItems[silentInstColumnHeader.Index].Text =
\r
160 (inst.SupportsSilentOnly)? "サイレントインストールのみサポート" :
\r
161 (inst.Silent)? "サイレントインストール" :
\r
162 (inst.IsSupportsSilent)? "手動でインストール" :
\r
163 "サイレントインストールできませんので、手動でインストールします";
\r
166 #region instsListViewのオーナードドロー関連
\r
168 void InstsListViewDrawSubItem(object sender, DrawListViewSubItemEventArgs e)
\r
170 if (e.Header == silentInstColumnHeader) {
\r
171 Installation inst = ((Installation) e.Item.Tag);
\r
173 //e.DrawBackground();
\r
174 e.Graphics.Clip.Intersect(e.Bounds);
\r
177 AppliStation.Util.GUIUtils.Graphics_DrawCenterImage(
\r
179 instListViewSilentInstallImageList.Images[0],
\r
181 } else if (inst.IsSupportsSilent) {
\r
182 AppliStation.Util.GUIUtils.Graphics_DrawCenterImage(
\r
184 instListViewSilentInstallImageList.Images[0],
\r
186 AppliStation.Util.GUIUtils.GetImageAttributeToGrayOut(0.5f));
\r
189 e.DrawDefault = true;
\r
193 void InstsListViewDrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
\r
195 if (e.Header == silentInstColumnHeader) {
\r
196 e.DrawBackground();
\r
197 e.Graphics.Clip.Intersect(e.Bounds);
\r
198 AppliStation.Util.GUIUtils.Graphics_DrawCenterImage(
\r
200 instListViewSilentInstallImageList.Images[0],
\r
203 e.DrawDefault = true;
\r
211 void InstsListViewItemChecked(object sender, ItemCheckedEventArgs e)
\r
213 System.Windows.Forms.ListView.ListViewItemCollection items = instsListView.Items;
\r
214 System.Windows.Forms.ListView.CheckedListViewItemCollection checkeds = instsListView.CheckedItems;
\r
217 selectAllCheckBox.CheckState =
\r
218 (checkeds == null || checkeds.Count == 0)? CheckState.Unchecked :
\r
219 (checkeds.Count == items.Count)? CheckState.Checked :
\r
220 CheckState.Indeterminate;
\r
223 runasCheckBox.Checked = GetShouldUseRunas();
\r
227 okButton.Enabled = (checkeds != null) && (checkeds.Count > 0);
\r
229 checkUnselectedDependencies();
\r
232 void InstsListViewContextMenuStripOpening(object sender, System.ComponentModel.CancelEventArgs e)
\r
234 System.Windows.Forms.ListView.CheckedIndexCollection chkIdxes = instsListView.CheckedIndices;
\r
235 System.Windows.Forms.ListView.SelectedIndexCollection selIdxes = instsListView.SelectedIndices;
\r
237 silentInstallStripMenuItem.Visible = selIdxes.Count > 0;
\r
238 if (selIdxes.Count > 0) {
\r
239 Installation inst0th = ((Installation) instsListView.Items[selIdxes[0]].Tag);
\r
240 bool bChecked = inst0th.Silent;
\r
241 bool bEnabled = (inst0th.IsSupportsSilent && (!inst0th.SupportsSilentOnly));
\r
242 silentInstallStripMenuItem.Checked = bChecked;
\r
243 silentInstallStripMenuItem.Enabled = bEnabled;
\r
245 for (int i = 1; i < selIdxes.Count; i++) {
\r
246 Installation inst = ((Installation) instsListView.Items[selIdxes[i]].Tag);
\r
248 if ( (bChecked != inst.Silent) ||
\r
249 (bEnabled != (inst.IsSupportsSilent && (!inst.SupportsSilentOnly))) ) {
\r
250 silentInstallStripMenuItem.CheckState = CheckState.Indeterminate;
\r
251 silentInstallStripMenuItem.Enabled = false;
\r
260 void SilentInstallStripMenuItemClick(object sender, EventArgs e)
\r
262 instsListView.BeginUpdate();
\r
263 bool silent = ! silentInstallStripMenuItem.Checked;
\r
264 foreach (ListViewItem item in instsListView.SelectedItems) {
\r
265 ((Installation) item.Tag).Silent = silent;
\r
266 instViewUpdateSilentInstallView(item);
\r
268 updateSilentInstallAsPossibleCheckBox();
\r
269 instsListView.EndUpdate();
\r
272 void SelectAllCheckBoxCheckedChanged(object sender, EventArgs e)
\r
274 instsListView.BeginUpdate();
\r
275 if (selectAllCheckBox.CheckState == CheckState.Checked) {
\r
276 foreach (ListViewItem item in instsListView.Items) {
\r
277 item.Checked = true;
\r
280 if (selectAllCheckBox.CheckState == CheckState.Unchecked) {
\r
281 foreach (ListViewItem item in instsListView.Items) {
\r
282 item.Checked = false;
\r
285 instsListView.EndUpdate();
\r
288 void updateSilentInstallAsPossibleCheckBox()
\r
290 bool isAllSilentAsPossible = true;
\r
291 bool isAllNotSilentAsPossible = true;
\r
292 bool canChangeSilent = false;
\r
294 foreach (ListViewItem item in instsListView.Items) {
\r
295 Installation inst = item.Tag as Installation;
\r
296 if (inst != null) {
\r
298 isAllNotSilentAsPossible = false;
\r
299 if (! inst.SupportsSilentOnly) {
\r
300 canChangeSilent = true;
\r
303 isAllSilentAsPossible = false;
\r
304 if (inst.IsSupportsSilent) {
\r
305 canChangeSilent = true;
\r
311 silentInstallAsPossibleCheckBox.Enabled = canChangeSilent;
\r
312 silentInstallAsPossibleCheckBox.CheckState =
\r
313 (isAllSilentAsPossible)? CheckState.Checked :
\r
314 (isAllNotSilentAsPossible)? CheckState.Unchecked :
\r
315 CheckState.Indeterminate;
\r
318 void SilentInstallAsPossibleCheckBoxCheckedChanged(object sender, EventArgs e)
\r
320 instsListView.BeginUpdate();
\r
321 if (silentInstallAsPossibleCheckBox.CheckState == CheckState.Checked) {
\r
322 foreach (ListViewItem item in instsListView.Items) {
\r
323 Installation inst = item.Tag as Installation;
\r
324 if (inst != null) {
\r
325 if (inst.IsSupportsSilent && inst.Silent == false) {
\r
326 inst.Silent = true;
\r
327 instViewUpdateSilentInstallView(item);
\r
332 if (silentInstallAsPossibleCheckBox.CheckState == CheckState.Unchecked) {
\r
333 foreach (ListViewItem item in instsListView.Items) {
\r
334 Installation inst = item.Tag as Installation;
\r
335 if (inst != null) {
\r
336 if ((!inst.SupportsSilentOnly) && inst.Silent == true) {
\r
337 inst.Silent = false;
\r
338 instViewUpdateSilentInstallView(item);
\r
343 instsListView.EndUpdate();
\r
346 void InstallationConfirmFormShown(object sender, EventArgs e)
\r
348 if (InvokeRequired) {
\r
349 Invoke(new MethodInvoker(resolveDependecies));
\r
351 resolveDependecies();
\r
358 private void resolveDependecies()
\r
360 if (requiredInstallations == null) {
\r
361 Installation[] resolved, dependencies;
\r
363 instsListView.BeginUpdate();
\r
365 DependeciesResolver.ResolveInstallations(
\r
366 selectedInstallations,
\r
371 requiredInstallations = dependencies;
\r
373 addInstsListItemPerGroup(requiredInstallations, instsListView.Groups["requires"], true);
\r
375 InstsListViewItemChecked(instsListView, null);
\r
376 updateSilentInstallAsPossibleCheckBox();
\r
377 instsListView.EndUpdate();
\r
382 /// 依存関係を確認してGUIに反映させる。
\r
383 /// 選択されていないが依存関係上必要なソフトを探し出す。
\r
385 /// <returns>選択されていないが依存関係上必要なソフトの個数(何もない場合はゼロ)</returns>
\r
386 private uint checkUnselectedDependencies()
\r
390 List<Package> instPkgs = new List<Package>();
\r
391 foreach (Installation inst in Installations) {
\r
392 instPkgs.Add(inst.InstalledPackage);
\r
395 List<Package> pkg = new List<Package>();
\r
396 foreach (Installation inst in DependeciesResolver.CreateRequiresInstallations(CheckedInstallations, pkgListMan, instPkgs)) {
\r
397 pkg.Add(inst.InstalledPackage);
\r
400 foreach (ListViewItem item in instsListView.Items) {
\r
401 if ((pkg.IndexOf(((Installation) item.Tag).InstalledPackage) >= 0) && !item.Checked) {
\r
402 item.ForeColor = Color.Red;
\r
405 item.ForeColor = Color.Empty;
\r
413 /// インストールするよう選択されたパッケージの配列
\r
415 public Installation[] CheckedInstallations {
\r
417 List<Installation> insts = new List<Installation>();
\r
418 foreach (ListViewItem item in instsListView.CheckedItems) {
\r
419 insts.Add((Installation) item.Tag);
\r
421 return insts.ToArray();
\r
430 public bool UseRunas {
\r
432 runasCheckBox.Checked = (! NaGet.Utils.IsAdministrators()) && value;
\r
437 return runasCheckBox.Checked;
\r
442 /// 選択されたパッケージを調査して、Runasを使うべきかいなかを返す
\r
444 public bool GetShouldUseRunas()
\r
446 if (NaGet.Utils.IsAdministrators()) {
\r
447 // 管理者権限で動いている場合は不要
\r
449 } else if (NaGet.Utils.IsUACEnabled()) {
\r
450 // UACが適用されている場合は標準では不要とする
\r
454 // ひとつでもPCターゲットなインストーラーがあれば必要とする
\r
455 foreach (Installation inst in CheckedInstallations) {
\r
456 if (inst.TargetPC) return true;
\r
462 void RunasCheckBoxCheckedChanged(object sender, EventArgs e)
\r
467 private void updateUseRunas()
\r
469 AppliStation.Util.NativeMethods.Button_SetElevationRequiredState(okButton, UseRunas);
\r