how to automate uninstall of a program via autoit? - autoit

I am trying to uninstall a program from add or remove programs via an AutoIt script.
*I dont want to uninstall via removing the registry keys.
* I dont want to uninstall via running an uninstaller.
I can open "add remove programs" by a appwiz.cpl command
However I am failing to recognize the correct program name from the list and invoke an uninstall.
All I want to do is recognize my program from the list, for example "Helloworld" and invoke an uninstall.

You can just loop through all your corresponding Registry Values of which your uninstall list in your "Add or remove programs" is made of... And then directly extract the command that you want to execute. I display it in a Message Box in this example, but you could directly compare the DisplayName to "Helloworld" and then execute the UninstallString with Run(...). This is the exact same as your "Add or remove programs" would invoke. It doesn't mean simply removing registry keys. And it doesn't mean just running "any" uninstaller but the proper one, needed to exactly uninstall this very program like clicking the "Uninstall" button in appwiz.cpl will invoke. So to perform what you asked for as a result, this solution works just fine. It does not acutally handle the appwiz.cpl and cycle through the list of programs...
$uninstall_path1 = "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall"
searchUninstallStrings($uninstall_path1)
$uninstall_path2 = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
searchUninstallStrings($uninstall_path2)
Func searchUninstallStrings($uninstall_path)
$i = 0
While True
$i += 1
Local $entry = RegEnumKey($uninstall_path, $i)
If #error <> 0 Then ExitLoop
$regPath = $uninstall_path & "\" & $entry
$DisplayName = RegRead($regPath, "DisplayName")
If $DisplayName <> "" Then
$message = $DisplayName & #CR
$UninstallString = RegRead($regPath, "UninstallString")
If $UninstallString <> "" Then
$message &= "Uninstall: '" & $UninstallString & "'"
MsgBox(4096, "SubKey #" & $i & ": " & $entry, $message)
EndIf
EndIf
WEnd
EndFunc
Good Luck!

I was able to successfully automate program uninstalls with the following command to open up the Programs and Features control panel menu followed by a series of keystrokes:
Run("C:\Windows\System32\control.exe appwiz.cpl")
WinWait("Programs and Features")
WinActivate("Programs and Features")
Send("ProgramNameHere")
Send("{Enter}")

Related

How to exec MariaDB Store Proc from Visual Foxpro?

I have a function/store proc in Maria DB
CREATE DEFINER=`root`#`localhost` PROCEDURE `test1`(var1 varchar(100))
BEGIN
select * from ttype where kode=var1;
END
I need to get a cursor from store proc, Howto get a cursor in vfp application, database in MariaDb/MySQL StoreProc?
I try with this in my Visual Foxpro :
Sqlexec(kon,"call test1 ('ABC')","test") --> not running
But when I use common select like this :
sqlexec(kon,"select * from ttype where kode='ABC'","test") --it's running well..
"Can you show me how to use aerror() in my case?"
You would use the AError() function always when any ODBC Remote action would fail, i.e. any of Vfp's SQL*() functions, like SqlStringConnect() for example or your proposed
sqlexec(kon,"select * from ttype where kode='ABC'","test") --it's running well
&& Actually you cannot know whether "it's running well" unless you are evaluating its return value like this:
Local lnResult, laSqlErrors[1], lcErrorMessage
lnResult = SqlExec(kon,"select * from ttype where kode='ABC'","test")
If m.lnResult = –1 && as documented in the F1 Help
AERROR(laSqlErrors)
lcErrorMessage = ;
TRANSFORM(laSqlErrors[1]) + ", " + ;
TRANSFORM(laSqlErrors[2])
&& now write a log and/or inform the user
ENDIF
&& to be continued

Conditional include of file

