AdvancedSharpAdbClient icon indicating copy to clipboard operation
AdvancedSharpAdbClient copied to clipboard

Pulling folder content

Open itapi opened this issue 1 year ago • 5 comments

What can we do for you?

this is my code to pull the dcim image on the android main storage:

async Task DownloadFiles()
{
   SyncService service = new SyncService(device);

   string folderPath = Environment.CurrentDirectory + "/downloaded_files";

   // Ensure the target folder exists, create it if needed
   if (!Directory.Exists(folderPath))
   {
       Directory.CreateDirectory(folderPath);
   }

   string source = "/sdcard/dcim";
   var files = await service.GetDirectoryListingAsync(source);

   // Download each file and save it to the local folder
   foreach (var file in files)
   {
       service = new SyncService(device);

       string localFilePath = Path.Combine(folderPath, file.Path);

       using (FileStream stream = File.OpenWrite(localFilePath))
       {
           string path = source + "/" + file.Path;        
           await service.PullAsync(path, stream);
       }
   }
}

I'm getting this error: Failed to pull '/sdcard/dcim/Camera'. read failed: Is a directory

I can't specify in advance the full path, "/sdcard/dcim/camera" because my program need to pull the entire "dcim" content,and it might be dynamic content,and contain many other folders inside....is there any way to pull is like using the simple shell command "adb pull /sdcard/dcim"(which would do the work perfectly)? Thanks in advance guys!

itapi avatar Mar 11 '24 17:03 itapi

It takes my afternoon...

await PullFolderAsync("/sdcard/Documents/SAI", "C:/Users/qq251/Downloads/Compressed/Test");

async Task PullFolderAsync(string remotePath, string localPath)
{
    if (!Directory.Exists(localPath))
    {
        Directory.CreateDirectory(localPath);
    }

    using SyncService service = new(device);

    FileStatistics stat = await service.StatAsync(remotePath);
    await PullFolderAsyncInternal(stat, remotePath, localPath);

    async Task PullFolderAsyncInternal(FileStatistics stat, string remotePath, string localPath)
    {
        if (stat.FileType.HasFlag(UnixFileType.Directory))
        {
            if (remotePath != stat.Path)
            {
                localPath = Path.Combine(localPath, stat.Path);
                remotePath = LinuxPath.Combine(remotePath, stat.Path);
            }
            if (!Directory.Exists(localPath))
            {
                Directory.CreateDirectory(localPath);
            }
            foreach (FileStatistics item in await service.GetDirectoryListingAsync(remotePath))
            {
                await PullFolderAsyncInternal(item, remotePath, localPath);
            }
        }
        else if (stat.FileType.HasFlag(UnixFileType.Regular))
        {
            string localFilePath = Path.Combine(localPath, stat.Path);
            await using FileStream stream = File.OpenWrite(localFilePath);
            await service.PullAsync(LinuxPath.Combine(remotePath, stat.Path), stream);
            await stream.FlushAsync();
        }
    }
}

wherewhere avatar Mar 12 '24 08:03 wherewhere

@wherewhere Thank you so much sir! But using your code leads to the famous The server returned an invalid sync response 0. error. I'm using the lastest release,v3.1.10(wpf app)

itapi avatar Mar 12 '24 15:03 itapi

Because I fixed it in new commit. You need to reopen the service after pull, push and list.

wherewhere avatar Mar 12 '24 15:03 wherewhere

It will be like in next version

using SyncService service = new(device); await PullFolderAsync("/sdcard/Documents/SAI", "C:/Users/qq251/Downloads/Compressed/Test");

async Task PullFolderAsync(string remotePath, string localPath)
{
    if (!Directory.Exists(localPath))
    {
        Directory.CreateDirectory(localPath);
    }

    using SyncService service = new(device);

    FileStatistics stat = await service.StatAsync(remotePath);
    await PullFolderAsyncInternal(stat, remotePath, localPath);

    async Task PullFolderAsyncInternal(FileStatistics stat, string remotePath, string localPath)
    {
        switch (stat.FileMode.GetFileType())
        {
            case UnixFileStatus.Directory:
                if (remotePath != stat.Path)
                {
                    localPath = Path.Combine(localPath, stat.Path);
                    remotePath = LinuxPath.Combine(remotePath, stat.Path);
                }
                if (!Directory.Exists(localPath))
                {
                    Directory.CreateDirectory(localPath);
                }
                foreach (FileStatistics item in await service.GetDirectoryListingAsync(remotePath))
                {
                    await PullFolderAsyncInternal(item, remotePath, localPath);
                }
                break;
            case UnixFileStatus.Regular:
                string localFilePath = Path.Combine(localPath, stat.Path);
                await using (FileStream stream = File.OpenWrite(localFilePath))
                {
                    await service.PullAsync(LinuxPath.Combine(remotePath, stat.Path), stream);
                    await stream.FlushAsync();
                }
                break;
        }
    }
}

wherewhere avatar Mar 19 '24 09:03 wherewhere

https://gist.github.com/wherewhere/53c49073c5da2c17536f99410899359d

wherewhere avatar Mar 20 '24 10:03 wherewhere