Jump to content

[Resolvido] [Uninstaller] Deletar arquivo após reboot


Muryllo
 Share

Recommended Posts

Boas, feliz ano novo a todos. Começando já este 2016 com um probleminha de programação 😛 ... Estou tendo um problema ao usar a função MoveFileEx para excluir um arquivo no próximo reboot do computador. Eu fiz uma classe básica com funções que eu irei utilizar durante o projeto, mas falta ainda a função de excluir o arquivo após carregar os drivers ou o autochk.exe ser executado. Trata-se de um uninstaller em vb.net.

Minha classe é essa :

Imports System.IO
Imports System.Environment
Imports System.Runtime.InteropServices
'
Public Class Uninstaller
   '
   <[DllImport]("KERNEL32.DLL", SetLastError:=True, EntryPoint:="MoveFileEx", CharSet:=CharSet.Auto)> _
   Public Shared Function MoveFileEx(ByVal lpfilename As String, ByVal lpnewpath As IntPtr, ByVal dwflags As Integer) As Integer
   End Function
   '
   <[DllImport]("KERNEL32.DLL", SetLastError:=True, EntryPoint:="MoveFileEx", CharSet:=CharSet.Auto)> _
   Public Shared Function MoveFileEx(ByVal lpfilename As String, ByVal lpnewpath As String, ByVal dwflags As Integer) As Integer
   End Function
   '
   <[DllImport]("KERNEL32.DLL", SetLastError:=True, EntryPoint:="DeleteFile", CharSet:=CharSet.Auto)> _
   Public Shared Function DeleteFile(ByVal lpfilename As String) As Integer
   End Function
   '
   <[DllImport]("KERNEL32.DLL", SetLastError:=True, EntryPoint:="RemoveDirectory", CharSet:=CharSet.Auto)> _
   Public Shared Function RemoveDirectory(ByVal lpdirectoryname As String) As Integer
   End Function
   '
   Public Enum MoveFileFlags
       MOVE_FILE_NULL = &H0
       MOVE_FILE_REPLACE_EXISTING = &H1
       MOVE_FILE_COPY_ALLOWED = &H2
       MOVE_FILE_DELAY_UNTIL_REBOOT = &H4
       MOVE_FILE_CREATE_HARDLINK = &H10
       MOVE_FILE_FAIL_IF_NOT_TRACKABLE = &H20
   End Enum
   '
   Public Shared Function NtSuccess(ByVal Status As Integer) As Boolean
       Try
           If Status = &H0 Then
               Return False
           Else
               Return True
           End If
       Catch NTSTATUS As Exception
           Return False
       End Try
   End Function
   '
   Public Shared Function Move_File_On_Reboot(ByVal Current_File_Path As String, ByVal New_File_Path As String) As Boolean
       Try
           If (NtSuccess(MoveFileEx(Current_File_Path, New_File_Path, MoveFileFlags.MOVE_FILE_DELAY_UNTIL_REBOOT))) = True Then
               Return True
           Else
               Return False
           End If
       Catch NTSTATUS As Exception
           Return False
       End Try
   End Function
   '
   Public Shared Function Replace_File_On_Reboot(ByVal File_Path As String, ByVal New_File As String) As Boolean
       Try
           Dim File_Path_Base As String = (Path.GetDirectoryName(File_Path) & "\")
           Dim New_File_Base As String = (Path.GetDirectoryName(New_File) & "\")
           Dim File_Temp_Base As String = (GetFolderPath(SpecialFolder.CommonApplicationData) & "\")
           If (Move_File_On_Reboot(New_File, File_Temp_Base & Path.GetFileName(New_File))) = True Then
               If (Move_File_On_Reboot(File_Path, New_File_Base & Path.GetFileName(New_File))) = True Then
                   If (Move_File_On_Reboot(File_Temp_Base & Path.GetFileName(New_File), File_Path_Base & Path.GetFileName(File_Path))) = True Then
                       Return True
                   Else
                       Return False
                   End If
               Else
                   Return False
               End If
           Else
               Return False
           End If
       Catch NTSTATUS As Exception
           Return False
       End Try
   End Function
   '
   Public Shared Function Delete_File_After_Reboot(ByVal File_Path As String) As Boolean
       Try
           If File.Exists(File_Path) = True Then
               If (NtSuccess(MoveFileEx(File_Path, IntPtr.Zero, MoveFileFlags.MOVE_FILE_DELAY_UNTIL_REBOOT))) = True Then
                   Return True
               Else
                   Return False
               End If
           Else
               Return False
           End If
       Catch NTSTATUS As Exception
           Return False
       End Try
   End Function
   '
   Public Shared Function Delete_File(ByVal File_Path As String) As Boolean
       Try
           If (File.Exists(File_Path)) = True Then
               If (NtSuccess(DeleteFile(File_Path))) = True Then
                   Return True
               Else
                   If (Delete_File_After_Reboot(File_Path)) = True Then
                       Return True
                   Else
                       Return False
                   End If
               End If
           Else
               Return False
           End If
       Catch NTSTATUS As Exception
           Return False
       End Try
   End Function
   '
   Public Shared Function Delete_Directory(ByVal Directory_Path As String) As Boolean
       Try
           If (Directory.Exists(Directory_Path)) = True Then
               If (NtSuccess(RemoveDirectory(Directory_Path))) = True Then
                   Return True
               Else
                   If (NtSuccess(MoveFileEx(Directory_Path, IntPtr.Zero, MoveFileFlags.MOVE_FILE_DELAY_UNTIL_REBOOT))) = True Then
                       Return True
                   Else
                       Return False
                   End If
               End If
           Else
               Return False
           End If
       Catch NTSTATUS As Exception
           Return False
       End Try
   End Function
   '
   Public Shared Function Delete_All_Files(ByVal Directory_Path As String) As Boolean
       Try
           If (Directory.Exists(Directory_Path)) = True Then
               Dim Directory_Info As DirectoryInfo = New DirectoryInfo(Directory_Path)
               For Each Current_File_Info As FileInfo In Directory_Info.GetFiles("*.*", SearchOption.TopDirectoryOnly)
                   Delete_File(Current_File_Info.FullName)
               Next
               For Each New_Directory_Info As DirectoryInfo In Directory_Info.GetDirectories()
                   Delete_All_Files(New_Directory_Info.FullName)
               Next
               Return True
           Else
               Return False
           End If
       Catch NTSTATUS As Exception
           Return False
       End Try
   End Function
   '
   Public Shared Function Delete_All_Directories(ByVal Directory_Path As String) As Boolean
       Try
           If (Directory.Exists(Directory_Path)) = True Then
               Dim Directory_Info As DirectoryInfo = New DirectoryInfo(Directory_Path)
               For Each Current_Directory_Info As DirectoryInfo In Directory_Info.GetDirectories("*.*", SearchOption.TopDirectoryOnly)
                   Delete_All_Directories(Current_Directory_Info.FullName)
                   Delete_Directory(Current_Directory_Info.FullName)
               Next
               Delete_Directory(Directory_Path)
               Return True
           Else
               Return False
           End If
       Catch NTSTATUS As Exception
           Return False
       End Try
   End Function
   '
   Public Shared Function Uninstall(ByVal Directory_Path As String) As Boolean
       Try
           If (Directory.Exists(Directory_Path)) = True Then
               If (Delete_All_Files(Directory_Path)) = True Then
                   If (Delete_All_Directories(Directory_Path)) = True Then
                       Return True
                   Else
                       Return False
                   End If
               Else
                   Return False
               End If
           Else
               Return False
           End If
       Catch NTSTATUS As Exception
           Return False
       End Try
   End Function
   '
End Class

O problema é o seguinte, toda essa classe aí está funcionando ok, porém eu tentei criar a função de exclusão no reboot que de acordo com a MSDN é :

MoveFileEx(CAMINHO_DO_ARQUIVO, NULL, 0x00000004);

Porém a função está retornando algo bem inesperado hahaha ... Ela entende definitivamente que o 0 "NULL" é o nome do arquivo a ser posto no novo diretório e ele move o arquivo do diretório atual para o diretório base da aplicação que chama a função e põe o nome 0...

Alguém conhece uma forma de corrigir isso ?

Obrigado e Feliz ano novo mais uma vez ^^

Edited by Muryllo
Link to comment
Share on other sites

O caminho que estás a passar é o caminho completo de um ficheiro?

Já experimentas-te ver se a função retorna erro?

A aplicação que estás a correr esse código está como administrador?

Link to comment
Share on other sites

O caminho é completo a função não retorna 0 e ele roda como administrador. Só que o arquivo é movido para o diretório da aplicação com o nome "0".

Estou tentando desta forma :

   Public Shared Function Delete_File_After_Reboot(ByVal File_Path As String) As Boolean
    Try
	    If File.Exists(File_Path) = True Then
		    If (NtSuccess(MoveFileEx(File_Path, 0, MoveFileFlags.MOVE_FILE_DELAY_UNTIL_REBOOT))) = True Then
			    Return True
		    Else
			    Return False
		    End If
	    Else
		    Return False
	    End If
    Catch NTSTATUS As Exception
	    Return False
    End Try
   End Function
Edited by Muryllo
Link to comment
Share on other sites

Perfeito ... A função retorna 0x00000001 (TRUE) e os dois últimos bytes da trilha lpnewpath são escritos com 0 (NULL). O sistema agora reconhece e exclui o arquivo.

Obrigado pela ajuda, a classe ficou assim :

Imports System.IO
Imports System.Environment
Imports System.Runtime.InteropServices
'
Public Class Uninstaller
   '
   <[DllImport]("KERNEL32.DLL", SetLastError:=True, EntryPoint:="MoveFileEx", CharSet:=CharSet.Auto)> _
   Public Shared Function MoveFileEx(ByVal lpfilename As String, ByVal lpnewpath As IntPtr, ByVal dwflags As Integer) As Integer
   End Function
   '
   <[DllImport]("KERNEL32.DLL", SetLastError:=True, EntryPoint:="MoveFileEx", CharSet:=CharSet.Auto)> _
   Public Shared Function MoveFileEx(ByVal lpfilename As String, ByVal lpnewpath As String, ByVal dwflags As Integer) As Integer
   End Function
   '
   <[DllImport]("KERNEL32.DLL", SetLastError:=True, EntryPoint:="DeleteFile", CharSet:=CharSet.Auto)> _
   Public Shared Function DeleteFile(ByVal lpfilename As String) As Integer
   End Function
   '
   <[DllImport]("KERNEL32.DLL", SetLastError:=True, EntryPoint:="RemoveDirectory", CharSet:=CharSet.Auto)> _
   Public Shared Function RemoveDirectory(ByVal lpdirectoryname As String) As Integer
   End Function
   '
   Public Enum MoveFileFlags
       MOVE_FILE_NULL = &H0
       MOVE_FILE_REPLACE_EXISTING = &H1
       MOVE_FILE_COPY_ALLOWED = &H2
       MOVE_FILE_DELAY_UNTIL_REBOOT = &H4
       MOVE_FILE_CREATE_HARDLINK = &H10
       MOVE_FILE_FAIL_IF_NOT_TRACKABLE = &H20
   End Enum
   '
   Public Shared Function NtSuccess(ByVal Status As Integer) As Boolean
       Try
           If Status = &H0 Then
               Return False
           Else
               Return True
           End If
       Catch NTSTATUS As Exception
           Return False
       End Try
   End Function
   '
   Public Shared Function Move_File_On_Reboot(ByVal Current_File_Path As String, ByVal New_File_Path As String) As Boolean
       Try
           If (NtSuccess(MoveFileEx(Current_File_Path, New_File_Path, MoveFileFlags.MOVE_FILE_DELAY_UNTIL_REBOOT))) = True Then
               Return True
           Else
               Return False
           End If
       Catch NTSTATUS As Exception
           Return False
       End Try
   End Function
   '
   Public Shared Function Replace_File_On_Reboot(ByVal File_Path As String, ByVal New_File As String) As Boolean
       Try
           Dim File_Path_Base As String = (Path.GetDirectoryName(File_Path) & "\")
           Dim New_File_Base As String = (Path.GetDirectoryName(New_File) & "\")
           Dim File_Temp_Base As String = (GetFolderPath(SpecialFolder.CommonApplicationData) & "\")
           If (Move_File_On_Reboot(New_File, File_Temp_Base & Path.GetFileName(New_File))) = True Then
               If (Move_File_On_Reboot(File_Path, New_File_Base & Path.GetFileName(New_File))) = True Then
                   If (Move_File_On_Reboot(File_Temp_Base & Path.GetFileName(New_File), File_Path_Base & Path.GetFileName(File_Path))) = True Then
                       Return True
                   Else
                       Return False
                   End If
               Else
                   Return False
               End If
           Else
               Return False
           End If
       Catch NTSTATUS As Exception
           Return False
       End Try
   End Function
   '
   Public Shared Function Delete_File_After_Reboot(ByVal File_Path As String) As Boolean
       Try
           If File.Exists(File_Path) = True Then
               If (NtSuccess(MoveFileEx(File_Path, IntPtr.Zero, MoveFileFlags.MOVE_FILE_DELAY_UNTIL_REBOOT))) = True Then
                   Return True
               Else
                   Return False
               End If
           Else
               Return False
           End If
       Catch NTSTATUS As Exception
           Return False
       End Try
   End Function
   '
   Public Shared Function Delete_File(ByVal File_Path As String) As Boolean
       Try
           If (File.Exists(File_Path)) = True Then
               If (NtSuccess(DeleteFile(File_Path))) = True Then
                   Return True
               Else
                   If (Delete_File_After_Reboot(File_Path)) = True Then
                       Return True
                   Else
                       Return False
                   End If
               End If
           Else
               Return False
           End If
       Catch NTSTATUS As Exception
           Return False
       End Try
   End Function
   '
   Public Shared Function Delete_Directory(ByVal Directory_Path As String) As Boolean
       Try
           If (Directory.Exists(Directory_Path)) = True Then
               If (NtSuccess(RemoveDirectory(Directory_Path))) = True Then
                   Return True
               Else
                   If (NtSuccess(MoveFileEx(Directory_Path, IntPtr.Zero, MoveFileFlags.MOVE_FILE_DELAY_UNTIL_REBOOT))) = True Then
                       Return True
                   Else
                       Return False
                   End If
               End If
           Else
               Return False
           End If
       Catch NTSTATUS As Exception
           Return False
       End Try
   End Function
   '
   Public Shared Function Delete_All_Files(ByVal Directory_Path As String) As Boolean
       Try
           If (Directory.Exists(Directory_Path)) = True Then
               Dim Directory_Info As DirectoryInfo = New DirectoryInfo(Directory_Path)
               For Each Current_File_Info As FileInfo In Directory_Info.GetFiles("*.*", SearchOption.TopDirectoryOnly)
                   Delete_File(Current_File_Info.FullName)
               Next
               For Each New_Directory_Info As DirectoryInfo In Directory_Info.GetDirectories()
                   Delete_All_Files(New_Directory_Info.FullName)
               Next
               Return True
           Else
               Return False
           End If
       Catch NTSTATUS As Exception
           Return False
       End Try
   End Function
   '
   Public Shared Function Delete_All_Directories(ByVal Directory_Path As String) As Boolean
       Try
           If (Directory.Exists(Directory_Path)) = True Then
               Dim Directory_Info As DirectoryInfo = New DirectoryInfo(Directory_Path)
               For Each Current_Directory_Info As DirectoryInfo In Directory_Info.GetDirectories("*.*", SearchOption.TopDirectoryOnly)
                   Delete_All_Directories(Current_Directory_Info.FullName)
                   Delete_Directory(Current_Directory_Info.FullName)
               Next
               Delete_Directory(Directory_Path)
               Return True
           Else
               Return False
           End If
       Catch NTSTATUS As Exception
           Return False
       End Try
   End Function
   '
   Public Shared Function Uninstall(ByVal Directory_Path As String) As Boolean
       Try
           If (Directory.Exists(Directory_Path)) = True Then
               If (Delete_All_Files(Directory_Path)) = True Then
                   If (Delete_All_Directories(Directory_Path)) = True Then
                       Return True
                   Else
                       Return False
                   End If
               Else
                   Return False
               End If
           Else
               Return False
           End If
       Catch NTSTATUS As Exception
           Return False
       End Try
   End Function
   '
End Class

Abraços.

Edited by Muryllo
Link to comment
Share on other sites

Porque é que tens duas assinaturas da mesma função? E porque é que usas a propriedade 'EntryPoint' se lhe vais dar o mesmo nome?

Eu também perguntava porque tens esse código cheio de try-catchs, mas como já o fiz numas perguntas tuas anteriores e tu não deste ouvidos não me dou ao trabalho 😉

Edited by He B TeMy
Link to comment
Share on other sites

O Visual Basic aceita duas assinaturas desde que não sejam idênticas. Eu uso as duas pois tem funções que necessitam passar string em lpnewpath e a outra de excluir no reboot necessita passar NULL (0). Sempre deixo meus códigos cheio de try catchs, eles não atrapalham o desempenho e não custa nada usá-los, não gosto de código a solta e odeio alertas JIT, eu evito isso ao máximo mas ok as vezes eu exagero.

Link to comment
Share on other sites

Duas assinaturas da mesma função não faz muito sentido, mas se não tens problema eu também não.

Usares try catch aí simplesmente não faz nada, se enches o teu código de try-catchs sem razão e fazes catch 'NTSTATUS' como se isso fosse algum erro que tu pudesses apanhar... mas pronto, como disse, já referi isso noutros threads teus, não o vou referir mais.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.