internal static void InstallPowershellArtifacts(PackageJson package, string fastPath, PackageSourceListRequest request)
        {
            var provider1 = PackageSourceListRequest.FindProvider(request, package.Type, request, true);         
            if (provider1 == null) return;

            // As the PowerShellGet may access the -source via $request.Options or PackageSources,
            // so we need to fill in both options and sources parameters
            var installRequest = PackageSourceListRequest.ExtendRequest(new Dictionary<string, string[]>
                           {
                                {"Source", new[] {package.Source ?? ""}}
                           }, new[] { package.Source ?? "" }, package.IsTrustedSource, request);

            var psid = PackageSourceListRequest.CreateCanonicalId(package, Constants.ProviderNames.PowerShellGet);
            var pkgs = request.PackageManagementService.FindPackageByCanonicalId(psid, installRequest)
             .Where(each => new SemanticVersion(each.Version) == new SemanticVersion(package.Version)).ToArray();
            
            switch (pkgs.Length)
            {
                case 0:
                    request.Warning(Resources.Messages.CannotFindPackage, Constants.ProviderName, psid);
                    break;
                case 1:
                    InstallPackageViaPowerShellGet(package, request, pkgs);
                    break;

                default:
                    request.Warning(Resources.Messages.FoundMorePackages, Constants.ProviderName, pkgs.Length, psid);
                    break;
            }
            return;
        }
        private static void InstallPackageViaPowerShellGet(PackageJson packageJson, PackageSourceListRequest request, SoftwareIdentity[] packages)
        {

            var provider = PackageSourceListRequest.FindProvider(request, packageJson.Type, request, true);
            if (provider == null) return;
            
            IHostApi installRequest = request;

            if (provider.Name.EqualsIgnoreCase(Constants.ProviderNames.PowerShellGet) && !request.ProviderServices.IsElevated) {
                // if we're not elevated, we want powershellget to install to the user scope
                installRequest = PackageSourceListRequest.ExtendRequest(
                    new Dictionary<string, string[]> {
                        {"Scope", new[] {"CurrentUser"}}
                    }, null, packageJson.IsTrustedSource, request);

            } else {
                installRequest = PackageSourceListRequest.ExtendRequest(
                    new Dictionary<string, string[]> {
                        {"Destination", new[] {packageJson.Destination ?? ""}}
                    }, null, packageJson.IsTrustedSource, request);
            }

            request.Debug("Calling '{0}' provider to install the package '{1}.{2}'", provider.Name, packageJson.Name, packageJson.Version);

            var installing = provider.InstallPackage(packages[0], installRequest);
          
            if (installing == null || !installing.Any())
            {
                request.Verbose(Resources.Messages.NumberOfPackagesRecevied, 0, provider.Name, "InstallPackage");
                request.Warning(Resources.Messages.FailToInstallPackage, Constants.ProviderName, packages[0].Name);
                return;
            }

            int packagesRecevied = 0;
            foreach (var i in installing)
            {
                request.YieldSoftwareIdentity(i.FastPackageReference, i.Name, i.Version, i.VersionScheme, i.Summary, i.Source, i.SearchKey, i.FullPath, i.PackageFilename);

                if (request.IsCanceled)
                {
                    installing.Cancel();
                }
                else
                {
                    request.Verbose(Resources.Messages.SuccessfullyInstalled, "{0}.{1}".format(packageJson.Name, packageJson.Version));
                    //load provider
                    if (packageJson.IsPackageProvider)
                    {
                        //Per provider development guidance: provider name and module name should be the same otherwise we can not import it.
                        request.PackageManagementService.ImportPackageProvider(request, packageJson.Name, null, null, null, isRooted: false, force: false);
                    }
                }
                packagesRecevied++;
            }

            request.Verbose(Resources.Messages.NumberOfPackagesRecevied, packagesRecevied, provider.Name, "install-package");
        }
Beispiel #3
0
        internal static void GetInstalledZipPackage(PackageJson package, PackageSourceListRequest request)
        {

            string path = Path.Combine(package.Destination, package.Name, package.Version);
            if (Directory.Exists(path))
            {
                if (Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories).Any())
                {
                    var fp = PackageSourceListRequest.MakeFastPathComplex(package.Source, package.Name, (package.DisplayName ?? ""), package.Version, path);

                    //the directory exists and contain files, we think the package has been installed.
                    request.YieldSoftwareIdentity(fp, package.Name, package.Version, package.VersionScheme, package.Summary, path, package.Name, path, path);
                }
            }
        }
