C#でGoogle Drive APIを使う方法|認証からファイル操作まで初心者向けに解説
はじめに
C#でGoogle Driveを操作できるようになると、業務システムや社内ツールからファイルのアップロード、一覧取得、ダウンロード、共有設定の変更などを自動化できます。たとえば、帳票PDFをGoogle Driveに保存する、バックアップファイルを定期アップロードする、指定フォルダ内のファイルを検索して処理する、といった処理をC#アプリケーションから実行できます。
この記事では、C#でGoogle Drive APIを使うための準備から、OAuth認証、ファイル一覧取得、アップロード、ダウンロード、更新、削除、フォルダ操作、共有設定までを初心者向けに解説します。サンプルは.NETのコンソールアプリを前提にしていますが、基本的な考え方はWindows Forms、WPF、ASP.NET Coreでも応用できます。
1. C#でGoogle Drive APIを使う前に知っておきたいこと
1-1. Google Drive APIでできること
Google Drive APIは、Google Drive上のファイルやフォルダをアプリケーションから扱うためのAPIです。Google公式ドキュメントでは、Drive APIを使ってDriveへのファイルアップロード、Driveからのファイルダウンロード、ファイルやフォルダの検索、共有設定、Drive UIとの連携などができると説明されています。Google for Developers
C#からGoogle Drive APIを使うと、主に次のような処理を実装できます。
・Google Drive内のファイル一覧を取得する
・ファイル名、ファイルID、MIMEタイプなどのメタデータを取得する
・ローカルファイルをGoogle Driveへアップロードする
・Google Drive上のファイルをダウンロードする
・Googleドキュメント、スプレッドシート、スライドをPDFやExcel形式でエクスポートする
・フォルダを作成する
・指定フォルダへファイルを移動する
・ファイル名や説明などのメタデータを更新する
・ファイルをゴミ箱へ移動する
・ファイルを完全削除する
・閲覧権限や編集権限を付与する
・共有リンクを作成する
Google Driveでは、通常のPDF、画像、CSV、ZIPなどのファイルだけでなく、GoogleドキュメントやGoogleスプレッドシートのようなGoogle Workspace形式のファイルも扱います。通常ファイルはダウンロード、Google Workspace形式のファイルはエクスポート、という違いを理解しておくと実装で迷いにくくなります。
1-2. C#からGoogle Driveを操作する主な用途
C# Google Drive API連携は、特にWindowsアプリや社内業務システムでよく使われます。たとえば、次のような用途があります。
・請求書PDFを自動でGoogle Driveに保存する
・日次バッチでCSVやExcelファイルをアップロードする
・Google Drive上のファイルを検索してダウンロードする
・顧客別、案件別、日付別のフォルダを自動作成する
・アップロード後に社内メンバーへ共有権限を付与する
・バックアップファイルをクラウド上に保管する
・Windows FormsやWPFアプリからDriveをファイル置き場として使う
C#にはGoogle API Client Library for .NETが用意されているため、REST APIを直接HTTPで呼び出さなくても、DriveServiceクラスを通じてGoogle Drive APIを操作できます。Googleの.NETクライアントライブラリでは、Googleアカウント、Google API Consoleプロジェクト、対象APIのNuGetパッケージを準備して利用する流れが案内されています。Google for Developers
1-3. この記事で作成するサンプルアプリの全体像
この記事では、C#のコンソールアプリで次のような処理を実装します。
1. Google CloudでDrive APIを有効化する
2. OAuthクライアントIDを作成し、credentials.jsonを取得する
3. C#プロジェクトにGoogle.Apis.Drive.v3を追加する
4. OAuth認証でDriveServiceを作成する
5. ファイル一覧を取得する
6. ファイルをアップロードする
7. ファイルをダウンロードする
8. ファイルを更新・削除する
9. フォルダを作成・移動する
10. 共有権限を設定する
サンプルでは、認証済みユーザー本人のGoogle Driveを操作します。初心者が最初に試す場合は、サービスアカウントよりもOAuth認証のほうが動作を理解しやすいです。ユーザーがブラウザでGoogleアカウントにログインし、アプリにDriveアクセス権限を許可することで、C#アプリからそのユーザーのGoogle Driveを操作できます。
1-4. OAuth認証とサービスアカウント認証の違い
Google Drive APIの認証には、大きく分けてOAuth認証とサービスアカウント認証があります。
OAuth認証は、人間のGoogleユーザーとしてDriveにアクセスする方法です。ユーザーがブラウザでログインし、アプリに対して許可した範囲の操作を実行します。個人のGoogle Driveや、ユーザー本人がアクセスできる共有ドライブを操作する場合に使います。Googleの認証フローでは、アプリの登録、スコープの指定、同意画面、アクセストークンの取得、必要に応じたリフレッシュトークンの利用といった流れで認可が行われます。Google for Developers
サービスアカウント認証は、人ではなくアプリケーション用のアカウントとしてGoogle APIにアクセスする方法です。Google公式ドキュメントでも、サービスアカウントは人ではなくアプリケーションが使う特殊なアカウントであり、サービスアカウント自身として操作したり、Google WorkspaceやCloud Identityユーザーの代理として操作したりする用途で説明されています。Google for Developers
注意点として、サービスアカウントを作っただけでは、個人のマイドライブ内のすべてのファイルを自由に操作できるわけではありません。個人Driveのファイルを操作したい場合は、そのファイルやフォルダをサービスアカウントのメールアドレスに共有するか、Google Workspace環境でドメイン全体の委任を構成する必要があります。初心者が自分のGoogle DriveをC#から操作したい場合は、まずOAuth認証で試すのがおすすめです。
2. Google Drive APIを使うための事前準備
2-1. Google Cloudプロジェクトを作成する
C#からGoogle Drive APIを使うには、最初にGoogle Cloudプロジェクトを作成します。Google APIは、どのプロジェクトのアプリとしてAPIを呼び出すのかを管理するため、プロジェクト単位でAPIの有効化、認証情報、OAuth同意画面、クォータなどを設定します。
基本的な流れは次のとおりです。
1. Google Cloud Consoleを開く
2. プロジェクト選択メニューから「新しいプロジェクト」を作成する
3. プロジェクト名を入力する
4. 作成したプロジェクトを選択する
プロジェクト名は、開発用であれば CSharp Drive API Sample のような分かりやすい名前で問題ありません。本番環境で使う場合は、開発環境、ステージング環境、本番環境でプロジェクトを分けると管理しやすくなります。
2-2. Google Drive APIを有効化する
プロジェクトを作成したら、Google Drive APIを有効化します。Google Workspace APIは、利用するAPIをCloudプロジェクトで有効化してから呼び出します。GoogleのWorkspace開発ガイドでも、開発を始める手順として、プロジェクト作成、API有効化、認証・認可の理解、OAuth同意画面の構成が案内されています。Google for Developers
手順は次のとおりです。
1. Google Cloud Consoleで対象プロジェクトを選択する
2. 「APIとサービス」へ移動する
3. 「ライブラリ」を開く
4. 「Google Drive API」を検索する
5. Google Drive APIを選択する
6. 「有効にする」をクリックする
APIを有効化していない状態でC#コードからDrive APIを呼び出すと、APIが有効ではないというエラーになることがあります。認証コードが正しくてもAPIが無効だと動かないため、最初に確認しましょう。
2-3. OAuth同意画面を設定する
OAuth認証を使う場合は、OAuth同意画面を設定します。これは、ユーザーがアプリにDriveアクセス権限を許可するときに表示される画面です。Google公式ドキュメントでは、OAuth 2.0を使うすべてのアプリで同意画面の設定が必要であり、アプリが必要とする最小限のスコープを選ぶことが推奨されています。Google for Developers
開発用アプリでは、次の項目を設定します。
・アプリ名
・ユーザーサポートメール
・対象ユーザー
・デベロッパーの連絡先メール
・テストユーザー
・利用するスコープ
個人のGoogleアカウントで試す場合は、対象ユーザーを外部にし、テストユーザーに自分のGoogleアカウントを追加します。Google Workspace組織内だけで使う場合は、組織の設定によって内部アプリとして構成できる場合があります。
2-4. 認証情報を作成してJSONファイルを取得する
C#のデスクトップアプリやコンソールアプリでOAuth認証を行う場合は、OAuthクライアントIDを作成します。Google公式ドキュメントでは、エンドユーザーを認証してユーザーデータにアクセスするにはOAuth 2.0クライアントIDを作成し、アプリの種類ごとにクライアントIDを作ると説明されています。デスクトップアプリの場合は、アプリケーションの種類で「Desktop app」を選択します。Google for Developers
手順は次のとおりです。
1. Google Cloud Consoleで「APIとサービス」または「Google Auth Platform」を開く
2. 「認証情報」または「Clients」を開く
3. 「認証情報を作成」から「OAuthクライアントID」を選択する
4. アプリケーションの種類で「デスクトップアプリ」を選択する
5. 名前を入力して作成する
6. JSONファイルをダウンロードする
7. ファイル名を credentials.json に変更する
ダウンロードした credentials.json は、C#アプリがOAuth認証を開始するために使います。このファイルにはクライアントIDなどが含まれるため、GitHubなどの公開リポジトリにコミットしないようにしてください。
2-5. Google Drive APIのスコープを理解する
スコープは、アプリがGoogle Driveに対してどの範囲の操作を許可されるかを表す文字列です。Google Drive APIのスコープには、最小限の認可で済むものから、広い範囲のユーザーデータにアクセスする制限付きスコープまであります。Google公式ドキュメントでは、Drive APIのスコープは非機密、機密、制限付きに分類され、制限付きスコープをサーバーに保存または転送する場合はセキュリティ評価が必要になることがあると説明されています。Google for Developers
よく使うスコープの例は次のとおりです。
C#// Drive全体への広いアクセス
DriveService.Scope.Drive
// アプリが作成または開いたファイルへのアクセス
DriveService.Scope.DriveFile
// ファイルメタデータの読み取り
DriveService.Scope.DriveMetadataReadonly
// ファイルの読み取り
DriveService.Scope.DriveReadonly
初心者向けのサンプルでは、アップロード、更新、削除、共有設定まで試すために DriveService.Scope.Drive を使うことがあります。ただし、本番環境では必要最小限のスコープを選ぶことが重要です。ファイル一覧を読むだけなら読み取り専用スコープ、アプリが作成したファイルだけ扱えばよいなら DriveFile などを検討しましょう。
3. C#プロジェクトの作成と必要なライブラリの導入
3-1. .NETプロジェクトを作成する
まず、C#のコンソールアプリを作成します。ここでは.NET 8を例にしますが、Google.Apis.Drive.v3パッケージはNuGet上で.NET 6.0以上、.NET Standard 2.0、.NET Framework 4.6.2以上などに対応していることが示されています。nuget
ターミナルまたはコマンドプロンプトで次のコマンドを実行します。
Bashdotnet new console -n CSharpGoogleDriveSample
cd CSharpGoogleDriveSample
作成後の構成は次のようになります。
CSharpGoogleDriveSample
├─ CSharpGoogleDriveSample.csproj
└─ Program.cs
3-2. NuGetでGoogle Drive APIライブラリを追加する
Google Drive APIをC#から扱うために、Google.Apis.Drive.v3 を追加します。
Bashdotnet add package Google.Apis.Drive.v3
Visual Studioを使う場合は、NuGetパッケージマネージャーから Google.Apis.Drive.v3 を検索してインストールしても構いません。
Google.Apis.Drive.v3 を追加すると、DriveService、FilesResource、PermissionsResource、Drive API用のデータ型などをC#から利用できるようになります。
3-3. credentials.jsonを配置する
Google Cloud ConsoleからダウンロードしたOAuthクライアントのJSONファイルを、プロジェクト直下に credentials.json という名前で配置します。
CSharpGoogleDriveSample
├─ CSharpGoogleDriveSample.csproj
├─ Program.cs
└─ credentials.json
実行時に credentials.json が出力ディレクトリへコピーされるよう、.csproj に次の設定を追加しておくと便利です。
XML<ItemGroup>
<None Update="credentials.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
credentials.json が見つからない場合、C#コードで FileNotFoundException が発生します。Visual Studioから実行するとカレントディレクトリが bin/Debug/net8.0 などになるため、コピー設定を忘れないようにしましょう。
3-4. Program.csの基本構成を用意する
以降のサンプルでは、次の using を使います。File という名前は System.IO.File とGoogle Drive APIの Google.Apis.Drive.v3.Data.File で衝突しやすいため、エイリアスを付けておくと安全です。
C#using Google.Apis.Auth.OAuth2;
using Google.Apis.Download;
using Google.Apis.Drive.v3;
using Google.Apis.Services;
using Google.Apis.Upload;
using Google.Apis.Util.Store;
using DriveFile = Google.Apis.Drive.v3.Data.File;
using Permission = Google.Apis.Drive.v3.Data.Permission;
Program.cs は、まず次のような構成にします。
C#internal class Program
{
private const string ApplicationName = "CSharp Google Drive Sample";
private static readonly string[] Scopes =
{
DriveService.Scope.Drive
};
private static async Task Main(string[] args)
{
var service = await CreateDriveServiceAsync();
Console.WriteLine("Google Drive APIの認証に成功しました。");
}
private static async Task<DriveService> CreateDriveServiceAsync()
{
using var stream = new FileStream("credentials.json", FileMode.Open, FileAccess.Read);
var credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.FromStream(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore("token.json", true)
);
return new DriveService(new BaseClientService.Initializer
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName
});
}
}
この時点では、認証して DriveService を作るだけです。次の章で、この認証処理の意味を詳しく見ていきます。
4. C#でGoogle Drive APIの認証処理を実装する
4-1. OAuth認証でDriveServiceを作成する
C#からGoogle Drive APIを呼び出す中心になるのが DriveService です。DriveService は、認証済みのHTTPクライアントを内部で使い、Files.List()、Files.Create()、Files.Get()、Permissions.Create() などのAPI呼び出しを実行します。
OAuth認証で DriveService を作るコードは次のとおりです。
C#private static async Task<DriveService> CreateDriveServiceAsync()
{
using var stream = new FileStream("credentials.json", FileMode.Open, FileAccess.Read);
var credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.FromStream(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore("token.json", true)
);
var service = new DriveService(new BaseClientService.Initializer
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName
});
return service;
}
ここで重要なのは、credentials.json はアプリの認証情報であり、token.json はユーザーが許可した後に保存されるトークン情報だという点です。credentials.json を配置しただけではDriveへアクセスできません。初回実行時にユーザーがブラウザで許可して、はじめてアクセストークンを使えるようになります。
4-2. 初回認証時のブラウザ認可フロー
初回実行時には、ブラウザが開き、Googleアカウントへのログインとアプリへの許可画面が表示されます。ユーザーが許可すると、C#アプリに認可結果が戻り、Google Drive APIを呼び出せるようになります。
開発時によくある流れは次のとおりです。
1. C#アプリを起動する
2. ブラウザが開く
3. Googleアカウントでログインする
4. OAuth同意画面で権限を確認する
5. アクセスを許可する
6. C#アプリに制御が戻る
7. token.jsonにトークンが保存される
OAuth同意画面で「このアプリは確認されていません」と表示されることがあります。開発中の外部アプリではよくある表示です。テストユーザーとして追加したGoogleアカウントでアクセスしているか、OAuth同意画面の設定が完了しているかを確認しましょう。
4-3. アクセストークンとリフレッシュトークンの保存場所
サンプルコードでは、次の部分でトークンの保存先を指定しています。
C#new FileDataStore("token.json", true)
この設定では、アプリ実行時のディレクトリに token.json フォルダが作成され、その中に認証トークンが保存されます。2回目以降の実行では、このトークンを使って再認証を省略できます。
スコープを変更した場合は、既存のトークンに古い権限しか含まれていないことがあります。その場合は、token.json フォルダを削除してから再実行し、ブラウザで再度認可してください。
4-4. 認証エラーが出たときの確認ポイント
認証エラーが出た場合は、次の項目を確認します。
・credentials.jsonが正しい場所にあるか
・OAuthクライアントIDの種類がデスクトップアプリになっているか
・Google Drive APIが有効化されているか
・OAuth同意画面が設定されているか
・外部アプリの場合、ログインユーザーがテストユーザーに追加されているか
・スコープ変更後にtoken.jsonを削除したか
・PCのブラウザで正しいGoogleアカウントにログインしているか
Google Drive APIの401エラーは、有効なアクセストークンが含まれていない場合や、アクセストークンが期限切れまたは無効な場合、必要なスコープの認可が不足している場合に発生します。公式のエラー解説でも、401の authError は無効な認証情報やスコープ不足が原因になり得ると説明されています。Google for Developers
5. C#でGoogle Driveのファイル一覧を取得する方法
5-1. Drive内のファイル一覧を取得する基本コード
Google Drive内のファイル一覧は、service.Files.List() で取得します。
C#private static async Task ListFilesAsync(DriveService service)
{
var request = service.Files.List();
request.PageSize = 10;
request.Fields = "nextPageToken, files(id, name, mimeType)";
request.Q = "trashed = false";
var result = await request.ExecuteAsync();
foreach (var file in result.Files)
{
Console.WriteLine($"{file.Name} / {file.Id} / {file.MimeType}");
}
}
Fields を指定しているのは、必要な項目だけを取得するためです。Google Drive API v3では、必要なフィールドを明示することでレスポンスを軽くできます。ファイルID、ファイル名、MIMEタイプだけでよい場合は、files(id, name, mimeType) のように指定します。
Q = "trashed = false" は、ゴミ箱内のファイルを除外する検索条件です。ファイル一覧の取得では、ゴミ箱に入っているファイルが混ざると処理しづらいため、基本的には指定しておくとよいでしょう。
5-2. ファイル名・ID・MIMEタイプを取得する
Google Drive APIでファイルを操作するときは、ファイル名よりもファイルIDが重要です。Google Drive上では同じ名前のファイルが複数存在できるため、更新、削除、ダウンロード、共有設定ではファイルIDを使います。
C#private static async Task PrintFileMetadataAsync(DriveService service)
{
var request = service.Files.List();
request.PageSize = 20;
request.Fields = "files(id, name, mimeType, size, modifiedTime, webViewLink)";
request.Q = "trashed = false";
var files = await request.ExecuteAsync();
foreach (var file in files.Files)
{
Console.WriteLine("----------");
Console.WriteLine($"Name : {file.Name}");
Console.WriteLine($"Id : {file.Id}");
Console.WriteLine($"MimeType : {file.MimeType}");
Console.WriteLine($"Size : {file.Size}");
Console.WriteLine($"Modified : {file.ModifiedTimeDateTimeOffset}");
Console.WriteLine($"View Link : {file.WebViewLink}");
}
}
Size は通常のバイナリファイルでは取得できますが、GoogleドキュメントやGoogleスプレッドシートのようなGoogle Workspace形式では通常ファイルと扱いが異なります。ダウンロードやエクスポート処理でも、このMIMEタイプの違いを見て処理を分けます。
5-3. フォルダ内のファイルだけを取得する
特定フォルダ内のファイルだけを取得するには、フォルダIDを使って parents 条件を指定します。
C#private static async Task ListFilesInFolderAsync(DriveService service, string folderId)
{
var request = service.Files.List();
request.PageSize = 50;
request.Fields = "files(id, name, mimeType)";
request.Q = $"'{folderId}' in parents and trashed = false";
var result = await request.ExecuteAsync();
foreach (var file in result.Files)
{
Console.WriteLine($"{file.Name} / {file.Id} / {file.MimeType}");
}
}
フォルダIDは、Google DriveのURLから確認できます。
https://drive.google.com/drive/folders/ここがフォルダID
C# Google Drive API連携では、フォルダ名ではなくフォルダIDを使うのが基本です。フォルダ名は重複する可能性があるため、アプリ内では一度フォルダIDを取得して保存しておくと安定します。
5-4. 検索条件を指定してファイルを絞り込む
Google Drive APIでは、Q に検索条件を指定してファイルを絞り込めます。たとえば、PDFだけ取得したい場合は次のようにします。
C#private static async Task SearchPdfFilesAsync(DriveService service)
{
var request = service.Files.List();
request.PageSize = 20;
request.Fields = "files(id, name, mimeType)";
request.Q = "mimeType = 'application/pdf' and trashed = false";
var result = await request.ExecuteAsync();
foreach (var file in result.Files)
{
Console.WriteLine($"{file.Name} / {file.Id}");
}
}
ファイル名に特定の文字列を含むファイルを検索する場合は、name contains を使います。
C#request.Q = "name contains '請求書' and trashed = false";
フォルダだけを検索する場合は、フォルダのMIMEタイプを指定します。
C#request.Q = "mimeType = 'application/vnd.google-apps.folder' and trashed = false";
複数条件を組み合わせることで、実務に近い検索ができます。
C#request.Q = "name contains '2026' and mimeType = 'application/pdf' and trashed = false";
検索文字列にシングルクォートが含まれる場合は、エスケープ処理が必要です。ユーザー入力をそのまま Q に埋め込むとエラーや意図しない検索になることがあるため、アプリ側で入力値を制御しましょう。
6. C#でGoogle Driveにファイルをアップロードする方法
6-1. ローカルファイルをDriveにアップロードする
ローカルファイルをGoogle Driveへアップロードするには、service.Files.Create() を使います。Google Drive APIでは、ファイル作成時または更新時にファイルデータをアップロードできます。また、アップロードにはシンプルアップロード、マルチパートアップロード、再開可能アップロードがあり、5MBを超える大きなファイルや通信断の可能性がある場合は再開可能アップロードが推奨されています。Google for Developers
C#private static async Task<string?> UploadFileAsync(
DriveService service,
string localFilePath,
string mimeType)
{
var fileMetadata = new DriveFile
{
Name = Path.GetFileName(localFilePath)
};
await using var stream = new FileStream(localFilePath, FileMode.Open, FileAccess.Read);
var request = service.Files.Create(fileMetadata, stream, mimeType);
request.Fields = "id, name, webViewLink";
var progress = await request.UploadAsync();
if (progress.Status == UploadStatus.Completed)
{
var uploadedFile = request.ResponseBody;
Console.WriteLine($"アップロード成功: {uploadedFile.Name}");
Console.WriteLine($"File ID: {uploadedFile.Id}");
Console.WriteLine($"URL: {uploadedFile.WebViewLink}");
return uploadedFile.Id;
}
Console.WriteLine($"アップロード失敗: {progress.Exception?.Message}");
return null;
}
呼び出し例は次のとおりです。
C#var fileId = await UploadFileAsync(
service,
@"C:\temp\sample.pdf",
"application/pdf"
);
MIMEタイプが分からない場合は application/octet-stream を指定できますが、可能であれば正しいMIMEタイプを指定したほうがDrive上で扱いやすくなります。
6-2. アップロード先フォルダを指定する
特定のフォルダへアップロードしたい場合は、メタデータの Parents にフォルダIDを指定します。
C#private static async Task<string?> UploadFileToFolderAsync(
DriveService service,
string localFilePath,
string mimeType,
string folderId)
{
var fileMetadata = new DriveFile
{
Name = Path.GetFileName(localFilePath),
Parents = new List<string> { folderId }
};
await using var stream = new FileStream(localFilePath, FileMode.Open, FileAccess.Read);
var request = service.Files.Create(fileMetadata, stream, mimeType);
request.Fields = "id, name, parents";
var progress = await request.UploadAsync();
if (progress.Status == UploadStatus.Completed)
{
Console.WriteLine($"アップロード成功: {request.ResponseBody.Name}");
return request.ResponseBody.Id;
}
Console.WriteLine($"アップロード失敗: {progress.Exception?.Message}");
return null;
}
Google Driveでは、現在のAPI仕様では複数親フォルダを持つ通常ファイル運用はサポートされません。フォルダを指定するときは、基本的に1つの親フォルダIDを指定します。Google公式ドキュメントでも、ファイルは1つの親フォルダのみを持ち、複数の親指定はサポートされないと説明されています。Google for Developers
6-3. MIMEタイプを指定してアップロードする
代表的なMIMEタイプは次のとおりです。
PDF : application/pdf
CSV : text/csv
テキスト : text/plain
JPEG : image/jpeg
PNG : image/png
ZIP : application/zip
Excel .xlsx : application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Word .docx : application/vnd.openxmlformats-officedocument.wordprocessingml.document
PowerPoint .pptx : application/vnd.openxmlformats-officedocument.presentationml.presentation
拡張子から簡易的にMIMEタイプを判定する関数を作るなら、次のように書けます。
C#private static string GetMimeType(string path)
{
return Path.GetExtension(path).ToLowerInvariant() switch
{
".pdf" => "application/pdf",
".csv" => "text/csv",
".txt" => "text/plain",
".jpg" or ".jpeg" => "image/jpeg",
".png" => "image/png",
".zip" => "application/zip",
".xlsx" => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
".docx" => "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
".pptx" => "application/vnd.openxmlformats-officedocument.presentationml.presentation",
_ => "application/octet-stream"
};
}
呼び出し側では次のように使います。
C#var path = @"C:\temp\report.xlsx";
var mimeType = GetMimeType(path);
await UploadFileAsync(service, path, mimeType);
6-4. 大容量ファイルをアップロードするときの注意点
大容量ファイルをアップロードする場合は、通信エラーやタイムアウトを考慮する必要があります。Googleの.NETクライアントライブラリのメディアアップロードガイドでは、ストリームを小さなチャンクに分けてアップロードできる再開可能アップロードは、大きなファイルやネットワーク中断の可能性が高い状況で特に有用だと説明されています。Google for Developers
実務では、次の点に注意しましょう。
・アップロード対象ファイルが存在するか事前に確認する
・ファイルサイズをログに出す
・UploadAsyncの結果を確認する
・失敗時は例外メッセージを記録する
・同じファイルを何度も重複アップロードしないようにする
・大容量ファイルでは再試行設計を入れる
・API制限やユーザーのDrive容量制限を考慮する
ファイルサイズを確認してからアップロードする例です。
C#private static void ValidateLocalFile(string path)
{
if (!System.IO.File.Exists(path))
{
throw new FileNotFoundException("アップロード対象ファイルが見つかりません。", path);
}
var info = new FileInfo(path);
Console.WriteLine($"Upload file: {info.FullName}");
Console.WriteLine($"Size: {info.Length:N0} bytes");
}
7. C#でGoogle Driveのファイルをダウンロードする方法
7-1. ファイルIDを指定してダウンロードする
Google Drive上の通常ファイルをダウンロードするには、ファイルIDを指定して service.Files.Get(fileId) を使います。Google Drive APIでは、Blobファイルの内容を取得する場合、files.get に alt=media を指定する考え方になりますが、クライアントライブラリではダウンロードメソッドがその処理を扱います。Google for Developers
C#private static async Task DownloadFileAsync(
DriveService service,
string fileId,
string savePath)
{
var request = service.Files.Get(fileId);
await using var stream = new FileStream(savePath, FileMode.Create, FileAccess.Write);
var progress = await request.DownloadAsync(stream);
if (progress.Status == DownloadStatus.Completed)
{
Console.WriteLine($"ダウンロード成功: {savePath}");
}
else
{
Console.WriteLine($"ダウンロード失敗: {progress.Exception?.Message}");
}
}
呼び出し例です。
C#await DownloadFileAsync(
service,
"Google DriveのファイルID",
@"C:\temp\downloaded.pdf"
);
7-2. 保存先パスを指定する
保存先パスを指定するときは、保存先フォルダが存在するか確認してからダウンロードしましょう。
C#private static async Task DownloadFileSafelyAsync(
DriveService service,
string fileId,
string savePath)
{
var directory = Path.GetDirectoryName(savePath);
if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
var request = service.Files.Get(fileId);
await using var stream = new FileStream(savePath, FileMode.Create, FileAccess.Write);
var progress = await request.DownloadAsync(stream);
if (progress.Status != DownloadStatus.Completed)
{
throw new InvalidOperationException(
$"ダウンロードに失敗しました: {progress.Exception?.Message}"
);
}
}
同じファイル名がすでに存在する場合、上のコードでは上書きされます。上書きを避けたい場合は、事前にファイル存在チェックを入れて、ファイル名に日時を付けるなどの工夫をしてください。
7-3. Googleドキュメント形式のファイルをエクスポートする
Googleドキュメント、Googleスプレッドシート、Googleスライドなどは、通常のバイナリファイルとしてそのままダウンロードするのではなく、PDF、Excel、Wordなどの形式へエクスポートします。Google公式ドキュメントでも、Google Workspaceドキュメントの内容は files.export を使ってアプリが扱える形式にエクスポートすると説明されています。Google for Developers
GoogleドキュメントをPDFとして保存する例です。
C#private static async Task ExportGoogleDocAsPdfAsync(
DriveService service,
string fileId,
string savePath)
{
var request = service.Files.Export(fileId, "application/pdf");
await using var stream = new FileStream(savePath, FileMode.Create, FileAccess.Write);
var progress = await request.DownloadAsync(stream);
if (progress.Status == DownloadStatus.Completed)
{
Console.WriteLine($"PDFエクスポート成功: {savePath}");
}
else
{
Console.WriteLine($"PDFエクスポート失敗: {progress.Exception?.Message}");
}
}
GoogleスプレッドシートをExcel形式でエクスポートする場合は、次のMIMEタイプを使います。
C#await ExportFileAsync(
service,
"スプレッドシートのファイルID",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
@"C:\temp\sheet.xlsx"
);
汎用的なエクスポート関数は次のように書けます。
C#private static async Task ExportFileAsync(
DriveService service,
string fileId,
string exportMimeType,
string savePath)
{
var request = service.Files.Export(fileId, exportMimeType);
await using var stream = new FileStream(savePath, FileMode.Create, FileAccess.Write);
var progress = await request.DownloadAsync(stream);
if (progress.Status != DownloadStatus.Completed)
{
throw new InvalidOperationException(
$"エクスポートに失敗しました: {progress.Exception?.Message}"
);
}
}
7-4. ダウンロードできない場合の原因と対処法
ダウンロードできない場合は、次の原因が考えられます。
・ファイルIDが間違っている
・認証ユーザーにファイルの閲覧権限がない
・Google Workspace形式のファイルを通常ダウンロードしようとしている
・ダウンロードが制限されている
・共有ドライブのファイルでsupportsAllDrivesが必要
・保存先フォルダが存在しない
・保存先ファイルが別プロセスで開かれている
Google Drive APIのエラー解説では、Google Workspaceドキュメントに対して通常のダウンロードを行おうとすると fileNotDownloadable が発生し、Docs Editors形式のファイルはエクスポートを使うよう案内されています。Google for Developers
通常ファイルかGoogle Workspace形式かを判定するには、MIMEタイプを確認します。
C#private static async Task<DriveFile> GetFileMetadataAsync(
DriveService service,
string fileId)
{
var request = service.Files.Get(fileId);
request.Fields = "id, name, mimeType, capabilities";
return await request.ExecuteAsync();
}
取得した MimeType が application/vnd.google-apps.document などで始まる場合は、エクスポート処理を使いましょう。
8. C#でGoogle Driveのファイルを更新・削除する方法
8-1. ファイル名やメタデータを更新する
ファイル名などのメタデータを更新するには、service.Files.Update() を使います。Drive API v3の files.update は、ファイルのメタデータ、内容、またはその両方を更新できます。また、更新時は変更したいフィールドだけを指定する考え方です。Google for Developers
C#private static async Task RenameFileAsync(
DriveService service,
string fileId,
string newName)
{
var fileMetadata = new DriveFile
{
Name = newName
};
var request = service.Files.Update(fileMetadata, fileId);
request.Fields = "id, name, modifiedTime";
var updatedFile = await request.ExecuteAsync();
Console.WriteLine($"更新後のファイル名: {updatedFile.Name}");
}
説明文やスターなど、更新できるメタデータはDrive APIのファイルリソース仕様に依存します。更新したい項目だけを DriveFile に設定しましょう。
8-2. 既存ファイルの中身を上書きする
既存ファイルの内容を上書きする場合も、Files.Update を使います。
C#private static async Task UpdateFileContentAsync(
DriveService service,
string fileId,
string localFilePath,
string mimeType)
{
var fileMetadata = new DriveFile
{
Name = Path.GetFileName(localFilePath)
};
await using var stream = new FileStream(localFilePath, FileMode.Open, FileAccess.Read);
var request = service.Files.Update(fileMetadata, fileId, stream, mimeType);
request.Fields = "id, name, modifiedTime";
var progress = await request.UploadAsync();
if (progress.Status == UploadStatus.Completed)
{
var updated = request.ResponseBody;
Console.WriteLine($"上書き成功: {updated.Name}");
}
else
{
Console.WriteLine($"上書き失敗: {progress.Exception?.Message}");
}
}
更新対象のファイルIDを間違えると別のファイルを上書きする可能性があります。ファイル名だけで判断せず、更新前にファイルID、ファイル名、MIMEタイプをログに出すと安全です。
8-3. ファイルをゴミ箱へ移動する
ファイルをゴミ箱へ移動するには、メタデータの Trashed を true に更新します。
C#private static async Task MoveToTrashAsync(
DriveService service,
string fileId)
{
var fileMetadata = new DriveFile
{
Trashed = true
};
var request = service.Files.Update(fileMetadata, fileId);
request.Fields = "id, name, trashed";
var result = await request.ExecuteAsync();
Console.WriteLine($"ゴミ箱へ移動しました: {result.Name}");
}
ゴミ箱への移動は、完全削除よりも安全です。業務アプリでは、いきなり完全削除するよりも、まずゴミ箱へ移動する設計のほうが事故を防ぎやすくなります。
8-4. ファイルを完全削除する
ファイルを完全削除するには、service.Files.Delete(fileId) を使います。Google Drive APIの files.delete は、ユーザーが所有するファイルをゴミ箱に移動せず完全削除するメソッドとして説明されています。共有ドライブ内のファイルでは、親フォルダに対する適切な権限が必要です。Google for Developers
C#private static async Task DeleteFilePermanentlyAsync(
DriveService service,
string fileId)
{
await service.Files.Delete(fileId).ExecuteAsync();
Console.WriteLine("ファイルを完全削除しました。");
}
完全削除は元に戻せないため、実装時は確認処理を入れましょう。
C#Console.Write("本当に完全削除しますか? yes と入力してください: ");
var input = Console.ReadLine();
if (input == "yes")
{
await DeleteFilePermanentlyAsync(service, fileId);
}
else
{
Console.WriteLine("削除をキャンセルしました。");
}
本番環境では、削除対象のファイルID、ファイル名、実行ユーザー、実行日時をログに残すことをおすすめします。
9. C#でGoogle Driveのフォルダ操作を行う方法
9-1. フォルダを作成する
Google Drive APIでは、フォルダもファイルの一種として扱われます。フォルダを作成するには、MIMEタイプに application/vnd.google-apps.folder を指定します。
C#private static async Task<string> CreateFolderAsync(
DriveService service,
string folderName,
string? parentFolderId = null)
{
var folderMetadata = new DriveFile
{
Name = folderName,
MimeType = "application/vnd.google-apps.folder"
};
if (!string.IsNullOrEmpty(parentFolderId))
{
folderMetadata.Parents = new List<string> { parentFolderId };
}
var request = service.Files.Create(folderMetadata);
request.Fields = "id, name";
var folder = await request.ExecuteAsync();
Console.WriteLine($"フォルダ作成: {folder.Name} / {folder.Id}");
return folder.Id;
}
呼び出し例です。
C#var folderId = await CreateFolderAsync(service, "請求書_2026");
親フォルダを指定してサブフォルダを作る場合は、次のようにします。
C#var childFolderId = await CreateFolderAsync(
service,
"2026-06",
parentFolderId: "親フォルダID"
);
9-2. フォルダIDを取得する
フォルダIDを取得するには、フォルダのMIMEタイプで検索します。
C#private static async Task<string?> FindFolderIdByNameAsync(
DriveService service,
string folderName)
{
var escapedName = folderName.Replace("'", "\\'");
var request = service.Files.List();
request.PageSize = 10;
request.Fields = "files(id, name)";
request.Q =
$"name = '{escapedName}' and " +
"mimeType = 'application/vnd.google-apps.folder' and " +
"trashed = false";
var result = await request.ExecuteAsync();
var folder = result.Files.FirstOrDefault();
return folder?.Id;
}
フォルダ名は重複する可能性があります。完全に一意にしたい場合は、親フォルダIDも条件に含めます。
C#request.Q =
$"name = '{escapedName}' and " +
$"'{parentFolderId}' in parents and " +
"mimeType = 'application/vnd.google-apps.folder' and " +
"trashed = false";
9-3. 指定フォルダにファイルを移動する
ファイルを別フォルダへ移動するには、現在の親フォルダを削除し、新しい親フォルダを追加します。Google公式ドキュメントでも、ファイルを移動するには parents プロパティのIDを更新し、files.update() の addParents と removeParents を使うと説明されています。Google for Developers
C#private static async Task MoveFileToFolderAsync(
DriveService service,
string fileId,
string targetFolderId)
{
var getRequest = service.Files.Get(fileId);
getRequest.Fields = "parents";
var file = await getRequest.ExecuteAsync();
var previousParents = file.Parents != null
? string.Join(",", file.Parents)
: string.Empty;
var updateRequest = service.Files.Update(new DriveFile(), fileId);
updateRequest.AddParents = targetFolderId;
updateRequest.RemoveParents = previousParents;
updateRequest.Fields = "id, parents";
var updatedFile = await updateRequest.ExecuteAsync();
Console.WriteLine($"移動完了: {updatedFile.Id}");
}
共有ドライブを扱う場合は、必要に応じて SupportsAllDrives = true を設定します。
C#getRequest.SupportsAllDrives = true;
updateRequest.SupportsAllDrives = true;
9-4. フォルダ階層を扱うときの注意点
フォルダ階層を扱うときは、次の点に注意してください。
・フォルダ名は重複できる
・フォルダIDで管理する
・同じファイルに複数の親フォルダは指定しない
・共有ドライブでは権限や移動制限が異なる
・深すぎる階層や大量ファイルを持つフォルダはエラーの原因になる
・移動前に現在の親フォルダを取得する
Google Drive APIのエラー解説では、マイドライブや共有ドライブのフォルダ階層が深すぎる場合、100階層を超えられないというエラーが説明されています。また、フォルダ直下の子要素数にも制限があります。Google for Developers
実務では、次のように階層を浅く保つ設計がおすすめです。
/システム名
/取引先
/2026
/06
日付、顧客ID、案件IDなどを組み合わせて、検索しやすく、深くなりすぎないフォルダ構成にしましょう。
10. C#でGoogle Driveの共有設定を変更する方法
10-1. ファイルに閲覧権限を付与する
Google Drive APIでは、ファイルやフォルダごとに permissions リソースが関連付けられています。権限には、対象を表す type と、操作範囲を表す role があり、type には user、group、domain、anyone、role には reader、commenter、writer などがあります。Google for Developers
特定ユーザーに閲覧権限を付与するコードは次のとおりです。
C#private static async Task AddReaderPermissionAsync(
DriveService service,
string fileId,
string emailAddress)
{
var permission = new Permission
{
Type = "user",
Role = "reader",
EmailAddress = emailAddress
};
var request = service.Permissions.Create(permission, fileId);
request.Fields = "id";
var result = await request.ExecuteAsync();
Console.WriteLine($"閲覧権限を付与しました。Permission ID: {result.Id}");
}
reader は閲覧者に相当します。Drive UIでいう「閲覧者」とほぼ同じ意味です。
10-2. 編集権限を付与する
編集権限を付与する場合は、Role に writer を指定します。Google Drive APIのロール対応では、マイドライブ上の writer はDrive UIの「編集者」に対応し、ファイルの表示、コメント、編集が可能です。Google for Developers
C#private static async Task AddWriterPermissionAsync(
DriveService service,
string fileId,
string emailAddress)
{
var permission = new Permission
{
Type = "user",
Role = "writer",
EmailAddress = emailAddress
};
var request = service.Permissions.Create(permission, fileId);
request.Fields = "id";
var result = await request.ExecuteAsync();
Console.WriteLine($"編集権限を付与しました。Permission ID: {result.Id}");
}
編集権限は強い権限です。外部ユーザーに付与する場合は、誤って重要ファイルを編集されないよう、付与対象を十分に確認しましょう。
10-3. 共有リンクを作成する
「リンクを知っている全員が閲覧可」にしたい場合は、Type = "anyone"、Role = "reader" を指定します。
C#private static async Task CreatePublicReadLinkAsync(
DriveService service,
string fileId)
{
var permission = new Permission
{
Type = "anyone",
Role = "reader"
};
var createRequest = service.Permissions.Create(permission, fileId);
createRequest.Fields = "id";
await createRequest.ExecuteAsync();
var getRequest = service.Files.Get(fileId);
getRequest.Fields = "id, name, webViewLink";
var file = await getRequest.ExecuteAsync();
Console.WriteLine($"共有リンク: {file.WebViewLink}");
}
この設定は非常に便利ですが、URLを知っている人が閲覧できる状態になります。機密情報、個人情報、社内資料には安易に使わないようにしましょう。
10-4. 権限を削除・変更する
権限を変更するには、まず権限一覧を取得し、対象のPermission IDを確認します。
C#private static async Task ListPermissionsAsync(
DriveService service,
string fileId)
{
var request = service.Permissions.List(fileId);
request.Fields = "permissions(id, type, role, emailAddress)";
var result = await request.ExecuteAsync();
foreach (var permission in result.Permissions)
{
Console.WriteLine(
$"{permission.Id} / {permission.Type} / {permission.Role} / {permission.EmailAddress}"
);
}
}
権限を変更する例です。
C#private static async Task UpdatePermissionRoleAsync(
DriveService service,
string fileId,
string permissionId,
string newRole)
{
var permission = new Permission
{
Role = newRole
};
var request = service.Permissions.Update(permission, fileId, permissionId);
request.Fields = "id, role";
var updated = await request.ExecuteAsync();
Console.WriteLine($"権限を変更しました: {updated.Role}");
}
権限を削除する例です。
C#private static async Task DeletePermissionAsync(
DriveService service,
string fileId,
string permissionId)
{
await service.Permissions.Delete(fileId, permissionId).ExecuteAsync();
Console.WriteLine("権限を削除しました。");
}
共有設定では、親フォルダから継承された権限に注意が必要です。Google公式ドキュメントでは、フォルダの権限は子要素へ伝播し、継承された権限は元の親側で調整する必要があると説明されています。また、同じファイルに対する同時の権限操作はサポートされず、最後の更新だけが適用される点にも注意が必要です。Google for Developers
11. よくあるエラーと解決方法
11-1. 403 Forbiddenが発生する原因
403 Forbiddenは、権限不足、クォータ超過、共有ドライブの制限、ストレージ容量不足など、さまざまな理由で発生します。Google Drive APIのエラー解説では、403エラーは使用量制限を超えた場合や、ユーザーに正しい権限がない場合に発生すると説明されています。Google for Developers
主な原因は次のとおりです。
・ファイルへの編集権限がない
・Drive APIのスコープが不足している
・共有ドライブのメンバーではない
・ドメインポリシーでDriveアプリが制限されている
・レート制限に達した
・ユーザーのDrive容量が不足している
・フォルダ階層やファイル数の制限に達した
対処法としては、まず例外レスポンスの reason を確認します。insufficientFilePermissions ならファイル権限、rateLimitExceeded ならリトライやバックオフ、storageQuotaExceeded ならユーザーの保存容量を確認します。
C#では、例外を次のように捕捉してログを出すと調査しやすくなります。
C#try
{
await service.Files.Delete(fileId).ExecuteAsync();
}
catch (Google.GoogleApiException ex)
{
Console.WriteLine($"API Error Code: {ex.HttpStatusCode}");
Console.WriteLine($"Message: {ex.Message}");
}
11-2. 401 Unauthorizedが発生する原因
401 Unauthorizedは、認証情報が無効な場合に発生します。アクセストークンの期限切れ、トークン破損、スコープ不足、認証フローの失敗などが原因です。
確認ポイントは次のとおりです。
・token.jsonを削除して再認証する
・credentials.jsonが正しいプロジェクトのものか確認する
・OAuth同意画面で必要なスコープを追加しているか確認する
・Googleアカウントを切り替えていないか確認する
・アプリのOAuthクライアントIDを削除していないか確認する
開発中にスコープを変更した場合、古い token.json が残っていると新しいスコープが反映されません。その場合は token.json を削除して再実行してください。
11-3. APIが有効化されていない場合の対処法
Google Drive APIを有効化していない場合、C#コードが正しくてもAPI呼び出しは失敗します。次の手順で確認します。
1. Google Cloud Consoleを開く
2. 対象プロジェクトを選択する
3. 「APIとサービス」を開く
4. 「有効なAPIとサービス」を確認する
5. Google Drive APIがなければ「ライブラリ」から有効化する
複数のGoogle Cloudプロジェクトを使っている場合、credentials.json を作成したプロジェクトと、Drive APIを有効化したプロジェクトが違っていることがあります。プロジェクトIDを必ず確認しましょう。
11-4. スコープ不足による権限エラーの対処法
スコープ不足の場合は、C#コードの Scopes を確認します。
C#private static readonly string[] Scopes =
{
DriveService.Scope.Drive
};
読み取りだけなら DriveReadonly、メタデータ読み取りだけなら DriveMetadataReadonly、アプリが扱うファイルに限定するなら DriveFile など、必要に応じてスコープを選びます。
スコープを変更したら、次の操作を行います。
1. C#コードのScopesを変更する
2. Google CloudのOAuth同意画面に必要なスコープを追加する
3. ローカルのtoken.jsonを削除する
4. アプリを再実行する
5. ブラウザで再度アクセス許可する
本番環境では、広すぎるスコープを避け、必要最小限のスコープを使うことが重要です。GoogleのOAuth同意画面設定でも、ユーザーは限定的で明確なスコープほど許可しやすいため、アプリに不要なスコープを要求しないことが推奨されています。Google for Developers
11-5. ファイルIDやフォルダIDが見つからない場合の確認点
ファイルIDやフォルダIDが見つからない場合は、次の点を確認します。
・IDに余分な文字が含まれていないか
・URL全体をIDとして渡していないか
・認証ユーザーに閲覧権限があるか
・ファイルがゴミ箱に入っていないか
・共有ドライブのファイルでsupportsAllDrivesが必要ではないか
・別のGoogleアカウントで認証していないか
Google DriveのURL例です。
ファイル:
https://drive.google.com/file/d/FILE_ID/view
フォルダ:
https://drive.google.com/drive/folders/FOLDER_ID
C#コードに渡すのは、URL全体ではなく FILE_ID または FOLDER_ID の部分だけです。
共有ドライブのファイルを扱う場合は、必要に応じて次のようにします。
C#var request = service.Files.Get(fileId);
request.SupportsAllDrives = true;
request.Fields = "id, name, mimeType";
var file = await request.ExecuteAsync();
12. C#でGoogle Drive APIを安全に使うためのポイント
12-1. 認証情報JSONを公開しない
credentials.json、サービスアカウントキー、token.json は公開してはいけません。GitHubなどに誤ってコミットしないよう、.gitignore に追加します。
gitignorecredentials.json
token.json/
*.p12
service-account*.json
本番環境では、認証情報をアプリケーションフォルダに直置きするのではなく、シークレット管理サービス、環境変数、暗号化ストレージなどを使って管理しましょう。
12-2. 必要最小限のスコープを指定する
Google Drive APIでは、できるだけ必要最小限のスコープを使うことが重要です。たとえば、ファイル一覧を表示するだけのアプリに、ファイル削除まで可能な広いスコープを与えるべきではありません。
用途別の考え方は次のとおりです。
ファイルメタデータを読むだけ:
DriveService.Scope.DriveMetadataReadonly
ファイルを読むだけ:
DriveService.Scope.DriveReadonly
アプリが作成・選択したファイルを扱う:
DriveService.Scope.DriveFile
Drive全体を操作する:
DriveService.Scope.Drive
DriveService.Scope.Drive は便利ですが、広い権限を持つため、本番利用では慎重に検討してください。制限付きスコープを使うアプリでは、公開範囲やデータの扱いによって追加の確認やセキュリティ要件が必要になる場合があります。Google for Developers
12-3. 本番環境でのトークン管理
開発中は FileDataStore("token.json", true) でローカルにトークンを保存しても構いません。しかし、本番環境ではトークン管理を慎重に設計する必要があります。
本番環境で考慮すべき点は次のとおりです。
・ユーザーごとにトークンを分離して保存する
・トークンを暗号化する
・不要になったトークンを削除できるようにする
・スコープ変更時に再認可できるようにする
・ログにアクセストークンやリフレッシュトークンを出力しない
・退職者や権限変更時の運用を決める
ASP.NET CoreなどのWebアプリで使う場合は、コンソールアプリの認証フローをそのまま使うのではなく、Webアプリ向けのOAuthリダイレクトURI、セッション管理、ユーザーごとのトークン保存を設計します。
12-4. API制限とクォータに注意する
Google Drive APIには使用量制限があります。公式の使用制限ドキュメントでは、メソッドごとに消費するクォータ単位が異なり、たとえば files.get のような読み取り、files.list のような一覧取得、files.update のような編集で消費量が異なることが示されています。また、ユーザーごとのアップロード量やファイルサイズにも制限があります。Google for Developers
クォータやレート制限に備えるには、次の対策が有効です。
・不要なAPI呼び出しを減らす
・Fieldsで必要な項目だけ取得する
・同じファイル情報を短時間に何度も取得しない
・大量処理では間隔を空ける
・429やrateLimitExceededでは指数バックオフで再試行する
・ファイル一覧取得ではページングを使う
ページング処理の例です。
C#private static async Task ListAllFilesAsync(DriveService service)
{
string? pageToken = null;
do
{
var request = service.Files.List();
request.PageSize = 100;
request.PageToken = pageToken;
request.Fields = "nextPageToken, files(id, name)";
request.Q = "trashed = false";
var result = await request.ExecuteAsync();
foreach (var file in result.Files)
{
Console.WriteLine($"{file.Name} / {file.Id}");
}
pageToken = result.NextPageToken;
} while (!string.IsNullOrEmpty(pageToken));
}
大量のファイルを扱う場合は、一覧取得、検索、更新、共有設定のAPI呼び出し回数が増えやすいため、設計段階でクォータを意識しておきましょう。
13. C# Google Drive APIに関するよくある質問
13-1. 無料でGoogle Drive APIは使える?
開発や一般的な利用では、Google Drive APIはクォータの範囲内で使えます。ただし、APIには使用制限があり、Google Workspaceユーザーのアップロード量やプロジェクト単位のクォータ単位などに制限があります。公式ドキュメントでは、日次の課金しきい値やメソッドごとのクォータ消費量、アップロード量の制約が案内されています。Google for Developers
また、Google Driveの保存容量はGoogleアカウントやGoogle Workspaceのプランに依存します。APIが使えることと、Driveに無制限に保存できることは別です。大量アップロードや業務利用では、保存容量、APIクォータ、組織のポリシーを確認してください。
13-2. Windows FormsやWPFでも使える?
Windows FormsやWPFでも、この記事の DriveService を作る処理は利用できます。違いは、コンソール出力ではなく、ボタンクリックや画面表示に処理を組み込む点です。
たとえば、WPFのボタンクリックでアップロードする場合は、次のような流れになります。
C#private async void UploadButton_Click(object sender, EventArgs e)
{
var service = await CreateDriveServiceAsync();
var path = @"C:\temp\sample.pdf";
var mimeType = GetMimeType(path);
var fileId = await UploadFileAsync(service, path, mimeType);
MessageBox.Show($"アップロード完了: {fileId}");
}
GUIアプリでは、API呼び出し中に画面が固まらないよう、async / await を使って非同期処理にすることが重要です。
13-3. ASP.NET Coreで使う場合はどうする?
ASP.NET CoreでGoogle Drive APIを使う場合は、コンソールアプリとは認証設計が異なります。コンソールアプリの GoogleWebAuthorizationBroker.AuthorizeAsync() は、ローカルユーザーがブラウザで認証する用途に向いています。一方、Webアプリでは、OAuthのリダイレクトURI、ログインユーザーごとのトークン保存、Cookieやセッションとの連携が必要です。
ASP.NET Coreでの典型的な設計は次のとおりです。
・GoogleログインまたはOAuth認可画面へリダイレクトする
・認可コードをコールバックURLで受け取る
・アクセストークンとリフレッシュトークンを取得する
・ユーザーIDに紐づけてトークンを安全に保存する
・DriveServiceをユーザーごとに作成する
サーバー側で複数ユーザーのDriveを扱う場合は、トークンの保存と削除、再認可、スコープ変更時の処理を必ず設計しましょう。
13-4. サービスアカウントで個人のGoogle Driveを操作できる?
サービスアカウントは、作成しただけでは個人のGoogle Driveを自由に操作できません。サービスアカウントは人間のGoogleアカウントとは別のアカウントです。そのため、個人のマイドライブ内のファイルを操作したい場合は、対象ファイルやフォルダをサービスアカウントのメールアドレスに共有する必要があります。
サービスアカウントでDriveServiceを作る基本コードは次のようになります。
C#private static DriveService CreateDriveServiceWithServiceAccount()
{
var credential = GoogleCredential
.FromFile("service-account.json")
.CreateScoped(DriveService.Scope.Drive);
return new DriveService(new BaseClientService.Initializer
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName
});
}
Google Workspace環境では、管理者がドメイン全体の委任を構成することで、サービスアカウントがユーザーの代理として操作できる場合があります。ただし、これは管理者設定とセキュリティ設計が必要な高度な構成です。個人利用や初心者の検証では、OAuth認証を使うほうが分かりやすいです。
13-5. Google Drive API v2とv3はどちらを使うべき?
新しくC#でGoogle Drive APIを使うなら、基本的にはDrive API v3を使うべきです。この記事でも Google.Apis.Drive.v3 を使っています。Google Drive API v3のRESTリファレンスでは、Drive API v3のサービスエンドポイントや各リソース、メソッドが現在のAPIとして案内されています。Google for Developers
v2とv3では、メソッド名、レスポンスのフィールド、ファイル一覧取得時の挙動などが異なる部分があります。古い記事やサンプルでは Google.Apis.Drive.v2 や Files.Insert が使われていることがありますが、これから実装する場合は Google.Apis.Drive.v3、Files.Create、Files.Update などv3の書き方に合わせましょう。
まとめ
C#でGoogle Drive APIを使うには、Google Cloudプロジェクトの作成、Google Drive APIの有効化、OAuth同意画面の設定、認証情報JSONの取得、NuGetパッケージの追加、OAuth認証による DriveService の作成が必要です。
基本の流れは次のとおりです。
1. Google Cloudでプロジェクトを作成する
2. Google Drive APIを有効化する
3. OAuth同意画面を設定する
4. OAuthクライアントIDを作成する
5. credentials.jsonをC#プロジェクトに配置する
6. Google.Apis.Drive.v3をNuGetで追加する
7. DriveServiceを作成する
8. Files.Listで一覧取得する
9. Files.Createでアップロードする
10. Files.GetまたはFiles.Exportでダウンロードする
11. Files.Updateで更新する
12. Files.Deleteで完全削除する
13. Permissions.Createで共有設定を変更する
初心者は、まずOAuth認証で自分のGoogle Driveのファイル一覧を取得するところから始めると理解しやすいです。その後、アップロード、ダウンロード、フォルダ作成、共有設定の順に機能を追加していけば、C#からGoogle Driveを実用的に操作できるようになります。
実務で使う場合は、認証情報を公開しないこと、必要最小限のスコープを使うこと、トークンを安全に保存すること、APIクォータやエラー時の再試行を考慮することが重要です。C#とGoogle Drive APIを組み合わせれば、ファイル管理、バックアップ、帳票保存、社内共有など、多くの業務を自動化できます。

