set {\r
installedPackage = value;\r
\r
+ installerIndex = getPreferInstallerIndex(value);\r
installerFile = getArchiveFilePath();\r
- installerIndex = GetPreferInstallerIndex(value);\r
}\r
}\r
\r
/// <summary>\r
- /// (保存される)インストーラのファイルのパス\r
+ /// (ä¿\9då\98ã\81\95ã\82\8cã\82\8b)ã\83¼ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83©ã\81®ã\83\95ã\82¡ã\82¤ã\83«ã\81®ã\83\91ã\82¹\r
/// </summary>\r
private string installerFile;\r
\r
private bool silent = false;\r
\r
/// <summary>\r
- /// 起動するインストーラのインデックス番号\r
+ /// èµ·å\8b\95ã\81\99ã\82\8bã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83©ã\83¼ã\81®ã\82¤ã\83³ã\83\87ã\83\83ã\82¯ã\82¹ç\95ªå\8f·\r
/// </summary>\r
protected int installerIndex = 0;\r
\r
}\r
\r
/// <summary>\r
+ /// インストーラーファイルを取得する\r
+ /// </summary>\r
+ public string InstallerFile {\r
+ get { return installerFile; }\r
+ }\r
+ \r
+ \r
+ #region インストール状態チェック関連\r
+ \r
+ /// <summary>\r
/// インストール可能か否か\r
/// </summary>\r
public bool IsInstallablePackage()\r
}\r
\r
/// <summary>\r
- /// インストーラの処理が成功してインストールされたプログラムが確認できるか否か。\r
+ /// ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83©ã\83¼ã\81®å\87¦ç\90\86ã\81\8cæ\88\90å\8a\9fã\81\97ã\81¦ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83«ã\81\95ã\82\8cã\81\9fã\83\97ã\83ã\82°ã\83©ã\83 ã\81\8c確èª\8dã\81§ã\81\8dã\82\8bã\81\8bå\90¦ã\81\8bã\80\82\r
/// </summary>\r
public bool InstallSuccessed {\r
get {\r
switch (InstalledPackage.Type) {\r
- case InstallerType.ARCHIVE: // アーカイブインストーラはフォルダの確認\r
+ case InstallerType.ARCHIVE:\r
+ case InstallerType.ITSELF:\r
+ // アーカイブインストーラーおよび配布exeそれ自身が実行ファイルのとき、\r
+ // (AppliStationの作る)プログラムフォルダーの存在のみで確認を行う。\r
return Directory.Exists(Path.Combine(NaGet.Env.ArchiveProgramFiles, InstalledPackage.Name));\r
case InstallerType.EXEC_INSTALLER:\r
case InstallerType.MSI_PACKAGE:\r
get {\r
switch (InstalledPackage.Type) {\r
case InstallerType.ARCHIVE:\r
+ case InstallerType.ITSELF:\r
case InstallerType.MSI_PACKAGE:\r
return true;\r
+ case InstallerType.EXEC_INSTALLER:\r
+ return ! string.IsNullOrEmpty(InstalledPackage.SilentInstallArguments);\r
default:\r
return false;\r
}\r
/// サイレントインストールだけをサポートしているか否か\r
/// </summary>\r
public bool SupportsSilentOnly {\r
- get { return InstalledPackage.Type == InstallerType.ARCHIVE; }\r
+ get {\r
+ return (InstalledPackage.Type == InstallerType.ARCHIVE)\r
+ || (InstalledPackage.Type == InstallerType.ITSELF);\r
+ }\r
}\r
\r
/// <summary>\r
/// </summary>\r
/// <remark>RunAsが必要か否かの判断にしようされる</remark>\r
public bool TargetPC {\r
- get { return InstalledPackage.Type != InstallerType.ARCHIVE; }\r
+ get {\r
+ return (InstalledPackage.Type != InstallerType.ARCHIVE)\r
+ && (InstalledPackage.Type != InstallerType.ITSELF);\r
+ }\r
}\r
\r
+ #endregion\r
+ \r
/// <summary>\r
/// ダウンロードを行う。\r
/// </summary>\r
File.Move(installerFile, newFile);\r
installerFile = newFile;\r
}\r
+ \r
+ // 権限を親フォルダーに落とす\r
+ try {\r
+ string targetDir = Path.GetDirectoryName(installerFile);\r
+ NaGet.Utils.SetAccessControlRecursive(targetDir, File.GetAccessControl(Path.GetDirectoryName(targetDir)));\r
+ } catch (Exception) {} // 失敗時は何もしない\r
+ }\r
+ }\r
+ \r
+ /// <summary>\r
+ /// インストーラーファイルをスキャンする\r
+ /// </summary>\r
+ /// <remarks>ウイルスのため退避・削除されたときも例外を投げずにあたかも正常かのように動作しえます。</remarks>\r
+ /// <exception cref="ComException">スキャンで意図せぬ動作があったとき</exception>\r
+ /// <param name="scanner">スキャナーオブジェクト</param>\r
+ /// <returns>スキャン結果</returns>\r
+ public DownloadScannerResult ScanInstallerFile(DownloadScanner scanner)\r
+ {\r
+ DownloadScannerResult result;\r
+ Exception e = null;\r
+ try {\r
+ result = scanner.Scan(installerFile, InstalledPackage.Installer[installerIndex].Url.Href);\r
+ } catch (Exception ex) {\r
+ result = DownloadScannerResult.ScannerNotFound;\r
+ e = ex;\r
+ }\r
+ \r
+ if ( e != null ) {\r
+ // ファイルが消されていないが例外が発生していたときは、その例外を投げる\r
+ throw e;\r
+ } else {\r
+ return result;\r
}\r
}\r
\r
try {\r
switch (type) {\r
case InstallerType.EXEC_INSTALLER:\r
- hProcess = Process.Start(installerfile);\r
+ if (Silent) {\r
+ hProcess = Process.Start(installerfile, InstalledPackage.SilentInstallArguments);\r
+ } else {\r
+ hProcess = Process.Start(installerfile);\r
+ }\r
\r
break;\r
case InstallerType.MSI_PACKAGE:\r
hProcess = Process.Start("msiexec", msiexecArgs);\r
break;\r
case InstallerType.ARCHIVE:\r
+ case InstallerType.ITSELF:\r
string argument = string.Format("-i \"{0}\" \"{1}\"", installerfile, this.InstalledPackage.Name);\r
hProcess = createExtractArchiveProcess(argument,\r
this.OutputDataReceived,\r
this.ErrorDataReceived);\r
+ // Note: ARCHIVEかITSELFの判断はarchive-instが行う\r
break;\r
default:\r
throw new NotImplementedException("Not implemented archive installation yet");\r
}\r
+ \r
+ if (NaGet.Env.InstallProcessOnBackground) {\r
+ try {\r
+ hProcess.PriorityClass = ProcessPriorityClass.Idle;\r
+ } catch (Exception) {}\r
+ }\r
+ \r
hProcess.WaitForExit();\r
\r
return hProcess.ExitCode;\r
}\r
\r
/// <summary>\r
- /// インストーラ等を起動してインストール作業を行う\r
+ /// インストーラー等を起動してインストール作業を行う\r
/// </summary>\r
- /// <returns>インストーラの終了コード</returns>\r
+ /// <returns>ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83©ã\83¼ã\81®çµ\82äº\86ã\82³ã\83¼ã\83\89</returns>\r
public int Install()\r
{\r
string installerFile = this.installerFile;\r
using (Process hProcess = createExtractArchiveProcess(argument,\r
this.OutputDataReceived,\r
this.ErrorDataReceived)) {\r
+ if (NaGet.Env.InstallProcessOnBackground) {\r
+ try {\r
+ hProcess.PriorityClass = ProcessPriorityClass.Idle;\r
+ } catch (Exception) {}\r
+ }\r
+ \r
hProcess.WaitForExit();\r
\r
if (hProcess.ExitCode != 0) {\r
}\r
}\r
\r
- \r
int exitCode = invokeInstaller(installerFile, InstalledPackage.Type);\r
\r
installed = true;\r
return exitCode;\r
}\r
\r
+ #region インストーラーファイル設定時の処理\r
+ \r
/// <summary>\r
- /// もっともふさわしいインストーラ番号を返す\r
+ /// もっともふさわしいインストーラー番号を返す\r
/// </summary>\r
/// <returns></returns>\r
- public static int GetPreferInstallerIndex(Package InstalledPackage)\r
+ private static int getPreferInstallerIndex(Package InstalledPackage)\r
{\r
if (InstalledPackage.Type == InstallerType.CANNOT_INSTALL) { // インストール不能パッケージ\r
return -1;\r
}\r
\r
/// <summary>\r
- /// ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83©ã\81®ä¸\80æ\99\82保存先パスを生成\r
+ /// ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83©ã\83¼ã\81®保存先パスを生成\r
/// </summary>\r
+ /// <remarks>installerIndexが求まっているものとして仮定して処理する</remarks>\r
private string getArchiveFilePath()\r
{\r
Package package = this.InstalledPackage;\r
\r
string folderName = string.Format("{0}({1})", package.Name, package.Version);\r
- string fileName = NaGet.Utils.Url2filename(package.Installer[0].Url.Href);\r
+ string subFolderName = string.Format("installer.{0}", (installerIndex >= 0)? installerIndex.ToString("D") : "X");\r
+ string fileName = NaGet.Utils.Url2filename(new Uri(package.Installer[0].Url.Href));\r
\r
- string folder = Path.Combine(NaGet.Env.ArchiveFolderPath, folderName);\r
+ string folder = Path.Combine(NaGet.Env.ArchiveFolderPath, Path.Combine(folderName, subFolderName));\r
\r
if (! File.Exists(Path.Combine(folder, fileName))) {\r
if (Directory.Exists(folder)) {\r
}\r
} else {\r
Directory.CreateDirectory(folder);\r
+ \r
+ // 権限を親フォルダーに合わせる\r
+ try {\r
+ Directory.SetAccessControl(folder, Directory.GetAccessControl(Path.GetDirectoryName(folder)));\r
+ } catch (Exception) {} // 失敗時無視\r
}\r
}\r
\r
return Path.Combine(folder, fileName);\r
}\r
\r
+ #endregion\r
+ \r
/// <summary>\r
/// すでにインストールされているパッケージを取得する\r
/// </summary>\r
}\r
\r
/// <summary>\r
- /// インストーラファイルを探す\r
+ /// ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83©ã\83¼ã\83\95ã\82¡ã\82¤ã\83«ã\82\92æ\8e¢ã\81\99\r
/// </summary>\r
- /// <param name="basedir">探すフォルダ</param>\r
- /// <param name="type">インストーラの種類</param>\r
- /// <returns>探し出されたインストーラファイルのフルパス。存在しないならばnull</returns>\r
+ /// <param name="basedir">探すフォルダー</param>\r
+ /// <param name="type">ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83©ã\83¼ã\81®ç¨®é¡\9e</param>\r
+ /// <returns>æ\8e¢ã\81\97å\87ºã\81\95ã\82\8cã\81\9fã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83©ã\83¼ã\83\95ã\82¡ã\82¤ã\83«ã\81®ã\83\95ã\83«ã\83\91ã\82¹ã\80\82å\98å\9c¨ã\81\97ã\81ªã\81\84ã\81ªã\82\89ã\81°null</returns>\r
private static string seekInstallerFile(string basedir, InstallerType type)\r
{\r
if (! Directory.Exists(basedir)) {\r
list.AddRange(Directory.GetFiles(basedir, "*.7z"));\r
list.AddRange(Directory.GetFiles(basedir, "*.tar*"));\r
break;\r
+ case InstallerType.ITSELF:\r
+ list.AddRange(Directory.GetFiles(basedir, "*.exe"));\r
+ break;\r
default:\r
return null;\r
}\r
/// <param name="outputReceived">標準出力用リスナ(null可)</param>\r
/// <param name="errorReceived">エラー出力用リスナ(null可)</param>\r
/// <returns>実行プロセス</returns>\r
- private Process createExtractArchiveProcess(string archiveInstArgs,\r
+ private static Process createExtractArchiveProcess(string archiveInstArgs,\r
EventHandler<NaGet.Utils.AnyDataEventArgs<string>> outputReceived,\r
EventHandler<NaGet.Utils.AnyDataEventArgs<string>> errorReceived)\r
{\r
new FileNotFoundException(errMsg, archiveInstExe));\r
}\r
\r
+ \r
+ \r
ProcessStartInfo procInfo = new ProcessStartInfo(archiveInstExe, archiveInstArgs);\r
procInfo.UseShellExecute = false;\r
procInfo.CreateNoWindow = true;\r
return string.Join(" ", strs);\r
}\r
\r
+ #region 便利メソッド群\r
+ \r
/// <summary>\r
/// パッケージ配列をインストール処理配列に変換する便利メソッド\r
/// </summary>\r
}\r
return insts;\r
}\r
+ \r
+ /// <summary>\r
+ /// パッケージがインストール可能かを戻します。\r
+ /// </summary>\r
+ /// <param name="pkg">検査対象のパッケージ</param>\r
+ /// <returns>インストール可能か否か</returns>\r
+ public static bool IsInstallablePackage(Package pkg)\r
+ {\r
+ int installerIndex = getPreferInstallerIndex(pkg);\r
+ return installerIndex >= 0;\r
+ }\r
+ \r
+ #endregion\r
}\r
}\r