Search files on Google Drive with C#


Please Share

google drive Are you working on an application that needs list the files from a users Google Drive account. Would you like to find only the directories on the currently authenticated users drive account? or possibly return only a single file type? This information can be found using the file.list method with the Q parameter. I am going to show you how to do that using C# and the Google .net client library.

Prerequisite

The first thing we will need to do is import the Google Drive API v3 NuGet package

Install-Package Google.Apis.Drive.v3

Authenticate

File list is private data which means it is owned by a user. In order to access it you must be authenticated to that user.


        /// <summary>
        /// This method requests Authentcation from a user using Oauth2.  
        /// Credentials are stored in System.Environment.SpecialFolder.Personal
        /// Documentation https://developers.google.com/accounts/docs/OAuth2
        /// </summary>
        /// <param name="clientSecretJson">Path to the client secret json file from Google Developers console.</param>
        /// <param name="userName">Identifying string for the user who is being authentcated.</param>
        /// <returns>DriveService used to make requests against the Drive API</returns>
        public static DriveService AuthenticateOauth(string clientSecretJson, string userName)
        {
            try
            {
                if (string.IsNullOrEmpty(userName))
                    throw new ArgumentNullException("userName");
                if (string.IsNullOrEmpty(clientSecretJson))
                    throw new ArgumentNullException("clientSecretJson");
                if (!File.Exists(clientSecretJson))
                    throw new Exception("clientSecretJson file does not exist.");

                // These are the scopes of permissions you need. It is best to request only what you need and not all of them
                string[] scopes = new string[] { DriveService.Scope.DriveReadonly};         	//View the files in your Google Drive                                                 
                UserCredential credential;
                using (var stream = new FileStream(clientSecretJson, FileMode.Open, FileAccess.Read))
                {
                    string credPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
                    credPath = Path.Combine(credPath, ".credentials/", System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);

                    // Requesting Authentication or loading previously stored authentication for userName
                    credential = GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets,
                                                                             scopes,
                                                                             userName,
                                                                             CancellationToken.None,
                                                                             new FileDataStore(credPath, true)).Result;
                }

                // Create Drive API service.
                return new DriveService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = credential,
                    ApplicationName = "Drive Oauth2 Authentication Sample"
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine("Create Oauth2 account DriveService failed" + ex.Message);
                throw new Exception("CreateServiceAccountDriveFailed", ex);
            }
        }

File.List

The File.list method allows us to list all of the files on Google drive. However if you are like me and your Google drive account contains a lot of files folders and random junk then sometimes its better to limit the results returned from the file.list method.

