Home > OS >  Problem downloading file from Google Drive using service account
Problem downloading file from Google Drive using service account

Time:09-13

This code has had me scratching my head for a few days now.

I am trying to implement auto-updates for my application using Google Drive and a service account.

In my Google Drive there is a folder called Update which is shared with the service account. In the Update folder are two files, a text file called Version.txt which is a string of the latest version number, and an executable file Update.exe which is the latest application version.

I can read the Version.txt file fine but when I try to download the ~1MB executable, there is a delay in which it seems to go through the motions of downloading the file, but the memory stream ms2 is always empty afterwards.

Anyone have any ideas? It may be be something to do with the service account authentication but I am not sure how to fix it.

public class GoogleDriveAccess
{
    //google drive file IDs
    private readonly static string versionFileID = @"blahblahblahblah";
    private readonly static string updateFileID = @"blehblehblehbleh";

    //check for updated assembly on google drive and install if authorised
    public async static void CheckForUpdate()
    {
        try
        {
            //load json key file from resources into a byte array
            var jsonFile = Properties.Resources.drive_access;

            //create service account keyfile from json byte array
            var serviceAccountKeyfile = System.Text.Encoding.Default.GetString(jsonFile);

            //create Google credentials with full access from service account keyfile
            GoogleCredential credential = GoogleCredential.FromJson(serviceAccountKeyfile)
                .CreateScoped(new[] { DriveService.ScopeConstants.Drive });

            //create Google drive service using credentials
            DriveService service = new DriveService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential
            });

            //get version file metadata
            var getRequest = service.Files.Get(versionFileID);

            //download version file to memory
            await using var ms = new MemoryStream();
            await getRequest.DownloadAsync(ms);

            //read memory stream into a string
            ms.Position = 0;
            var sr = new StreamReader(ms);
            string textUpdateVersion = sr.ReadToEnd().Trim();

            //obtain our current assembly version
            Version currentVersion = Assembly.GetEntryAssembly().GetName().Version;

            //create an assembly version from the downloaded version text file
            Version updateVersion = new Version(textUpdateVersion);

            //if downloaded version is higher than our current version then request to download new assembly
            if (updateVersion > currentVersion)
            {
                //prompt user to commence update
                DialogResult result = MessageBox.Show($"Would you like to update to the latest version {updateVersion}?", Properties.Resources.AppName, MessageBoxButtons.YesNo);
                if (result == DialogResult.Yes)
                {
                    //get update file metadata
                    getRequest = service.Files.Get(updateFileID);

                    //download update file to memory
                    await using var ms2 = new MemoryStream();
                    await getRequest.DownloadAsync(ms2);

                    //***ms2 is always empty here***

                    //convert file to binary
                    ms2.Position = 0;
                    var br = new BinaryReader(ms2);
                    byte[] bin = br.ReadBytes(Convert.ToInt32(ms2.Length));

                    //rest of code

                }
            }
        }
        catch
        {
           //deal with any exceptions
        }
    }
}

CodePudding user response:

There is an optional pram for enter image description here

try and set that to true

getRequest = service.Files.Get(updateFileID);
getRequest.AcknowledgeAbuse  = true;

Then see if it wont let you download it.

CodePudding user response:

In the end it seems that Google thought my file was infected with a virus.

Adding getRequest.AcknowledgeAbuse did not change anything, the result was the same.

Changing the file extension from .exe to .bin also did not do anything as the web app still saw the filename as update.bin.exe.

In the end I had to delete the file from GD and re-upload it with the .bin extension.

Now my stream has the file contents at last.

  • Related