src/Microsoft.PackageManagement.NuGetProvider/NugetLightClient.cs
/// <summary>
/// Download a package that matches the given version and name and install it on the local system.
/// </summary>
/// <param name="packageName">Package name</param>
/// <param name="version">Package version</param>
/// <param name="request">An object passed in from the PackageManagement platform that contains APIs that can be used to interact with it </param>  
/// <param name="source">Package source</param>
/// <param name="queryUrl">Full uri</param>
/// <param name="packageHash">the hash of the package</param>
/// <param name="packageHashAlgorithm">the hash algorithm of the package</param>
/// <param name="progressTracker">progress tracker to help keep track of progressid, start and end of the progress</param>
/// <returns>PackageItem object</returns>
Download a package that matches the given version and name and install it on the local system.
Download a package that matches the given version and name and install it on the local system .
internal static PackageItem InstallPackage(
            string packageName,
            string version,
            NuGetRequest request,
            PackageSource source,
            string queryUrl,
            string packageHash,
            string packageHashAlgorithm,
            ProgressTracker progressTracker
            ) 
        {
            request.Debug(Messages.DebugInfoCallMethod, "NuGetClient", "InstallPackage");
            string destinationPath = request.Destination;
            request.Verbose(string.Format(CultureInfo.InvariantCulture, "InstallPackage' - name='{0}', version='{1}',destination='{2}'", packageName, version, destinationPath));
            string directoryToDeleteWhenFailed = string.Empty;
            bool needToDelete = false;
            string installFullPath = string.Empty;
            try
            {
                if (!Directory.Exists(destinationPath)) {
                    Directory.CreateDirectory(destinationPath);
                    directoryToDeleteWhenFailed = destinationPath;
                }
                string installDir = FileUtility.MakePackageDirectoryName(request.ExcludeVersion.Value, destinationPath, packageName, version);
                if (!Directory.Exists(installDir)) {
                    Directory.CreateDirectory(installDir);
                    if (String.IsNullOrWhiteSpace(directoryToDeleteWhenFailed))
                    {
                        directoryToDeleteWhenFailed = installDir;
                    }
                }
                string fileName = FileUtility.MakePackageFileName(request.ExcludeVersion.Value, packageName, version, NuGetConstant.PackageExtension);
                installFullPath = Path.Combine(installDir, fileName);
                int endProgressDownloading = progressTracker.ConvertPercentToProgress(0.7);
                DownloadPackage(packageName, version, installFullPath, queryUrl, request, source, new ProgressTracker(progressTracker.ProgressID, progressTracker.StartPercent, endProgressDownloading));
                if (!File.Exists(installFullPath))
                {
                    needToDelete = true;
                    request.WriteError(ErrorCategory.ResourceUnavailable, installFullPath, Constants.Messages.PackageFailedInstallOrDownload, packageName,
                        CultureInfo.CurrentCulture.TextInfo.ToLower(Constants.Download));
                    return null;
                }
                #region verify hash
                if (string.IsNullOrWhiteSpace(packageHash))
                {
                    request.Verbose(string.Format(CultureInfo.CurrentCulture, Resources.Messages.HashNotFound, packageName));
                    var pkgItem = InstallPackageLocal(packageName, version, request, source, installFullPath, new ProgressTracker(progressTracker.ProgressID, endProgressDownloading, progressTracker.EndPercent));
                    return pkgItem;
                }
                using (FileStream stream = File.OpenRead(installFullPath))
                {
                    HashAlgorithm hashAlgorithm = null;
                    switch (packageHashAlgorithm == null ? string.Empty : packageHashAlgorithm.ToLowerInvariant())
                    {
                        case "sha256":
                            hashAlgorithm = SHA256.Create();
                            break;
                        case "md5":
                            hashAlgorithm = MD5.Create();
                            break;
                        case "sha512":
                        default:
                            hashAlgorithm = SHA512.Create();
                            break;
                    }
                    if (hashAlgorithm == null)
                    {
                        needToDelete = true;
                        request.WriteError(ErrorCategory.SecurityError, packageHashAlgorithm, Constants.Messages.HashNotSupported, packageHashAlgorithm);
                        return null;
                    }
                    byte[] computedHash = hashAlgorithm.ComputeHash(stream);
                    byte[] downloadedHash = Convert.FromBase64String(packageHash);
                    if (!Enumerable.SequenceEqual(computedHash, downloadedHash))
                    {
                        request.Verbose(Constants.Messages.HashNotMatch, packageName);
                    }
                    var pkgItem = InstallPackageLocal(packageName, version, request, source, installFullPath, new ProgressTracker(progressTracker.ProgressID, endProgressDownloading, progressTracker.EndPercent));
                    return pkgItem;
                }
                #endregion
            }
            catch (Exception ex)
            {
                ex.Dump(request);
                request.WriteError(ErrorCategory.InvalidResult, packageName, Resources.Messages.PackageFailedToInstallReason, packageName, ex.Message);
                needToDelete = true;
            }
            finally
            {
                if (needToDelete)
                {
                    if (!String.IsNullOrWhiteSpace(directoryToDeleteWhenFailed) && Directory.Exists(directoryToDeleteWhenFailed))
                    {
                        try
                        {
                            FileUtility.DeleteDirectory(directoryToDeleteWhenFailed, true, isThrow: false);
                        }
                        catch { }
                    }
                    if (File.Exists(installFullPath))
                    {
                        FileUtility.DeleteFile(installFullPath, isThrow: false);
                    }
                }
            }
            return null;
        }
