Google Driveのファイル、フォルダの一覧を取得する - C#

C#でGoogle Driveのファイル、フォルダの一覧を取得するコードを紹介します。

事前準備

Google Drive API の有効化

Google Drive APIを有効化します。手順はこちらの記事を参照してください。

Google APIのサービスアカウントを作成

Google APIのサービスアカウントを作成します。アカウントの作成手順はこちらの記事 を参照してください。

Google API サービスアカウントの認証キーを作成

Google API サービスアカウントの認証キーを作成します。 作成の具体的な手順はこちらの記事を参照してください。
今回はJSON形式のキーファイルを作成しています。

Google Driveの準備

Google Drive にログインし共有フォルダを作成し、先の手順で作成したサービスアカウントと共有します。
具体的な操作手順はこちらの記事を参照して下さい。

C#プロジェクトの作成

C#のプロジェクトを作成します。今回はWindows Formアプリケーションを作成します。
作成したプロジェクトに Google.Apis.Drive.V3 パッケージをインストールします。 インストールの手順はこちらの記事を参照してください。

プログラム1

キーファイルの配置

プロジェクトフォルダにJSON形式で取得したキーファイルを配置します。プロパティウィンドウで[出力ディレクトリにコピー]のプロパティを "常にコピーする"に設定して、ファイルが出力ディレクトリに配置される設定にします。

UI

下図のフォームを作成します。ボタンと複数行のテキストボックスを配置します。

コード

下記コードを記述します。button1のクリックイベントを実装します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Google.Apis.Drive.v3;
using System.IO;

namespace GoogleDriveView
{
  public partial class FormSimpleView : Form
  {
    public FormSimpleView()
    {
      InitializeComponent();
    }

    static string[] Scopes = { DriveService.Scope.Drive };
    string credPath = "token.json";

    private void button1_Click(object sender, EventArgs e)
    {
      FileStream fs = new FileStream("(取得したJSON形式のキーファイル名)", FileMode.Open, FileAccess.Read);
      Google.Apis.Auth.OAuth2.GoogleCredential credential = Google.Apis.Auth.OAuth2.GoogleCredential.FromStream(fs).CreateScoped(Scopes);

      Google.Apis.Services.BaseClientService.Initializer init = new Google.Apis.Services.BaseClientService.Initializer();
      init.HttpClientInitializer = credential;
      init.ApplicationName = "My Test App";
      DriveService service = new DriveService(init);

      FilesResource.ListRequest listRequest = service.Files.List();
      listRequest.PageSize = 1000;
      listRequest.Fields = "nextPageToken, files(id, name)";

      IList<Google.Apis.Drive.v3.Data.File> files = listRequest.Execute().Files;

      if (files != null && files.Count > 0) {
        foreach (Google.Apis.Drive.v3.Data.File f in files) {
          textBox1.Text += string.Format("{0} : {1}\r\n", f.Name, f.Id);
        }
      }
    }
  }
}

解説

JSON形式のキーファイルを世も組む、ファイルストリームオブジェクトを作成します。
GoogleCredential.FromStream()メソッドを呼び出し、ファイルからGoogleCredential オブジェクトを作成します。 オブジェクト作成の際には、CreateScoped() メソッドを呼び出し、操作権限のスコープも設定します。
      FileStream fs = new FileStream("(取得したJSON形式のキーファイル名)", FileMode.Open, FileAccess.Read);
      Google.Apis.Auth.OAuth2.GoogleCredential credential = Google.Apis.Auth.OAuth2.GoogleCredential.FromStream(fs).CreateScoped(Scopes);

BaseClientService.Initializer オブジェクトを作成します。 作成した.BaseClientService.Initializerオブジェクトの HttpClientInitializer に先に作成した、GoogleCredential オブジェクトを設定します。 また、ApplicationName にこのアプリケーションの名称を設定します。
DriveServiceオブジェクトのコンストラクタに作成した BaseClientService.Initializer オブジェクトを与えて、DriveServiceオブジェクトを作成します。
      Google.Apis.Services.BaseClientService.Initializer init = new Google.Apis.Services.BaseClientService.Initializer();
      init.HttpClientInitializer = credential;
      init.ApplicationName = "My Test App";
      DriveService service = new DriveService(init);

