[C#] Mover archivos de windows || Isolated Storage

Iniciado por n-utz, 22 Julio 2017, 05:32 AM

0 Miembros y 1 Visitante están viendo este tema.

n-utz

Buenas gente, miren vengo con una idea que necesito que me orienten para poder hacerla.

La idea es esta >

Tengo varias 'resumenes' en txt que completo dia a dia en mi PC, y despues los voy copiando/reemplazando en la carpeta desktop de Google Drive, resulta que siempre reemplazo los mismos archivos, es decir mantengo actualizados mis resumenes de Google Drive y siempre son los mismos.

Se me ocurrio poder hacer algun programa (tengo la idea de .exe en la cabeza) que ejecute una macro o pedazo de codigo que mueva y reemplace los archivos de cierta carpeta/s a la de Google Drive y haga todo el proceso solo con tan solo ejecutar el .exe .

Por otro lado, estoy buscando información sobre como poder usar el Isolated Storage, no suelo entender la libreria de ms.

Si pueden orientarme en este asunto les agradezco, planeo hacerlo en VS 2017 con C#.

Eleкtro

#1
Hola.

Voy a empezar fuerte. Veamos...

Si quieres seguir mi consejo, entonces aquí debes plantearte el siguiente dilema (o al menos yo en tu lugar me lo plantearía muy seriamente):

- Si quieres crear una Macro, entonces usa cualquier herramienta para crear macros, no necesitas recurrir a un lenguaje de alto nivel como C#, de hecho lo que harías en 5 horas en C#, lo haces en 5 minutos con cualquier herramienta enfocada a las macros.
 Una herramienta excelente sería JitBit Macro Recorder.

- Si quieres usar C# para automatizar de forma programática la subida y sobreescirtura de archivos en Google Drive, entonces olvídate de crear macros, y usa la API de Google Drive para .NET, el resultado será un algoritmo informático optimizado en donde la subida/sobreescritura del archivo se realizaría en segundo plano o background, de forma asincrónica y resumible, y donde podrías controlar cualquier posible fallo/excepción al intentar subir/sobreescribir el archivo. Esta sofisticación, con una macro, requeriría mucho más esfuerzo y análisis en comparación para conseguir hacerlo... y hacerlo medianamente bien.

Si tu decisión final es seguir queriendo utilizar C# para desarrollar una macro, pues en mi humilde opinión eso que propones sería lo mismo que pretender estudiar la profesión de maquinista de trenes... sólo para usar trenes de juguete.

[youtube=640,360]https://www.youtube.com/watch?v=m_yEMTRQ82Q[/youtube]

Es así, de verdad, para crear una macro en plan "automatizar pulsaciones del teclado y del ratón junto a análisis de comparación de imagen o automatización web" no necesitas C#, y de hecho el resultado no sería tan eficiente ( teniendo en cuenta que para empezar no sabes demasiado bien como hacerlo, y para eso deberías recurrir al aprendizaje de conceptos de software automation en .NET, o recurrir a metodologías rudimentarias con la WinAPI, lo que te llevaría mucho tiempo. ) en comparación con recurrir a una herramienta especializada en crear macros... como por ejemplo la herramienta que ya mencioné más arriba.




Partiendo de la premisa de arriba, y asumiendo que te hayas replanteado el problema para enfocarlo de forma óptima y utilizar C# junto a la API de Google Drive, entonces te explicaré el procedimiento...:

Antes de poder utilizar la API, primero existen unos pasos preeliminares que basicamente consisten en registrar una clave de la API de Google Drive para tu uso personal, con la que generar un archivo.json para poder realizar la autorización OAuthv2 en los servicios de Google Drive desde tu código/aplicación.

Aquí te explican paso a paso el qué y el cómo debes llevar a cabo el registro de la API:
...solo se toma de 5 o 10 minutos en hacerlo.

Cita de: https://developers.google.com/drive/v3/web/quickstart/dotnetStep 1: Turn on the Drive API

   Use this wizard to create or select a project in the Google Developers Console and automatically turn on the API. Click Continue, then Go to credentials.
   On the Add credentials to your project page, click the Cancel button.
   At the top of the page, select the OAuth consent screen tab. Select an Email address, enter a Product name if not already set, and click the Save button.
   Select the Credentials tab, click the Create credentials button and select OAuth client ID.
   Select the application type Other, enter the name "Drive API Quickstart", and click the Create button.
   Click OK to dismiss the resulting dialog.
   Click the file_download (Download JSON) button to the right of the client ID.
   Move this file to your working directory and rename it client_secret.json.

Bien. El segundo paso sería descargar/instalar la API v3 de Google Drive para .NET:
( también necesitas descargar todas las dependencias que se indican al pie de página. )

Ten en cuenta que puedes automatizar la instalación de la API de Google Drive ( incluyendo sus dependencias ) en Visual Studio, simplemente creando un nuevo proyecto de C#, abriendo la consola de NuGet y escribiendo el siguiente comando en dicha consola:
Install-Package Google.Apis.Drive.v3

Llegados a este punto, ahora ya puedes empezar a desarrollar tu algoritmo con la API. Lo primero sería desarrollar una funcionalidad para la autentificación de usuario con la API de Google Drive, seguidamente otra funcionalidad para buscar/identificar el archivo que quieres sobreescribir, y por último implementar la funcionalidad para llevar a cabo la subida/sobreescritura del archivo.

...¿Que cómo se hace todo eso?, pues leyendo y poniendo en práctica todo lo leido, por supuesto, esto no es cosa de "hacer click y listo". Aquí tienes la documentación oficial de la API:


Esto es, mayórmente, sobre lo que debes documentarte:


PD: No es tan dificil como parece. Por si te sirve de ánimos: yo ya hice clientes en .NET con funcionalidades sincrónicas y asincónicas para administrar la cuenta de Youtube, Gmail, y Drive. Aprendido el manejo de uno, aprendidos todos xD, ya que las APIS de cada servicio de Google solo cambian en los nombres de sus miembros, pero su modo de empleo es practicamente idéntico...

Si tienes cualquier duda al respecto, no dudes en preguntar.

Saludos!








TickTack

Hola Elektro,

desde el viernes que quize ayudar pero siempre hubo algo que no me dejo escribir una respuesta.

Yo crei que solo se trataba de mover archivos de una carpeta a otra.

Bueno pero antes de borrar mi codigo me gustaria publicarlo aqui (a menos que no este bien).

Envidiame, Elektro... jajaja. No. Si soy el peor... ni siquiera funciona:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Pasador_de_archivos
{
    public partial class Form1 : Form
    {
        string carpetaorigen;
        string carpetadestino;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            foreach (string line in File.ReadLines(@"Datos.txt", Encoding.UTF8))
            {
                if(line.Contains("Origen"))
                {
                    carpetaorigen = line.Substring(8);
                }

                if(line.Contains("Destino"))
                {
                    carpetadestino = line.Substring(9);
                }
            }

            File.Move(carpetaorigen, carpetadestino);
        }
    }
}