Lets look at the basic File.list code for C#.

  
 public class DriveListExample
    {
        public class FilesListOptionalParms
        {
            /// 
            /// The source of files to list.
            /// 
            public string Corpus { get; set; }
            /// 
            /// A comma-separated list of sort keys. Valid keys are 'createdTime', 'folder', 'modifiedByMeTime', 'modifiedTime', 'name', 'quotaBytesUsed', 'recency', 'sharedWithMeTime', 'starred', and 'viewedByMeTime'. Each key sorts ascending by default, but may be reversed with the 'desc' modifier. Example usage: ?orderBy=folder,modifiedTime desc,name. Please note that there is a current limitation for users with approximately one million files in which the requested sort order is ignored.
            /// 
            public string OrderBy { get; set; }
            /// 
            /// The maximum number of files to return per page.
            /// 
            public int? PageSize { get; set; }
            /// 
            /// The token for continuing a previous list request on the next page. This should be set to the value of 'nextPageToken' from the previous response.
            /// 
            public string PageToken { get; set; }
            /// 
            /// A query for filtering the file results. See the "Search for Files" guide for supported syntax.
            /// 
            public string Q { get; set; }
            /// 
            /// A comma-separated list of spaces to query within the corpus. Supported values are 'drive', 'appDataFolder' and 'photos'.
            /// 
            public string Spaces { get; set; }
            /// 
            /// Selector specifying a subset of fields to include in the response.
            /// 
            public string fields { get; set; }
            /// 
            /// Alternative to userIp.
            /// 
            public string quotaUser { get; set; }
            /// 
            /// IP address of the end user for whom the API call is being made.
            /// 
            public string userIp { get; set; }
        }

        /// 
        /// Lists or searches files. 
        /// Documentation https://developers.google.com/drive/v3/reference/files/list
        /// Generation Note: This does not always build corectly.  Google needs to standardise things I need to figuer out which ones are wrong.
        /// 
        /// Authenticated drive service.  
        /// Optional paramaters.        /// FileListResponse
        public static Google.Apis.Drive.v3.Data.FileList ListFiles(DriveService service, FilesListOptionalParms optional = null)
        {
            try
            {
                // Initial validation.
                if (service == null)
                    throw new ArgumentNullException("service");

                // Building the initial request.
                var request = service.Files.List();
                // Applying optional parameters to the request.                
                request = (FilesResource.ListRequest)SampleHelpers.ApplyOptionalParms(request, optional);
                // Requesting data.
                return request.Execute();
            }
            catch (Exception ex)
            {
                throw new Exception("Request Files.List failed.", ex);
            }
        }


    }
    public static class SampleHelpers
    {

        /// 
        /// Using reflection to apply optional parameters to the request.  
        /// 
        /// If the optonal parameters are null then we will just return the request as is.
        /// 
        /// The request. 
        /// The optional parameters. 
        /// 
        public static object ApplyOptionalParms(object request, object optional)
        {
            if (optional == null)
                return request;

            System.Reflection.PropertyInfo[] optionalProperties = (optional.GetType()).GetProperties();

            foreach (System.Reflection.PropertyInfo property in optionalProperties)
            {
                // Copy value from optional parms to the request.  They should have the same names and datatypes.
                System.Reflection.PropertyInfo piShared = (request.GetType()).GetProperty(property.Name);
                if (property.GetValue(optional, null) != null) // TODO Test that we do not add values for items that are null
                    piShared.SetValue(request, property.GetValue(optional, null), null);
            }

            return request;
        }
    }

Search

Searching for files in Google drive is slightly limited you cant search on all the files i recommend you check the Search for files documentation to see what it is possible to search on. I am going to cover a couple of the most common uses here.

List files no search

Lets start by running the code without searching.

  
var service = GoogleSamplecSharpSample.Drivev3.Auth.Oauth2Example.AuthenticateOauth(@"[Full path to json credentials file]", "UserName");
var files = DriveListExample.ListFiles(service);

This is going to return 100 files in no particular order. If you are interested in pagination and then I have another tutorial on that subject here List All files on Google drive

By file name

What if you know the name of the file or part of the name well you can search on name. Fulltext is also nice it allows you to search on “Full text of the file including name, description, content, and indexable text.”

  
var service = GoogleSamplecSharpSample.Drivev3.Auth.Oauth2Example.AuthenticateOauth(@"[Full path to json credentials file]", "UserName");
var files = DriveListExample.ListFiles(service, new DriveListExample.FilesListOptionalParms() { Q = "name contains 'Make'" });

List files only directories

It is also possible to search for only one type of file say you just want to return all the Google sheets on your account? What if you just wanted to find all the folders well folders is a mimetype of “application/vnd.google-apps.folder” so we can search on just that.

  
var service = GoogleSamplecSharpSample.Drivev3.Auth.Oauth2Example.AuthenticateOauth(@"[Full path to json credentials file]", "UserName");
var folders = DriveListExample.ListFiles(service, new DriveListExample.FilesListOptionalParms { Q = "mimeType = 'application/vnd.google-apps.folder'" });

Conclusion

Rather than return all of the files on your Google drive account it can be a good idea to search for only the files you want for example just image files or just text files. You can do that with the Q parameter in the file list method.

Please Share


Linda Lawton

About Linda Lawton

My name is Linda Lawton I have more than 20 years experience working as an application developer and a database expert. I have also been working with Google APIs since 2012 and I have been contributing to the Google .Net client library since 2013. In 2013 I became a a Google Developer Experts for Google Analytics.

Leave a comment

Your email address will not be published. Required fields are marked *