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

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

概要

C#のプログラムからOneDriveのディレクトリのファイル、フォルダの一覧を取得するコードを紹介します。

事前準備

アクセストークンを取得するためのプログラムを作成する前に、アプリケーションの登録や設定が必要です。

Azure Active Directory へのプログラム登録

Azure Active Directory にプログラムを登録します。 手順はこちらの記事を参照してください。

パブリック クライアント フローを有効にする

登録したアプリケーションのパブリック クライアント フローを有効にします。 手順はこちらの記事を参照してください。

ファイルAPIのAPIアクセス許可を追加

File.ReadWrite, または File.ReadWrite.All, File.Read. File.Read.All いずれかのアクセス許可を追加します。
手順はこちらの記事を参照してください。

APIのアクセス許可

アプリケーションのAPIのアクセス許可を与えます。 手順はこちらの記事を参照して下さい。

Microsoft.Graph ライブラリのインストール

作成したプロジェクトに Microsoft.Graph パッケージをインストールします。 インストール手順はこちらの記事を参照してください。

OneDriveの準備

OneDriveにサインインしてファイルを配置しフォルダも作成します。
今回はルートフォルダに下図のファイルとフォルダを配置しました。


folder1 の中は下図のファイルを配置しています。

プログラム : ルートフォルダのファイル一覧を取得する

ルートフォルダのファイル一覧を取得します。

UI

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

コード

下記コードを記述します。ボタンのClickイベントを実装します。
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 Microsoft.Identity.Client;
using Microsoft.Graph;

namespace SimpleCallApi
{
  public partial class FormListFile : Form
  {
    public static IPublicClientApplication PublicClientApp;
    private string ClientId = "(クライアントID)";
    private string TenantId = "(テナントID)";


    public FormListFile()
    {
      InitializeComponent();
    }

    private async void button1_Click(object sender, EventArgs e)
    {
      PublicClientApplicationBuilder app = PublicClientApplicationBuilder.Create(ClientId);
      app = app.WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient");
      app = app.WithAuthority(AzureCloudInstance.AzurePublic, TenantId);
      PublicClientApp = app.Build();

      string[] scopes = new string[] { "User.ReadWrite.All" };
      string password = "(パスワード)";
      System.Security.SecureString secpass = new System.Security.SecureString();

      foreach (char c in password) secpass.AppendChar(c);

      AcquireTokenByUsernamePasswordParameterBuilder builder = PublicClientApp.AcquireTokenByUsernamePassword(scopes, "(アカウント)", secpass);
      AuthenticationResult authResult = await builder.ExecuteAsync();

      DelegateAuthenticationProvider prov = new DelegateAuthenticationProvider(
        (requestMessage) =>
        {
          requestMessage.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("bearer", authResult.AccessToken);
          return Task.FromResult(0);
        }
        );
      GraphServiceClient client = new GraphServiceClient(prov);

      IDriveItemChildrenCollectionPage items = await client.Me.Drive.Root.Children.Request().GetAsync();

      foreach (DriveItem item in items) {
        if (item.Folder == null) {
          textBox1.Text += string.Format("{0}\r\n", item.Name);
        }
        else {
          textBox1.Text += string.Format("{0}\tフォルダ\r\n", item.Name);
        }
      }
    }
  }
}

解説

クライアントIDとテナントIDはAzure Active Directory の登録アプリケーション画面の値を利用します。
詳しくはこちらの記事を参照してください。
    private string ClientId = "(クライアントID)";
    private string TenantId = "(テナントID)";

MSALの初期化のコードです。
      PublicClientApplicationBuilder app = PublicClientApplicationBuilder.Create(ClientId);
      app = app.WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient");
      app = app.WithAuthority(AzureCloudInstance.AzurePublic, TenantId);
      PublicClientApp = app.Build();

パスワードの文字列の SecureString を作成します。(パスワード) の値はOneDrive にサインインするアカウントのパスワードです。
      string[] scopes = new string[] { "User.ReadWrite.All" };
      string password = "(パスワード)";
      System.Security.SecureString secpass = new System.Security.SecureString();
      foreach (char c in password) secpass.AppendChar(c);