Tambien queria comentar que para descargar archivos de Google Drive siempre me gusto este archivo.cs: https://gist.github.com/yasirkula/d0ec0c07b138748e5feaecbd93b6223c/archive/40ea0967c6e8e8ee3a3bb837d75be00f4400b4d5.zip

Saludos
Citar
"Ninguna mentira puede inventarse lo suficientemente patán: el pueblo hispanohablante la cree. Por una consigna que se les dio, persiguieron a sus compatriotas con mayor encarnizamiento que a sus verdaderos enemigos."

Eleкtro

#3
Cita de: TickTack en 23 Julio 2017, 20:24 PMYo crei que solo se trataba de mover archivos de una carpeta a otra.

No sé, espero no haberme equivocado yo... por que de lo contrario estoy escribiendo mucho para nada xD. Lo que yo he interpretado es que el usuario pretende subir un archivo local, a una carpeta llamada "desktop" en su cuenta de Google Drive, y sobreescribir ese archivo existente por el archivo local. Como ya digo, espero no haberme equivocado yo xD.




( Me tomo la libertad de hacer doble post, por que el código de este comentario no cabe en el de arriba. )

No suelo entregarle el trabajo hecho a nadie, sino las herramientas para hacerlo, pero entiendo que hablar de APIs de terceros (y más siendo tan "completas" o extensas como las de Google) es sinónimo de pereza y dificultad... basicamente por que hay que aprender muy bien como funciona "internamente" para poder hacer algo con esa API.

Bueno, pues voy a intentar ayudarte un poco más en ese aspecto compartiendo contigo (y con los demás a los que les pueda resultar útil) un código que he extraido de mi framework comercial ElektroKit, que si a alguien le interesa... lo puede encontrar en mi firma de usuario.
El código original lo he recortado mucho solamente para dejar los miembros/funcionalidades que tú necesitarías para reproducir esa "macro", es decir la funcionalidad de autorización, la de identificar el archivo a sobreescribir, y la de sobreescribirlo.

EDITO: Lo he tenido que recortar muchísimo más de lo que esperaba para que quepa. Maldito límite de 30.000 caracteres XD.

Bueno, aquí lo tienes:

Código (vbnet) [Seleccionar]
#Region " Google Drive Scopes "

Namespace Google.Drive.Enums

   ''' <summary>
   ''' Specifies the OAuthv2 scopes for use with the Google Drive API.
   ''' </summary>
   <Flags>
   Public Enum DriveScopes As Integer

       ''' <summary>
       ''' View and manage the files in your Google Drive.
       ''' </summary>
       Full = 2

       ''' <summary>
       ''' View and manage its own configuration data in your Google Drive.
       ''' </summary>
       ApplicationData = 4

       ''' <summary>
       ''' View and manage Google Drive files and folders that you have opened or created with this application.
       ''' </summary>
       Files = 8

       ''' <summary>
       ''' View and manage metadata of files in your Google Drive.
       ''' </summary>
       Metadata = 16

       ''' <summary>
       ''' Modify your Google Apps Script scripts' behavior.
       ''' </summary>
       Scripts = 32

       ''' <summary>
       ''' View the files in your Google Drive.
       ''' </summary>
       [ReadOnly] = 64

       ''' <summary>
       ''' View metadata for files in your Google Drive.
       ''' </summary>
       MetadataReadonly = 128

       ''' <summary>
       ''' View the photos, videos and albums in your Google Photos.
       ''' </summary>
       PhotosReadonly = 256

   End Enum

End Namespace

#End Region


+

Código (vbnet) [Seleccionar]
#Region " Option Statements "

Option Strict On
Option Explicit On
Option Infer Off

#End Region

#Region " Imports "

Imports Google.Apis.Auth.OAuth2
Imports Google.Apis.Drive.v3
Imports Google.Apis.Drive.v3.Data
Imports Google.Apis.Services
Imports Google.Apis.Upload
Imports Google.Apis.Util.Store

Imports Google.Drive.Enums

#End Region

#Region " Google Drive Client "

Namespace Google.Drive.Types

   ''' ----------------------------------------------------------------------------------------------------
   ''' <summary>
   ''' A client for Google Drive service.
   ''' </summary>
   ''' ----------------------------------------------------------------------------------------------------
   Public NotInheritable Class DriveClient : Implements IDisposable