Beispiel #4
0
        /// <summary>
        /// Uninstalls a package
        /// </summary>
        /// <param name="package">package defined in the PackageSourceList</param>
        /// <param name="fastPackageReference"></param>
        /// <param name="request">An object passed in from the PackageManagement that contains functions that can be used to interact with its Provider</param>
        /// <param name="fastPackReftable"></param> 
        internal static void UninstallNuGetPackage(PackageJson package, string fastPackageReference, PackageSourceListRequest request, Dictionary<string, SoftwareIdentity> fastPackReftable)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            request.Debug(Resources.Messages.DebugInfoCallMethod, Constants.ProviderName, string.Format(CultureInfo.InvariantCulture, "UninstallNuGetPackage' - fastReference='{0}'", fastPackageReference));

            var unInstallRequest = PackageSourceListRequest.ExtendRequest(
                new Dictionary<string, string[]>
                {
                    {"Destination", new[] {package.Destination ?? ""}}
                }, null, package.IsTrustedSource, request);

            var provider = PackageSourceListRequest.FindProvider(request, package.Type, request, true);
            if (provider != null)
            {
                request.Debug("{0}: Using the provider '{1} to uninstall the package '{2}'", Constants.ProviderName, provider.Name, package.Name);

                if (!fastPackReftable.ContainsKey(fastPackageReference))
                {
                    request.WriteError(ErrorCategory.InvalidData, fastPackageReference, Resources.Messages.FailedToGetPackageObject, Constants.ProviderName, fastPackageReference);                   
                    return;
                }

                var p = fastPackReftable[fastPackageReference];

                //calling NuGet for uninstall
                var installing = provider.UninstallPackage(p, unInstallRequest);

                foreach (var i in installing)
                {
                    request.YieldSoftwareIdentity(i.FastPackageReference, i.Name, i.Version, i.VersionScheme, i.Summary, i.Source, i.SearchKey, i.FullPath, i.PackageFilename);

                    if (request.IsCanceled)
                    {
                        installing.Cancel();
                    }
                }
            } 
        }
Beispiel #5
0
        internal static void GeInstalledNuGetPackages(PackageJson package, string requiredVersion, string minimumVersion, string maximumVersion, Dictionary<string, SoftwareIdentity> fastPackReftable, PackageSourceListRequest request)
        { 
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            request.Debug(Resources.Messages.DebugInfoCallMethod, Constants.ProviderName, string.Format(CultureInfo.InvariantCulture, "GeInstalledNuGetPackages' - name='{0}', requiredVersion='{1}',minimumVersion='{2}', maximumVersion='{3}'", package.Name, requiredVersion, minimumVersion, maximumVersion));

            //clone the request
            //nuget provider may not know the location of the package gets installed.
            //we need to pass around the destination path to nuget provider
            var installedRequest = PackageSourceListRequest.ExtendRequest(
                   new Dictionary<string, string[]> {
                        {"Destination", new[] { package.Destination ?? ""}}
                   }, null, package.IsTrustedSource, request);

            var provider = PackageSourceListRequest.FindProvider(request, package.Type, request);
            if (provider != null)
            {
                //calling NuGet provider
                var packagesInstalled = provider.GetInstalledPackages(package.Name, requiredVersion, minimumVersion, maximumVersion, installedRequest);
                if (packagesInstalled != null)
                {
                    foreach (var i in packagesInstalled)
                    {
                        request.Debug("Found an installed package '{0}.{1} from {2}' ", i.Name, i.Version, i.Source);
                        var info = PackageSourceListRequest.MakeFastPathComplex(i.Source, i.Name, "", i.Version, "");

                        fastPackReftable.AddOrSet(info, i);

                        // make it semver because in find-package we use semver
                        var version = i.Version.CompareVersion(package.Version) ? package.Version : i.Version;
                        request.YieldSoftwareIdentity(info, i.Name, version, i.VersionScheme, i.Summary, i.Source, i.SearchKey, i.FullPath, i.PackageFilename);

                    }
                }
            }
        }
Beispiel #6
0
        internal static void InstallProviderFromInstaller(PackageJson package, string fastPath, PackageSourceListRequest request) {
           
            request.Debug(Resources.Messages.DebugInfoCallMethod, Constants.ProviderName, string.Format(CultureInfo.InvariantCulture, "InstallProviderFromInstaller' - name='{0}', fastPath='{1}'", package.Name, fastPath));

            //install any dependency packages
            InstallDependencies(package, request);

            switch (package.Type.ToLowerInvariant()) {
                case Constants.MediaType.MsiPackage:
                case Constants.MediaType.MsuPackage:
                    InstallPackageFile(package, fastPath, request);
                    break;
                case Constants.MediaType.AppxPackage:
                    //TODO for future whenever needed to support appx packages
                    break;
                case Constants.MediaType.NuGetPackage:
                    NupkgInstaller.InstallNuGetPackage(package, fastPath, request);
                    break;
                case Constants.MediaType.ZipPackage:
                    ZipPackageInstaller.InstallZipPackage(package, fastPath, request);
                    break;
                case Constants.MediaType.ExePackage:
                    ExePackageInstaller.InstallExePackage(package, fastPath, request);
                    break;               
                case Constants.MediaType.PsArtifacts:
                    PowerShellArtifactInstaller.InstallPowershellArtifacts(package, fastPath, request);
                    break;

                default:
                    request.WriteError(ErrorCategory.InvalidData, fastPath, Resources.Messages.UnknownMediaType, package.Name, package.Source, package.Type);
                   break;
            }
            return;
        }
