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方法仅支持上传单个文件,要上传完整文件夹需按以下步骤操作:
- 先在Google Drive上创建对应文件夹
- 遍历本地文件夹中的所有文件,逐个上传至刚创建的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
相关产品推荐
相关产品推荐

