Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #59 da revista programar. Faz já o download aqui!

startuga

Progress bar count files

Mensagens Recomendadas

startuga    0
startuga

Boas pessoal,

O código abaixo foi desenvolvido por mim para criar um sistema de copia de dados entre computadores e uma NAS, utilizando o famoso robocopy.

Contudo estou a tentar implementar uma progress bar para conseguir ter noção da quantidade de ficheiros já transferidos e de se ainda falta muito para terminar.

Já tenho a progress bar implementada no código contudo não está a fazer o que necessito.

Podem ajudar?

Obrigado,

Imports System
Imports System.IO
Imports System.Diagnostics
Imports System.Threading
Imports System.Windows.Forms

Public Class T3chs_RoboCopy
   'functoin to check folder's size
   Public Overloads Function DirectorySize(ByVal sPath As String, ByVal bRecursive As Boolean) As Long
       Dim lngNumberOfDirectories As Long
       Dim Size As Long
       Try
           Dim fil As FileInfo
           Dim diDir As New DirectoryInfo(sPath)
           For Each fil In diDir.GetFiles()
               Size += fil.Length
           Next fil
           If bRecursive = True Then
               Dim diSubDir As DirectoryInfo
               For Each diSubDir In diDir.GetDirectories()
                   Size += DirectorySize(diSubDir.FullName, True)
                   lngNumberOfDirectories += 1
               Next
           End If
           Return Size
       Catch fex As System.IO.FileNotFoundException
           ' File not found. Take no action
       Catch ex As Exception
           ' Another error occurred
           Return 0
       End Try
   End Function
   Private Sub btn_pcnas_Click(sender As Object, e As EventArgs) Handles btn_pcnas.Click
       Dim oProcess As New ProcessStartInfo
       Dim processInfo As New System.Diagnostics.ProcessStartInfo()
       Dim struser As String = InputBox("Verify Username", "Enter Username:", "Please enter the username:", MsgBoxStyle.Exclamation)
       Dim strpathname As String = InputBox("Create folder", "Enter Folder Name:", "Please enter the foldername:", MsgBoxStyle.Exclamation)
       Dim fsizeappdata As Long = (DirectorySize("C:\Users\" & struser & "\Appdata", True))
       Dim fsizeuserdata As Long = (DirectorySize("C:\Users\" & struser, True))
       Dim totalsize = (Int((fsizeuserdata - fsizeappdata) / (1024) / 1024))

       '#-----------------------------------------------------------------------------------------------------------------------------------#'
       Dim xNewLocataion = ("k:\segurancas\" & strpathname) '#apagar
       Dim xFilesCount = (DirectorySize("C:\Users\" & struser, True))
       Dim xFilesTransferred As Integer = 0
       For Each xfiles In ("C:\Users\" & struser)

           xFilesTransferred += 1
           ProgressBar1.Value = xFilesTransferred * 100 / xFilesCount
           ProgressBar1.Update()
           txt_percentage.Text = (xFilesTransferred * 100 / xFilesCount & " % complete")
           txt_percentage.Update()
       Next
       '#-----------------------------------------------------------------------------------------------------------------------------------#'
       'connect to network driver & create bck folder
       processInfo.FileName = "C:\WINDOWS\system32\net"
       processInfo.Arguments = "use k: \\nas\public"
       System.Diagnostics.Process.Start(processInfo)
       My.Computer.FileSystem.CreateDirectory("k:\segurancas\" & strpathname)
       'robocopy for user files
       oProcess.FileName = "C:\Windows\System32\robocopy.exe"
       oProcess.Arguments = "C:\Users\" & struser & " k:\segurancas\" & strpathname & " /e /copy:dt /xjd /xjf /xa:SH /xd ""Links"" ""Searches"" ""Saved Games"" ""AppData"" "
       Process.Start(oProcess)
       'robocopy for *.pst outlook files
       If (Directory.Exists("C:\Users\" & struser & "\AppData\Local\Microsoft\Outlook")) Then
           oProcess.FileName = "C:\Windows\System32\robocopy.exe"
           My.Computer.FileSystem.CreateDirectory("k:\segurancas\" & strpathname & "\Outlook")
           oProcess.Arguments = "C:\Users\" & struser & "\AppData\Local\Microsoft\Outlook k:\segurancas\" & strpathname & "\Outlook /e /copy:dt"
           Process.Start(oProcess)
       Else
           MsgBox("This folder doesn't exist!", MsgBoxStyle.Critical)
       End If

   End Sub
End Class

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
ribeiro55    46
ribeiro55

Olá startuga,

Handlers dos controlos do form são executados no Thread do interface, o que não é boa prática e faz com que detalhes menores fiquem para prioridades inferiores do "scheduler", vá.

Como a execução do ciclo é custosa, actualizar o aspecto da barra de progresso é uma função sem importância.

Muito provavelmente vês a barra a começar, mas depois só a vês cheia no fim, sem progresso intermédio. Isto porque é mais importante terminar o ciclo do que actualizar o interface.

Operações deste tipo devem ser entregues a outras threads, para que o interface possa ter a mesma prioridade.

Se não estás confortável com Threads, espreita o artigo http://wiki.portugal-a-programar.pt/dev_net:vb.net:backgroundworkers

Alternativamente, podes usar o Application.DoEvents, que tenta igualar a importância daquilo que há para fazer, mas dentro da mesma Thread (não aconselho. vai-te atrasar as duas funções)


Sérgio Ribeiro


"Great coders aren't born. They're compiled and released"
"Expert coders do not need a keyboard. They just throw magnets at the RAM chips"

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
startuga    0
startuga

Olá startuga,

Handlers dos controlos do form são executados no Thread do interface, o que não é boa prática e faz com que detalhes menores fiquem para prioridades inferiores do "scheduler", vá.

Como a execução do ciclo é custosa, actualizar o aspecto da barra de progresso é uma função sem importância.

Muito provavelmente vês a barra a começar, mas depois só a vês cheia no fim, sem progresso intermédio. Isto porque é mais importante terminar o ciclo do que actualizar o interface.

Operações deste tipo devem ser entregues a outras threads, para que o interface possa ter a mesma prioridade.

Se não estás confortável com Threads, espreita o artigo http://wiki.portugal-a-programar.pt/dev_net:vb.net:backgroundworkers

Alternativamente, podes usar o Application.DoEvents, que tenta igualar a importância daquilo que há para fazer, mas dentro da mesma Thread (não aconselho. vai-te atrasar as duas funções)

Não existe forma mais simples de fazer? :/

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
ribeiro55    46
ribeiro55

Existem sempre as simples, e depois as correctas.

Também te falei da alternativa que tens: Application.DoEvents.

Basta colocares essa linha de código depois de dares o Value à progress bar.

Vai ser exactamente o que esperas que seja? Não. Mas é simples :)


Sérgio Ribeiro


"Great coders aren't born. They're compiled and released"
"Expert coders do not need a keyboard. They just throw magnets at the RAM chips"

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
startuga    0
startuga

Existem sempre as simples, e depois as correctas.

Também te falei da alternativa que tens: Application.DoEvents.

Basta colocares essa linha de código depois de dares o Value à progress bar.

Vai ser exactamente o que esperas que seja? Não. Mas é simples :)

Eu tenho esta função que me vai verificar o tamanho das pastas,

   'function to check folder's size
   Public Overloads Function DirectorySize(ByVal sPath As String, ByVal bRecursive As Boolean) As Long
       Dim lngNumberOfDirectories As Long
       Dim Size As Long
       Try
           Dim fil As FileInfo
           Dim diDir As New DirectoryInfo(sPath)
           For Each fil In diDir.GetFiles()
               Size += fil.Length
           Next fil
           If bRecursive = True Then
               Dim diSubDir As DirectoryInfo
               For Each diSubDir In diDir.GetDirectories()
                   Size += DirectorySize(diSubDir.FullName, True)
                   lngNumberOfDirectories += 1
               Next
           End If
           Return Size
       Catch fex As System.IO.FileNotFoundException
           ' File not found. Take no action
       Catch ex As Exception
           ' Another error occurred
           Return 0
       End Try
   End Function

É através dela que quero preencher o progress bar, contudo não sei se algo está errado nela, pois não a estou a conseguir chamar utilizando este código

       Do Until bcksize = (DirectorySize("k:\segurancas\" & strpathname, True)) < totalsize = (Int((fsizeuserdata - fsizeappdata) / (1024) / 1024))
           ProgressBar1.Value += 1
           ProgressBar1.Update()
           Application.DoEvents()
       Loop

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.