#Region " Private Fields "

       Private client As DriveService
       Private credential As UserCredential
       Private ReadOnly authExceptionMessage As String =
           "The user has not yet authorized the usage of this application.
            Call 'DriveClient.Authorize()' or 'DriveClient.AuthorizeAsync()' methods."
       Private scopeDict As New Dictionary(Of DriveScopes, String)(StringComparison.Ordinal) From
       {
           {DriveScopes.Full, DriveService.Scope.Drive},
           {DriveScopes.ApplicationData, DriveService.Scope.DriveAppdata},
           {DriveScopes.Files, DriveService.Scope.DriveFile},
           {DriveScopes.Metadata, DriveService.Scope.DriveMetadata},
           {DriveScopes.MetadataReadonly, DriveService.Scope.DriveMetadataReadonly},
           {DriveScopes.PhotosReadonly, DriveService.Scope.DrivePhotosReadonly},
           {DriveScopes.ReadOnly, DriveService.Scope.DriveReadonly},
           {DriveScopes.Scripts, DriveService.Scope.DriveScripts}
       }

#End Region

#Region " Properties "

       ''' <summary>
       ''' Gets the client credentials.
       ''' </summary>
       Public ReadOnly Property Secrets As ClientSecrets

       ''' <summary>
       ''' Gets the mail address to authorize Drive service. (e.g: "mail@gmail.com")
       ''' </summary>
       Public ReadOnly Property MailAddress As String

       ''' <summary>
       ''' Gets the current Drive OAuthv2 scopes.
       ''' </summary>
       Public ReadOnly Property Scopes As DriveScopes

       ''' <summary>
       ''' Gets a value that determines whether Google Drive API authorization was done.
       ''' </summary>
       Public ReadOnly Property IsAuthorized As Boolean
           Get
               Return isAuthorizedB
           End Get
       End Property
       Private isAuthorizedB As Boolean = False

#End Region

#Region " Constructors "

       Private Sub New()
       End Sub

       ''' <param name="apiFile">
       ''' The <c>client_secrets.json</c> file generated by Drive API console that contains the OAuthv2 login data
       ''' such as the client id, client secret, and redirection URI.
       ''' </param>
       ''' <param name="mailAddress">
       ''' The mail address to authorize Drive service. (e.g: "mail@gmail.com")
       ''' </param>
       ''' <param name="scopes">
       ''' The Drive OAuthv2 scope.
       ''' </param>
       Public Sub New(apiFile As FileInfo, mailAddress As String, scopes As DriveScopes)
           Me.MailAddress = mailAddress
           Me.Scopes = scopes
           Using sr As FileStream = apiFile.OpenRead()
               Me.Secrets = GoogleClientSecrets.Load(sr).Secrets
           End Using
       End Sub

#End Region

#Region " Public Methods "

#Region " Authorization "

       ''' <summary>
       ''' Authorizes this instance to use Google Drive API services.
       ''' </summary>
       ''' <example>
       ''' <code>
       ''' Dim client As New DriveClient("C:\secrets.json", "mail@gmail.com", DriveScopes.Full)
       ''' Dim credential As UserCredential = client.Authorize()
       ''' </code>
       ''' </example>
       Public Function Authorize() As UserCredential
           Dim t As Task(Of UserCredential) = Task.Run(AddressOf Me.AuthorizeAsync)
           t.Wait(Timeout.Infinite)
           Return t.Result
       End Function

       ''' <summary>
       ''' Authorizes this instance to use Google Drive API services.
       ''' </summary>
       ''' <example>
       ''' <code>
       ''' Dim client As New DriveClient("C:\secrets.json", "mail@gmail.com", DriveScopes.Full)
       ''' Dim credential As UserCredential = Await client.AuthorizeAsync()
       ''' </code>
       ''' </example>
       Public Async Function AuthorizeAsync() As Task(Of UserCredential)
           Dim scopeUrls As String() = GetScopeUrls(Scopes)

           Me.credential =
                Await GoogleWebAuthorizationBroker.AuthorizeAsync(Secrets,
                                                                  scopeUrls.ToArray(),
                                                                  MailAddress,
                                                                  CancellationToken.None,
                                                                  New FileDataStore("UNET", fullPath:=False))

           Me.client = New DriveService(New BaseClientService.Initializer() With {
                                        .HttpClientInitializer = Me.credential,
                                        .ApplicationName = "UNET" ', .ApiKey = ""
           })

           isAuthorizedB = True
           Return Me.credential
       End Function