FilesResource.ListRequest オブジェクトを作成します。作成したFilesResource.ListRequestオブジェクトのPageSize、Fields プロパティを設定します。
      FilesResource.ListRequest listRequest = service.Files.List();
      listRequest.PageSize = 1000;
      listRequest.Fields = "nextPageToken, files(id, name)";

ファイルの一覧リストを取得します。リストは、IList<Google.Apis.Drive.v3.Data.File>オブジェクトで取得します。
取得の実行は、FilesResource.ListRequestオブジェクトのExcute()メソッドを実行し、戻り値のGoogle.Apis.Drive.v3.Data.FileList オブジェクトのFilesメソッドを呼び出して、 IList<Google.Apis.Drive.v3.Data.File>オブジェクトを取得します。
      IList<Google.Apis.Drive.v3.Data.File> files = listRequest.Execute().Files;

取得したIList<Google.Apis.Drive.v3.Data.File>オブジェクトの項目をテキストボックスに表示します。
      if (files != null && files.Count > 0) {
        foreach (Google.Apis.Drive.v3.Data.File f in files) {
          textBox1.Text += string.Format("{0} : {1}\r\n", f.Name, f.Id);
        }
      }

実行結果

上記のプロジェクトを実行します。下図のウィンドウが表示されます。


[button1]をクリックします。テキストボックスに下図のメッセージが表示されます。 先に、Google Drive で設定したサービスアカウントにアクセス権を付与した共有フォルダが表示されています。

ファイルを追加した場合の結果

共有フォルダとして作成した "My Test Folder" にファイルをアップロードして追加します。(下図)


プロジェクトを実行し、[button1]をクリックします。 追加したファイルと共有フォルダのリストが表示されます。フォルダ分けしても、すべてのファイルが列挙される動作になっています。

プログラム2:指定フォルダのファイル一覧の表示

さらに別のフォルダを作成し、ファイルを配置します。


先ほどのプロジェクトを実行します。すべてのファイルが一覧で取得されています。ファイル数が増えると見通しが悪くなるため、 指定したフォルダのファイルのみを取得したいです。

UI

下図のフォームを作成します。ボタンを1つ、テキストボックスを2つ配置します。

コード

下記のコードを作成します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Google.Apis.Drive.v3;
using System.IO;

namespace GoogleDriveView
{
  public partial class FormFolderView : Form
  {
    public FormFolderView()
    {
      InitializeComponent();
    }

    static string[] Scopes = { DriveService.Scope.Drive };

    private void button1_Click(object sender, EventArgs e)
    {
      FileStream fs = new FileStream("(取得したJSON形式のキーファイル名)", FileMode.Open, FileAccess.Read);
      Google.Apis.Auth.OAuth2.GoogleCredential credential = Google.Apis.Auth.OAuth2.GoogleCredential.FromStream(fs).CreateScoped(Scopes);

      Google.Apis.Services.BaseClientService.Initializer init = new Google.Apis.Services.BaseClientService.Initializer();
      init.HttpClientInitializer = credential;
      init.ApplicationName = "My Test App";
      DriveService service = new DriveService(init);

      FilesResource.ListRequest listRequest = service.Files.List();
      listRequest.PageSize = 1000;
      listRequest.Fields = "nextPageToken, files(id, name)";
      listRequest.Q = string.Format("'{0}' in parents",textBox1.Text);

      IList<Google.Apis.Drive.v3.Data.File> files = listRequest.Execute().Files;

      if (files != null && files.Count > 0) {
        foreach (Google.Apis.Drive.v3.Data.File f in files) {
          textBox2.Text += string.Format("{0} : {1}\r\n", f.Name, f.Id);
        }
      }
    }
  }
}

解説

コードのロジックは先のプログラムとほぼ同じです。異なる部分は下記の、Qプロパティを設定する部分です。
Qプロパティにクエリを設定します。今回の例では、指定したIDを親要素に持つ項目のみを列挙するクエリを設定しています。 この指定により、指定したIDのフォルダ内にあるファイルやフォルダのみを表示する動作となります。
  listRequest.Q = string.Format("'{0}' in parents",textBox1.Text);

実行結果

プロジェクトを実行します。下図のウィンドウが表示されます。


上部のテキストボックスにフォルダのIDを入力します。フォルダのIDは先のプログラム等で調べることができます。 IDの入力後に[button1]をクリックします。


指定したフォルダ内のファイルやフォルダの一覧が下部のテキストボックスに表示されます。


