Similar question as here. Just for Google Drive
instead of Dropbox
:
类似的问题在这里。仅适用于Google云端硬盘而不是Dropbox:
How do I programmatically locate my Google Drive
folder using C#?
如何使用C#以编程方式找到我的Google云端硬盘文件夹?
- Registry?
- 注册?
- Environment Variable?
- 环境变量?
- Etc...
- 等等...
2 个解决方案
#1
14
I personally think, the best way is to access the same file through SQLite3.
我个人认为,最好的方法是通过SQLite3访问同一个文件。
string dbFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Google\\Drive\\sync_config.db");
if (!File.Exists(dbFilePath))
dbFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Google\\Drive\\user_default\\sync_config.db");
string csGdrive = @"Data Source="+ dbFilePath + ";Version=3;New=False;Compress=True;";
SQLiteConnection con = new SQLiteConnection(csGdrive);
con.Open();
SQLiteCommand sqLitecmd = new SQLiteCommand(con);
//To retrieve the folder use the following command text
sqLitecmd.CommandText = "select * from data where entry_key='local_sync_root_path'";
SQLiteDataReader reader = sqLitecmd.ExecuteReader();
reader.Read();
//String retrieved is in the format "\\?\<path>" that's why I have used Substring function to extract the path alone.
Console.WriteLine("Google Drive Folder: " + reader["data_value"].ToString().Substring(4));
con.Dispose();
You can get the SQLite library for .Net from here. Also add reference to System.Data.SQLite
and include it in your project to run the above code.
您可以从此处获取.Net的SQLite库。还要添加对System.Data.SQLite的引用,并将其包含在项目中以运行上面的代码。
To retrieve the user, relpace entry_key='user_email'
from the above code
要检索用户,请从上面的代码中重新输入entry_key ='user_email'
#2
4
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 :-) ).
我接受了Sarath的回答,将其重新修改为更具弹性(引用数据源路径,null取决于读者索引,附加错误检查,“使用”因此对象被适当处理,添加了一堆注释,并抛出一些LINQ(因为,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.
这个特定的实现捕获并记录异常,然后在任何错误上返回string.Empty ...因为这是我当前应用程序需要它的方式。如果您的应用需要例外,请删除try / catch。
/// <summary>
/// Retrieves the local Google Drive directory, if any.
/// </summary>
/// <returns>Directory, or string.Empty if it can't be found</returns>
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;
}
}
#1
14
I personally think, the best way is to access the same file through SQLite3.
我个人认为,最好的方法是通过SQLite3访问同一个文件。
string dbFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Google\\Drive\\sync_config.db");
if (!File.Exists(dbFilePath))
dbFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Google\\Drive\\user_default\\sync_config.db");
string csGdrive = @"Data Source="+ dbFilePath + ";Version=3;New=False;Compress=True;";
SQLiteConnection con = new SQLiteConnection(csGdrive);
con.Open();
SQLiteCommand sqLitecmd = new SQLiteCommand(con);
//To retrieve the folder use the following command text
sqLitecmd.CommandText = "select * from data where entry_key='local_sync_root_path'";
SQLiteDataReader reader = sqLitecmd.ExecuteReader();
reader.Read();
//String retrieved is in the format "\\?\<path>" that's why I have used Substring function to extract the path alone.
Console.WriteLine("Google Drive Folder: " + reader["data_value"].ToString().Substring(4));
con.Dispose();
You can get the SQLite library for .Net from here. Also add reference to System.Data.SQLite
and include it in your project to run the above code.
您可以从此处获取.Net的SQLite库。还要添加对System.Data.SQLite的引用,并将其包含在项目中以运行上面的代码。
To retrieve the user, relpace entry_key='user_email'
from the above code
要检索用户,请从上面的代码中重新输入entry_key ='user_email'
#2
4
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 :-) ).
我接受了Sarath的回答,将其重新修改为更具弹性(引用数据源路径,null取决于读者索引,附加错误检查,“使用”因此对象被适当处理,添加了一堆注释,并抛出一些LINQ(因为,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.
这个特定的实现捕获并记录异常,然后在任何错误上返回string.Empty ...因为这是我当前应用程序需要它的方式。如果您的应用需要例外,请删除try / catch。
/// <summary>
/// Retrieves the local Google Drive directory, if any.
/// </summary>
/// <returns>Directory, or string.Empty if it can't be found</returns>
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;
}
}