#End Region

#Region " Get Files "

       ''' <summary>
       ''' Gets all the files stored in the current user account.
       ''' </summary>
       ''' <example>
       ''' <code>
       '''     Dim client As New DriveClient("C:\secrets.json", "mail@gmail.com", DriveScopes.Full)
       '''     Dim credential As UserCredential = client.Authorize()
       '''     Dim files As List(Of File) = client.GetFiles()
       '''
       '''     For Each file As File In files
       '''         Dim sb As New StringBuilder
       '''         With sb
       '''             .AppendLine(String.Format("Id: {0}", file.Id))
       '''             .AppendLine(String.Format("Owned By Me?: {0}", file.OwnedByMe))
       '''             .AppendLine(String.Format("Name: {0}", file.Name))
       '''         End With
       '''         Console.WriteLine(sb.ToString)
       '''     Next file
       ''' </code>
       ''' </example>
       Public Function GetFiles() As List(Of File)
           If Not (isAuthorizedB) Then
               Throw New InvalidOperationException(authExceptionMessage)

           Else
               Dim t As Task(Of List(Of File)) = Task.Run(AddressOf GetFilesAsync)
               t.Wait(Timeout.Infinite)
               Return t.Result

           End If
       End Function

       ''' <summary>
       ''' Asynchronously gets all the files stored in the current user account.
       ''' </summary>
       ''' <example>
       ''' <code>
       '''     Dim client As New DriveClient("C:\secrets.json", "mail@gmail.com", DriveScopes.Full)
       '''     Dim credential As UserCredential = Await client.AuthorizeAsync()
       '''     Dim files As List(Of File) = Await client.GetFilesAsync()
       '''
       '''     For Each file As File In files
       '''         Dim sb As New StringBuilder
       '''         With sb
       '''             .AppendLine(String.Format("Id: {0}", file.Id))
       '''             .AppendLine(String.Format("Owned By Me?: {0}", file.OwnedByMe))
       '''             .AppendLine(String.Format("Name: {0}", file.Name))
       '''         End With
       '''         Console.WriteLine(sb.ToString)
       '''     Next file
       ''' </code>
       ''' </example>
       Public Async Function GetFilesAsync() As Task(Of List(Of File))

           If Not (isAuthorizedB) Then
               Throw New InvalidOperationException(authExceptionMessage)

           Else
               Dim request As FilesResource.ListRequest = Me.client.Files.List()
               With request
                   .PageSize = 100
                   .IncludeTeamDriveItems = False
                   .SupportsTeamDrives = False
                   .Fields = "nextPageToken, files"
                   .Q = "not mimeType contains 'folder'"
               End With

               Dim response As FileList = Await request.ExecuteAsync()

               Dim files As New List(Of File)
               Do While True

                   For Each file As File In response.Files
                       Dim getRequest As FilesResource.GetRequest = Me.client.Files.Get(file.Id)
                       With getRequest
                           .SupportsTeamDrives = False
                           .Fields = "*"
                       End With

                       Dim getResponse As File = Await getRequest.ExecuteAsync()
                       getRequest.AcknowledgeAbuse = True
                       files.Add(getResponse)
                   Next file

                   If Not String.IsNullOrEmpty(response.NextPageToken) Then
                       request.PageToken = response.NextPageToken
                       response = Await request.ExecuteAsync()
                   Else
                       Exit Do
                   End If

               Loop

               Return files

           End If

       End Function

       ''' <summary>
       ''' Asynchronously gets the files stored in the current user account that matches the specified search criteria.
       ''' </summary>
       ''' <example>
       ''' <code>
       '''     Dim client As New DriveClient("C:\secrets.json", "mail@gmail.com", DriveScopes.Full)
       '''     Dim credential As UserCredential = Await client.AuthorizeAsync()
       '''     Dim predicate As Func(Of File, Boolean) =
       '''         Function(f As File) f.Name.Equals("My Folder Name", StringComparison.OrdinalIgnoreCase)
       '''     Dim files As List(Of File) = Await client.GetFilesAsync(predicate)
       '''
       '''     For Each file As File In files
       '''         Dim sb As New StringBuilder
       '''         With sb
       '''             .AppendLine(String.Format("Id: {0}", file.Id))
       '''             .AppendLine(String.Format("Name: {0}", file.Name))
       '''         End With
       '''         Console.WriteLine(sb.ToString)
       '''     Next file
       ''' </code>
       ''' </example>
       Public Async Function GetFilesAsync(predicate As Func(Of File, Boolean)) As Task(Of List(Of File))
           Dim folders As List(Of File) = Await GetFilesAsync()
           Return folders.Where(predicate).ToList()
       End Function

       ''' <summary>
       ''' Gets a file stored in the current user account that matches the specified file id.
       ''' </summary>
       ''' <example>
       ''' <code>
       '''     Dim client As New DriveClient("C:\secrets.json", "mail@gmail.com", DriveScopes.Full)
       '''     Dim credential As UserCredential = client.Authorize()
       '''     Dim file As File) = client.GetFileById(" File Id. ")
       '''
       '''     Dim sb As New StringBuilder
       '''     With sb
       '''          .AppendLine(String.Format("Id: {0}", file.Id))
       '''          .AppendLine(String.Format("Owned By Me?: {0}", file.OwnedByMe))
       '''          .AppendLine(String.Format("Name: {0}", file.Name))
       '''     End With
       '''     Console.WriteLine(sb.ToString)
       ''' </code>
       ''' </example>
       Public Function GetFileById(id As String) As File
           If Not (isAuthorizedB) Then
               Throw New InvalidOperationException(authExceptionMessage)

           Else
               Dim t As Task(Of File) = Task.Run(Function() GetFileByIdAsync(id))
               t.Wait(Timeout.Infinite)
               Return t.Result

           End If
       End Function

       ''' <summary>
       ''' Asynchronously gets a file stored in the current user account that matches the specified file id.
       ''' </summary>
       ''' <example>
       ''' <code>
       '''     Dim client As New DriveClient("C:\secrets.json", "mail@gmail.com", DriveScopes.Full)
       '''     Dim credential As UserCredential = Await client.AuthorizeAsync()
       '''     Dim file As File) = Await client.GetFileByIdAsync(" File Id. ")
       '''
       '''     Dim sb As New StringBuilder
       '''     With sb
       '''          .AppendLine(String.Format("Id: {0}", file.Id))
       '''          .AppendLine(String.Format("Owned By Me?: {0}", file.OwnedByMe))
       '''          .AppendLine(String.Format("Name: {0}", file.Name))
       '''     End With
       '''     Console.WriteLine(sb.ToString)
       ''' </code>
       ''' </example>
       Public Async Function GetFileByIdAsync(id As String) As Task(Of File)
           If Not (isAuthorizedB) Then
               Throw New InvalidOperationException(authExceptionMessage)

           Else
               Dim predicate As Func(Of File, Boolean) =
                     Function(f As File) f.Id.Equals(id, StringComparison.OrdinalIgnoreCase)

               Dim result As List(Of File) = Await Task.Run(Function() GetFilesAsync(predicate))
               Return result.DefaultIfEmpty(Nothing).SingleOrDefault()

           End If
       End Function

#End Region

#Region " Update (replace) File "

       ''' <summary>
       ''' Updates (replaces) a existing file in the specified folder.
       ''' </summary>
       ''' <example>
       ''' <code>
       ''' Private Sub UpdateFile()
       '''
       '''    Dim client As New DriveClient("C:\secrets.json", "mail@gmail.com", DriveScopes.Full)
       '''    Dim credential As UserCredential = client.Authorize()
       '''
       '''    Dim srcFile As New FileInfo("C:\File.ext")
       '''    Dim dstFile As File = client.GetFilesByName("File to update.ext").Single()
       '''
       '''    Dim result As KeyValuePair(Of Upload.ResumableUpload, File) =
       '''        client.UpdateFile(srcFile, dstFile)
       '''        
       '''    Dim upload As ResumableUpload = result.Key
       '''    
       '''    Select Case upload.GetProgress().Status
       '''    
       '''        Case Upload.UploadStatus.Failed
       '''            Console.WriteLine("Upload Failed.")
       '''            ' ToDo: Retry/Resume Upload?:
       '''            ' upload.Upload()
       '''            ' upload.Resume()
       '''            
       '''        Case Upload.UploadStatus.Completed
       '''            Dim dstFile As ResumableUpload = result.Value
       '''            Dim sb As New StringBuilder
       '''            With sb
       '''                .AppendLine(String.Format("Id: {0}", dstFile.Id))
       '''                .AppendLine(String.Format("Name: {0}", dstFile.Name))
       '''            End With
       '''        Console.WriteLine(sb.ToString)
       '''        
       '''    End Select
       '''
       ''' End Sub
       ''' </code>
       ''' </example>
       ''' <param name="srcFile">
       ''' The source file to upload.
       ''' </param>
       ''' <param name="dstFile">
       ''' The metadata of the existing file being updated.
       ''' </param>
       Public Function UpdateFile(srcFile As FileInfo, dstFile As File) As KeyValuePair(Of ResumableUpload, File)
           If Not (isAuthorizedB) Then
               Throw New InvalidOperationException(authExceptionMessage)

           Else
               Dim t As Task(Of KeyValuePair(Of ResumableUpload, File)) =
                   Task.Run(Function() Me.UpdateFileAsync(srcFile, dstFile, Nothing, Nothing))
               t.Wait(Timeout.Infinite)
               Return t.Result

           End If
       End Function

       ''' <summary>
       ''' Updates (replaces) a existing file in the specified folder.
       ''' </summary>
       ''' <example>
       ''' <code>
       ''' Private Sub UpdateFile()
       '''
       '''    Dim client As New DriveClient("C:\secrets.json", "mail@gmail.com", DriveScopes.Full)
       '''    Dim credential As UserCredential = client.Authorize()
       '''
       '''    Dim srcFile As New FileInfo("C:\File.ext")
       '''
       '''    Dim result As KeyValuePair(Of Upload.ResumableUpload, File) =
       '''        client.UpdateFile(srcFile, "File Id")
       '''        
       '''    Dim upload As ResumableUpload = result.Key
       '''    
       '''    Select Case upload.GetProgress().Status
       '''    
       '''        Case Upload.UploadStatus.Failed
       '''            Console.WriteLine("Upload Failed.")
       '''            ' ToDo: Retry/Resume Upload?:
       '''            ' upload.Upload()
       '''            ' upload.Resume()
       '''            
       '''        Case Upload.UploadStatus.Completed
       '''            Dim dstFile As ResumableUpload = result.Value
       '''            Dim sb As New StringBuilder
       '''            With sb
       '''                .AppendLine(String.Format("Id: {0}", dstFile.Id))
       '''                .AppendLine(String.Format("Name: {0}", dstFile.Name))
       '''            End With
       '''        Console.WriteLine(sb.ToString)
       '''        
       '''    End Select
       '''
       ''' End Sub
       ''' </code>
       ''' </example>
       ''' <param name="srcFile">
       ''' The source file to upload.
       ''' </param>
       ''' <param name="dstFileId">
       ''' The identifier of the existing file being updated.
       ''' </param>
       Public Function UpdateFile(srcFile As FileInfo, dstFileId As String) As KeyValuePair(Of ResumableUpload, File)
           If Not (isAuthorizedB) Then
               Throw New InvalidOperationException(authExceptionMessage)

           Else
               Dim dstFile As File = GetFileById(dstFileId)
               If (dstFile Is Nothing) Then
                   Throw New Exception(String.Format("File not found with the specified Id: {0}", dstFileId))
               End If

               Dim t As Task(Of KeyValuePair(Of ResumableUpload, File)) =
                   Task.Run(Function() Me.UpdateFileAsync(srcFile, dstFile, Nothing, Nothing))
               t.Wait(Timeout.Infinite)
               Return t.Result

           End If
       End Function

       ''' <summary>
       ''' Asynchronously updates (replaces) a existing file in the specified folder.
       ''' </summary>
       ''' <example>
       ''' <code>
       ''' Private Async Sub UpdateFile()
       '''
       '''    Dim client As New DriveClient("C:\secrets.json", "mail@gmail.com", DriveScopes.Full)
       '''    Dim credential As UserCredential = Await client.AuthorizeAsync()
       '''
       '''    Dim srcFile As New FileInfo("C:\File.ext")
       '''    Dim dstFile As File = client.GetFilesByName("File to update.ext").Single()
       '''
       '''    Dim result As KeyValuePair(Of Upload.ResumableUpload, File) =
       '''        Await client.UpdateFileAsync(srcFile, dstFile, AddressOf Me.Upload_ProgressChanged, Nothing)
       '''
       '''     Dim sb As New StringBuilder
       '''     With sb
       '''         .AppendLine(String.Format("Id: {0}", result.Value.Id))
       '''         .AppendLine(String.Format("Name: {0}", result.Value.Name))
       '''     End With
       '''     Console.WriteLine(sb.ToString)
       '''
       ''' End Sub
       '''
       ''' Public Sub Upload_ProgressChanged(e As Upload.IUploadProgress)
       '''
       '''     Select Case e.Status
       '''
       '''         Case Upload.UploadStatus.Uploading
       '''             Console.WriteLine("Bytes sent: {0}", e.BytesSent)
       '''
       '''         Case Upload.UploadStatus.Completed
       '''             Console.WriteLine("Upload completed.")
       '''
       '''         Case Upload.UploadStatus.Failed
       '''             Console.WriteLine("Upload failed. Reason: {0}", e.Exception.Message)
       '''
       '''         Case Else
       '''             ' Do Nothing.
       '''
       '''     End Select
       '''
       ''' End Sub
       ''' </code>
       ''' </example>
       ''' <param name="srcFile">
       ''' The source file to upload.
       ''' </param>
       ''' <param name="dstFile">
       ''' The metadata of the existing file being updated.
       ''' </param>
       ''' <param name="progressHandler">
       ''' A event handler that will receive progress changes of the upload operation.
       ''' </param>
       ''' <param name="cancellationToken">
       ''' A cancellation token to cancel the upload operation.
       ''' </param>
       Public Async Function UpdateFileAsync(srcFile As FileInfo,
                                             dstFile As File,
                                             progressHandler As Action(Of IUploadProgress),
                                             cancellationToken As CancellationToken) As Task(Of KeyValuePair(Of ResumableUpload, File))

           If Not (isAuthorizedB) Then
               Throw New InvalidOperationException(authExceptionMessage)

           Else
               Dim request As FilesResource.UpdateMediaUpload
               Dim progress As IUploadProgress
               Using stream As New FileStream(srcFile.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)

                   Dim dstFileTemp As New File() With {
                       .AppProperties = dstFile.AppProperties,
                       .Name = srcFile.Name,
                       .Description = dstFile.Description,
                       .Kind = dstFile.Kind,
                       .Properties = dstFile.Properties,
                       .OriginalFilename = dstFile.OriginalFilename,
                       .Trashed = dstFile.Trashed,
                       .WritersCanShare = dstFile.WritersCanShare
                   }

                   request = Me.client.Files.Update(dstFileTemp, dstFile.Id, stream, dstFile.MimeType)
                   With request
                       .AddParents = String.Join(",", dstFile.Parents)
                       .ChunkSize = 262144
                       .SupportsTeamDrives = False
                       .Fields = "*"
                   End With

                   AddHandler request.ProgressChanged, progressHandler
                   progress = Await request.UploadAsync(cancellationToken)
                   RemoveHandler request.ProgressChanged, progressHandler
               End Using

               Dim response As File = request.ResponseBody
               Return New KeyValuePair(Of ResumableUpload, File)(request, response)

           End If

       End Function

       ''' <summary>
       ''' Asynchronously updates (replaces) a existing file in the specified folder.
       ''' </summary>
       ''' <example>
       ''' <code>
       ''' Private Async Sub UpdateFile()
       '''
       '''    Dim client As New DriveClient("C:\secrets.json", "mail@gmail.com", DriveScopes.Full)
       '''    Dim credential As UserCredential = Await client.AuthorizeAsync()
       '''
       '''    Dim srcFile As New FileInfo("C:\File.ext")
       '''
       '''    Dim result As KeyValuePair(Of Upload.ResumableUpload, File) =
       '''        Await client.UpdateFileAsync(srcFile, "File Id", AddressOf Me.Upload_ProgressChanged, Nothing)
       '''
       '''     Dim sb As New StringBuilder
       '''     With sb
       '''         .AppendLine(String.Format("Id: {0}", result.Value.Id))
       '''         .AppendLine(String.Format("Name: {0}", result.Value.Name))
       '''     End With
       '''     Console.WriteLine(sb.ToString)
       '''
       ''' End Sub
       '''
       ''' Public Sub Upload_ProgressChanged(e As Upload.IUploadProgress)
       '''
       '''     Select Case e.Status
       '''
       '''
       '''         Case Upload.UploadStatus.Uploading
       '''             Console.WriteLine("Bytes sent: {0}", e.BytesSent)
       '''
       '''         Case Upload.UploadStatus.Completed
       '''             Console.WriteLine("Upload completed.")
       '''
       '''         Case Upload.UploadStatus.Failed
       '''             Console.WriteLine("Upload failed. Reason: {0}", e.Exception.Message)
       '''
       '''         Case Else
       '''             ' Do Nothing.
       '''
       '''     End Select
       '''
       ''' End Sub
       ''' </code>
       ''' </example>
       ''' <param name="srcFile">
       ''' The source file to upload.
       ''' </param>
       ''' <param name="dstFileId">
       ''' The identifier of the existing file being updated.
       ''' </param>
       ''' <param name="progressHandler">
       ''' A event handler that will receive progress changes of the upload operation.
       ''' </param>
       ''' <param name="cancellationToken">
       ''' A cancellation token to cancel the upload operation.
       ''' </param>
       Public Async Function UpdateFileAsync(srcFile As FileInfo,
                                             dstFileId As String,
                                             progressHandler As Action(Of IUploadProgress),
                                             cancellationToken As CancellationToken) As Task(Of KeyValuePair(Of ResumableUpload, File))

           If Not (isAuthorizedB) Then
               Throw New InvalidOperationException(authExceptionMessage)

           Else
               Dim dstFile As File = Await GetFileByIdAsync(dstFileId)
               If (dstFile Is Nothing) Then
                   Throw New Exception(String.Format("File not found with the specified Id: {0}", dstFileId))
               End If

               Return Await Me.UpdateFileAsync(srcFile, dstFile, progressHandler, cancellationToken)

           End If

       End Function

