C#控制台程序获取Google Drive文件下载URL及下载配置咨询
搞定C#控制台程序通过Google Drive API v2下载文件的问题
嘿,我来帮你解决这个下载文件的问题!你现在能访问文件内容但没法下载,主要是没配置好权限,也没针对不同文件类型实现对应的下载逻辑。咱们一步步来:
一、先把Google Cloud项目的关键配置弄对
这是基础,没配置好的话API调用肯定出问题:
- 启用Google Drive API:登录Google Cloud Console,找到API库,搜索「Google Drive API」然后启用它。
- 创建桌面应用的OAuth凭据:
- 进入「凭据」页面,点击「创建凭据」→「OAuth客户端ID」。
- 应用类型选「桌面应用」,随便填个名称,创建后下载生成的
credentials.json文件,放到你的控制台项目根目录,记得在属性里设置「复制到输出目录」为「始终复制」。
- 配置OAuth同意屏幕:
- 切换到「OAuth同意屏幕」页面,选「外部」(个人测试的话选内部也可以)。
- 添加API范围:至少勾选
https://www.googleapis.com/auth/drive.readonly——要是你以后需要修改文件可以选更宽的drive范围,但下载只读就够了。
二、代码层面实现下载逻辑
你已经有了列文件的方法,现在要加下载的代码。注意要分两种情况:普通文件(比如PDF、图片)和Google原生文件(比如Docs、Sheets),后者得导出成指定格式才能下载。
1. 普通文件的直接下载方法
public static void DownloadFile(DriveService service, Google.Apis.Drive.v2.Data.File file, string savePath) { // 先判断这个文件能不能直接下载 if (string.IsNullOrEmpty(file.WebContentLink)) { Console.WriteLine($"⚠️ 文件「{file.Title}」不支持直接下载(大概率是Google原生文档)"); return; } // 发送请求下载文件 var downloadRequest = service.HttpClient.GetAsync(file.WebContentLink); downloadRequest.Wait(); // 把流写入本地文件 using (var stream = downloadRequest.Result.Content.ReadAsStreamAsync().Result) { using (var localFileStream = new FileStream(savePath, FileMode.Create, FileAccess.Write)) { stream.CopyTo(localFileStream); Console.WriteLine($"✅ 文件「{file.Title}」已下载到:{savePath}"); } } }
2. Google原生文件的导出下载方法
像Google Docs、Sheets这类文件,不能直接下载,得调用导出接口转成常见格式(比如PDF、docx):
public static void ExportGoogleFile(DriveService service, Google.Apis.Drive.v2.Data.File file, string savePath, string exportMimeType) { try { // 创建导出请求,指定文件ID和目标MIME类型 var exportRequest = service.Files.Export(file.Id, exportMimeType); using (var memoryStream = new MemoryStream()) { exportRequest.Download(memoryStream); // 把内存流写入本地文件 using (var localFileStream = new FileStream(savePath, FileMode.Create, FileAccess.Write)) { memoryStream.Position = 0; memoryStream.CopyTo(localFileStream); Console.WriteLine($"✅ Google文件「{file.Title}」已导出并保存到:{savePath}"); } } } catch (Exception ex) { Console.WriteLine($"❌ 导出文件失败:{ex.Message}"); } }
给你列几个常用的导出MIME类型对应:
- Google Docs →
application/vnd.openxmlformats-officedocument.wordprocessingml.document(转docx) - Google Sheets →
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet(转xlsx) - Google Slides →
application/vnd.openxmlformats-officedocument.presentationml.presentation(转pptx) - 所有原生文件都能转PDF →
application/pdf
3. 把列表和下载整合起来
在你的ListFiles方法之后,遍历文件列表,自动判断文件类型并下载:
public static void ListAndDownloadAllFiles(DriveService service, string localDownloadFolder) { var fileList = ListFiles(service); // 先创建本地下载文件夹 if (!Directory.Exists(localDownloadFolder)) { Directory.CreateDirectory(localDownloadFolder); } foreach (var file in fileList.Items) { // 判断是不是Google原生文件(MIME类型以application/vnd.google-apps.开头) bool isGoogleNative = file.MimeType.StartsWith("application/vnd.google-apps."); string baseSavePath = Path.Combine(localDownloadFolder, file.Title); if (isGoogleNative) { // 这里演示转成PDF,你可以根据文件类型换对应的MIME类型 ExportGoogleFile(service, file, $"{baseSavePath}.pdf", "application/pdf"); } else { // 简单处理重名问题,你可以根据需求优化 string finalSavePath = baseSavePath; int counter = 1; while (File.Exists(finalSavePath)) { finalSavePath = $"{baseSavePath}_{counter}"; counter++; } DownloadFile(service, file, finalSavePath); } } }
三、踩坑排查小贴士
- 要是碰到权限错误:检查OAuth范围是不是加对了,还有用户第一次授权的时候有没有允许对应的权限。
- 某些文件下载失败:确认你的授权账号有权限访问这个文件,文件没设成私有或者限制访问。
- 大文件下载:如果文件超过100MB,建议用分块下载,换成
service.Files.Get(file.Id).DownloadWithStatus(stream)来处理,避免内存爆掉。
内容的提问来源于stack exchange,提问作者Golnaz Saraji




