el Guille, la Web del Visual Basic, C#, .NET y más...
Ir al índice de Visual Studio 2008 y .NET Framework 3.5 Utilidades .NET Framework 3.5

Actualización de gsCopia (v1.0.1.6)

 
Publicado el 14/Dic/2007
Actualizado el 16/Dic/2007
Autor: Guillermo 'guille' Som

Actualización de la utilidad gsCopia (v1.0.1.6 del 14/Dic/07). En esta revisión se hacen una serie de comprobaciones para permitir usar caracteres comodines en los ficheros a copiar además de comprobar si se ejecuta como administrador.



 

Introducción:

en esta revisión de la utilidad gsCopia, se hacen ciertas comprobaciones de que el path a copiar (el origen) es correcto (o casi), además de que se comprueba si se usan caracteres comodines o algún nombre de fichero, en esos casos, se pasa esa información a la utilidad de copia y hará lo que se espera.
Por ejemplo, si le indicas algo como lo de la figura 1, se copiarán solo los ficheros con la extensión .dll del directorio indicado.
También puedes usar los caracteres comodines para hacer otros filtros, como es el caso de la figura 2, en el que se indica que solo se copien los ficheros que empiecen por FP y tengan la extensión .dll (fp*.dll)

Nota:
Debes tener en cuenta que yo solo lo he probado con xcopy y con robocopy, si usas otra utilidad, deberías hacer tus propias comprobaciones.

También se comprueba si se está ejecutando como administrador y se avisa por medio de un "escudito".
En la figura 1 puedes ver ese escudo cuando se ejecuta en Windows Vista y no se está ejecutando como administrador:

Figura 1. La utilidad en ejecución (no como administrador)
Figura 1. La utilidad en ejecución (no como administrador)

Si se ejecuta como administrador, se muestra un escudo verde, tal como puedes ver en la figura 2:

Figura 2. La utilidad en ejecución (como administrador)
Figura 2. La utilidad en ejecución (como administrador)

Al pulsar en el escudo (haciendo un clic), te muestra un mensaje de aviso indicando ese hecho.

Además de estos cambios, también he hecho unos cambios menores, como es que se deshabilite el botón de comprobación si se selecciona la opción "Deshabilitar los botones de selección".

Y también he asignado correctamente algunos tooltips que se me colaron al copiar y pegar controles, je, je.

 

Aquí tienes el código con los cambios que he hecho en esta revisión 1.0.1.6.
Pulsa en el siguiente link si quieres ver el código anterior (el de la versión 1.0.1.0)

 

Este es el bucle del método btnCopiar_Click, el resto del código de ese método no ha cambiado.