Beispiel #7
0
        internal static void InstallNuGetPackage(PackageJson package, string fastPath, PackageSourceListRequest request)
        {
            request.Debug(Resources.Messages.DebugInfoCallMethod, Constants.ProviderName, string.Format(CultureInfo.InvariantCulture, "InstallNuGetPackage' - name='{0}', fastPath='{1}'", package.Name, fastPath));

            var canonicalId = PackageSourceListRequest.CreateCanonicalId(package, Constants.ProviderNames.NuGet); // "nuget:jquery/2.1.0#http://nuget.org/api/v2";
            var pkgs = request.PackageManagementService.FindPackageByCanonicalId(canonicalId, request.As<IHostApi>())
                        .Where(each => string.IsNullOrWhiteSpace(package.Version) ||
                        (new SemanticVersion(each.Version) == new SemanticVersion(package.Version))).ToArray();

            switch (pkgs.Length)
            {
                case 0:
                    request.Warning(Resources.Messages.CannotFindPackage, Constants.ProviderName, canonicalId);
                    return;
                case 1:
                    InstallPackageReference(package, request, pkgs);
                    return;

                default:
                    request.Warning(Resources.Messages.FoundMorePackages, Constants.ProviderName, pkgs.Length, canonicalId);
                    return;
            }
        }
Beispiel #8
0
        private static void InstallPackageReference(PackageJson package, PackageSourceListRequest request, SoftwareIdentity[] packages)
        {
            var installRequest = PackageSourceListRequest.ExtendRequest(
                           new Dictionary<string, string[]>
                           {
                                {"Destination", new[] {package.Destination ?? ""}}
                           },
                           new[] { package.Source ?? "" },
                           package.IsTrustedSource,
                           request);

            var provider = PackageSourceListRequest.FindProvider(request, package.Type, installRequest, true);   
            if (provider == null)
            {
                return;
            }

            var installing = provider.InstallPackage(packages[0], installRequest);
            foreach (var i in installing)
            {
                request.YieldSoftwareIdentity(i.FastPackageReference, i.Name, i.Version, i.VersionScheme, i.Summary, i.Source, i.SearchKey, i.FullPath, i.PackageFilename);
                if (request.IsCanceled)
                {
                    installing.Cancel();
                }
            }
        }
Beispiel #9
0
        internal static bool InstallExePackage(PackageJson package, string fastPath, PackageSourceListRequest request) {

            ProgressTracker tracker = new ProgressTracker(request.StartProgress(0, Resources.Messages.Installing));
         
            var exePackage = Path.ChangeExtension(Path.GetTempFileName(), "exe");
            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 (!package.IsTrustedSource)
                {
                    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.Error(ErrorCategory.InvalidOperation, Resources.Messages.FailedToDownload, Constants.ProviderName, package.Source, exePackage);
            }

            return false;
        }
Beispiel #10
0
        internal static bool VerifyHash(string fileFullPath,PackageJson package, PackageSourceListRequest request)
        {
            //skip in case the skip switch is specified
            if (request.SkipHashValidation.Value)
            {
                request.Verbose(Resources.Messages.SkipHashValidation);
                return true;                   
            }
            PackageHash packageHash = package.Hash;
            if (packageHash==null || string.IsNullOrWhiteSpace(packageHash.algorithm) || string.IsNullOrWhiteSpace(packageHash.hashCode))
            {
                request.WriteError(ErrorCategory.InvalidArgument, Constants.ProviderName, Resources.Messages.HashNotSpecified, package.Name);
                return false;
            }
            try
            {
                HashAlgorithm hashAlgorithm = null;
                switch (packageHash.algorithm.ToLowerInvariant())
                {
                    case "sha256":
                        hashAlgorithm = SHA256.Create();
                        break;

                    case "md5":
                        hashAlgorithm = MD5.Create();
                        break;

                    case "sha512":
                        hashAlgorithm = SHA512.Create();
                        break;                    
                    default:
                        request.WriteError(ErrorCategory.InvalidArgument, Constants.ProviderName, Resources.Messages.InvalidHashAlgorithm, packageHash.algorithm);
                        return false;
                }

                using (FileStream stream = File.OpenRead(fileFullPath))
                {
                    // compute the hash
                    byte[] computedHash = hashAlgorithm.ComputeHash(stream);
                    // convert the original hash we got from json
                    byte[] hashFromJSON = Convert.FromBase64String(package.Hash.hashCode);
                    if (!Enumerable.SequenceEqual(computedHash, hashFromJSON))
                    {
                        request.WriteError(ErrorCategory.InvalidOperation, Constants.ProviderName, Resources.Messages.HashVerificationFailed, package.Name, package.Source);
                        return false;
                    }
                    else
                    {
                        request.Verbose(Resources.Messages.HashValidationSuccessful);
                    }
                }
            }
            catch
            {
                request.WriteError(ErrorCategory.InvalidOperation, Constants.ProviderName, Resources.Messages.HashVerificationFailed, package.Name, package.Source);
                return false;
            }
            
           return true;
        }