internal static PackageItem InstallPackage ( string packageName , string version , NuGetRequest request , PackageSource source , string queryUrl , string packageHash , string packageHashAlgorithm , ProgressTracker progressTracker ) { request . Debug ( Messages . DebugInfoCallMethod , " " , " " ) ; string destinationPath = request . Destination ; request . Verbose ( string . Format ( CultureInfo . InvariantCulture , " " , packageName , version , destinationPath ) ) ; string directoryToDeleteWhenFailed = string . Empty ; bool needToDelete = false ; string installFullPath = string . Empty ; try { if ( ! Directory . Exists ( destinationPath ) ) { Directory . CreateDirectory ( destinationPath ) ; directoryToDeleteWhenFailed = destinationPath ; } string installDir = FileUtility . MakePackageDirectoryName ( request . ExcludeVersion . Value , destinationPath , packageName , version ) ; if ( ! Directory . Exists ( installDir ) ) { Directory . CreateDirectory ( installDir ) ; if ( String . IsNullOrWhiteSpace ( directoryToDeleteWhenFailed ) ) { directoryToDeleteWhenFailed = installDir ; } } string fileName = FileUtility . MakePackageFileName ( request . ExcludeVersion . Value , packageName , version , NuGetConstant . PackageExtension ) ; installFullPath = Path . Combine ( installDir , fileName ) ; int endProgressDownloading = progressTracker . ConvertPercentToProgress ( 0.7 ) ; DownloadPackage ( packageName , version , installFullPath , queryUrl , request , source , new ProgressTracker ( progressTracker . ProgressID , progressTracker . StartPercent , endProgressDownloading ) ) ; if ( ! File . Exists ( installFullPath ) ) { needToDelete = true ; request . WriteError ( ErrorCategory . ResourceUnavailable , installFullPath , Constants . Messages . PackageFailedInstallOrDownload , packageName , CultureInfo . CurrentCulture . TextInfo . ToLower ( Constants . Download ) ) ; return null ; } region  verify hash if ( string . IsNullOrWhiteSpace ( packageHash ) ) { request . Verbose ( string . Format ( CultureInfo . CurrentCulture , Resources . Messages . HashNotFound , packageName ) ) ; var pkgItem = InstallPackageLocal ( packageName , version , request , source , installFullPath , new ProgressTracker ( progressTracker . ProgressID , endProgressDownloading , progressTracker . EndPercent ) ) ; return pkgItem ; } using ( FileStream stream = File . OpenRead ( installFullPath ) ) { HashAlgorithm hashAlgorithm = null ; switch ( packageHashAlgorithm == null ? string . Empty : packageHashAlgorithm . ToLowerInvariant ( ) ) { case " " : hashAlgorithm = SHA256 . Create ( ) ; break ; case " " : hashAlgorithm = MD5 . Create ( ) ; break ; case " " : default : hashAlgorithm = SHA512 . Create ( ) ; break ; } if ( hashAlgorithm == null ) { needToDelete = true ; request . WriteError ( ErrorCategory . SecurityError , packageHashAlgorithm , Constants . Messages . HashNotSupported , packageHashAlgorithm ) ; return null ; } byte [ ] computedHash = hashAlgorithm . ComputeHash ( stream ) ; byte [ ] downloadedHash = Convert . FromBase64String ( packageHash ) ; if ( ! Enumerable . SequenceEqual ( computedHash , downloadedHash ) ) { request . Verbose ( Constants . Messages . HashNotMatch , packageName ) ; } var pkgItem = InstallPackageLocal ( packageName , version , request , source , installFullPath , new ProgressTracker ( progressTracker . ProgressID , endProgressDownloading , progressTracker . EndPercent ) ) ; return pkgItem ; } endregion } catch ( Exception ex ) { ex . Dump ( request ) ; request . WriteError ( ErrorCategory . InvalidResult , packageName , Resources . Messages . PackageFailedToInstallReason , packageName , ex . Message ) ; needToDelete = true ; } finally { if ( needToDelete ) { if ( ! String . IsNullOrWhiteSpace ( directoryToDeleteWhenFailed ) && Directory . Exists ( directoryToDeleteWhenFailed ) ) { try { FileUtility . DeleteDirectory ( directoryToDeleteWhenFailed , true , isThrow : false ) ; } catch { } } if ( File . Exists ( installFullPath ) ) { FileUtility . DeleteFile ( installFullPath , isThrow : false ) ; } } } return null ; }
Download a package that matches the given version and name and install it on the local system.
Download a package that matches the given version and name and install it on the local system .
//If the destination folder does not exists, create it // delete the destinationPath later on if we fail to install and if destinationPath did not exist before //Create a folder under the destination path to hold the package // if directoryToDeleteWhenFailed is null then the destinationPath already exists before so we should not delete it //Get the package file name based on the version and id // we assume downloading takes 70% of the progress //download to fetch the package // check that we have the file // error message is package failed to be downloaded //we don't enable checking for hash here because it seems like nuget provider does not //checks that there is hash. Otherwise we don't carry out the install // if no hash (for example, vsts feed, install the package but log verbose message) //parse the package // Verify the hash // Flows to default case // default to sha512 algorithm // delete the file downloaded. VIRUS!!! // compute the hash // convert the original hash we got from the feed // if they are not equal, just issue out verbose because there is a current bug in backend // where editing the published module will result in a package with a different hash than the one // provided on the feed // delete the file downloaded. VIRUS!!! //parse the package // the error will be package "packageName" failed to install because : "reason" // if the directory exists just delete it because it will contains the file as well // if for some reason, we can't delete the directory or if we don't need to delete the directory // then we have to delete installFullPath
None
packageName
string
None
version
string
None
request
NuGetRequest
An object passed in from the PackageManagement platform that contains APIs that can be used to interact with it
An object passed in from the PackageManagement platform that contains APIs that can be used to interact with it
source
PackageSource
None
queryUrl
string
None
packageHash
string
the hash of the package
the hash of the package
packageHashAlgorithm
string
the hash algorithm of the package
the hash algorithm of the package
progressTracker
ProgressTracker
progress tracker to help keep track of progressid, start and end of the progress
progress tracker to help keep track of progressid start and end of the progress