Search code examples
c#google-apigoogle-drive-apigoogle-oauthgoogle-api-dotnet-client

Upload JPG file to Google Drive throwing System.UnauthorizedAccessException Access to the path 'c:\foldername' is denied


I am trying to upload a JPG from my local drive to Google Drive. I set up OAuth 2.0 Client IDs on Google Clouds APIs and Services. I added Everyone group to that folder. Also, grant full control permission. But, it still throws the following error when I run the program.

"Exception has occurred: CLR/System.UnauthorizedAccessException An unhandled exception of type 'System.UnauthorizedAccessException' occurred in System.Private.CoreLib.dll: 'Access to the path 'c:\folderName' is denied.'

The error throws on the following line

using (var stream = new FileStream(filePath,
                           FileMode.Open))
                {
                    // Create a new file, with metadata and stream.
                    request = service.Files.Create(
                        fileMetadata, stream, "image/jpeg");
                    request.Fields = "id";
                    request.Upload();
                }

Thank you for your help.

Here is my code:

    namespace DocUploader
{
    class Program
    {
        static string[] Scopes = { DriveService.Scope.Drive };
        static string ApplicationName = "App Name";

        static string filePath = "c:\\folderName";

        static void Main(string[] args)
        {
            try
            {
                UserCredential credential;
                // Load client secrets.
                using (var stream =
                       new FileStream("credentials.json", FileMode.Open, FileAccess.Read))
                {
                    string credPath = "token.json";
                    credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
                        GoogleClientSecrets.FromStream(stream).Secrets,
                        Scopes,
                        "user",
                        CancellationToken.None,
                        new FileDataStore(credPath, true)).Result;
                    Console.WriteLine("Credential file saved to: " + credPath);
                }

                // Create Drive API service.
                var service = new DriveService(new BaseClientService.Initializer
                {
                    HttpClientInitializer = credential,
                    ApplicationName = ApplicationName
                });

                // Upload file photo.jpg on drive.
                var fileMetadata = new Google.Apis.Drive.v3.Data.File()
                {
                    Name = "photo.jpg"
                };
                FilesResource.CreateMediaUpload request;
                // Create a new file on drive.
                using (var stream = new FileStream(filePath,
                           FileMode.Open))
                {
                    // Create a new file, with metadata and stream.
                    request = service.Files.Create(
                        fileMetadata, stream, "image/jpeg");
                    request.Fields = "id";
                    request.Upload();
                }

                var file = request.ResponseBody;
                // Prints the uploaded file id.
                Console.WriteLine("File ID: " + file.Id);
            }
            catch (Exception e)
            {
                if (e is AggregateException)
                {
                    Console.WriteLine("Credential Not found");
                }
                else if (e is FileNotFoundException)
                {
                    Console.WriteLine("File not found");
                }
                else
                {
                    throw;
                }
            }
        }
    }
}

Solution

  • The user you are running your code from does not have access to files stored in c:\folderName.

    beyond that i suspect that "c:\folderName"; is in fact the name of the folder. I dont think that the following will be able to load a FileStream for a folder.

    using (var stream = new FileStream(filePath, FileMode.Open))
    

    Upload Quickstart.

    using Google.Apis.Auth.OAuth2;
    using Google.Apis.Drive.v3;
    using Google.Apis.Services;
    using Google.Apis.Upload;
    
    Console.WriteLine("Hello, World!");
    
    // Installed file credentials from google developer console.
    const string credentialsJson = @"C:\Development\FreeLance\GoogleSamples\Credentials\credentials.json";
    
    // used to store authorization credentials.
    var userName = "user";
    
    // scope of authorization needed from the user
    var scopes = new[] { DriveService.Scope.Drive };
    
    // file to upload
    
    var filePath = @"C:\Development\FreeLance\GoogleSamples\Data\image.png";
    var fileName = Path.GetFileName(filePath);
    var folderToUploadTo = "root";
    
    
    var credential = GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.FromFile(credentialsJson).Secrets,
        scopes,
        userName,
        CancellationToken.None).Result;
    
    
    // Create the  Drive service.
    var service = new DriveService(new BaseClientService.Initializer()
    {
        HttpClientInitializer = credential,
        ApplicationName = "Daimto Drive upload Quickstart"
    });
    
    
    // Upload file photo.jpg on drive.
    var fileMetadata = new Google.Apis.Drive.v3.Data.File()
    {
        Name = fileName,
        Parents = new List<string>() { folderToUploadTo }
    };
    
    var fsSource = File.OpenRead(filePath);
    
    // Create a new file, with metadatafileName and stream.
    var request = service.Files.Create(
        fileMetadata, fsSource, "image/jpeg");
    request.Fields = "id";
    
    var results = await request.UploadAsync(CancellationToken.None);
    
    if (results.Status == UploadStatus.Failed)
    {
        Console.WriteLine($"Error uploading file: {results.Exception.Message}");
    }
    
    // the file id of the new file we created
    var fileId = request.ResponseBody?.Id;
    
    Console.WriteLine($"fileId {fileId}");
    
    Console.ReadLine();
    

    code slightly altered from: How to upload to Google Drive API from memory with C#