Beispiel #11
0
        internal static void GetInstalledExePackages(PackageJson package, string requiredVersion, string minimumVersion, string maximumVersion, Request request) {
            if (request == null) {
                throw new ArgumentNullException("request");
            }

            request.Debug("Calling '{0}::GetInstalledPackages' '{1}','{2}','{3}','{4}'", Constants.ProviderName, package.Name, requiredVersion, minimumVersion, maximumVersion);

#if !CORECLR
            if (Environment.Is64BitOperatingSystem) {
                using (var hklm64 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64).OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", RegistryKeyPermissionCheck.ReadSubTree, RegistryRights.ReadKey)) {
#else
            if (System.Runtime.InteropServices.RuntimeInformation.OSArchitecture == System.Runtime.InteropServices.Architecture.X64) {
                using (var hklm64 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64).OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall")) {
#endif
                                                                                                                                                                                                                                                        if (!YieldPackages("hklm64", hklm64, package.Name, package.DisplayName, requiredVersion, minimumVersion, maximumVersion, package, request)) {
                        return;
                    }
                }

                using (var hkcu64 = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64).OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", false)) {
                    if (!YieldPackages("hkcu64", hkcu64, package.Name, package.DisplayName, requiredVersion, minimumVersion, maximumVersion, package, request)) {
                        return;
                    }
                }
            }

            using (var hklm32 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", false)) {
                if (!YieldPackages("hklm32", hklm32, package.Name, package.DisplayName, requiredVersion, minimumVersion, maximumVersion, package, request)) {
                    return;
                }
            }

            using (var hkcu32 = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry32).OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", false)) {
                if (!YieldPackages("hkcu32", hkcu32, package.Name, package.DisplayName, requiredVersion, minimumVersion, maximumVersion, package, request)) {
                }
            }
        }
Beispiel #12
0
        private static bool YieldPackages(string hive, RegistryKey regkey, string name, string displayname, string requiredVersion, string minimumVersion, string maximumVersion, PackageJson package, Request request)
        {
            //TODO make it wildcard match, follow the fastfrence format, get-package git no results, get-package git*

            if (regkey != null)
            {
                var includeSystemComponent = request.GetOptionValue("IncludeSystemComponent").IsTrue();

                foreach (var key in regkey.GetSubKeyNames())
                {
                    var subkey = regkey.OpenSubKey(key);
                    if (subkey != null)
                    {
                        var properties = subkey.GetValueNames().ToDictionaryNicely(each => each.ToString(), each => (subkey.GetValue(each) ?? string.Empty).ToString(), StringComparer.OrdinalIgnoreCase);

                        //if (!includeWindowsInstaller && properties.ContainsKey("WindowsInstaller") && properties["WindowsInstaller"] == "1")
                        //{
                        //    continue;
                        //}

                        if (!includeSystemComponent && properties.ContainsKey("SystemComponent") && properties["SystemComponent"] == "1")
                        {
                            continue;
                        }

                        var productName = "";

                        if (!properties.TryGetValue("DisplayName", out productName))
                        {
                            // no product name?
                            continue;
                        }

 
                        if (IsMatch(name, productName) || IsMatch(displayname, productName))
                        {
                            var productVersion = properties.Get("DisplayVersion") ?? "";
                            var publisher = properties.Get("Publisher") ?? "";
                            var uninstallString = properties.Get("QuietUninstallString") ?? properties.Get("UninstallString") ?? "";
                            var comments = properties.Get("Comments") ?? "";

                            var fp = hive + @"\" + subkey;

                            if (!string.IsNullOrEmpty(requiredVersion))
                            {
                                if (new SemanticVersion(requiredVersion) != new SemanticVersion(productVersion))
                                {
                                    continue;
                                }
                            }
                            else {
                                if (!string.IsNullOrEmpty(minimumVersion) && new SemanticVersion(minimumVersion) > new SemanticVersion(productVersion))
                                {
                                    continue;
                                }
                                if (!string.IsNullOrEmpty(maximumVersion) && new SemanticVersion(maximumVersion) < new SemanticVersion(productVersion))
                                {
                                    continue;
                                }
                            }

                            fp = PackageSourceListRequest.MakeFastPathComplex(package.Destination ?? "", package.Name, package.DisplayName, productVersion, fp);
  
                            var source = properties.Get("InstallLocation") ?? "";
                            //we use name here because find-package uses name (not displayname) in the PSL.json, 

                            if (request.YieldSoftwareIdentity(fp, name, productVersion, "unknown", comments, source, name, "", "") != null)
                            {
                                if (properties.Keys.Where(each => !string.IsNullOrWhiteSpace(each)).Any(k => request.AddMetadata(fp, k.MakeSafeFileName(), properties[k]) == null))
                                {
                                    return false;
                                }
                            }
                        }
                    }
                }
            }
            return true;
        }