アクセストークンを取得します。(アカウント) の値はOneDrive にサインインするMicrosoft アカウントのメールアドレスになります。
      AcquireTokenByUsernamePasswordParameterBuilder builder = PublicClientApp.AcquireTokenByUsernamePassword(scopes, "(アカウント)", secpass);
      AuthenticationResult authResult = await builder.ExecuteAsync();

GraphServiceClient オブジェクトを作成します。DelegateAuthenticationProvider オブジェクトを作成し、GraphServiceClientのコンストラクタの第一引数に DelegateAuthenticationProvider オブジェクトを与えます。
      DelegateAuthenticationProvider prov = new DelegateAuthenticationProvider(
        (requestMessage) =>
        {
          requestMessage.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("bearer", authResult.AccessToken);
          return Task.FromResult(0);
        }
        );
      GraphServiceClient client = new GraphServiceClient(prov);

OneDriveのファイルを取得します。ルートディレクトリのファイルを取得するには、GraphServiceClient オブジェクトの Me.Drive.Root.Children で取得できます。 項目を取得するには、Request().GetAsync() メソッドを呼び出します。
項目の一覧はIDriveItemChildrenCollectionPage オブジェクトで取得できます。個々の要素にアクセスするには、foreach ループで取得します。
フォルダの判定は、項目のDriveItem オブジェクトの Folder プロパティを確認します。値がnullの場合はファイルになります。 フォルダの場合は Folderプロパティに値が設定されています。
下記のコードでは foreach ループでIDriveItemChildrenCollectionPage オブジェクトから個々のアイテムを取り出し、ファイル名である Name プロパティを テキストボックスに表示します。
      IDriveItemChildrenCollectionPage items = await client.Me.Drive.Root.Children.Request().GetAsync();

      foreach (DriveItem item in items) {
        if (item.Folder == null) {
          textBox1.Text += string.Format("{0}\r\n", item.Name);
        }
        else {
          textBox1.Text += string.Format("{0}\tフォルダ\r\n", item.Name);
        }
      }

実行結果

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


[button1]をクリックします。テキストボックスに下図の文字列が表示されます。 最初に準備した One Driveのルートディレクトリのファイル名とフォルダ名が取得できていることが 確認できます。


OneDrive のルートディレクトリのファイル、フォルダ一覧を取得できました。

IDを取得する

上記のコードではファイルやフォルダの名称を取得しましたが、ファイルのダウンロードなどで、ファイルやフォルダを指定するためのIDを取得する必要があります。 IDを取得する場合は、DriveItem オブジェクトのIdプロパティを参照します。IDを画面に表示する場合はテキストボックスへの表示部分を下記のコードに変更します。
      foreach (DriveItem item in items) {
        if (item.Folder == null) {
          textBox1.Text += string.Format("{0}\t{1}\r\n", item.Name, item.Id);
        }
        else {
          textBox1.Text += string.Format("{0}\t{1}\tフォルダ\r\n", item.Name, item.Id);
        }
      }

上記のコードに変更後、プロジェクトを実行し[button1]をクリックします。下図の表示結果となります。
ファイル名、フォルダ名の右側に表示されている、01VGRRKK... の文字列がそれぞれの項目のIDとなります。

プログラム : サブフォルダのファイル一覧を取得する

サブフォルダのファイル一覧を取得するコードを紹介します。サブフォルダのファイルを取得する場合は、 GraphServiceClient オブジェクトの Me.Drive.Items["(フォルダのID)"] を利用します。

UI

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

コード

下記のコードを記述します。
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 Microsoft.Identity.Client;
using Microsoft.Graph;

namespace SimpleCallApi
{
  public partial class FormListSubFolder : Form
  {
    public FormListSubFolder()
    {
      InitializeComponent();
    }

    public static IPublicClientApplication PublicClientApp;
    private string ClientId = "(クライアントID)";
    private string TenantId = "(テナントID)";


