Jump to content
Sign in to follow this  
storme

DirectoryCleanup, DirectoryRemove, FileRemove

Recommended Posts

storme

G'day All

I've been fighting with this script for a while now and I thought it was time to bring it out and have a few people laugh at it, tell me there is an easier way and for me to go beat my head into a brick wall for being so stupid. :(

Anyway on to the first step in the plan..... :(

The script came out of another script I'm writing to cleanup my computer. (The usual thing temp directory, IE cache, etc.) But with FileDelete kept missing files, so I went on a journey to discover how to KILL THEM ALL >_< and this is the point I’ve reached.

To delete a file/directory the script tries the following in order:

(If the file/directory is deleted on any step it skips the following steps.

1. Standard - FileDelete/FileRecycle

2. Runs Unlocker.exe then FileDelete/FileRecycle

3. Runs takeown.exe then FileDelete/FileRecycle

4. If the deletetion is a file then it kills the process then FileDelete/FileRecycle

5. IF all else fails it adds it to the PendingFileRenameOperations to be deleted on the next restart.

Please feel free to look though the code and make any suggestions or improvements you think appropriate.

If there is something that should be added then please let me know.

There is still a LOT of debug lines in the code that are staying there until I have it finalised, just ignore them.

BEWARE if this script does its job properly it will DELETE FILES

(I know it sounds silly but I don’t want anyone to post here and say that my script has deleted their important files.)

#include <File.au3>
#include <Misc.au3>
Opt("MustDeclareVars", 1)

;Stop script from running more than once
_Singleton(@ScriptName)

If Not @Compiled Then
    Opt("TrayIconDebug", 1)
EndIf

FileInstall("takeown.exe", @TempDir & "\takeown.exe", 1)
FileInstall("Unlocker.exe", @TempDir & "\Unlocker.exe", 1)
FileInstall("UnlockerDriver5.sys", @TempDir & "\UnlockerDriver5.sys", 1)

; TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST

Global $RL = 0
Run(@ScriptDir & "\MAKE_directories.bat")
Sleep(1000)
DirectoryCleanup("tst_dir", True)
Exit

; TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST


; Delete the contents of specified directory
; DON'T delete directory
Func DirectoryCleanup($Directory, $removeSubDir = True, $Recycle = True)
    Local $searchHandle ; Handle for search string
    Local $fileName ; Name of current file
    Local $result ; Store result of various actions for later compare

    If FileExists($Directory) Then
        ;Try standard delete
        If $Recycle Then
            $result = FileRecycle($Directory & "\*.*")
            ConsoleWrite("DC " & $RL & "FileRecycle(" & $Directory & " & '\*.*') result = " & $result & @CR)
        Else
            $result = FileDelete($Directory & "\*.*")
            ConsoleWrite("DC " & $RL & "FileDelete(" & $Directory & " & '\*.*') result = " & $result & @CR)
        EndIf
        
        ;Check and delete any files/directories left
        $searchHandle = FileFindFirstFile($Directory & "\*")
        If $searchHandle <> -1 Then
            While 1
                $fileName = FileFindNextFile($searchHandle)
                If @error = 1 Then ExitLoop ; no more files
                ConsoleWrite(@CR & "DC " & $RL & "FileFindNextFile = " & $Directory & "\" & $fileName & @CR)
                
                ;Check if Directory
                If StringInStr(FileGetAttrib($Directory & "\" & $fileName), "D") <> 0 Then
                    ConsoleWrite("DC " & $RL & "DIRECTORY" & @CR)
                    DirectoryRemove($Directory, $removeSubDir, $Recycle)
                Else
                    ConsoleWrite("DC " & $RL & "FILE" & @CR)
                    FileRemove($Directory & "\" & $fileName)
                EndIf
            WEnd
            FileClose($searchHandle)
        EndIf
    EndIf
EndFunc   ;==>DirectoryCleanup

;Remove directory & it's contents
Func DirectoryRemove($Directory, $removeSubDir = True, $Recycle = True)
    Local $searchHandle ; Handle for search string
    Local $fileName ; Name of current file
    Local $result = True; Store result of various actions for later compare

    If Not FileExists($Directory) Then Return $result

    $RL = $RL + 1
    
    ;Try a quick deletion - If it works then no need for fancy stuff
    If $removeSubDir And StringInStr(FileGetAttrib($Directory & "\" & $fileName), "D") Then ; If subdirectories aren't to be removed then can't just delete
        If $Recycle Then
            $result = FileRecycle($Directory)
            ConsoleWrite("DR " & $RL & "FileRecycle(" & $Directory & ") result = " & $result & @CR)
        Else
            $result = FileDelete($Directory)
            ConsoleWrite("DR " & $RL & "FileDelete(" & $Directory & ") result = " & $result & @CR)
        EndIf
    EndIf
    
    If FileExists($Directory) Then
        If $Recycle Then
            $result = FileRecycle($Directory & "\*.*")
            ConsoleWrite("DR " & $RL & "FileRecycle(" & $Directory & " & '\*.*') result = " & $result & @CR)
        Else
            $result = FileDelete($Directory & "\*.*")
            ConsoleWrite("DR " & $RL & "FileDelete(" & $Directory & " & '\*.*') result = " & $result & @CR)
        EndIf
        
        ;Check and delete any files/directories left
        $searchHandle = FileFindFirstFile($Directory & "\*")
        If $searchHandle <> -1 Then
            While 1
                $fileName = FileFindNextFile($searchHandle)
                If @error = 1 Then ExitLoop ; no more files
                ConsoleWrite(@CR & "DR " & $RL & "FileFindNextFile = " & $Directory & "\" & $fileName & @CR)
                
                ;Check if Directory
                If StringInStr(FileGetAttrib($Directory & "\" & $fileName), "D") <> 0 Then
                    ConsoleWrite("DR " & $RL & "DIRECTORY" & @CR)

                    If $removeSubDir Then
                        ;**TODO**  Use TAKEOWN to take ownership of the Directory before deleting.
                        ;"takeown /f " & $fileName & "/r /dY"

                        ;Remove Directory
                        FileRemove($Directory & "\" & $fileName) ; Try to remove directory
                        If FileExists($Directory & "\" & $fileName) Then
                            ;Removal Failed (must be a "stuck" file) recursivly check sub directory
                            ConsoleWrite("DR " & $RL & "DIRECTORY - Recurse" & @CR)
                            $result = DirectoryRemove($Directory & "\" & $fileName)
                            FileRemove($Directory & "\" & $fileName) ; Try to remove directory again (should be empty)
                            $RL = $RL - 1
                        EndIf
                    EndIf
                Else
                    ConsoleWrite("DR " & $RL & "FILE" & @CR)
                    $result = FileRemove($Directory & "\" & $fileName)
                EndIf
            WEnd
            FileClose($searchHandle)
        EndIf
    EndIf
    Return $result
EndFunc   ;==>DirectoryRemove

;Remove file even if it's locked/inuse/etc
Func FileRemove($fileName, $Recycle = True)
    Local $result = True
    If FileExists($fileName) = 0 Then Return

    ;Try basic delete/recycle
    If $Recycle Then
        $result = FileRecycle($fileName)
        ConsoleWrite("FR FileRecycle(" & $fileName & ") result = " & $result & @CR)
    Else
        $result = FileDelete($fileName)
        ConsoleWrite("RF FileDelete(" & $fileName & ") result = " & $result & @CR)
    EndIf

    ;Test if Bsic delete worked
    If Not $result Then
        ;Basic delete failed
        ;Reset attributes so file can be deleted (untested)
        FileSetAttrib($fileName, "-RSH+N")
        
        ;try methods of unlocking files
        For $Attempt = 1 To 3
            Select
                Case $Attempt = 1
                    ConsoleWrite("FR UNLOCKER " & $fileName & @CR)
                    ;Remove open handles to files
                    ConsoleWrite('\Unlocker.exe "' & _PathFull($fileName) & '" -S -D')
                    RunWait(@TempDir & '\Unlocker.exe "' & _PathFull($fileName) & '" -S -D');, @SW_HIDE)
                    If @error Then
                        MsgBox(0, "Unlocker.exe -S Error", @error & @CR & $fileName)
                    EndIf

                Case $Attempt = 2
                    ;**TODO**  Use TAKEOWN to take ownership of the file before deleting.
                    ConsoleWrite("FR Takeown " & $fileName & @CR)
                    RunWait(@TempDir & "\takeown.exe " & $fileName, "", @SW_HIDE)
                    If @error Then
                        MsgBox(0, "takeown.exe Error", @error)
                    EndIf
                    
                Case $Attempt = 3
                    ConsoleWrite("FR Close process " & $fileName & @CR)
                    ;CLOSE running programs
                    ;extract only filename to feed to processkill
                    Local $szDrive, $szDir, $szFName, $szExt
                    _PathSplit($fileName, $szDrive, $szDir, $szFName, $szExt)
                    ProcessKill($szFName & $szExt)
            EndSelect
            $result = True ; reset for new clean
            If FileExists($fileName) Then
                If $Recycle Then
                    $result = FileRecycle($fileName)
                    ConsoleWrite("FR FileRecycle(" & $fileName & ") result = " & $result & @CR)
                Else
                    $result = FileDelete($fileName)
                    ConsoleWrite("RF FileDelete(" & $fileName & ") result = " & $result & @CR)
                EndIf
            Else
                ExitLoop
            EndIf
        Next

        If Not $result Then
            ; Only Files can be deleted like this (Check if it's a file)
            If StringInStr(FileGetAttrib($fileName), "D") = 0 Then
                ConsoleWrite(" MOVE FILE on restart " & $fileName & ") result = " & $result & @CR)
                ;Delete File on system restart
                Local $pe = "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager"
                Local $pv = "PendingFileRenameOperations"
                RegWrite($pe, $pv, "REG_MULTI_SZ", "\??\" & FileGetShortName($fileName) & @LF & @LF & RegRead($pe, $pv))
            Else
                ;ConsoleWrite(" WILL NOT MOVE DIRECTORY on restart " & $fileName & @CR)
            EndIf
            ;**TODO** What about sending to "recycling bin" ?? how can I do that on restart ??
        EndIf
    EndIf
    ConsoleWrite("FR Result = " & $result & @CR)
    Return $result
EndFunc   ;==>FileRemove

Func ProcessKill($ProcessKill_in);PID or the name of the process
    ;dexto http://www.autoitscript.com/forum/index.php?showtopic=95999&view=findpost&p=690149
    Local $ProcessKill_PID, $ProcessKill_all, $ProcessKill_trackEach, $ProcessKill_each, $ProcessKill_PIDtoKill
    Local $ProcessKill_objWMIService, $ProcessKill_procToKill, $ProcessKill_track
    
    If IsNumber($ProcessKill_in) Then
        $ProcessKill_PID = $ProcessKill_in
    Else
        $ProcessKill_all = ProcessList($ProcessKill_in)
        If @error Then Return 0

        $ProcessKill_trackEach = 0
        For $ProcessKill_each = 1 To $ProcessKill_all[0][0]
            $ProcessKill_trackEach += ProcessKill($ProcessKill_all[$ProcessKill_each][1])
        Next

        If $ProcessKill_trackEach == $ProcessKill_all[0][0] Then
            Return 1
        Else
            Return 0
        EndIf
    EndIf

    $ProcessKill_PIDtoKill = ProcessExists($ProcessKill_PID)
    If $ProcessKill_PIDtoKill == 0 Then
        Return 0
    EndIf

    ProcessClose($ProcessKill_PIDtoKill)
    Sleep(300)
    If ProcessExists($ProcessKill_PIDtoKill) == 0 Then
        Return 1
    EndIf

    $ProcessKill_objWMIService = ObjGet("winmgmts:\root\cimv2")
    $ProcessKill_procToKill = $ProcessKill_objWMIService.ExecQuery("Select * from win32_process where processid = " & $ProcessKill_PIDtoKill)

    $ProcessKill_track = 0
    For $ProcessKill_procToKillThread In $ProcessKill_procToKill
        $ProcessKill_track += ConsoleWrite($ProcessKill_procToKillThread.Terminate & @CRLF)
    Next

    If $ProcessKill_track > 0 Then
        Return 0
    EndIf
    Return 1
EndFunc   ;==>ProcessKill


Func SetStatus($text)
    ;TODO Use to set status line or label or ....
EndFunc   ;==>SetStatus

The attached zip file contains the script, unlocker, takeown and my test batch file.

EDIT: Forgot to click "Attach this file" DOH!

Thanks in advance for ALL constructive comments.

directorycleanV0.07.zip

Edited by storme

Share this post


Link to post
Share on other sites
storme

Well no interest...sigh...but not to worry I wrote it for my little project and though others mught find it usefull.

Anyway I've adding some new options to the functions (all optional) that allow you to decide which of the optionals (unlock, takeown, etc) you want to use.

I HAVN'T undated the zip file in the first post yet.

#include <File.au3>
#include <Misc.au3>
Opt("MustDeclareVars", 1)

;Stop script from running more than once
_Singleton(@ScriptName)

If Not @Compiled Then
    Opt("TrayIconDebug", 1)
EndIf

FileInstall("takeown.exe", @TempDir & "\takeown.exe", 1)
FileInstall("Unlocker.exe", @TempDir & "\Unlocker.exe", 1)
FileInstall("UnlockerDriver5.sys", @TempDir & "\UnlockerDriver5.sys", 1)

; TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST

Global $RL = 0
Run(@ScriptDir & "\MAKE_directories.bat")
Sleep(1000)
DirectoryCleanup("tst_dir", True, True, True, True, True, True)
Exit

; TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST


; Delete the contents of specified directory
; DON'T delete directory
Func DirectoryCleanup($Directory, $removeSubDir = True, $Recycle = True, $Unlock = False, $Takeown = False, $KillProcess = False, $DelOnReboot = False)
    Local $searchHandle ; Handle for search string
    Local $fileName ; Name of current file
    Local $result ; Store result of various actions for later compare

    If FileExists($Directory) Then
        ;Try standard delete
        If $Recycle Then
            $result = FileRecycle($Directory & "\*.*")
            ConsoleWrite("DC " & $RL & "FileRecycle(" & $Directory & " & '\*.*') result = " & $result & @CR)
        Else
            $result = FileDelete($Directory & "\*.*")
            ConsoleWrite("DC " & $RL & "FileDelete(" & $Directory & " & '\*.*') result = " & $result & @CR)
        EndIf
        
        ;Check and delete any files/directories left
        $searchHandle = FileFindFirstFile($Directory & "\*")
        If $searchHandle <> -1 Then
            While 1
                $fileName = FileFindNextFile($searchHandle)
                If @error = 1 Then ExitLoop ; no more files
                ConsoleWrite(@CR & "DC " & $RL & "FileFindNextFile = " & $Directory & "\" & $fileName & @CR)
                
                ;Check if Directory
                If StringInStr(FileGetAttrib($Directory & "\" & $fileName), "D") <> 0 Then
                    ConsoleWrite("DC " & $RL & "DIRECTORY" & @CR)
                    DirectoryRemove($Directory, $removeSubDir, $Recycle, $Unlock, $Takeown, $KillProcess, $DelOnReboot)
                Else
                    ConsoleWrite("DC " & $RL & "FILE" & @CR)
                    FileRemove($Directory & "\" & $fileName, $Unlock, $Takeown, $KillProcess, $DelOnReboot)
                EndIf
            WEnd
            FileClose($searchHandle)
        EndIf
    EndIf
EndFunc   ;==>DirectoryCleanup

;Remove directory & it's contents
Func DirectoryRemove($Directory, $removeSubDir = True, $Recycle = True, $Unlock = False, $Takeown = False, $KillProcess = False, $DelOnReboot = False)
    Local $searchHandle ; Handle for search string
    Local $fileName ; Name of current file
    Local $result = True; Store result of various actions for later compare

    If Not FileExists($Directory) Then Return $result

    $RL = $RL + 1
    
    ;Try a quick deletion - If it works then no need for fancy stuff
    If $removeSubDir And StringInStr(FileGetAttrib($Directory & "\" & $fileName), "D") Then ; If subdirectories aren't to be removed then can't just delete
        If $Recycle Then
            $result = FileRecycle($Directory)
            ConsoleWrite("DR " & $RL & "FileRecycle(" & $Directory & ") result = " & $result & @CR)
        Else
            $result = FileDelete($Directory)
            ConsoleWrite("DR " & $RL & "FileDelete(" & $Directory & ") result = " & $result & @CR)
        EndIf
    EndIf
    
    If FileExists($Directory) Then
        If $Recycle Then
            $result = FileRecycle($Directory & "\*.*")
            ConsoleWrite("DR " & $RL & "FileRecycle(" & $Directory & " & '\*.*') result = " & $result & @CR)
        Else
            $result = FileDelete($Directory & "\*.*")
            ConsoleWrite("DR " & $RL & "FileDelete(" & $Directory & " & '\*.*') result = " & $result & @CR)
        EndIf
        
        ;Check and delete any files/directories left
        $searchHandle = FileFindFirstFile($Directory & "\*")
        If $searchHandle <> -1 Then
            While 1
                $fileName = FileFindNextFile($searchHandle)
                If @error = 1 Then ExitLoop ; no more files
                ConsoleWrite(@CR & "DR " & $RL & "FileFindNextFile = " & $Directory & "\" & $fileName & @CR)
                
                ;Check if Directory
                If StringInStr(FileGetAttrib($Directory & "\" & $fileName), "D") <> 0 Then
                    ConsoleWrite("DR " & $RL & "DIRECTORY" & @CR)

                    If $removeSubDir Then
                        ;**TODO**  Use TAKEOWN to take ownership of the Directory before deleting.
                        ;"takeown /f " & $fileName & "/r /dY"

                        ;Remove Directory
                        FileRemove($Directory & "\" & $fileName) ; Try to remove directory
                        If FileExists($Directory & "\" & $fileName) Then
                            ;Removal Failed (must be a "stuck" file) recursivly check sub directory
                            ConsoleWrite("DR " & $RL & "DIRECTORY - Recurse" & @CR)
                            $result = DirectoryRemove($Directory & "\" & $fileName, $Unlock, $Takeown, $KillProcess, $DelOnReboot)
                            FileRemove($Directory & "\" & $fileName, $Unlock, $Takeown, $KillProcess, $DelOnReboot) ; Try to remove directory again (should be empty)
                            $RL = $RL - 1
                        EndIf
                    EndIf
                Else
                    ConsoleWrite("DR " & $RL & "FILE" & @CR)
                    $result = FileRemove($Directory & "\" & $fileName, $Unlock, $Takeown, $KillProcess, $DelOnReboot)
                EndIf
            WEnd
            FileClose($searchHandle)
        EndIf
    EndIf
    Return $result
EndFunc   ;==>DirectoryRemove

;Remove file even if it's locked/inuse/etc
Func FileRemove($fileName, $Recycle = True, $Unlock = False, $Takeown = False, $KillProcess = False, $DelOnReboot = False)
    Local $result = True
    If FileExists($fileName) = 0 Then Return

    ;Try basic delete/recycle
    If $Recycle Then
        $result = FileRecycle($fileName)
        ConsoleWrite("FR FileRecycle(" & $fileName & ") result = " & $result & @CR)
    Else
        $result = FileDelete($fileName)
        ConsoleWrite("RF FileDelete(" & $fileName & ") result = " & $result & @CR)
    EndIf

    ;Test if Bsic delete worked
    If Not $result Then
        ;Basic delete failed
        ;Reset attributes so file can be deleted (untested)
        FileSetAttrib($fileName, "-RSH+N")
        
        ;try methods of unlocking files
        For $Attempt = 1 To 3
            Select
                Case $Attempt = 1 And $Unlock
                    ConsoleWrite("FR UNLOCKER " & $fileName & @CR)
                    ;Remove open handles to files
                    ConsoleWrite('\Unlocker.exe "' & _PathFull($fileName) & '" -S -D')
                    RunWait(@TempDir & '\Unlocker.exe "' & _PathFull($fileName) & '" -S -D');, @SW_HIDE)
                    If @error Then
                        MsgBox(0, "Unlocker.exe -S Error", @error & @CR & $fileName)
                    EndIf

                Case $Attempt = 2 And $Takeown
                    ;**TODO**  Use TAKEOWN to take ownership of the file before deleting.
                    ConsoleWrite("FR Takeown " & $fileName & @CR)
                    RunWait(@TempDir & "\takeown.exe " & $fileName, "", @SW_HIDE)
                    If @error Then
                        MsgBox(0, "takeown.exe Error", @error)
                    EndIf
                    
                Case $Attempt = 3 And $KillProcess
                    ConsoleWrite("FR Close process " & $fileName & @CR)
                    ;CLOSE running programs
                    ;extract only filename to feed to processkill
                    Local $szDrive, $szDir, $szFName, $szExt
                    _PathSplit($fileName, $szDrive, $szDir, $szFName, $szExt)
                    ProcessKill($szFName & $szExt)
            EndSelect
            $result = True ; reset for new clean
            If FileExists($fileName) Then
                If $Recycle Then
                    $result = FileRecycle($fileName)
                    ConsoleWrite("FR FileRecycle(" & $fileName & ") result = " & $result & @CR)
                Else
                    $result = FileDelete($fileName)
                    ConsoleWrite("RF FileDelete(" & $fileName & ") result = " & $result & @CR)
                EndIf
            Else
                ExitLoop
            EndIf
        Next

        If (Not $result) And $DelOnReboot Then
            ; Only Files can be deleted like this (Check if it's a file)
            If StringInStr(FileGetAttrib($fileName), "D") = 0 Then
                ConsoleWrite(" MOVE FILE on restart " & $fileName & ") result = " & $result & @CR)
                ;Delete File on system restart
                Local $pe = "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager"
                Local $pv = "PendingFileRenameOperations"
                RegWrite($pe, $pv, "REG_MULTI_SZ", "\??\" & FileGetShortName($fileName) & @LF & @LF & RegRead($pe, $pv))
            Else
                ;ConsoleWrite(" WILL NOT MOVE DIRECTORY on restart " & $fileName & @CR)
            EndIf
            ;**TODO** What about sending to "recycling bin" ?? how can I do that on restart ??
        EndIf
    EndIf
    ConsoleWrite("FR Result = " & $result & @CR)
    Return $result
EndFunc   ;==>FileRemove

Func ProcessKill($ProcessKill_in);PID or the name of the process
    ;dexto http://www.autoitscript.com/forum/index.php?showtopic=95999&view=findpost&p=690149
    Local $ProcessKill_PID, $ProcessKill_all, $ProcessKill_trackEach, $ProcessKill_each, $ProcessKill_PIDtoKill
    Local $ProcessKill_objWMIService, $ProcessKill_procToKill, $ProcessKill_track
    
    If IsNumber($ProcessKill_in) Then
        $ProcessKill_PID = $ProcessKill_in
    Else
        $ProcessKill_all = ProcessList($ProcessKill_in)
        If @error Then Return 0

        $ProcessKill_trackEach = 0
        For $ProcessKill_each = 1 To $ProcessKill_all[0][0]
            $ProcessKill_trackEach += ProcessKill($ProcessKill_all[$ProcessKill_each][1])
        Next

        If $ProcessKill_trackEach == $ProcessKill_all[0][0] Then
            Return 1
        Else
            Return 0
        EndIf
    EndIf

    $ProcessKill_PIDtoKill = ProcessExists($ProcessKill_PID)
    If $ProcessKill_PIDtoKill == 0 Then
        Return 0
    EndIf

    ProcessClose($ProcessKill_PIDtoKill)
    Sleep(300)
    If ProcessExists($ProcessKill_PIDtoKill) == 0 Then
        Return 1
    EndIf

    $ProcessKill_objWMIService = ObjGet("winmgmts:\root\cimv2")
    $ProcessKill_procToKill = $ProcessKill_objWMIService.ExecQuery("Select * from win32_process where processid = " & $ProcessKill_PIDtoKill)

    $ProcessKill_track = 0
    For $ProcessKill_procToKillThread In $ProcessKill_procToKill
        $ProcessKill_track += ConsoleWrite($ProcessKill_procToKillThread.Terminate & @CRLF)
    Next

    If $ProcessKill_track > 0 Then
        Return 0
    EndIf
    Return 1
EndFunc   ;==>ProcessKill


Func SetStatus($text)
    ;TODO Use to set status line or label or ....
EndFunc   ;==>SetStatus

Feedback is most welcome.

Share this post


Link to post
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
Sign in to follow this  

×