指定したフォルダ内の項目のみを取得できました。

プログラム3:フォルダのみを表示、ファイルのみを表示

Google ドライブのリスト取得時にフォルダのみを表示する方法を紹介します。

UI

下図のフォームを作成します。テキストボックスを2つ、ボタン、ラジオボタンを配置します。

コード

下記のコードを記述します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Google.Apis.Drive.v3;
using System.IO;

namespace GoogleDriveView
{
  public partial class FormMimeQuery : Form
  {
    public FormMimeQuery()
    {
      InitializeComponent();
    }
    
    static string[] Scopes = { DriveService.Scope.Drive };

    private void button1_Click(object sender, EventArgs e)
    {
      FileStream fs = new FileStream("(取得したJSON形式のキーファイル名)", FileMode.Open, FileAccess.Read);
      Google.Apis.Auth.OAuth2.GoogleCredential credential = Google.Apis.Auth.OAuth2.GoogleCredential.FromStream(fs).CreateScoped(Scopes);

      Google.Apis.Services.BaseClientService.Initializer init = new Google.Apis.Services.BaseClientService.Initializer();
      init.HttpClientInitializer = credential;
      init.ApplicationName = "My Test App";
      DriveService service = new DriveService(init);

      FilesResource.ListRequest listRequest = service.Files.List();
      listRequest.PageSize = 1000;


      listRequest.Fields = "nextPageToken, files(id, name)";

      if (radioButton1.Checked == true) {
        if (textBox1.Text == "") {
          listRequest.Q = "mimeType='application/vnd.google-apps.folder'";
        }
        else {
          listRequest.Q = string.Format("mimeType = 'application/vnd.google-apps.folder' and '{0}' in parents", textBox1.Text);
        }
      }
      else if (radioButton2.Checked == true) {
        if (textBox1.Text == "") {
          listRequest.Q = string.Format("mimeType != 'application/vnd.google-apps.folder'", textBox1.Text);
        }
        else {
          listRequest.Q = string.Format("mimeType != 'application/vnd.google-apps.folder' and '{0}' in parents", textBox1.Text);
        }
      }
      else {
        if (textBox1.Text == "") {
        }
        else {
          listRequest.Q = string.Format("'{0}' in parents", textBox1.Text);
        }
      }


      IList<Google.Apis.Drive.v3.Data.File> files = listRequest.Execute().Files;

      if (files != null && files.Count > 0) {
        foreach (Google.Apis.Drive.v3.Data.File f in files) {
          textBox2.Text += string.Format("{0} : {1}\r\n", f.Name, f.Id);
        }
      }
    }
  }
}

解説

認証やファイルリストの取得は先の例と同様です。
フォルダのみを表示する場合には、FilesResource.ListRequestオブジェクトのQプロパティの指定で、mimeType='application/vnd.google-apps.folder' を設定します。 Google Driveでは、フォルダのMIMETypeは"application/vnd.google-apps.folder" であるため、MIMETypeの条件設定でフォルダのみを表示できます。
また、他の条件と組み合わせる場合は、and 句を利用します。
  if (textBox1.Text == "") {
    listRequest.Q = "mimeType='application/vnd.google-apps.folder'";
  }
  else {
    listRequest.Q = string.Format("mimeType = 'application/vnd.google-apps.folder' and '{0}' in parents", textBox1.Text);
  }

ファイルのみを表示する場合は != 演算子を利用してフォルダ以外を表示することで実現しています。
  if (textBox1.Text == "") {
    listRequest.Q = string.Format("mimeType != 'application/vnd.google-apps.folder'", textBox1.Text);
  }
  else {
    listRequest.Q = string.Format("mimeType != 'application/vnd.google-apps.folder' and '{0}' in parents", textBox1.Text);
  }

実行結果

プロジェクトを実行します。下図のウィンドウが表示されます。


ラジオボタンの[指定なし]をクリックして、チェックを変更します。[button1]をクリックします。すべてのファイルとフォルダの一覧がテキストボックスに表示されます。


続いて上部のテキストボックスに、フォルダのIDを入力して、[button1]をクリックします。入力したIDのフォルダ内にあるファイルとファイルの一覧が、下部のテキストボックスに表示されます。


ラジオボタンの[ファイルのみ]をクリックしてチェックをつけます。[button1]をクリックすると、 下部のテキストボックスに指定したフォルダ内の項目が表示されますが、ファイルのみが表示され、フォルダは一覧には表示されないです。