For Each datoOri As String In datosOrig
    progressBar1.Value = 0

    ' Quitar las comillas dobles que tenga                  (14/Dic/07)
    datoOri = datoOri.Trim((ChrW(34) & " ").ToCharArray)

    ' Es posible que el origen tenga una especificación     (14/Dic/07)
    ' por ejemplo: c:\datos\*.txt
    Dim di As DirectoryInfo = Nothing
    Dim dirOriTmp As String = datoOri
    ' Si tiene caracteres comodines, usar el nombre del directorio
    If dirOriTmp.IndexOfAny("*?".ToCharArray) > -1 Then
        dirOriTmp = Path.GetDirectoryName(datoOri)
        ' Si se usa robocopy, indicar los ficheros como argumento
        ' El formato es: 
        '   ROBOCOPY source destination [file [file]...] [options]
        ' por tanto, se pueden agregar a los parámetros
        If util.Contains("robocopy") Then
            Dim index As Integer = datoOri.LastIndexOf("\")
            If index > -1 Then
                params = ChrW(34) & datoOri.Substring(index + 1) & ChrW(34) & " " & params
                datoOri = datoOri.Substring(0, index)
                dirOriTmp = datoOri
            Else
                ' Si llega aquí es que algo no va bien...
                MessageBox.Show("Parece que el origen: " & vbCrLf & _
                                datoOri & vbCrLf & _
                                "no es un directorio correcto.", _
                                "Copiar", _
                                MessageBoxButtons.OK, _
                                MessageBoxIcon.Exclamation)
                ' Restaurar los valores internos
                Me.Cursor = Cursors.Default
                progressBar1.Visible = False
                statusInfo.Text = statusInfo.Tag.ToString
                btnCopiar.Text = "Copiar"
                habilitarControles(True)
                yaEstoy = False

                cboDestino.Focus()
                Exit Sub
            End If
        End If
    ElseIf dirOriTmp.EndsWith("\") Then
        ' Si acaba en \ quitarlo, porque no copiará nada con xcopy (con robocopy también funciona así)
        dirOriTmp = dirOriTmp.Substring(0, dirOriTmp.Length - 1)
        datoOri = dirOriTmp
    End If
    ' Último intento,
    ' si da error es que hay algo más que no está bien
    ' Intentarlo al menos 2 veces...
    Dim intentos As Integer = 0
    Dim conFallo As Boolean = False
    While intentos < 2
        Try
            di = New DirectoryInfo(dirOriTmp)
            ' Si llega aquí, es que no ha dado error
            conFallo = False
            Exit While
        Catch ex As Exception
            ' en ese caso, se filtra el directorio
            dirOriTmp = Path.GetDirectoryName(dirOriTmp)
            intentos += 1
            conFallo = True
        End Try
    End While
    ' Si llega con fallos, avisar y salir
    If conFallo Then
        MessageBox.Show("Parece que el origen: " & vbCrLf & _
                        datoOri & vbCrLf & _
                        "no es un directorio correcto.", _
                        "Copiar", _
                        MessageBoxButtons.OK, _
                        MessageBoxIcon.Exclamation)
        ' Restaurar los valores internos
        Me.Cursor = Cursors.Default
        progressBar1.Visible = False
        statusInfo.Text = statusInfo.Tag.ToString
        btnCopiar.Text = "Copiar"
        habilitarControles(True)
        yaEstoy = False

        cboDestino.Focus()
        Exit Sub
    End If

    ' Si no existe, es que será un fichero                  (14/Dic/07)
    If di.Exists = False Then
        ' El directorio será el padre:
        dirOriTmp = di.Parent.FullName
        di = New DirectoryInfo(dirOriTmp)
    End If

    ' Usar siempre el directorio de origen
    Dim dirDest As String = dest & If(dest.EndsWith("\"), "", "\") & di.Name
    Dim sb As New StringBuilder
    ' Usar comillas dobles por si tiene espacios            (14/Dic/07)
    sb.AppendFormat("""{0}"" ""{1}"" {2}", datoOri, dirDest, params)

    statusInfo.Text = "Copiando en " & dirDest & "..."

    Dim proceso As New Process
    With proceso
        .StartInfo.Arguments = sb.ToString
        .StartInfo.FileName = util
        If My.Settings.OcultarVentana Then
            .StartInfo.WindowStyle = ProcessWindowStyle.Minimized
        Else
            .StartInfo.WindowStyle = ProcessWindowStyle.Normal
        End If
        .StartInfo.WorkingDirectory = datoOri
        .Start()
        progressBar1.Value = 1
        Do
            Application.DoEvents()
            If cancelar Then
                .Kill()
                .Close()
                Exit For
            End If
        Loop While .HasExited = False
    End With
Next

Para ver las cosas nuevas, busca (14/Dic/07), y como más o menos está comentado todo lo que he hecho, pues no tendrás problemas para entender los cambios.

Al principio del evento Form_Load he hecho la comprobación de si se está ejecutando como administrador, y lo único que hago es usar una imagen u otra según como se esté ejecutando.

Private Sub Form1_Load() Handles MyBase.Load
    ' Comprobar si se ejecuta como administrador                (14/Dic/07)
    comoAdministrador = EsAdministrador()
    If comoAdministrador Then
        Me.statusOpAdmin.Image = My.Resources.escudo16_OK
        Me.statusOpAdmin.ToolTipText = " Ejecutando como administrador "
    Else
        Me.statusOpAdmin.Image = My.Resources.escudo16_Exclamation
        Me.statusOpAdmin.ToolTipText = " No estás ejecutando como administrador "
    End If

La variable comoAdministrador está definida en el formulario, y es de tipo Boolean, se usará también en el código que te mostraré más abajo.

El control statusOpAdmin en realidad es una etiqueta del StatusStrip. Y cuando se produce el evento Click se ejecuta el siguiente código en el que se muestra un MessageBox con el texto adecuado:

Private Sub statusOpAdmin_Click(ByVal sender As Object, _
                                ByVal e As System.EventArgs) _
                                Handles statusOpAdmin.Click
    If comoAdministrador Then
        MessageBox.Show("Estás ejecutando la aplicación como administrador" & vbCrLf & _
                        "de esta forma no tendrás problemas al copiar.", _
                        "Copiar", _
                        MessageBoxButtons.OK, _
                        MessageBoxIcon.Information)
    Else
        MessageBox.Show("No estás ejecutando la aplicación como administrador" & vbCrLf & _
                        "es posible que algunas cosas no las puedas copiar." & vbCrLf & _
                        "Si detectas problemas al copiar, " & _
                        "deberías ejecutar la aplicación como adminsitrador.", _
                        "Copiar", _
                        MessageBoxButtons.OK, _
                        MessageBoxIcon.Exclamation)
    End If
End Sub

 

La función que comprueba si es administrador o no es la que ya te mostré hace unos meses, pero te la pongo aquí nuevamente:

' Comprobar si se ejecuta como administrador
Private Function EsAdministrador() As Boolean
    My.User.InitializeWithWindowsUser()
    Return My.User.IsInRole(ApplicationServices.BuiltInRole.Administrator)
End Function

 

Y esto es todo... aunque parezcan pocos cambios, en realidad hacen que la utilidad sea más "útil", je, je.

 

Nos vemos.
Guillermo


Código de ejemplo (comprimido):

Pulsa estos links para ver todo lo relacionado con esta utilidad:

Nota:
Tanto los ZIPs como la instalación con ClickOnce incluyen la última versión.


 


La fecha/hora en el servidor es: 23/12/2024 7:26:36

La fecha actual GMT (UTC) es: 

©Guillermo 'guille' Som, 1996-2024