Zied.M
Zied.M

Reputation: 215

download a file from drive

I want to download a file from google drive with vb.net . I have a gridview where à list all my file exist in drive , and when i select a file (in grid ) , i download it . after searching in different website , i try to do it ,but i have a problem

Here is my code

Public Sub DownloadFile(index As String)
    CreateService()
    Dim url As String = ""
    Dim list = Service.Files.List()
    ' list.Fields = "nextPageToken, items(id, title)"
    Dim count = list.Execute()
    For Each fich In count.Items
        If (fich.Title = index) Then
            url = fich.WebContentLink
            Exit For
        End If
    Next
    Dim Downloader = New MediaDownloader(Service)
    ' figure out the right file type base on UploadFileName extension
    Dim Filename = index
    Dim FileStream = New System.IO.FileStream(Filename, System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite)
    Dim progress = Downloader.DownloadAsync(url, FileStream)
    If DownloadStatus.Downloading.Completed Then
        MessageBox.Show("succeful download")
    Else
        MessageBox.Show("erreur")
    End If

When the messagebox affich a succeful download , i found the file in my application directory , but i can't open it , his size is 0KB

Index is rowselected value (in grid)

Upvotes: 1

Views: 3702

Answers (1)

Jeremy
Jeremy

Reputation: 863

Since you are using an asynchronous download method first you should use Await in front to ensure the remainder of your method executes following the download. However, you haven't provided enough code to fully understand the process of your method and what else could be wrong.

You should follow this pattern to download a file: https://developers.google.com/api-client-library/dotnet/guide/media_download

This is an example and shouldn't be taken literally. You will want to add parameters to the method to fill in the APP_NAME_HERE, BUCKET_HERE, OBJECT_HERE, FILE_PATH_HERE.

Public Shared Sub DownloadFile()
    ' Create the service using the client credentials.
    Dim storageService = New StorageService(New 
    BaseClientService.Initializer() With
        {
            .HttpClientInitializer = credential,
            .ApplicationName = "APP_NAME_HERE"
        })
    ' Get the client request object for the bucket and desired object.
    Dim getRequest = storageService.Objects.Get("BUCKET_HERE", "OBJECT_HERE")
    Using fileStream As New System.IO.FileStream(
        "FILE_PATH_HERE",
        System.IO.FileMode.Create,
        System.IO.FileAccess.Write)
        ' Add a handler which will be notified on progress changes.
        ' It will notify on each chunk download and when the
        ' download is completed or failed.
        AddHandler getRequest.MediaDownloader.ProgressChanged, AddressOf Download_ProgressChanged
        getRequest.Download(fileStream)
    End Using
End Sub

Private Shared Sub  Download_ProgressChanged(IDownloadProgress progress)
    Console.WriteLine(progress.Status & " " & progress.BytesDownloaded);
End Sub

This is the method for using the Google Cloud API as you were using, but you more than likely want to use the Google Drive API:

Imports System.Net
Imports Google.Apis.Authentication
Imports Google.Apis.Drive.v2
Imports Google.Apis.Drive.v2.Data

Public Class MyClass

    ''' <summary>
    ''' Download a file and return a stream with its content.
    ''' </summary>
    ''' <param name="authenticator">
    ''' Authenticator responsible for creating authorized web requests.
    ''' </param>
    ''' <param name="file">Drive File instance.</param>
    ''' <returns>File's content if successful, null otherwise.</returns>
    Public Shared Function System.IO.Stream DownloadFile(authenticator As IAuthenticator, webFile As File)

        If Not String.IsNullOrEmpty(webFile.DownloadUrl) Then
            Try
                Dim request = WebRequest.Create(New Uri(webFile.DownloadUrl))
                authenticator.ApplyAuthenticationToRequest(request)
                Dim response = request.GetResponse()
                If response.StatusCode = HttpStatusCode.OK Then
                    Return response.GetResponseStream()
                End If

                Console.WriteLine("An error occurred: " & response.StatusDescription)
                Return null

            Catch (e as Exception)
                Console.WriteLine("An error occurred: " & e.Message)
                Return null
            End Try
        End If

        ' The file doesn't have any content stored on Drive.
        Return null;
    End Function
End Class

What you have is quite close, these changes should make it work.

Public Sub DownloadFile(service As DriveService, fileName As String, outputStream As Stream)
    Dim list = service.Files.List().Execute()
    Dim file = list.FirstOrDefault(Function(x) x.Title.Equals(fileName))
    If file Is Nothing Then
        Console.WriteLine("File not found.")
        Return
    End If
    Dim request = service.Files.Get(file.Id)

    ' Add a handler which will be notified on progress changes.
    ' It will notify on each chunk download and when the
    ' download is completed or failed.
    AddHandler request.MediaDownloader.ProgressChanged,
            Sub(IDownloadProgress progress)
                Select Case progress.Status
                    Case DownloadStatus.Downloading
                        Console.WriteLine(progress.BytesDownloaded)

                    case DownloadStatus.Completed
                        Console.WriteLine("Download complete.")

                    Case DownloadStatus.Failed:
                        Console.WriteLine("Download failed.")

                End Select
            End Sub
        request.Download(outputStream);
End Sub

Upvotes: 1

Related Questions