#End Region

#End Region

#Region " Private Methods "

       Private Function GetScopeUrls(scopes As DriveScopes) As String()

           Return (From scope As KeyValuePair(Of DriveScopes, String) In Me.scopeDict
                   Where Scopes.HasFlag(scope.Key)
                   Select scope.Value).ToArray()

       End Function

#End Region

#Region " IDisposable Implementation "

       Private isDisposed As Boolean = False

       Public Sub Dispose() Implements IDisposable.Dispose
           Me.Dispose(isDisposing:=True)
           GC.SuppressFinalize(obj:=Me)
       End Sub

       Private Sub Dispose(isDisposing As Boolean)

           If (Not Me.isDisposed) AndAlso (isDisposing) Then

               If (Me.client IsNot Nothing) Then
                   Me.client.Dispose()
                   Me.client = Nothing
               End If

           End If

           Me.isDisposed = True

       End Sub

#End Region

   End Class

End Namespace

#End Region







• ¿Qué necesito para usar el código de arriba?

Puedes copiar todo el código en un nuevo proyecto de VB.NET para generar una dll que puedes usar sin complicación desde C#, o bien puedes traducir todo el código a C# con cualquier herramienta online de conversión de código VB.NET a C#, como por ejemplo http://converter.telerik.com/ (ojo, no existe la herramienta perfecta, puede producir errores de compilación que necesitarían ser arreglados manuálmente.)

