X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=na-get-lib%2FNaGet.Packages.Install%2FInstallation.cs;h=de5d2a1610fbf13ae98c3eee156e0cce54fdb4ca;hb=7e429ad7b8cbb759d75e3d6fce01ee9598387679;hp=8ff6026c7ecc226cc5a6e78e1b95c4fd0656def4;hpb=eaa937a13f4e1238a992a3ad79b84a7288954603;p=applistation%2FAppliStation.git diff --git a/na-get-lib/NaGet.Packages.Install/Installation.cs b/na-get-lib/NaGet.Packages.Install/Installation.cs index 8ff6026..de5d2a1 100644 --- a/na-get-lib/NaGet.Packages.Install/Installation.cs +++ b/na-get-lib/NaGet.Packages.Install/Installation.cs @@ -3,6 +3,7 @@ using System.IO; using System.Diagnostics; using NaGet.Net; using NaGet.SubCommands; +using System.Xml.Serialization; namespace NaGet.Packages.Install { @@ -12,15 +13,25 @@ namespace NaGet.Packages.Install /// public class Installation { + private Package installedPackage; + /// /// インストールするパッケージ /// - public Package InstalledPackage; + public Package InstalledPackage { + get { return installedPackage; } + set { + installedPackage = value; + + installerFile = getArchiveFilePath(); + installerIndex = GetPreferInstallerIndex(value); + } + } /// /// (保存される)インストーラのファイルのパス /// - public string InstallerFile; + private string installerFile; /// /// インストールが完了されたか否かのフラグ @@ -50,27 +61,30 @@ namespace NaGet.Packages.Install /// /// コンストラクタ /// - /// インストールするパッケージ - public Installation(Package package) + public Installation() { - InstalledPackage = package; - InstallerFile = getArchiveFilePath(); - installerIndex = GetPreferInstallerIndex(package); } /// /// コンストラクタ /// /// インストールするパッケージ - /// (保存される)インストーラのファイルのパス - protected Installation(Package package, string installerfile) + public Installation(Package package) { InstalledPackage = package; - InstallerFile = installerfile; - installerIndex = GetPreferInstallerIndex(package); } /// + /// インストーラファイルを取得する + /// + public string InstallerFile { + get { return installerFile; } + } + + + #region インストーラ状態チェック関連 + + /// /// インストール可能か否か /// public bool IsInstallablePackage() @@ -83,7 +97,7 @@ namespace NaGet.Packages.Install /// public bool Downloaded { get { - return File.Exists(InstallerFile) && ((File.GetAttributes(InstallerFile) & FileAttributes.Hidden) != FileAttributes.Hidden); + return File.Exists(installerFile) && ((File.GetAttributes(installerFile) & FileAttributes.Hidden) != FileAttributes.Hidden); } } @@ -100,7 +114,10 @@ namespace NaGet.Packages.Install public bool InstallSuccessed { get { switch (InstalledPackage.Type) { - case InstallerType.ARCHIVE: // アーカイブインストーラはフォルダの確認 + case InstallerType.ARCHIVE: + case InstallerType.ITSELF: + // アーカイブインストーラおよび配布exeそれ自身が実行ファイルのとき、 + // (AppliStationの作る)プログラムフォルダの存在のみで確認を行う。 return Directory.Exists(Path.Combine(NaGet.Env.ArchiveProgramFiles, InstalledPackage.Name)); case InstallerType.EXEC_INSTALLER: case InstallerType.MSI_PACKAGE: @@ -116,7 +133,7 @@ namespace NaGet.Packages.Install /// public bool Silent { get { - return (IsSupportsSilentOnly)? true : + return (SupportsSilentOnly)? true : (IsSupportsSilent)? silent : false; } @@ -130,8 +147,11 @@ namespace NaGet.Packages.Install get { switch (InstalledPackage.Type) { case InstallerType.ARCHIVE: + case InstallerType.ITSELF: case InstallerType.MSI_PACKAGE: return true; + case InstallerType.EXEC_INSTALLER: + return ! string.IsNullOrEmpty(InstalledPackage.SilentInstallArguments); default: return false; } @@ -141,11 +161,27 @@ namespace NaGet.Packages.Install /// /// サイレントインストールだけをサポートしているか否か /// - public bool IsSupportsSilentOnly { - get { return InstalledPackage.Type == InstallerType.ARCHIVE; } + public bool SupportsSilentOnly { + get { + return (InstalledPackage.Type == InstallerType.ARCHIVE) + || (InstalledPackage.Type == InstallerType.ITSELF); + } } /// + /// 選択されたパッケージは、AppliStationではなくPCへのインストールをするのか否かを返す。 + /// + /// RunAsが必要か否かの判断にしようされる + public bool TargetPC { + get { + return (InstalledPackage.Type != InstallerType.ARCHIVE) + && (InstalledPackage.Type != InstallerType.ITSELF); + } + } + + #endregion + + /// /// ダウンロードを行う。 /// /// ダウンローダオブジェクト @@ -153,14 +189,45 @@ namespace NaGet.Packages.Install { if (! Installed) { string url = InstalledPackage.Installer[installerIndex].Url.Href; - downloader.Download(url, InstallerFile); + downloader.Download(url, installerFile); // サーバ指定のファイル名に変更する if (! string.IsNullOrEmpty(downloader.DownloadedFileName)) { - string newFile = Path.Combine(Path.GetDirectoryName(InstallerFile), downloader.DownloadedFileName); - File.Move(InstallerFile, newFile); - InstallerFile = newFile; + string newFile = Path.Combine(Path.GetDirectoryName(installerFile), downloader.DownloadedFileName); + File.Move(installerFile, newFile); + installerFile = newFile; } + + // 権限を親フォルダに落とす + try { + string targetDir = Path.GetDirectoryName(installerFile); + NaGet.Utils.SetAccessControlRecursive(targetDir, File.GetAccessControl(Path.GetDirectoryName(targetDir))); + } catch (Exception) {} // 失敗時は何もしない + } + } + + /// + /// インストーラファイルをスキャンする + /// + /// ウイルスのため退避・削除されたときも例外を投げずにあたかも正常かのように動作しえます。 + /// スキャンで意図せぬ動作があったとき + /// スキャン後にインストーラファイルが存在しないとき + /// スキャナーオブジェクト + public void ScanInstallerFile(DownloadScanner scanner) + { + Exception e = null; + try { + scanner.Scan(installerFile, InstalledPackage.Installer[installerIndex].Url.Href); + } catch (System.Runtime.InteropServices.COMException ex) { + e = ex; + } + + if (! File.Exists(installerFile)) { + // ファイルが消されているならばFileNotFoundExceptionを出す + throw new FileNotFoundException(string.Empty, installerFile, e); + } else if ( e != null ) { + // ファイルが消されていないが例外が発生していたときは、その例外を投げる + throw e; } } @@ -183,7 +250,7 @@ namespace NaGet.Packages.Install HashValue[] hashValues = InstalledPackage.Installer[installerIndex].Hash; if (hashValues != null) { foreach (HashValue hash in hashValues) { - if (! hash.Validate(InstallerFile)) { + if (! hash.Validate(installerFile)) { return false; } } @@ -202,25 +269,38 @@ namespace NaGet.Packages.Install try { switch (type) { case InstallerType.EXEC_INSTALLER: - hProcess = Process.Start(installerfile); + if (Silent) { + hProcess = Process.Start(installerfile, InstalledPackage.SilentInstallArguments); + } else { + hProcess = Process.Start(installerfile); + } break; case InstallerType.MSI_PACKAGE: - string msiexecArgs = string.Format("{0} /i \"{1}\"", + string msiexecArgs = string.Format("{0} /norestart /i \"{1}\" REBOOT=ReallySuppress", (Silent)? "/passive" : string.Empty, installerfile); hProcess = Process.Start("msiexec", msiexecArgs); break; case InstallerType.ARCHIVE: + case InstallerType.ITSELF: string argument = string.Format("-i \"{0}\" \"{1}\"", installerfile, this.InstalledPackage.Name); hProcess = createExtractArchiveProcess(argument, this.OutputDataReceived, this.ErrorDataReceived); + // Note: ARCHIVEかITSELFの判断はarchive-instが行う break; default: throw new NotImplementedException("Not implemented archive installation yet"); } + + if (NaGet.Env.InstallProcessOnBackground) { + try { + hProcess.PriorityClass = ProcessPriorityClass.Idle; + } catch (Exception) {} + } + hProcess.WaitForExit(); return hProcess.ExitCode; @@ -237,7 +317,7 @@ namespace NaGet.Packages.Install /// インストーラの終了コード public int Install() { - string installerFile = this.InstallerFile; + string installerFile = this.installerFile; string tempDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); // アーカイブされているなら一旦展開 @@ -248,6 +328,12 @@ namespace NaGet.Packages.Install using (Process hProcess = createExtractArchiveProcess(argument, this.OutputDataReceived, this.ErrorDataReceived)) { + if (NaGet.Env.InstallProcessOnBackground) { + try { + hProcess.PriorityClass = ProcessPriorityClass.Idle; + } catch (Exception) {} + } + hProcess.WaitForExit(); if (hProcess.ExitCode != 0) { @@ -261,7 +347,6 @@ namespace NaGet.Packages.Install } } - int exitCode = invokeInstaller(installerFile, InstalledPackage.Type); installed = true; @@ -302,7 +387,7 @@ namespace NaGet.Packages.Install } /// - /// インストーラの一時保存先パスを生成 + /// インストーラの保存先パスを生成 /// private string getArchiveFilePath() { @@ -320,6 +405,11 @@ namespace NaGet.Packages.Install } } else { Directory.CreateDirectory(folder); + + // 権限を親フォルダに合わせる + try { + Directory.SetAccessControl(folder, Directory.GetAccessControl(Path.GetDirectoryName(folder))); + } catch (Exception) {} // 失敗時無視 } } @@ -367,6 +457,9 @@ namespace NaGet.Packages.Install list.AddRange(Directory.GetFiles(basedir, "*.7z")); list.AddRange(Directory.GetFiles(basedir, "*.tar*")); break; + case InstallerType.ITSELF: + list.AddRange(Directory.GetFiles(basedir, "*.exe")); + break; default: return null; } @@ -408,6 +501,8 @@ namespace NaGet.Packages.Install new FileNotFoundException(errMsg, archiveInstExe)); } + + ProcessStartInfo procInfo = new ProcessStartInfo(archiveInstExe, archiveInstArgs); procInfo.UseShellExecute = false; procInfo.CreateNoWindow = true; @@ -421,8 +516,8 @@ namespace NaGet.Packages.Install /// public virtual void RemoveDownloadedFile() { - if (Downloaded && File.Exists(InstallerFile)) { - File.Delete(InstallerFile); + if (Downloaded && File.Exists(installerFile)) { + File.Delete(installerFile); } }