I'd like to include certain script only if it's present. Unfortunately #include is processed before the execution, so I can't make it conditional like this:
If FileExists(#ScriptDir & "\common.au3") Then
#include "common.au3"
EndIf
I tried to use Execute to evaluate the read file in place via Execute(ReadFile(...)). But that seems to only process single statements - I couldn't declare multiple functions for example.
Is there a different way to conditionally include another file?
Probably not a good design choice but if you really need to do somethin like this, try #OnAutoItStartRegister:
#OnAutoItStartRegister "_OnAutoItStart_CreateIncludes"
#include "include_collection.au3"
If IsDeclared("iExample_Common") Then
MsgBox(64, "", "Common.au3 exists")
Else
MsgBox(16, "", "Common.au3 wasnt included")
EndIf
MsgBox(0, "", "Your Script here")
Func _OnAutoItStart_CreateIncludes()
If StringInStr($CmdLineRaw, '-_OnAutoItStart_CreateIncludes', 1) Then Return
If FileExists(#ScriptDir & "\common.au3") And Not StringInStr(FileRead("include_collection.au3"), '#include "common.au3"') Then
FileWrite("include_collection.au3", '#include "common.au3"')
EndIf
$iPID = Run('"' & #AutoItExe & '" ' & $CmdLineRaw & ' -_OnAutoItStart_CreateIncludes', #WorkingDir, Default, 2)
While ProcessExists($iPID)
ConsoleWrite(StdoutRead($iPID))
Sleep(10)
WEnd
Exit
EndFunc ;==>_OnAutoItStart_CreateIncludes
Create an additional empty file "include_collection.au3" as well.
In this example, I created "commons.au3" containing a statement "$iExample_commons = 1234'.
Note: Once the file is included this way, it should not be deleted otherwise your script will fail again. This could probably be overcome too but at some point it will become very messy.
Maybe it's a better Idea to wrap a launcher around your application which will add/remove include lines before startup as needed.

Fastest way to read and work with a binary file

Im working on a script that work with a Binary file Inside of loop and read its bytes Consecutive , (also be able to Go back and forth inside the file (savepos) (setpos))
But I dont know I need to use what method so its not bad for performance
My first attempt was to use FileRead with FileHandle, But sadly This made the speed of the program slower as the program progressed and read further from file (Program finish after like 30 min for a 10MB file)
$File = FileOpen($Path, 16)
$tTimer = TimerInit()
$ndx = 4
for $i=0 to 100000
$test = FileRead($File, $ndx)
$ndx += 4
ConsoleWrite($test & #CRLF)
Next
ConsoleWrite(TimerDiff($ttimer) &" Sekunden"& #CRLF)
So I tried to first read whole File into a variable and then read the binary from it with BinaryMid
But this method was even more slower...
$File = FileOpen($Path, 16)
$Readfilee = FileRead($File)
$tTimer = TimerInit()
$ndx = 4
for $i=0 to 100000
$test = _BinaryRead(4)
ConsoleWrite($test & #CRLF)
Next
ConsoleWrite(round(TimerDiff($ttimer) /1000,2) &" Sekunden"& #CRLF)
Func _BinaryRead($iCount)
$ndx += $iCount
Return BinaryMid($Readfilee, $GNOW - $iCount, $iCount)
EndFunc
so I want to know what can I do for reading Bin file as fast as possible?
sorry if its not a good question, Im new in autoit
You don't need to read the file byte-by-byte, the function FileRead() do everything for you in only one step, you can use something like this:
$hFile = FileOpen($Path, $FO_BINARY)
$tTimer = TimerInit()
$bFileContent = FileRead($hFile)
FileClose($hFile)
; Now you can use $bFileContent as you want.
ConsoleWrite(TimerDiff($ttimer) &" Sekunden"& #CRLF)

SciTE Script - How to get inside a Tree Control to set checkboxes

I'm using AutoIt and SciTE to create an installation script. The problem I am running into is that there is a tree menu for selection of features. I can select the whole treeview (SysTreeView32), but am not sure how to get inside it to check the boxes without doing a mouse move and click (not a great option).
The Treeview looks like this:
The Control Info from AutoIT is like this:
I'm sure it is possible, just can't figure out how to do it. This is my first attempt a such a script. Creating a response file does not work for this exe for some reason. So - this appears to be my only way out to create a somewhat silent install (not silent anymore, but at least automated).
* EDIT - Current State of Things *
I did figure out how to do some of this, but I still can't figure out if the items is selected before accessing it. So - since it toggles, I could be turning off a feature I want!
$hWnd = WinWaitActive($WindowTitle, 'Select Features')
$tvCtl = ControlGetHandle($WindowTitle, '', 'SysTreeView321')
$firstItem = _GUICtrlTreeView_FindItem($tvCtl, 'eBooks')
_GUICtrlTreeView_SelectItem($tvCtl, $firstItem, $TVGN_FIRSTVISIBLE)
_GUICtrlTreeView_ClickItem($tvCtl, $firstItem, "left", True, 1)
Send('{SPACE}')
I wouldn't think I would have to send the space since I sent the ClickItem, but seems so.
I could also do this:
ControlTreeView($hWnd, '', $tvCtl, 'Select', '#0')
ControlSend($hWnd, '', $tvCtl, ' ')
That will toggle the first one. So - i can count them all up and do it that way.
But when I check for "IsEnabled" or "IsChecked", it always says NO. So - I can't check the ones I need only. I have to hope their status is what I expect.
Here is how I am checking "IsChecked" and "IsEnabled":
If ControlCommand($hWnd, '', $logTool, 'IsEnabled') then
ConsoleWrite('Log Tool - IsEnabled' & #CRLF)
Else
ConsoleWrite('Log Tool - NOTEnabled' & #CRLF)
EndIf
and
If ControlCommand($hWnd, '', $logTool, 'IsChecked') then
ConsoleWrite('Log Tool - IsChecked' & #CRLF)
Else
ConsoleWrite('Log Tool - NOTChecked' & #CRLF)
EndIf
It always comes back NOTEnabled and NOTChecked. I made sure that I ran the same procedure above: FindItem, SelectItem, ClickItem. And, the correct item is highlighted/selected when this procedure is run - I can see that. So - it just isn't returning a proper value.
Opt('WinTitleMatchMode', 2)
$hWnd = WinGetHandle("InstallShield Wizard") ; Notice the correct title
$hTree = ControlGetHandle($hWnd, '', "[CLASS:SysTreeView32;INSTANCE:1]")
; == Now you can interact with the treeview with functions from "GuiTreeView.au3"
EDIT:
Try this
; Select the item so:
_GUICtrlTreeView_SelectItem($hTree, $hItem, $TVGN_CARET)
; Get checked state:
_GUICtrlTreeView_GetChecked($hTree, $hItem)
For more deatails read the AutoIt help.

Autoit get current caret position Or current text box position

So i am working on a project and i got stuck on this part.
I am trying to locate the position of ether the typing caret(The blinking line while typing) or the current text box that is being typed in.
The main part that is hard is i am looking to do this for every input on my computer (Firefox search, Notepad, Renaming files, writing this post...)
I am beginning to doubt that auto-it can do this, i am open to using another language that can do this. (I have not checked any other language but Auto-it yet)
I have tested "WinGetCaretPos()" and a few other random scripts, but they had the same problem, they don't return the correct position.
~Thanks
Not all controls are standard window controls that can be accessed with AutoIt functions. Many programs (especially browsers) have nonstandard controls so "every input" on the computer might be hard to get.
Here is an example of how to get the control information of any active window that is giving focus to a control AND has standard windows controls.
HotKeySet("{ESC}", "Terminate")
While 1
Sleep(500)
GetControlFocus()
WEnd
Func GetControlFocus()
Local $hWinHandle = WinGetHandle("[Active]")
Local $sControl = ControlGetFocus($hWinHandle)
Local $sText = "The active window handle is: " & $hWinHandle & #CRLF
If $sControl <> "" Then
$sText &= "The control with focus in the active window is: " & $sControl & #CRLF
Local $aPos = ControlGetPos($hWinHandle, "", $sControl)
$sText &= "Mouse position: X: " & $aPos[0] & " Y: " & $aPos[1] & #CRLF & "Size: " & $aPos[2] & ", " & $aPos[3]
Else
$sText &= "The active window is not giving focus to a control that AutoIt recognizes."
EndIf
ToolTip($sText, 0, 0)
EndFunc ;==>GetControlFocus
Func Terminate()
Exit
EndFunc ;==>Terminate
You can get the control position of other programs using IUIAutomation and this UDF. But it would not be as simple as using a few standard AutoIt functions.

Resources