3

Thanks to this article,

How do I programmatically locate my Dropbox folder using C#?

I can programmtically find the Dropbox folder. Now, without installing and using various APIs, how can I do the same for GoogleDrive and MS SkyDrive?

Vb.Net or C# solutions are OK...

Community
  • 1
  • 1
Chiwda
  • 1,233
  • 7
  • 30
  • 52

4 Answers4

2

I found part of the answer here...

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

Here is my code for three of the main Webfolder services

Dim StoreFolder As String = ""
' Dropbox
Dim dbPath As String = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Dropbox\\host.db")
Dim lines() As String = System.IO.File.ReadAllLines(dbPath)
Dim dbBase64Text As Byte() = Convert.FromBase64String(lines(1))
StoreFolder = System.Text.ASCIIEncoding.ASCII.GetString(dbBase64Text)

' SkyDrive
StoreFolder = My.Computer.Registry.GetValue("HKEY_CURRENT_USER\Software\Microsoft\SkyDrive", "UserFolder", Nothing)

' Google Drive
Dim dbPath As String = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Google\\Drive\\sync_config.db")
File.Copy(dbPath, "temp.db", True)
StoreFolder = File.ReadAllText("temp.db", System.Text.Encoding.ASCII)
StoreFolder = StoreFolder.Substring(StoreFolder.IndexOf("local_sync_root_pathvalue") + 29)
StoreFolder = StoreFolder.Substring(0, StoreFolder.IndexOf(Char.ConvertFromUtf32(24)))
Community
  • 1
  • 1
Chiwda
  • 1,233
  • 7
  • 30
  • 52
  • 1
    This is not working. Just a trash instead of string. This code also contains number of errors: 1) never work with file names like that! You are copying to Current Directory! You never know what is a current directory for an application that currently access your library. Application can use current directory on it's own, or may not use it at all and then it all depends on launching... if you launch it as sub\sub\app.exe then you'll gonna have a problems... throwing each time temp.db uncontrollable... – Dmitry Gusarov Nov 09 '13 at 08:17
  • 1
    2) you are reading in ASCII. ASCII is an always red flag, think twice before use it. I do understand that you are trying to make binary work here on byte level, but I have no idea how are you going to handle hieroglyphs in my path... 3) all this offsets and stop bytes is just not working for me now. I've received a trash – Dmitry Gusarov Nov 09 '13 at 08:20
  • 1
    About working with file path - also note that in most cases link to an application contains 'Start In' the same as app's location. And you can not write files near your exe file, because of isolation and permissions. Sorry, but this is how crapware appears in this world. PS: all my comments are about GoogleDrive location – Dmitry Gusarov Nov 09 '13 at 08:24
  • "... handle hieroglyphs in my path." You have got to be kidding me! :-) Anyway, this is code I wrote for a MVP application which I would eventually convert to C++ and would naturally be more robust. Incidentally, I keep (and will even in a final app) ini files in the same place as my executables, I don't think there is a problem there. – Chiwda Nov 01 '14 at 05:06
  • 1
    It is ok until you are going to write this ini files from you program... And until you are going to access them with relative path as in your example... I'm strongly against publishing code like this because a lot of people will copy-paste it... If you install your app in ProgramFiles, it just will not work for non administrative accounts... use %tmp% at least for copying temp.db – Dmitry Gusarov Nov 07 '14 at 12:41
  • On my Windows 8, the location for OneDrive is `HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\SkyDrive`. – Uwe Keim Apr 10 '15 at 07:58
2

OneDrive / SkyDrive

The solution of Chiwda led my to the right direction but was not directly working on my machine (Windows 8.1 German), because the registry key was not present.

Instead, this worked:

private static string getOneDriveFolderPath()
{
    var value1 = Registry.GetValue(
        @"HKEY_CURRENT_USER\Software\Microsoft\SkyDrive", 
        @"UserFolder", null);

    var path1 = value1 as string;
    if (path1 != null && Directory.Exist(path1)) return path1;

    var value2 = Registry.GetValue(
        @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\SkyDrive",
        @"UserFolder", null);

    var path2 = value2 as string;
    if (path2 != null && Directory.Exists(path2)) return path2;

    var value3 = Registry.GetValue(
        @"HKEY_CURRENT_USER\Software\Microsoft\OneDrive",
        @"UserFolder", null);

    var path3 = value3 as string;
    if (path3 != null && Directory.Exists(path3)) return path3;

    return null;
}

The code first tries the path in Chiwda's answer than tries the path that was present on my machine.

Community
  • 1
  • 1
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
  • 1
    This worked. But I reversed the order, checking first for #3 because it is probably the most recent and current value to use if whenever more than one exists. – JnLlnd Sep 21 '18 at 16:24
1

Google Drive

Again, Chiwda's solution showed me the right way. Google Drive needs to have an SQLite library available in order to read the path to the local folder.

My code:

private static string checkGetGoogleDriveLocation()
{
    var appDataPath = Environment.GetFolderPath(
                          Environment.SpecialFolder.LocalApplicationData);
    var dbPath = Path.Combine(appDataPath, 
                     @"Google\Drive\user_default\sync_config.db");

    if (!File.Exists(dbPath)) return null;

    var tmp = dbPath + Guid.NewGuid();
    File.CopyFile(dbPath, tmp);

    var folderPath = tryGetFolderFromGoogleDriveDB(tmp);
    if (string.IsNullOrEmpty(folderPath) || !Directory.Exists(folderPath)) return null;

    File.Delete(folderPath);

    return folderPath;
}

I've implemented the tryGetFolderFromGoogleDriveDB function with the help of the "sqlite-net" NuGet package which is also available on GitHub:

private static string tryGetFolderFromGoogleDriveDB(string dbFilePath)
{
    using (var conn = new SQLiteConnection(dbFilePath, SQLiteOpenFlags.ReadOnly))
    {
        var cmd = conn.CreateCommand(
            @"select data_value from data where entry_key='local_sync_root_path'");
        return cmd.ExecuteScalar<string>();
    }
}

Please note that the sqlite-net package does P/Invoke the native sqlite3.dll file so you have to ensure that it is stored in the same folder as your executable you are using this code with.

Community
  • 1
  • 1
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
0

Not quite what you will be able to use, but you may be able to reverse-engineer it for VB.net. A solution I have used for VBA to save some documents to a users Dropbox folder. It looks for it in default installation location and if it does not find it, then prompts for the folder. Most people will leave the default location anyway IMO, so its rare that it will miss it. From memory, SkyDrive and Google Drive follow the same default location patterns too, so a small tweak should be able to find all of them.

Sub finddropbox()
Dim strOS, localdrive, dropboxfolder As String
Dim folderSelect As FileDialog
Dim objWMIService, colOperatingSystems, objOperatingSystem

strComputer = "."    
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colOperatingSystems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")

For Each objOperatingSystem In colOperatingSystems
    strOS = objOperatingSystem.Caption
Next

If InStr(strOS, "XP") Then
    localdrive = Environ("USERPROFILE") & "\My Documents\"
Else
    localdrive = Environ("USERPROFILE")
End If

dropboxfolder = localdrive & "Dropbox\"
If Dir(dropboxfolder, vbDirectory) = vbNullString Then
    Set folderSelect = Application.FileDialog(msoFileDialogFolderPicker)
        With folderSelect
            .Title = "Select Dropbox Folder"
            .AllowMultiSelect = False
            .InitialFileName = Environ("SYSTEMDRIVE")
            If .Show = -1 Then
                dropboxfolder = .SelectedItems(1)
            End If
       End With
End If

Debug.Print dropboxfolder

End Sub
bmgh1985
  • 779
  • 1
  • 14
  • 38