Beispiel #13
0
        internal static bool InstallExePackage(PackageJson package, string fastPath, PackageSourceListRequest request)
        {
            ProgressTracker tracker = new ProgressTracker(request.StartProgress(0, Resources.Messages.Installing));

            var exePackage = Path.ChangeExtension(Path.GetTempFileName(), "exe");

            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 (!package.IsTrustedSource)
                {
                    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.Error(ErrorCategory.InvalidOperation, Resources.Messages.FailedToDownload, Constants.ProviderName, package.Source, exePackage);
            }

            return(false);
        }
Beispiel #14
0
        private static IEnumerable<PackageJson> GetDependencies(PackageJson packageJson, PackageSourceListRequest request) {

            if (packageJson.DependencyObjects == null) {
                yield break;
            }

            bool force = request.GetOptionValue("Force") != null;
            foreach (var dep in packageJson.DependencyObjects.Where(dep => (dep != null) && !dep.IsCommonDefinition)) {
                if (!force) {
                    var provider = PackageSourceListRequest.FindProvider(request, dep.Type, request, true);

                    if(provider == null)
                    {
                        //FindProvider logged an error already
                        break;
                    }
                    //Check whether the dependency package is installed
                    var installedPackages = provider.GetInstalledPackages(dep.Name, requiredVersion: null, minimumVersion: dep.Version, maximumVersion: null, requestObject: request);

                    if (installedPackages == null || !installedPackages.Any()) {
                        request.Verbose(Resources.Messages.DependencyNotInstalled, dep.Name);
                        yield return dep;
                    } else {
                        request.Verbose(Resources.Messages.DependencyInstalled, dep.Name);
                    }
                } else {
                    yield return dep;
                }
            }
        }
Beispiel #15
0
        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;
        }
Beispiel #16
0
        private static void InstallPackageViaPowerShellGet(PackageJson packageJson, PackageSourceListRequest request, SoftwareIdentity[] packages)
        {
            var provider = PackageSourceListRequest.FindProvider(request, packageJson.Type, request, true);

            if (provider == null)
            {
                return;
            }

            IHostApi installRequest = request;

            if (provider.Name.EqualsIgnoreCase(Constants.ProviderNames.PowerShellGet) && !request.ProviderServices.IsElevated)
            {
                // if we're not elevated, we want powershellget to install to the user scope
                installRequest = PackageSourceListRequest.ExtendRequest(
                    new Dictionary <string, string[]> {
                    { "Scope", new[] { "CurrentUser" } }
                }, null, packageJson.IsTrustedSource, request);
            }
            else
            {
                installRequest = PackageSourceListRequest.ExtendRequest(
                    new Dictionary <string, string[]> {
                    { "Destination", new[] { packageJson.Destination ?? "" } }
                }, null, packageJson.IsTrustedSource, request);
            }

            request.Debug("Calling '{0}' provider to install the package '{1}.{2}'", provider.Name, packageJson.Name, packageJson.Version);

            var installing = provider.InstallPackage(packages[0], installRequest);

            if (installing == null || !installing.Any())
            {
                request.Verbose(Resources.Messages.NumberOfPackagesReceived, 0, provider.Name, "InstallPackage");
                request.Warning(Resources.Messages.FailToInstallPackage, Constants.ProviderName, packages[0].Name);
                return;
            }

            int packagesReceived = 0;

            foreach (var i in installing)
            {
                request.YieldSoftwareIdentity(i.FastPackageReference, i.Name, i.Version, i.VersionScheme, i.Summary, i.Source, i.SearchKey, i.FullPath, i.PackageFilename);

                if (request.IsCanceled)
                {
                    installing.Cancel();
                }
                else
                {
                    request.Verbose(Resources.Messages.SuccessfullyInstalled, "{0}.{1}".format(packageJson.Name, packageJson.Version));
                    //load provider
                    if (packageJson.IsPackageProvider)
                    {
                        //Per provider development guidance: provider name and module name should be the same otherwise we can not import it.
                        request.PackageManagementService.ImportPackageProvider(request, packageJson.Name, null, null, null, isRooted: false, force: false);
                    }
                }
                packagesReceived++;
            }

            request.Verbose(Resources.Messages.NumberOfPackagesReceived, packagesReceived, provider.Name, "install-package");
        }