ラジオボタンの[ファイルのみ]をクリックしてチェックした場合の結果です。フォルダが表示されていないことが確認できます。


ラジオボタンの[フォルダのみ]をクリックしてチェックした場合の結果です。フォルダのみが表示されていることが確認できます。


上部のテキストボックスにフォルダのIDを入力すると、フォルダ内のファイル、フォルダを表示できます。

プログラム4:ページ繰りする場合

ファイル数が非常に多い場合、すべてのファイルを取得すると非常に長い処理時間がかかります。 一回の取得処理でファイル情報を取得する個数を少なくして、逐次的に処理することができます。 ファイルを取得する個数h、FilesResource.ListRequest オブジェクトの PageSize プロパティを利用します。

UI

下図のフォームを作成します。テキストボックスとボタンを配置します。

コード

下記のコードを記述します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Google.Apis.Drive.v3;
using System.IO;

namespace GoogleDriveView
{
  public partial class FormViewPage : Form
  {
    public FormViewPage()
    {
      InitializeComponent();
    }

    static string[] Scopes = { DriveService.Scope.Drive };


    private void button1_Click(object sender, EventArgs e)
    {
      FileStream fs = new FileStream("ipentectest-854e0153b985.json", FileMode.Open, FileAccess.Read);
      Google.Apis.Auth.OAuth2.GoogleCredential credential = Google.Apis.Auth.OAuth2.GoogleCredential.FromStream(fs).CreateScoped(Scopes);

      Google.Apis.Services.BaseClientService.Initializer init = new Google.Apis.Services.BaseClientService.Initializer();
      init.HttpClientInitializer = credential;
      init.ApplicationName = "My Test App";
      DriveService service = new DriveService(init);

      FilesResource.ListRequest listRequest = service.Files.List();
      listRequest.PageSize = 3;
      listRequest.Fields = "nextPageToken, files(id, name)";

      while (true) {
        Google.Apis.Drive.v3.Data.FileList flist = listRequest.Execute();
        IList<Google.Apis.Drive.v3.Data.File> files = flist.Files;

        if (files != null && files.Count > 0) {
          textBox1.Text += "---\r\n";
          foreach (Google.Apis.Drive.v3.Data.File f in files) {
            textBox1.Text += string.Format("{0} : {1}\r\n", f.Name, f.Id);
          }
        }

        if (string.IsNullOrWhiteSpace(flist.NextPageToken) == true) {
          break;
        }
        else {
          listRequest.PageToken = flist.NextPageToken;
          flist = listRequest.Execute();
        }
      }
    }
  }
}

解説

認証の処理やファイルの取得処理は先ほどのプログラムと同様です。
ファイルを取得後に、Google.Apis.Drive.v3.Data.FileLis オブジェクトの NextPageToken プロパティを確認し、 値がnullや空文字でなければ、次のページがあると判定し、FilesResource.ListRequestオブジェクトの PageToken プロパティにNextPageTokenの値を設定し再度、 FilesResource.ListRequestオブジェクトの Execute() メソッドを呼び出すことで、次のファイル情報を取得できます。
      while (true) {
        Google.Apis.Drive.v3.Data.FileList flist = listRequest.Execute();
        IList<Google.Apis.Drive.v3.Data.File> files = flist.Files;

        if (files != null && files.Count > 0) {
          textBox1.Text += "---\r\n";
          foreach (Google.Apis.Drive.v3.Data.File f in files) {
            textBox1.Text += string.Format("{0} : {1}\r\n", f.Name, f.Id);
          }
        }

        if (string.IsNullOrWhiteSpace(flist.NextPageToken) == true) {
          break;
        }
        else {
          listRequest.PageToken = flist.NextPageToken;
          flist = listRequest.Execute();
        }
      }

実行結果

プロジェクトを実行します。下図のウィンドウが表示されます。


[button1]ボタンをクリックします。下図のメッセージがテキストボックスに表示されます。 FilesResource.ListRequest オブジェクトの PageSize プロパティが3に設定されているため、1回のExecute() メソッドで3件のファイル情報が取得できます。 くり返し、Execute() メソッドを呼び出して3件ずつファイルの情報が取得できている動作になっていることが確認できます。

著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
最終更新日: 2022-12-14
作成日: 2021-07-25
iPentec all rights reserverd.