Como ya dije, no me gusta darle todo el trabajo hecho a nadie, pero al menos te doy varias opciones para hacerlo más sencillo :P.


• ¿Cómo utilizo el código de arriba para mis propósitos?

1. Usar la función Authorize / AuthorizeAsync para llevar a cabo la autorización OAuthv2 en Google Drive.

2. Usar la función GetFiles / GetFilesAsyncpara listar los archivos contenidos en tu GoogleDrive, para identificar el archivo que quieres sobreescribir. Dicha función devolverá una colección de objetos Google.Apis.Drive.v3.Data.File, y en la propiedad "File.Id" está expuesto el identificador de cada archivo devuelto. La intención de usar esta función será para obtener dicho identificador.

3. Usar la función UpdateFile / UpdateFileAsync para sobreescribir un archivo existente, pasándole el Id. del archivo (objeto "file") que obtuviste previamente.

Fin. En esencia es así de sencillo.

Si te fijas bien en el código fuente, podrás ver que para cada uno de las funciones escribí un ejemplo de código que demuestra el modo de empleo de cada una. No resulta dificil traducir esos pequeños códigos de ejemplo a C# si lo llegases a necesitar.

Tampoco es necesario que lo uses, simplemente puedes tomar ese código en VB.NET como un punto de partida que puedes reproducir en C#, y extenderlo a tus necesidades.

