private static void InstallPackageFile(PackageJson package, string fastPath, PackageSourceListRequest request) { request.Debug(Resources.Messages.DebugInfoCallMethod, Constants.ProviderName, string.Format(CultureInfo.InvariantCulture, "InstallPackageFile' - name='{0}', fastPath='{1}'", package.Name, fastPath)); // get a temp file name, msi or msu var providerType = package.Type.ToLowerInvariant(); var destination = Path.ChangeExtension(Path.GetTempFileName(), providerType); //download the msi package to the temp file WebDownloader.DownloadFile(package.Source, destination, request, null); if (!File.Exists(destination)) { return; } // validate the file if (!WebDownloader.VerifyHash(destination, package, request)) { return; } if (!package.IsTrustedSource) { if (!request.ShouldContinueWithUntrustedPackageSource(package.Name, package.Source)) { request.Warning(Constants.Messages.UserDeclinedUntrustedPackageInstall, package.Name); return; } } var installRequest = PackageSourceListRequest.ExtendRequest(new Dictionary <string, string[]> { { "Source", new[] { package.Source ?? "" } } }, new[] { package.Source ?? "" }, package.IsTrustedSource, request); request.Verbose(Resources.Messages.CallMsiForInstall, package.Name); if (request.ProviderServices.Install(destination, "", installRequest)) { // it installed ok!exit request.YieldFromSwidtag(package, fastPath); return; } else { request.WriteError(ErrorCategory.InvalidOperation, Constants.ProviderName, Resources.Messages.PackageFailedInstall, package.Name); } }
internal void PromptAndDownloadSampleJSON() { bool force = this.GetOptionValue("Force") != null; if (force || this.ShouldContinue(Resources.Messages.QueryDownloadPackageSourceList.format(DefaultJSONSourceLocation), Resources.Messages.PackageSourceListNotFound.format(DefaultJSONFileLocation))) { WebDownloader.DownloadFile(DefaultJSONSourceLocation, DefaultJSONFileLocation, this, null); WebDownloader.DownloadFile(DefaultJSONCatalogFileLocation, DefaultCatlogFileLocation, this, null); if (System.IO.File.Exists(DefaultJSONFileLocation) && System.IO.File.Exists(DefaultCatlogFileLocation) && PackageSourceListProvider.TestCatalogFile(DefaultJSONFileLocation, DefaultCatlogFileLocation, this)) { this.AddPackageSource("PSL", DefaultJSONFileLocation, false, false); } } }
internal static bool InstallExePackage(PackageJson package, string fastPath, PackageSourceListRequest request) { ProgressTracker tracker = new ProgressTracker(request.StartProgress(0, Resources.Messages.Installing)); var providerType = package.Type.ToLowerInvariant(); var exePackage = Path.ChangeExtension(Path.GetTempFileName(), providerType); if (!string.IsNullOrWhiteSpace(package.Destination)) { request.Verbose(Resources.Messages.DestinationNotSupported, package.Type); } try { WebDownloader.DownloadFile(package.Source, exePackage, request, tracker); if (File.Exists(exePackage)) { request.Verbose("Package: '{0}'", exePackage); // validate the file if (!WebDownloader.VerifyHash(exePackage, package, request)) { return(false); } if (!request.ShouldContinueWithUntrustedPackageSource(package.Name, package.Source)) { request.Warning(Constants.Messages.UserDeclinedUntrustedPackageInstall, package.Name); return(false); } // Prepare the process to run var processArguments = string.IsNullOrWhiteSpace(package.InstallArguments) ? "/VERYSILENT /CLOSEAPPLICATIONS /NORESTART /NOCANCEL /SP /qn" : package.InstallArguments; var start = new ProcessStartInfo { FileName = exePackage, Arguments = processArguments, UseShellExecute = false, RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true, //LoadUserProfile = true, }; double percent = tracker.StartPercent; Timer timer = null; object timerLock = new object(); bool cleanUp = false; Action cleanUpAction = () => { lock (timerLock) { // check whether clean up is already done before or not if (!cleanUp) { try { if (timer != null) { // stop timer timer.Change(Timeout.Infinite, Timeout.Infinite); // dispose it timer.Dispose(); } } catch { } cleanUp = true; } } }; // Run the external process & wait for it to finish using (var proc = Process.Start(start)) { var timer1 = timer; timer = new Timer(_ => { percent += 0.025; // percent between startProgress and endProgress var progressPercent = tracker.ConvertPercentToProgress(percent); if (progressPercent < 90) { request.Progress(tracker.ProgressID, (int)progressPercent, Resources.Messages.InstallingPackage, package.Source); } if (request.IsCanceled) { cleanUpAction(); } }, null, 100, 3000); proc.WaitForExit(); // Retrieve the app's exit code var exitCode = proc.ExitCode; if (exitCode != 0) { request.WriteError(ErrorCategory.InvalidOperation, fastPath, Resources.Messages.InstallFailed, package.Name, proc.StandardError.ReadToEnd()); request.CompleteProgress(tracker.ProgressID, false); return(false); } else { request.CompleteProgress(tracker.ProgressID, true); request.YieldFromSwidtag(package, fastPath); request.Verbose(Resources.Messages.SuccessfullyInstalled, package.Name); } cleanUpAction(); } return(true); } else { request.WriteError(ErrorCategory.InvalidOperation, Constants.ProviderName, Resources.Messages.FailedToDownload, Constants.ProviderName, package.Source); } return(false); } catch (Exception ex) { request.Error(ErrorCategory.InvalidOperation, "install-package", ex.Message); ex.Dump(request); return(false); } finally { if (File.Exists(exePackage)) { exePackage.TryHardToDelete(); } } }
internal static bool InstallZipPackage(PackageJson package, string fastPath, PackageSourceListRequest request) { if (request.RemoveFromPath.Value) { request.Warning(Resources.Messages.AddOrRemovePath, Constants.ProviderName, "RemoveFromPath", "Uninstall-Package"); } // download the exe package var providerType = package.Type.ToLowerInvariant(); var file = Path.ChangeExtension(Path.GetTempFileName(), providerType); if (string.IsNullOrWhiteSpace(package.Destination)) { request.Error(ErrorCategory.InvalidOperation, Constants.ProviderName, Resources.Messages.DestinationRequired); return(false); } WebDownloader.DownloadFile(package.Source, file, request, null); if (!File.Exists(file)) { return(false); } // validate the file if (!WebDownloader.VerifyHash(file, package, request)) { file.TryHardToDelete(); return(false); } if (!request.ShouldContinueWithUntrustedPackageSource(package.Name, package.Source)) { request.Warning(Constants.Messages.UserDeclinedUntrustedPackageInstall, package.Name); file.TryHardToDelete(); return(false); } Timer timer = null; object timerLock = new object(); bool cleanUp = false; ProgressTracker tracker = new ProgressTracker(request.StartProgress(0, "Installing Zip Package............")); double percent = tracker.StartPercent; Action cleanUpAction = () => { lock (timerLock) { // check whether clean up is already done before or not if (!cleanUp) { try { if (timer != null) { // stop timer timer.Change(Timeout.Infinite, Timeout.Infinite); timer.Dispose(); timer = null; } } catch { } cleanUp = true; } } }; // extracted folder string extractedFolder = string.Concat(file.GenerateTemporaryFilename()); var versionFolder = ""; try { timer = new Timer(_ => { percent += 0.025; var progressPercent = tracker.ConvertPercentToProgress(percent); if (progressPercent < 90) { request.Progress(tracker.ProgressID, (int)progressPercent, string.Format(CultureInfo.CurrentCulture, "Copying files ...")); } if (request.IsCanceled) { cleanUpAction(); } }, null, 0, 1000); //unzip the file ZipFile.ExtractToDirectory(file, extractedFolder); if (Directory.Exists(extractedFolder)) { versionFolder = Path.Combine(package.Destination, package.Name, package.Version); // create the directory version folder if not exist if (!Directory.Exists(versionFolder)) { Directory.CreateDirectory(versionFolder); } // The package will be installed to destination\packageName\version\ // However, a few packages have a package name as its top level folder after zip. // So the installed folder will look like this: // \destination\foobarPackage\1.0.1\foobarPackage // In this case we directly copy the files to \destination\foobarPackage\1.0.1. var extractedTopLevelFolder = Directory.EnumerateDirectories(extractedFolder, "*", SearchOption.TopDirectoryOnly); while (!Directory.GetFiles(extractedFolder).Any() && extractedTopLevelFolder.Count() == 1) { extractedFolder = extractedTopLevelFolder.FirstOrDefault(); //in case the zip contains version folder extractedTopLevelFolder = Directory.EnumerateDirectories(extractedFolder, "*", SearchOption.TopDirectoryOnly); } FileUtility.CopyDirectory(extractedFolder, versionFolder, true); request.YieldFromSwidtag(package, fastPath); request.Verbose(Resources.Messages.SuccessfullyInstalledToDestination, package.Name, package.Destination); AddEnvironmentVariable(request, versionFolder); return(true); } else { request.Warning("Failed to download a Zip package {0} from {1}", package.Name, package.Source); } } catch (Exception e) { request.Debug(e.StackTrace); if (e is System.UnauthorizedAccessException) { request.WriteError(ErrorCategory.InvalidOperation, package.Name, Resources.Messages.InstallFailed, package.Name, "UnauthorizedAccessException. The requested operation likely requires elevation, i.e., launch PowerShell as administer"); } else { request.WriteError(ErrorCategory.InvalidOperation, package.Name, Resources.Messages.InstallFailed, package.Name, e.Message); } if (!(e is UnauthorizedAccessException || e is IOException)) { // something wrong, delete the version folder versionFolder.TryHardToDelete(); } } finally { cleanUpAction(); file.TryHardToDelete(); extractedFolder.TryHardToDelete(); request.CompleteProgress(tracker.ProgressID, true); } return(false); }
internal static bool InstallZipPackage(PackageJson package, string fastPath, PackageSourceListRequest request) { // download the exe package var file = Path.ChangeExtension(Path.GetTempFileName(), "exe"); WebDownloader.DownloadFile(package.Source, file, request, null); if (!File.Exists(file)) { return(false); } // validate the file if (!WebDownloader.VerifyHash(file, package, request)) { return(false); } if (!package.IsTrustedSource) { if (!request.ShouldContinueWithUntrustedPackageSource(package.Name, package.Source)) { request.Warning(Constants.Messages.UserDeclinedUntrustedPackageInstall, package.Name); return(false); } } Timer timer = null; object timerLock = new object(); bool cleanUp = false; ProgressTracker tracker = new ProgressTracker(request.StartProgress(0, "Installing Zip Package............")); double percent = tracker.StartPercent; Action cleanUpAction = () => { lock (timerLock) { // check whether clean up is already done before or not if (!cleanUp) { try { if (timer != null) { // stop timer timer.Change(Timeout.Infinite, Timeout.Infinite); timer.Dispose(); timer = null; } } catch { } cleanUp = true; } } }; // extracted folder string extractedFolder = string.Concat(file.GenerateTemporaryFilename()); try { timer = new Timer(_ => { percent += 0.025; var progressPercent = tracker.ConvertPercentToProgress(percent); if (progressPercent < 90) { request.Progress(tracker.ProgressID, (int)progressPercent, string.Format(CultureInfo.CurrentCulture, "Copying files ...")); } if (request.IsCanceled) { cleanUpAction(); } }, null, 0, 1000); //unzip the file ZipFile.ExtractToDirectory(file, extractedFolder); if (Directory.Exists(extractedFolder)) { var versionFolder = Path.Combine(package.Destination, package.Name, package.Version); // create the directory version folder if not exist if (!Directory.Exists(versionFolder)) { Directory.CreateDirectory(versionFolder); } try { FileUtility.CopyDirectory(extractedFolder, versionFolder, true); request.YieldFromSwidtag(package, fastPath); } catch (Exception e) { request.CompleteProgress(tracker.ProgressID, false); request.Debug(e.StackTrace); if (!(e is UnauthorizedAccessException || e is IOException)) { // something wrong, delete the version folder versionFolder.TryHardToDelete(); return(false); } } return(true); } else { request.Warning("Failed to download a Zip package {0} from {1}", package.Name, package.Source); } } finally { cleanUpAction(); file.TryHardToDelete(); extractedFolder.TryHardToDelete(); request.CompleteProgress(tracker.ProgressID, true); } return(false); }
private static void InstallPackageFile(PackageJson package, string fastPath, PackageSourceListRequest request) { request.Debug(Resources.Messages.DebugInfoCallMethod, Constants.ProviderName, string.Format(CultureInfo.InvariantCulture, "InstallPackageFile' - name='{0}'", package.Name)); // get a temp file name, msi or msu var providerType = package.Type.ToLowerInvariant(); var destination = Path.ChangeExtension(Path.GetTempFileName(), providerType); try { //download the msi package to the temp file WebDownloader.DownloadFile(package.Source, destination, request, null); if (!File.Exists(destination)) { return; } // validate the file if (!WebDownloader.VerifyHash(destination, package, request)) { return; } // For unsigned msi packages, the MSI provider will prompt a user if he wants to install it. // However if the signed msi package but the PackageSource is untrusted, MSI provider does not prompt. So we prompt here. if (request.ProviderServices.IsSignedAndTrusted(destination, request)) { if (!request.ShouldContinueWithUntrustedPackageSource(package.Name, package.Source)) { request.Warning(Constants.Messages.UserDeclinedUntrustedPackageInstall, package.Name); return; } } if (!string.IsNullOrWhiteSpace(package.Destination)) { request.Verbose(Resources.Messages.DestinationNotSupported, package.Type); } var installRequest = PackageSourceListRequest.ExtendRequest(new Dictionary <string, string[]> { { "Source", new[] { package.Source ?? "" } } }, new[] { package.Source ?? "" }, request); request.Verbose(Resources.Messages.CallMsiForInstall, package.Name); if (request.ProviderServices.Install(destination, "", installRequest)) { // it installed ok!exit request.YieldFromSwidtag(package, fastPath); return; } else { request.WriteError(ErrorCategory.InvalidOperation, Constants.ProviderName, Resources.Messages.PackageFailedInstall, package.Name); } } finally { if (File.Exists(destination)) { destination.TryHardToDelete(); } } }