Beispiel #17
0
        private void UnInstallMsiPackage(PackageSourceListRequest request,  string fastPath, PackageJson package)
        {
            request.Debug(Resources.Messages.DebugInfoCallMethod, PackageProviderName, string.Format(CultureInfo.InvariantCulture, "UnInstallMsiPackage' - name='{0}', fastPath='{1}'", package.Name, fastPath));

            string sourceLocation;
            string id;
            string displayName;
            string version;
            string fastPackageReference;

            if (!request.TryParseFastPathComplex(fastPath: fastPath, regex: PackageSourceListRequest.RegexFastPathComplex, location: out sourceLocation, id: out id, displayname: out displayName, version: out version, fastpath: out fastPackageReference))
            {
                //we don't need to error out even if fastpath is not correct because msi provider is expected to handle the uninstall-package.
                request.Verbose(Resources.Messages.UnsupportMSIUninstall, Constants.ProviderName, package.Name);
                return;
            }

            // Normally uninstall-package will be handled by MSI provider. Here we added a special case for handling uninstall-package nodejs
            // which msi provider unable to deal with (node.js only for msi)
            if (id != null && id.EqualsIgnoreCase("nodejs"))
            {

                var provider = PackageSourceListRequest.FindProvider(request, Constants.ProviderNames.Msi, request);

                if (provider != null)
                {

                    if (!_fastPackReftable.ContainsKey(fastPackageReference))
                    {
                        request.WriteError(ErrorCategory.InvalidData, fastPackageReference, Resources.Messages.FailedToGetPackageObject, Constants.ProviderName, fastPackageReference);
                        return;
                    }

                    request.Verbose(Resources.Messages.UninstallingPackage, Constants.ProviderName, package.Name);

                    var p = _fastPackReftable[fastPackageReference];

                    var installing = provider.UninstallPackage(p, request);

                    foreach (var i in installing)
                    {
                        request.YieldSoftwareIdentity(i.FastPackageReference, i.Name, i.Version, i.VersionScheme,
                            i.Summary, package.Source, i.SearchKey, i.FullPath, i.PackageFilename);
                        if (request.IsCanceled)
                        {
                            installing.Cancel();
                        }
                        return;
                    }
                }
            }
            else
            {
                //no-op for uninstalling the msi packages. only install-package nodejs is supported because msi can not handle it
                request.Verbose(Resources.Messages.UnsupportMSIUninstall, Constants.ProviderName, package.Name);
                return;
            }
           
        }
Beispiel #18
0
        private void GetMsiInstalledPackage(string name, PackageJson package, string requiredVersion, string minimumVersion, string maximumVersion, PackageSourceListRequest request) {

            request.Debug(Resources.Messages.DebugInfoCallMethod, PackageProviderName, string.Format(CultureInfo.InvariantCulture, "GetMsiInstalledPackage' - name='{0}', requiredVersion='{1}',minimumVersion='{2}', maximumVersion='{3}'", name, requiredVersion, minimumVersion, maximumVersion));

            var provider = PackageSourceListRequest.FindProvider(request, package.Type, request);
            if (provider != null) {
                var packagesInstalled = provider.GetInstalledPackages(package.Name, requiredVersion, minimumVersion, maximumVersion, request);

                if (!packagesInstalled.Any()) {
                    packagesInstalled = provider.GetInstalledPackages(package.DisplayName, requiredVersion, minimumVersion, maximumVersion, request);
                }
                foreach (var i in packagesInstalled)
                {
                    request.Debug("found a package '{0}.{1}' installed from '{2}'", i.Name, i.Version, i.Source);
 
                    var info = PackageSourceListRequest.MakeFastPathComplex(i.Source, name, (package.DisplayName?? ""), i.Version, i.FastPackageReference);

                    _fastPackReftable.AddOrSet(i.FastPackageReference, i);

                    // check if the installed version matches with the one specified in the PSL.json.
                    // If so, we choose PSL.json.
                    var version = i.Version.CompareVersion(package.Version) ? package.Version : i.Version;
                    //we use displayname here because msi provider uses the displayname. 
                    request.YieldSoftwareIdentity(info, package.DisplayName, version, i.VersionScheme, i.Summary, package.Source, i.SearchKey, i.FullPath, i.PackageFilename);
                    return;
                }           
            }
        }