PD: Me gustaría pensar que este código le podrá servir de utilidad ...a quien sea. ^^

Un saludo!








TickTack

WWWWWWWWWWWWWWWWWowwwwwwwwwwwwwwwww.....

Hasta a mi me podria servir esto en futuro.....

Gracias por tu aporte!!!

Impresionante lo que pusiste...
Citar
"Ninguna mentira puede inventarse lo suficientemente patán: el pueblo hispanohablante la cree. Por una consigna que se les dio, persiguieron a sus compatriotas con mayor encarnizamiento que a sus verdaderos enemigos."

Eleкtro

#5
Cita de: TickTack en 23 Julio 2017, 20:44 PMHasta a mi me podria servir esto en futuro.....

Ojalá, aunque está muy recortado. Es versión "slim". :xD

Cita de: TickTack en 23 Julio 2017, 20:44 PMGracias por tu aporte!!!

Gracias a ti también por colaborar con tu código, aunque al parecer no te funciona, jeje.

En un principio no entiendo muy bien por qué buscas un archivo llamado "datos.txt" y que contenga lineas con el texto "Origen" y "Destino" dentro de ese archivo, pero bueno, creo que das a entender un formato similar a esto:

Datos.txt
Origen: C:\CarpetaOrigen1
Destino: C:\CarpetaDestino1

