' BORRA LOS ARCHIVOS TEMPORALES Y LA CARPETA QUE LOS CONTIENE
' (VARIABLE DE ENTORNO TEMP, DEFINIDA PARA EL USUARIO ACTUAL)
'
' MUESTRA AL USUARIO INFORMACIÓN SOBRE:
'
' - Nº DE ARCHIVOS ENCONTRADOS EN LA EJECUCIÓN ACTUAL
' - Nº DE ARCHIVOS BORRADOS EN LA EJECUCIÓN ACTUAL
' - Nº TOTAL ACUMULADO DE ARCHIVOS BORRADOS POR EL PROGRAMA
' (LEYENDO ESTE DATO DESDE UN TXT EN C:\WINDOWS)

'manejo de archivos y carpetas
Imports System.IO
'obtener variables de entorno
Imports System.Environment
'tratar cadenas de texto (ejemplo: codificación usada al escribir en un archivo de texto)
Imports System.Text
'proporciona clases e interfaces que permiten la programación multiproceso
Imports System.Threading

Public Class Form1
   Inherits System.Windows.Forms.Form

   '   'procedimiento Main para que la aplicación arranque desde aquí y no desde Form1
   '   <STAThread()> _
   'Public Shared Sub Main()
   '      Application.Run(New Form1)
   '   End Sub

