You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#控制台程序上传文件夹至Google Drive遇权限拒绝问题

问题描述

开发C#控制台程序时,上传文件夹至Google Drive环节触发权限拒绝报错。完整流程及现状如下:

  • 创建新文件夹(正常运行)
  • 通过第三方API下载文件(正常运行)
  • 将文件移入新文件夹(正常运行)
  • 上传文件夹至Google Drive(报错:Access to the path 'C:\Users\tbrockington\source\repos\GoogleDriveBuildController\GoogleDriveBuildController\bin\Debug\Silhouette Go 1221' is denied.)

已确认信息:

  • 文件夹创建正常,直接上传单个.zip文件时流程可正常执行
  • Google API已开启,凭证文件credentials.json放置在bin目录
  • 控制台输出符合预期
  • 已关闭杀毒软件,处于开发环境
  • 尝试修改FileAccess.Read为.Write、添加自定义权限设置代码均无效
  • 程序需无人值守运行,无法手动修改文件夹权限

创建文件夹代码

public static async Task CreateFolderToStoreDownloads()
{
    // 获取可执行文件所在目录
    string currentDirectory = AppDomain.CurrentDomain.BaseDirectory;

    // 组合目标文件夹路径
    string targetFolder = Path.Combine(currentDirectory, $"{TargetDirectory}");

    try
    {
        // 检查文件夹是否已存在
        if (!Directory.Exists(targetFolder))
        {
            // 不存在则创建
            Directory.CreateDirectory($"{targetFolder}");
            Console.WriteLine("空文件夹创建成功。");
        }
        else
        {
            Console.WriteLine("文件夹已存在。");

            string newID = $"{EntryArgsName} {BuildId} 1";
            string newTargetFolder = Path.Combine(currentDirectory, $"{newID}");

            TargetDirectory = newID;

            Directory.CreateDirectory(newTargetFolder);
            Console.WriteLine($"新文件夹名称: {newID}");
            Console.WriteLine("");
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("发生错误: " + ex.Message);
    }
}

上传至Google Drive代码

public static async Task UploadFilesToGoogleDrive()
{
    Console.WriteLine($"正在上传目录: {TargetDirectory}");

    string credentialsPath = "credentials.json";
    // string folderId = "1Ro77nizxMbe_5RfsyLCPsIviHMJXiDd6";

    string filePath = $"{TargetDirectory}";

    GoogleCredential credential;

    using (var stream = new FileStream(credentialsPath, FileMode.Open, FileAccess.Read))
    {
        credential = GoogleCredential.FromStream(stream).CreateScoped(new[]
        {
            DriveService.ScopeConstants.DriveFile
        });
    }

    try
    {

        var service = new DriveService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = credential,
            ApplicationName = "Google DRIVE upload app"
        });


        var fileMetaData = new Google.Apis.Drive.v3.Data.File()
        {
            Name = Path.GetFileName(filePath),
        };

        FilesResource.CreateMediaUpload request;

        using (var stream = new FileStream(filePath, FileMode.Open))
        {
            request = service.Files.Create(fileMetaData, stream, "");
            request.Upload();
        }

        var uploadedFile = request.ResponseBody;

        // Console.WriteLine($"文件: {fileMetaData.Name} - 已上传,ID: {uploadedFile.Id}");

        Console.WriteLine("上传完成");
    }
    catch (Exception ex)
    {
        Console.WriteLine("");

        Console.WriteLine($"上传工件时出错: {ex.Message}");
    }
}

尝试过的无效权限设置代码

public static void RequestWritePermissions(string directoryPath)
{
    // 定义新的目录安全规则,添加写入权限
    DirectorySecurity directorySecurity = new DirectorySecurity();
    directorySecurity.AddAccessRule(new FileSystemAccessRule(Environment.UserName, FileSystemRights.Write, AccessControlType.Allow));

    // 为指定路径设置目录安全规则
    Directory.CreateDirectory(directoryPath, directorySecurity);
}

解决方案

核心错误:你试图用FileStream打开文件夹,但FileStream仅支持操作文件,无法直接打开文件夹,这才是权限拒绝报错的根本原因,与文件夹本身的权限设置无关。

Google Drive API的Files.Create方法仅支持上传单个文件,要上传完整文件夹需按以下步骤操作:

  1. 先在Google Drive上创建对应文件夹
  2. 遍历本地文件夹中的所有文件,逐个上传至刚创建的Drive文件夹下

修改后的上传代码示例

public static async Task UploadFolderToGoogleDrive()
{
    Console.WriteLine($"正在上传目录: {TargetDirectory}");
    string credentialsPath = "credentials.json";
    string localFolderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, TargetDirectory);

    // 初始化Drive服务
    GoogleCredential credential;
    using (var stream = new FileStream(credentialsPath, FileMode.Open, FileAccess.Read))
    {
        credential = GoogleCredential.FromStream(stream).CreateScoped(new[]
        {
            DriveService.ScopeConstants.DriveFile
        });
    }

    var service = new DriveService(new BaseClientService.Initializer()
    {
        HttpClientInitializer = credential,
        ApplicationName = "Google DRIVE upload app"
    });

    try
    {
        // 1. 在Google Drive上创建对应的文件夹
        var driveFolderMetadata = new Google.Apis.Drive.v3.Data.File()
        {
            Name = Path.GetFileName(localFolderPath),
            MimeType = "application/vnd.google-apps.folder"
        };

        var folderRequest = service.Files.Create(driveFolderMetadata);
        folderRequest.Fields = "id";
        var driveFolder = folderRequest.Execute();
        string driveFolderId = driveFolder.Id;
        Console.WriteLine($"Drive上已创建文件夹,ID: {driveFolderId}");

        // 2. 遍历本地文件夹中的所有文件并上传
        foreach (var filePath in Directory.GetFiles(localFolderPath))
        {
            // 适配.NET Core/.NET 5+:使用FileExtensionContentTypeProvider获取MIME类型
            var provider = new FileExtensionContentTypeProvider();
            if (!provider.TryGetContentType(filePath, out string mimeType))
            {
                mimeType = "application/octet-stream";
            }

            var fileMetadata = new Google.Apis.Drive.v3.Data.File()
            {
                Name = Path.GetFileName(filePath),
                Parents = new List<string> { driveFolderId } // 指定上传到刚创建的Drive文件夹下
            };

            using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                var uploadRequest = service.Files.Create(fileMetadata, stream, mimeType);
                uploadRequest.Upload();
                Console.WriteLine($"已上传文件: {Path.GetFileName(filePath)}");
            }
        }

        Console.WriteLine("整个文件夹上传完成");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"上传文件夹时出错: {ex.Message}");
    }
}

额外说明

  • 若使用.NET Core/.NET 5+,需安装Microsoft.AspNetCore.StaticFiles包以使用FileExtensionContentTypeProvider
  • 无需修改文件夹权限,问题根源为错误的文件操作方式而非权限不足

内容的提问来源于stack exchange,提问作者user22722316

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 16:02:35