Origen: C:\CarpetaOrigen2
Destino: C:\CarpetaDestino2

Origen: C:\CarpetaOrigen3
Destino: C:\CarpetaDestino3
etc...


Pero luego haces una llamada a File.Move(), que además lo tienes colocado FUERA del ciclo, aparte, creo que es evidente por que no funciona eso de mover una carpeta como si fuese un archivo xD (en su lugar puedes usar el método Directory.Move(), que además puede mover archivos también).

Teniendo un archivo de texto con el formato de arriba, quizás lo que realmente querías hacer es algo así:

Código (csharp) [Seleccionar]
DirectoryInfo srcDir = null;
DirectoryInfo dstDir = null;

foreach (string line in File.ReadLines(@".\datos.txt", Encoding.Default)) {
   if (line.StartsWith("origen", StringComparison.OrdinalIgnoreCase)) {
       srcDir = new DirectoryInfo(line.Substring(line.IndexOf(' ')));
   }

   if (line.StartsWith("destino", StringComparison.OrdinalIgnoreCase)) {
       dstDir = new DirectoryInfo(line.Substring(line.IndexOf(' ')));
   }

   if ((srcDir != null) && (dstDir != null)) {
       try {
           if (!srcDir.Exists) {
               throw new DirectoryNotFoundException(srcDir.FullName);
           }

           if (!dstDir.Exists) {
               dstDir.Create();
           }
           srcDir.MoveTo(Path.Combine(dstDir.FullName, srcDir.Name));

       } catch (Exception ex) {
           throw;

       } finally {
           srcDir = null;
           dstDir = null;

       }

   }

}


Saludos!








TickTack

Hola Elektro,

ahhh si!! Ese codigo que tienes ahi ese era necesario para mover carpetas...

Yo, pero lo que queria mostrar es como mover archivos.

El documento de textos, en realidad es:

Origen: C:\CarpetaOrigen1\archivo.txt
Destino: C:\CarpetaDestino1\archivo.txt

Origen: C:\CarpetaOrigen2\archivo.txt
Destino: C:\CarpetaDestino2\archivo.txt

Origen: C:\CarpetaOrigen3\archivo.txt
Destino: C:\CarpetaDestino3\archivo.txt
etc...

Por eso use File.Move(). Tenia por entendido de que en el segundo parametro de ese metodo tambien tenia que ser pasado el nombre del archivo y su tipo como si ya existiese en la otra carpeta.....


Pero ves...

Ya publicaste otro codigo de como mover carpetas que tambien me podria servir en mis futuras operaciones de programas jejejej....


Muchas gracias
Citar
"Ninguna mentira puede inventarse lo suficientemente patán: el pueblo hispanohablante la cree. Por una consigna que se les dio, persiguieron a sus compatriotas con mayor encarnizamiento que a sus verdaderos enemigos."