Download files from Google Drive with C# 4


Please Share

google drive Are you working on an application that needs download files from a users Google Drive account. I am going to show you how to do that using C# and the Google .Net Client library.

Prerequisite

The first thing we will need to do is import the Google Drive API v3 NuGet package

Install-Package Google.Apis.Drive.v3

Authenticate

File list is private data which means it is owned by a user. In order to access it you must be authenticated to that user. We also need a users permission to download the file once we have listed it.


        /// <summary>
        /// This method requests Authentcation from a user using Oauth2.  
        /// Credentials are stored in System.Environment.SpecialFolder.Personal
        /// Documentation https://developers.google.com/accounts/docs/OAuth2
        /// </summary>
        /// <param name="clientSecretJson">Path to the client secret json file from Google Developers console.</param>
        /// <param name="userName">Identifying string for the user who is being authentcated.</param>
        /// <returns>DriveService used to make requests against the Drive API</returns>
        public static DriveService AuthenticateOauth(string clientSecretJson, string userName)
        {
            try
            {
                if (string.IsNullOrEmpty(userName))
                    throw new ArgumentNullException("userName");
                if (string.IsNullOrEmpty(clientSecretJson))
                    throw new ArgumentNullException("clientSecretJson");
                if (!File.Exists(clientSecretJson))
                    throw new Exception("clientSecretJson file does not exist.");

                // These are the scopes of permissions you need. It is best to request only what you need and not all of them
                string[] scopes = new string[] { DriveService.Scope.DriveReadonly};         	//View the files in your Google Drive                                                 
                UserCredential credential;
                using (var stream = new FileStream(clientSecretJson, FileMode.Open, FileAccess.Read))
                {
                    string credPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
                    credPath = Path.Combine(credPath, ".credentials/", System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);

                    // Requesting Authentication or loading previously stored authentication for userName
                    credential = GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets,
                                                                             scopes,
                                                                             userName,
                                                                             CancellationToken.None,
                                                                             new FileDataStore(credPath, true)).Result;
                }

                // Create Drive API service.
                return new DriveService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = credential,
                    ApplicationName = "Drive Oauth2 Authentication Sample"
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine("Create Oauth2 account DriveService failed" + ex.Message);
                throw new Exception("CreateServiceAccountDriveFailed", ex);
            }
        }

File.List

My tutorial on searching for files with the file.list method contains the code you will need to list files. I wont be adding that here i recommend you check out that tutorial first. Search files with Google Drive with C#.


Download File

Downloading a file is done with the Files.get method and a media downloader from the client library to download your file.


 private static void DownloadFile(Google.Apis.Drive.v3.DriveService service, Google.Apis.Drive.v3.Data.File file, string saveTo)
        {

            var request = service.Files.Get(file.Id);
            var stream = new System.IO.MemoryStream();

            // Add a handler which will be notified on progress changes.
            // It will notify on each chunk download and when the
            // download is completed or failed.
            request.MediaDownloader.ProgressChanged += (Google.Apis.Download.IDownloadProgress progress) =>
               {
                   switch (progress.Status)
                   {
                       case Google.Apis.Download.DownloadStatus.Downloading:
                           {
                               Console.WriteLine(progress.BytesDownloaded);
                               break;
                           }
                       case Google.Apis.Download.DownloadStatus.Completed:
                           {
                               Console.WriteLine("Download complete.");
                               SaveStream(stream, saveTo);
                               break;
                           }
                       case Google.Apis.Download.DownloadStatus.Failed:
                           {
                               Console.WriteLine("Download failed.");
                               break;
                           }
                   }
               };
            request.Download(stream);

        }

Assuming that the file download succeeds then we save the file to the hard drive.


private static void SaveStream(System.IO.MemoryStream stream, string saveTo)
{
     using (System.IO.FileStream file = new System.IO.FileStream(saveTo, System.IO.FileMode.Create, System.IO.FileAccess.Write))
        {
         stream.WriteTo(file);
         }
}

Putting it all together

By using file.list I can search for the files that I am interested in then loop though each one downloading it.


// Connect to Google
var service = GoogleSamplecSharpSample.Drivev3.Auth.Oauth2Example.AuthenticateOauth(@"[Location of the Json cred file]", "test");
//List the files with the word 'make' in the name.
var files = DriveListExample.ListFiles(service, 
                 new DriveListExample.FilesListOptionalParms() { Q = "name contains 'Make'" , Fields= "*"});
foreach (var item in files.Files)
     {
     // download each file
     DriveDownload.Download(service, item, string.Format(@"C:\FilesFromGoogleDrive\{0}",item.Name));
      }

Conclusion

Downloading files from Google drive can be quite useful using media downloader makes it quite simple. I have considered setting up a windows service to mirror my google drive account down to my PC and back up to Google Drive. This way i can keep the data backed up and in sync.

Please Share


Linda Lawton

About Linda Lawton

My name is Linda Lawton I have more than 20 years experience working as an application developer and a database expert. I have also been working with Google APIs since 2012 and I have been contributing to the Google .Net client library since 2013. In 2013 I became a a Google Developer Experts for Google Analytics.


Leave a comment

Your email address will not be published. Required fields are marked *

4 thoughts on “Download files from Google Drive with C#