#Region " Código generado por el Diseñador de Windows Forms "

   Public Sub New()
     MyBase.New()

     'El Diseñador de Windows Forms requiere esta llamada.
     InitializeComponent()

     'Agregar cualquier inicialización después de la llamada a InitializeComponent()

   End Sub

   'Form reemplaza a Dispose para limpiar la lista de componentes.
   Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
     If disposing Then
       If Not (components Is Nothing) Then
         components.Dispose()
       End If
     End If
     MyBase.Dispose(disposing)
   End Sub

   'Requerido por el Diseñador de Windows Forms
   Private components As System.ComponentModel.IContainer

   'NOTA: el Diseñador de Windows Forms requiere el siguiente procedimiento
   'Puede modificarse utilizando el Diseñador de Windows Forms. 
   'No lo modifique con el editor de código.
   Friend WithEvents Label1 As System.Windows.Forms.Label
   Friend WithEvents Button1 As System.Windows.Forms.Button
   Friend WithEvents Label2 As System.Windows.Forms.Label
   Friend WithEvents Label3 As System.Windows.Forms.Label
   Friend WithEvents Label1a As System.Windows.Forms.Label
   Friend WithEvents Label2a As System.Windows.Forms.Label
   Friend WithEvents Label3a As System.Windows.Forms.Label
   Friend WithEvents GroupBox1 As System.Windows.Forms.GroupBox
   Friend WithEvents PictureBox2 As System.Windows.Forms.PictureBox
   Friend WithEvents ToolTip1 As System.Windows.Forms.ToolTip
   <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
     Me.components = New System.ComponentModel.Container
     Dim resources As System.Resources.ResourceManager = New System.Resources.ResourceManager(GetType(Form1))
     Me.Label1 = New System.Windows.Forms.Label
     Me.Button1 = New System.Windows.Forms.Button
     Me.Label2 = New System.Windows.Forms.Label
     Me.Label3 = New System.Windows.Forms.Label
     Me.Label1a = New System.Windows.Forms.Label
     Me.Label2a = New System.Windows.Forms.Label
     Me.Label3a = New System.Windows.Forms.Label
     Me.GroupBox1 = New System.Windows.Forms.GroupBox
     Me.PictureBox2 = New System.Windows.Forms.PictureBox
     Me.ToolTip1 = New System.Windows.Forms.ToolTip(Me.components)
     Me.SuspendLayout()
     '
     'Label1
     '
     Me.Label1.Font = New System.Drawing.Font("Tahoma", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
     Me.Label1.Location = New System.Drawing.Point(168, 24)
     Me.Label1.Name = "Label1"
     Me.Label1.Size = New System.Drawing.Size(184, 16)
     Me.Label1.TabIndex = 4
     Me.Label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft
     '
     'Button1
     '
     Me.Button1.Font = New System.Drawing.Font("Tahoma", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
     Me.Button1.Location = New System.Drawing.Point(78, 112)
     Me.Button1.Name = "Button1"
     Me.Button1.Size = New System.Drawing.Size(87, 24)
     Me.Button1.TabIndex = 0
     Me.Button1.Text = "OK (Esc)"
     '
     'Label2
     '
     Me.Label2.Font = New System.Drawing.Font("Tahoma", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
     Me.Label2.Location = New System.Drawing.Point(168, 48)
     Me.Label2.Name = "Label2"
     Me.Label2.Size = New System.Drawing.Size(184, 16)
     Me.Label2.TabIndex = 5
     Me.Label2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft
     '
     'Label3
     '
     Me.Label3.Font = New System.Drawing.Font("Tahoma", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
     Me.Label3.Location = New System.Drawing.Point(168, 72)
     Me.Label3.Name = "Label3"
     Me.Label3.Size = New System.Drawing.Size(184, 16)
     Me.Label3.TabIndex = 6
     Me.Label3.TextAlign = System.Drawing.ContentAlignment.MiddleLeft
     '
     'Label1a
     '
     Me.Label1a.Font = New System.Drawing.Font("Tahoma", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
     Me.Label1a.Location = New System.Drawing.Point(16, 24)
     Me.Label1a.Name = "Label1a"
     Me.Label1a.Size = New System.Drawing.Size(152, 16)
     Me.Label1a.TabIndex = 1
     Me.Label1a.Text = "Archivos encontrados:"
     Me.Label1a.TextAlign = System.Drawing.ContentAlignment.MiddleLeft
     '
     'Label2a
     '
     Me.Label2a.Font = New System.Drawing.Font("Tahoma", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
     Me.Label2a.Location = New System.Drawing.Point(16, 48)
     Me.Label2a.Name = "Label2a"
     Me.Label2a.Size = New System.Drawing.Size(152, 16)
     Me.Label2a.TabIndex = 2
     Me.Label2a.Text = "Archivos borrados:"
     Me.Label2a.TextAlign = System.Drawing.ContentAlignment.MiddleLeft
     '
     'Label3a
     '
     Me.Label3a.Font = New System.Drawing.Font("Tahoma", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
     Me.Label3a.Location = New System.Drawing.Point(16, 72)
     Me.Label3a.Name = "Label3a"
     Me.Label3a.Size = New System.Drawing.Size(152, 16)
     Me.Label3a.TabIndex = 3
     Me.Label3a.Text = "Total acumulado:"
     Me.Label3a.TextAlign = System.Drawing.ContentAlignment.MiddleLeft
     '
     'GroupBox1
     '
     Me.GroupBox1.Location = New System.Drawing.Point(8, 8)
     Me.GroupBox1.Name = "GroupBox1"
     Me.GroupBox1.Size = New System.Drawing.Size(352, 88)
     Me.GroupBox1.TabIndex = 7
     Me.GroupBox1.TabStop = False
     '
     'PictureBox2
     '
     Me.PictureBox2.Cursor = System.Windows.Forms.Cursors.Hand
     Me.PictureBox2.Image = CType(resources.GetObject("PictureBox2.Image"), System.Drawing.Image)
     Me.PictureBox2.Location = New System.Drawing.Point(248, 104)
     Me.PictureBox2.Name = "PictureBox2"
     Me.PictureBox2.Size = New System.Drawing.Size(40, 40)
     Me.PictureBox2.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage
     Me.PictureBox2.TabIndex = 9
     Me.PictureBox2.TabStop = False
     Me.ToolTip1.SetToolTip(Me.PictureBox2, "Información sobre el programa")
     '
     'Form1
     '
     Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
     Me.ClientSize = New System.Drawing.Size(370, 156)
     Me.Controls.Add(Me.PictureBox2)
     Me.Controls.Add(Me.Label3a)
     Me.Controls.Add(Me.Label2a)
     Me.Controls.Add(Me.Label1a)
     Me.Controls.Add(Me.Label3)
     Me.Controls.Add(Me.Label2)
     Me.Controls.Add(Me.Button1)
     Me.Controls.Add(Me.Label1)
     Me.Controls.Add(Me.GroupBox1)
     Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
     Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon)
     Me.MaximizeBox = False
     Me.MinimizeBox = False
     Me.Name = "Form1"
     Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen
     Me.Text = "Borrar TEMP"
     Me.ResumeLayout(False)

   End Sub

#End Region

   'variables declaradas a nivel de clase
   '
   'ruta a la carpeta definida en la variable de entorno TEMP
   Protected rutaTemp As String = Environment.GetEnvironmentVariable("TEMP")
   'ruta a la carpeta de sistema (WINDIR --> directorio de Windows)
   Protected rutaWindir As String = Environment.GetEnvironmentVariable("WINDIR")
   'variable para la ruta completa al archivo de texto que registra el nº de archivos borrados
   Protected rutaTxt As String = rutaWindir & "\Borrar_TEMP.txt"
   'variables para guardar nº de archivos
   'iCuentaTempAll --> todos los archivos encontrados en TEMP
   Protected iCuentaTempAll As Integer
   'lCuentaBorrados --> nº de archivos borrados hasta la fecha
   Protected lCuentaBorrados As Long

   'al cargar el formulario
   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
     'pulsar la tecla ESC equivale a pulsar el botón OK
     Me.CancelButton = Me.Button1
     'llamar al método:
     '- comprobar si el archivo "Borrar_TEMP.txt" existe (crearlo si no existe)
     Call archivoTxt()
   End Sub

   'comprobar si el archivo de registro existe (crearlo si no existe)
   Protected Sub archivoTxt()
     Dim archivo As New FileInfo(rutaTxt)
     'si "Borrar_TEMP.txt" no existe --> crearlo e informar al usuario para que reinicie
     If archivo.Exists = False Then
       archivo.CreateText()
       Dim aviso As String
       aviso = "Se ha creado el archivo ""Borrar_TEMP.txt"" en la carpeta de Windows." & vbCrLf & _
       "Es necesario reiniciar el programa para su correcto funcionamiento." & vbCrLf & _
       "Pulsa ""Aceptar"" y el programa se cerrará y reiniciará automáticamente."
       MessageBox.Show(aviso, "Reiniciar el programa", MessageBoxButtons.OK)
       '
       'cerrar el formulario y que se vuelva a abrir automáticamente para que en el nuevo inicio
       'lea correctamente desde el archivo Borrar_TEMP.txt y muestre la información
       '
       'crear un nuevo hilo (thread) que se enlaza con el método nuevoForm()
       'que arrancará otra instancia diferente de Form1 
       Dim hilo As New Thread(AddressOf nuevoForm)
       hilo.Start()
       'cerrar la aplicación y su hilo actual
       Application.Exit()
       '
       'si "Borrar_TEMP.txt" ya existe --> ejecutar el programa con normalidad
     Else
       'llamar a los métodos:
       '- leer el nº de archivos del directorio y el nº acumulado de archivos borrados en "Borrar_TEMP.txt"
       '- leer el nº de archivos borrados en la ejecucion actual y escribir en "Borrar_TEMP.txt"
       Call listadoPre()
       Call listadoPost()
     End If
   End Sub

   'método que inicia de nuevo la aplicación
   Public Shared Sub nuevoForm()
     'detenerse 0,2 segundos
     Thread.Sleep(200)
     'iniciar de nuevo la aplicación en el nuevo hilo
     Application.Run(New Form1)
   End Sub

   'método que cuenta los archivos y las carpetas de TEMP antes del borrado
   Protected Sub listadoPre()
     Try
       'variables para guardar el nº de archivos
       'iCuentaTempPre = nº de archivos en la raíz de TEMP
       'iCuentaSubdirPre = nº de carpetas en la raíz de TEMP
       'iCuentaSubdirFilesPre = nº de archivos en las carpetas de la raíz de TEMP
       Dim iCuentaTempPre, iCuentaSubdirPre, iCuentaSubdirFilesPre As Integer
       'la clase DirectoryInfo expone métodos de instancia para crear, mover y 
       'enumerar archivos en directorios y subdirectorios
       'se utiliza para operaciones típicas como copiar, mover, cambiar de nombre,
       'crear y eliminar directorios
       Dim dirTemp As New DirectoryInfo(rutaTemp)
       'comprobar si el directorio existe
       If dirTemp.Exists = True Then
         'contar los archivos de la raíz  de TEMP (no en subdirectorios)
         iCuentaTempPre = dirTemp.GetFiles.Length
         'contar todos los subdirectorios  de TEMP
         Dim dirSub As FileSystemInfo() = dirTemp.GetDirectories()
         iCuentaSubdirPre = dirSub.Length
         'contar todos los archivos de cada subdirectorio (sólo en el primer nivel de subdirectorios)
         Dim dirTemp2 As New DirectoryInfo(rutaTemp)
         For Each dirTemp2 In dirSub
            iCuentaSubdirFilesPre += dirTemp2.GetFileSystemInfos.Length
         Next
         'mostrar información en la etiqueta de texto
         Me.Label1.Text = (iCuentaTempPre + iCuentaSubdirFilesPre).ToString
         'valor de t = nº total de archivos encontrados antes de borrar TEMP
         iCuentaTempAll = (iCuentaTempPre + iCuentaSubdirFilesPre)
         '
         'leer el nº de archivos borrados hasta la fecha desde un archivo de texto guardado en %WINDIR%
         'el archivo se llama C:\Windows\Borrar_TEMP.txt (siendo %WINDIR% = C:\Windows en este caso)
         'las clases Stream.Reader y Stream.Writer permiten tratar con archivos de texto secuenciales
         Dim srLector As StreamReader
         'variable para la primera línea del archivo de texto
         Dim sLinea As String
         '
         'leer la primera línea y pasarla a lCuentaBorrados
         srLector = New StreamReader(rutaTxt)
         sLinea = srLector.ReadLine
         lCuentaBorrados = CLng(sLinea)
         'cerrar el archivo
         srLector.Close()
         '
         'el método DirectoryInfo.Delete elimina una instancia de DirectoryInfo
         'especificando si se van a eliminar los subdirectorios y los archivos (True o False)
         'se asigna al directorio de archivos temporales
         dirTemp.Delete(True)
       Else
         'si no existe el directorio TEMP
         Me.Label1.Text = "0"
         Me.Label2.Text = "0"
       End If
       'capturar excepciones
     Catch pollo As Exception
       'pasar por alto la excepción si la causa es no poder borrar archivos por estar en uso
       ' (excepción System.IO.IOException o System.UnauthorizedAccessException)
       Dim sTipo1, sTipo2 As String
       sTipo1 = "System.IO.IOException"
       sTipo2 = "System.UnauthorizedAccessException"
       If Not pollo.GetType.ToString = sTipo1 And Not pollo.GetType.ToString = sTipo2 Then
         MessageBox.Show(pollo.Message, "Aviso del programa", MessageBoxButtons.OK)
         Application.Exit()
       End If
     End Try
   End Sub

   'método que cuenta los archivos  de TEMP después del borrado
   'estos archivos son los que no han podido ser borrados porque están en uso
   Protected Sub listadoPost()
     Try
       'variables para guardar el nº de archivos
       'iCuentaTempPost = nº de archivos en la raíz de TEMP
       'iCuentaSubdirPost = nº de carpetas en la raíz de TEMP
       'iCuentaSubdirFilesPost = nº de archivos en las carpetas de la raíz de TEMP
       Dim iCuentaTempPost, iCuentaSubdirPost, iCuentaSubdirFilesPost As Integer
       'la clase DirectoryInfo expone métodos de instancia para crear, mover y 
       'enumerar archivos en directorios y subdirectorios
       'se utiliza para operaciones típicas como copiar, mover, cambiar de nombre,
       'crear y eliminar directorios
       Dim dirTemp As New DirectoryInfo(rutaTemp)
       'comprobar si el directorio existe
       If dirTemp.Exists = True Then
         'contar los archivos de la raíz de TEMP (no en subdirectorios),
         iCuentaTempPost = dirTemp.GetFiles.Length
         '
         'ahora no hace falta contar los archivos de las subcarpetas pues el método
         'dirTemp.Delete(True) las ha eliminado
         'contar todos los subdirectorios de TEMP
         'Dim dirSub As FileSystemInfo() = dirTemp.GetDirectories()
         'iCuentaSubdirPost = dirSub.Length
         'contar todos los archivos de cada subdirectorio (sólo en el primer nivel de subdirectorios)
         'Dim dirTemp2 As New DirectoryInfo(rutaTemp)
         'For Each dirTemp2 In dirSub
         '   iCuentaSubdirFilesPost += dirTemp2.GetFileSystemInfos.Length
         'Next
         '
         'nº de archivos borrados hasta la fecha + nº de archivos borrados en la ejecución actual
         lCuentaBorrados = lCuentaBorrados + (iCuentaTempAll - iCuentaTempPost)
         '
         'escribir el nº de archivos en un archivo de texto guardado en %WINDIR%
         'el archivo se llama C:\Windows\Borrar_TEMP.txt (siendo %WINDIR% = C:\Windows en este caso)
         'las clases Stream.Reader y Stream.Writer permiten tratar con archivos de texto secuenciales
         Dim swEscritor As StreamWriter
         'variable para la primera línea del archivo de texto
         Dim sLinea As String
         ' StreamWriter recibe 3 parámetros:
         '- String con la ruta al archivo
         '- True para añadir texto al existente, False para sobreescribir el texto existente
         '- codificación de caracteres que se utilizará (default: página de códigos ANSI usada por el sistema)
         swEscritor = New StreamWriter(rutaTxt, False, Encoding.Default)
         sLinea = CStr(lCuentaBorrados)
         'escribir el valor de lCuentaBorrados en la primera línea
         swEscritor.WriteLine(sLinea)
         'cerrar el archivo
         swEscritor.Close()
         '
         'mostrar información en la etiqueta de texto
         'variable iCuentaTempAll --> total de archivos encontrados antes de borrar TEMP
         'restándole los archivos no borrados por estar en uso --> archivos borrados realmente
         Me.Label2.Text = (iCuentaTempAll - iCuentaTempPost).ToString
         'variable lCuentaBorrados --> nº de archivos borrados hasta la fecha + nº de archivos borrados en la ejecución actual
         If lCuentaBorrados = 0 Then
            Me.Label3.Text = "Ningún archivo"
         Else
            Me.Label3.Text = lCuentaBorrados.ToString("#,#") & " archivos"
         End If
       Else
         'crear el directorio temporal en caso de que no exista
         'algunos programas arrancan con errores si no detectan la presencia del directorio definido en TEMP
         'por ejemplo: Visual Studio da error de compilador, Media Player no inicia correctamente...
         dirTemp.Create()
         Me.Label1.Text = "0"
         Me.Label2.Text = "0"
       End If
       'capturar excepciones
     Catch pollo As Exception
       MessageBox.Show("AVISO: " & pollo.Message, "Aviso del programa", MessageBoxButtons.OK)
       Application.Exit()
     End Try
   End Sub

   Private Sub PictureBox2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PictureBox2.Click
     Dim ayuda As String = "Borra los archivos temporales y la carpeta que los contiene" & vbCrLf & _
     "(variable de entorno TEMP, definida para el usuario actual)." & vbCrLf & vbCrLf & _
     "Muestra al usuario información sobre:" & vbCrLf & _
     "- Nº de archivos encontrados en la ejecución actual." & vbCrLf & _
     "- Nº de archivos borrados en la ejecución actual." & vbCrLf & _
     "- Nº total acumulado de archivos borrados por el programa" & vbCrLf & _
     " (leyendo este dato desde un archivo de texto en C:\WINDOWS)."
     MessageBox.Show(ayuda, "Acerca de...", MessageBoxButtons.OK)
   End Sub

   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
     'cerrar la aplicación
     Application.Exit()
   End Sub

End Class