Beispiel #19
0
        internal bool YieldFromSwidtag(PackageJson package, string searchKey)
        {
            if (package == null)
            {
                return !IsCanceled;
            }

            var targetFilename = package.FilePath;
            var summary = package.Summary;

            var fastPath = MakeFastPath(package);

            // As 'nodejs' become 'node.js' after the install, GetInstalledPackage() will return node.js. To skip installing node.js  
            // if already installed, we need to return the node.js i.e., use display name for msi provider.
            if (package.Type.EqualsIgnoreCase(Constants.MediaType.MsiPackage))
            {
                if (!string.IsNullOrWhiteSpace(package.DisplayName))
                {
                    package.Name = package.DisplayName;
                }
            }

            if (YieldSoftwareIdentity(fastPath, package.Name, package.SemVer.ToString(), package.VersionScheme, summary, package.Source, searchKey, null, targetFilename) != null)
            {
                //this is a trusted source
                if (AddMetadata(fastPath, "FromTrustedSource", "true") == null)
                {
                    return !IsCanceled;
                }

                if (AddMetadata(fastPath, "Source", package.Source) == null)
                {
                    return !IsCanceled;
                }
                if (AddMetadata(fastPath, "Type", package.Type) == null)
                {
                    return !IsCanceled;
                }

                if (package.Dependencies != null)
                {
                    //iterate thru the dependencies and add them to the software identity.
                    foreach (var dependency in package.Dependencies)
                    {
                        // foreach (var pkg in dependency)
                        {
                            AddDependency("PSL", dependency.Name, dependency.Version, null, null);
                        }
                    }
                }
            }
            return !IsCanceled;
        }
Beispiel #20
0
 internal string MakeFastPath(PackageJson package)
 {
     return string.Format(CultureInfo.InvariantCulture, @"${0}\{1}", package.Name.ToBase64(), package.Version.ToBase64());
 }
Beispiel #21
0
        internal static string CreateCanonicalId(PackageJson package, string providerName)
        {
            // example: "nuget:jquery/2.1.0#http://nuget.org/api/v2"
            if (package == null || string.IsNullOrEmpty(package.Name) || string.IsNullOrEmpty(providerName))
            {
                return null;
            }
            if (string.IsNullOrWhiteSpace(package.Version) && string.IsNullOrWhiteSpace(package.Source))
            {
                return "{0}:{1}".format(CultureInfo.CurrentCulture.TextInfo.ToLower(providerName), package.Name);
            }
            if (string.IsNullOrWhiteSpace(package.Source))
            {
                return "{0}:{1}/{2}".format(CultureInfo.CurrentCulture.TextInfo.ToLower(providerName), package.Name, package.Version);
            }

            Uri pkgId;
            var source = package.Source;
            if (Uri.TryCreate(package.Source, UriKind.Absolute, out pkgId))
            {
                source = pkgId.AbsoluteUri;
            }

            if (string.IsNullOrWhiteSpace(package.Version))
            {
                "{0}:{1}#{2}".format(CultureInfo.CurrentCulture.TextInfo.ToLower(providerName), package.Name, source);
            }

            return "{0}:{1}/{2}#{3}".format(CultureInfo.CurrentCulture.TextInfo.ToLower(providerName), package.Name, package.Version, source);
        }
        internal static void GeInstalledPowershellArtifacts(PackageJson package, string requiredVersion, string minimumVersion, string maximumVersion, Dictionary<string, SoftwareIdentity> fastPackReftable, PackageSourceListRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            request.Debug(Resources.Messages.DebugInfoCallMethod, Constants.ProviderName, string.Format(CultureInfo.InvariantCulture, "GeInstalledPowershellArtifacts' - name='{0}', requiredVersion='{1}',minimumVersion='{2}', maximumVersion='{3}'", package.Name, requiredVersion, minimumVersion, maximumVersion));

            var provider = PackageSourceListRequest.FindProvider(request, package.Type, request);
            if (provider == null) return;

            //calling the PowerShellGet provider
            request.Debug("Calling '{0}' provider to get installed packages '{1}.{2}'", provider.Name, package.Name, package.Version);

            var packagesInstalled = provider.GetInstalledPackages(package.Name, requiredVersion, minimumVersion, maximumVersion, request).ToArray();

            if (packagesInstalled == null || !packagesInstalled.Any())
            {
                request.Verbose(Resources.Messages.NumberOfPackagesRecevied, 0, provider.Name, "GetInstalledPackages");
                return;
            }          
            
            foreach (var i in packagesInstalled)
            {
                request.Debug("Found an installed package '{0}.{1} from {2}' ", i.Name, i.Version, i.Source);
                var info = PackageSourceListRequest.MakeFastPathComplex(i.Source, i.Name, "", i.Version, "");

                fastPackReftable.AddOrSet(info, i);

                // check if the installed version matches with the one specified in the PSL.json.
                // If so, we choose PSL.json.
                var version = i.Version.CompareVersion(package.Version) ? package.Version : i.Version;
                request.YieldSoftwareIdentity(info, i.Name, version, i.VersionScheme, i.Summary, i.Source, i.SearchKey, i.FullPath, i.PackageFilename);
            }                       
        }