    private async void button1_Click(object sender, EventArgs e)
    {
      PublicClientApplicationBuilder app = PublicClientApplicationBuilder.Create(ClientId);
      app = app.WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient");
      app = app.WithAuthority(AzureCloudInstance.AzurePublic, TenantId);
      PublicClientApp = app.Build();

      string[] scopes = new string[] { "User.ReadWrite.All" };
      string password = "(OneDriveにサインインするアカウントのパスワード)";
      System.Security.SecureString secpass = new System.Security.SecureString();

      foreach (char c in password) secpass.AppendChar(c);

      AcquireTokenByUsernamePasswordParameterBuilder builder = PublicClientApp.AcquireTokenByUsernamePassword(scopes, "(OneDriveにサインインするアカウント)", secpass);
      AuthenticationResult authResult = await builder.ExecuteAsync();

      DelegateAuthenticationProvider prov = new DelegateAuthenticationProvider(
        (requestMessage) =>
        {
          requestMessage.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("bearer", authResult.AccessToken);
          return Task.FromResult(0);
        }
        );
      GraphServiceClient client = new GraphServiceClient(prov);

      IDriveItemChildrenCollectionPage items;
      if (string.IsNullOrEmpty(textBox1.Text) == true) {
        items = await client.Me.Drive.Root.Children.Request().GetAsync();
      }
      else {
        items = await client.Me.Drive.Items[textBox1.Text].Children.Request().GetAsync();
      }


      foreach (DriveItem item in items) {
        if (item.Folder == null) {
          textBox2.Text += string.Format("{0}\t{1}\r\n", item.Name, item.Id);
        }
        else {
          textBox2.Text += string.Format("{0}\t{1}\tフォルダ\r\n", item.Name, item.Id);
        }
      }
    }
  }
}

解説

アクセストークンの取得とGraphServiceClientオブジェクトの作成については先のプログラムを参照してください。

以下のコードで指定したフォルダのファイル、フォルダの一覧を取得します。
テキストボックスに何も入力されていない場合は、ルートディレクトリのファイル一覧を取得するため client.Me.Drive.Root.Children.Request().GetAsync(); を実行します。 テキストボックスに入力されている場合は、入力されている文字列のIDを持つフォルダのファイル一覧を取得するため、 client.Me.Drive.Items[(取得するフォルダのID)].Children.Request().GetAsync(); を実行します。
ファイルの一覧を格納するIDriveItemChildrenCollectionPage オブジェクトを非同期で取得するため、.Request().GetAsync() を記述します。
  IDriveItemChildrenCollectionPage items;
  if (string.IsNullOrEmpty(textBox1.Text) == true) {
    items = await client.Me.Drive.Root.Children.Request().GetAsync();
  }
  else {
    items = await client.Me.Drive.Items[textBox1.Text].Children.Request().GetAsync();
  }

取得した、IDriveItemChildrenCollectionPage オブジェクトを foreach ループで処理します。個々の要素は DriveItem オブジェクトに格納されています。 DriveItemオブジェクトの Name プロパティにファイル名が格納されており、Id プロパティに要素のIDの文字列が格納されています。 フォルダの判定は先のプログラムと同様に、Folder プロパティが null かどうかで判定します。
  foreach (DriveItem item in items) {
    if (item.Folder == null) {
      textBox2.Text += string.Format("{0}\t{1}\r\n", item.Name, item.Id);
    }
    else {
      textBox2.Text += string.Format("{0}\t{1}\tフォルダ\r\n", item.Name, item.Id);
    }
  }

実行結果

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


上部のテキストボックスに何も入力せずに[button1]ボタンをクリックします。OneDriveのルートフォルダーのファイル一覧が表示されます。


続いて上部のテキストボックスに "folder1" のIDを入力します。IDは先ほどのルートフォルダーの一覧表示時に表示されたIDを利用しています。


テキストボックス入力後、[button1] ボタンをクリックします。folder1 フォルダー内のファイルの一覧が下部のテキストボックスに表示されます。


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