How do I programmatically locate my Google Drive folder using C#?

前端 未结 2 1306
眼角桃花
眼角桃花 2020-12-06 00:28

Similar question as here. Just for Google Drive instead of Dropbox:

How do I programmatically locate my Google Drive folder us

2条回答
  •  难免孤独
    2020-12-06 00:57

    I took Sarath's answer, reworked it to be more resilient (quotes around data source path, null conditional on the reader indexing, additional error checking, "using" so objects are disposed appropriately, added a bunch of comments, and threw in some LINQ (because, linq :-) ).

    This particular implementation catches and logs exceptions, and then returns string.Empty on any error...because that's how my current app needs it. Remove the try/catch if your app wants exceptions.

    /// 
    /// Retrieves the local Google Drive directory, if any.
    /// 
    /// Directory, or string.Empty if it can't be found
    public static string GetGoogleDriveDirectory()
    {
        try
        {
            // Google Drive's sync database can be in a couple different locations. Go find it. 
            string appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
            string dbName = "sync_config.db";
            var pathsToTry = new[] { @"Google\Drive\" + dbName, @"Google\Drive\user_default\"+ dbName };
    
            string syncDbPath = (from p in pathsToTry
                                where File.Exists(Path.Combine(appDataPath, p))
                                select Path.Combine(appDataPath, p))
                                .FirstOrDefault();
            if (syncDbPath == null)
                throw new FileNotFoundException("Cannot find Google Drive sync database", dbName);
    
            // Build the connection and sql command
            string conString = string.Format(@"Data Source='{0}';Version=3;New=False;Compress=True;", syncDbPath);
            using (var con = new SQLiteConnection(conString))
            using (var cmd = new SQLiteCommand("select * from data where entry_key='local_sync_root_path'", con))
            {
                // Open the connection and execute the command
                con.Open();
                var reader = cmd.ExecuteReader();
                reader.Read();
    
                // Extract the data from the reader
                string path = reader["data_value"]?.ToString();
                if (string.IsNullOrWhiteSpace(path))
                    throw new InvalidDataException("Cannot read 'local_sync_root_path' from Google Drive configuration db");
    
                // By default, the path will be prefixed with "\\?\" (unless another app has explicitly changed it).
                // \\?\ indicates to Win32 that the filename may be longer than MAX_PATH (see MSDN). 
                // Parts of .NET (e.g. the File class) don't handle this very well, so remove this prefix.
                if (path.StartsWith(@"\\?\"))
                    path = path.Substring(@"\\?\".Length);
    
                return path;
            }
        }
        catch (Exception ex)
        {
            Trace.TraceError("Cannot determine Google Drive location. Error {0} - {1}", ex.Message, ex.StackTrace);
            return string.Empty;
        }
    }
    

提交回复
热议问题