Beispiel #23
0
        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);
            }
        }
Beispiel #24
0
        internal static void InstallDependencies(PackageJson packageJson, PackageSourceListRequest request)
        {
            //TODO dependency chain check

            //let's install dependency first in case it is needed for installing the actual package
            if (packageJson.DependencyObjects != null)
            {
                var dependencies = GetDependencies(packageJson, request);

                if (dependencies != null)
                {
                    foreach (var dep in dependencies.Where(dep => (dep != null) && !dep.IsCommonDefinition))
                    {
                        //dependency source trusty follows its parent
                        dep.IsTrustedSource |= packageJson.IsTrustedSource;
                        var id = PackageSourceListRequest.CreateCanonicalId(dep, dep.Name);
                        InstallProviderFromInstaller(dep, id, request);
                    }
                }
            }
        }
Beispiel #25
0
        private static bool YieldPackages(string hive, RegistryKey regkey, string name, string displayname, string requiredVersion, string minimumVersion, string maximumVersion, PackageJson package, Request request)
        {
            //TODO make it wildcard match, follow the fastfrence format, get-package git no reults, get-package git*

            if (regkey != null)
            {
                var includeSystemComponent = request.GetOptionValue("IncludeSystemComponent").IsTrue();

                foreach (var key in regkey.GetSubKeyNames())
                {
                    var subkey = regkey.OpenSubKey(key);
                    if (subkey != null)
                    {
                        var properties = subkey.GetValueNames().ToDictionaryNicely(each => each.ToString(), each => (subkey.GetValue(each) ?? string.Empty).ToString(), StringComparer.OrdinalIgnoreCase);

                        //if (!includeWindowsInstaller && properties.ContainsKey("WindowsInstaller") && properties["WindowsInstaller"] == "1")
                        //{
                        //    continue;
                        //}

                        if (!includeSystemComponent && properties.ContainsKey("SystemComponent") && properties["SystemComponent"] == "1")
                        {
                            continue;
                        }

                        var productName = "";

                        if (!properties.TryGetValue("DisplayName", out productName))
                        {
                            // no product name?
                            continue;
                        }


                        if (IsMatch(name, productName) || IsMatch(displayname, productName))
                        {
                            var productVersion  = properties.Get("DisplayVersion") ?? "";
                            var publisher       = properties.Get("Publisher") ?? "";
                            var uninstallString = properties.Get("QuietUninstallString") ?? properties.Get("UninstallString") ?? "";
                            var comments        = properties.Get("Comments") ?? "";

                            var fp = hive + @"\" + subkey;

                            if (!string.IsNullOrEmpty(requiredVersion))
                            {
                                if (new SemanticVersion(requiredVersion) != new SemanticVersion(productVersion))
                                {
                                    continue;
                                }
                            }
                            else
                            {
                                if (!string.IsNullOrEmpty(minimumVersion) && new SemanticVersion(minimumVersion) > new SemanticVersion(productVersion))
                                {
                                    continue;
                                }
                                if (!string.IsNullOrEmpty(maximumVersion) && new SemanticVersion(maximumVersion) < new SemanticVersion(productVersion))
                                {
                                    continue;
                                }
                            }

                            fp = PackageSourceListRequest.MakeFastPathComplex(package.Destination ?? "", package.Name, package.DisplayName, productVersion, fp);

                            var source = properties.Get("InstallLocation") ?? "";
                            //we use name here because find-package uses name (not displayname) in the PSL.json,

                            if (request.YieldSoftwareIdentity(fp, name, productVersion, "unknown", comments, source, name, "", "") != null)
                            {
                                if (properties.Keys.Where(each => !string.IsNullOrWhiteSpace(each)).Any(k => request.AddMetadata(fp, k.MakeSafeFileName(), properties[k]) == null))
                                {
                                    return(false);
                                }
                            }
                        }
                    }
                }
            }
            return(true);
        }