Autoit starts app without focus - autoit

Using AutoIt 3.3.14.2 to start Entrust etunprot.exe application. The Entrust application starts, but does not have focus. After the application starts the AutoIt script is supposed to enter the password, but doesn't because of no focus. When I click on the application to give it focus then the password is entered and the script continues and finishes successfully. I originally used WinWaitActive and replaced it with WinWait and WinActivate to try and fix the problem. Here is the code:
; Terminate script if no command-line arguments
If $CmdLine[0] = 0 Then Exit (1)
Run("C:\Program Files\Entrust\Password Unprotect\etunprot.exe " & $CmdLine[1])
WinWait("Entrust Password Unprotect", "OK")
WinActivate("Entrust Password Unprotect", "OK")
; Enter the password text
Send("password")
; Submit the password
Send("{ENTER}")
WinWait("Entrust Password Unprotect", "Enter name of output folder")
WinActivate("Entrust Password Unprotect", "Enter name of output folder")
; Enter the name of the output folder
Send($CmdLine[2])
; Unprotect the enp file
Send("{ENTER}")

Try
WinWait("Entrust Password Unprotect", "")
WinActivate("Entrust Password Unprotect", "")

Try this to get the Windows of your process. Maybe it helps you out.
#include <Array.au3>
$re = ProcessGetWindow(ProcessExists('Greenshot.exe'))
_ArrayDisplay($re)
Func ProcessGetWindow($PId)
$PId = ProcessExists($PId)
If $PId = 0 Then
SetError(1)
Else
Local $WinList = WinList()
Local $WindowTitle[1][2]
Local $x = 0
For $i = 1 To $WinList[0][0]
If WinGetProcess($WinList[$i][1], "") = $PId And $WinList[$i][0] <> "" Then
ReDim $WindowTitle[$x + 1][2]
$WindowTitle[$x][0] = $WinList[$i][0]
$WindowTitle[$x][1] = $WinList[$i][1]
$x += 1
EndIf
Next
Return $WindowTitle
EndIf
EndFunc ;==>ProcessGetWindow

Related

If statement not working AutoIT

I am having trouble with the code I am writing. I have a table which lists staff member details. I am trying to have an email address copy to the clipboard when you select a record and right click. I have the following code:
#include <GUIConstantsEx.au3>
#include <mssql.au3>
#include <MsgBoxConstants.au3>
#include <Array.au3>
#include <WindowsConstants.au3>
#include <AutoItConstants.au3>
global $title = "E-Mail address lookup"
global $name = InputBox($title,"Please type the name of the person you wish to find")
global $sqlCon = _MSSQL_Con("server", "username", "password", "directory-plus")
global $result = _MSSQL_GetRecord($sqlCon, "autoit_view","*", "WHERE cn LIKE '%" & StringStripWS($name,3) & "%'")
if StringLen(StringStripWS($name,3)) < 1 then
MsgBox(0, $title, "Name cannot be empty")
Else
Global $rset = UBound($result) - 1
Global $ControlID = GUICreate($title, 500, 150)
Global $idListview = GUICtrlCreateListView("Deparment|E-Mail Address|Name|Telephone Number", 10, 10, 480, 150)
for $count = 1 to $rset step 1
GUICtrlCreateListViewItem($result[$count][0] & "|" & $result[$count][2] & "|" & $result[$count][1] & "|" & $result[$count][2], $idListview)
if MouseClick($MOUSE_CLICK_RIGHT)==1 Then
ClipPut($result[$count][2])
EndIf
Next
GUISetState(#SW_SHOW)
GUISetState()
While 1
Global $Msg = GUIGetMsg()
Switch $Msg
Case -3, $ControlID
Exit
EndSwitch
WEnd
EndIf
I would have thought my IF statement within the for loop would do the trick but, when I run my code, it just copies whatever is in email address column in the last row when in fact I want it to copy the email address when you right click on a particular row but I'm not sure how to do it.
Your code has two major problems. The first is that MouseClick() doesn't check for the mouse button being pressed, but instead sends a mouse button click. Since sending a mouse button click is going to succeed, MouseClick($MOUSE_CLICK_RIGHT)==1 will evaluate to true. For each list view item you create, you are putting the email address on the clipboard.
The second problem is that the if statement is in the wrong place. It's executed just after you create each list view item.
Instead, change your While statement as follows
While 1
Global $Msg = GUIGetMsg()
Switch $Msg
Case -3, $ControlID
Exit
case $GUI_EVENT_SECONDARYDOWN
$selecteditem=StringSplit(GUICtrlRead(GUICtrlRead($idListview)),"|")
if #error=0 and $selecteditem[0]>1 Then
ClipPut($selecteditem[2])
EndIf
EndSwitch
WEnd

Close windows in reverse order of creation

I have a program with a main window and multiple other windows and want to use autoit to close these windows. The main window however refuses to close if other windows of the program are open and creates a warning message.
To avoid this, I want to close the other windows first.
Because of the way the program is written, the windows are NOT in a parent-child relationship, so I cannot use "EnumChildWindows" in "user32.dll".
So my other option would be to obtain the order or time the windows were created at, and close them in reversed order. Is there any way to do this?
You can try to get it by the process. The function below will return the z-order of the windows, as far as I know, without you tracking the "creation time" of the windows themselves from within your own code, you won't get a solution that can do that.
#include <WinAPIProc.au3>
#include <WinAPISys.au3>
#region - Example
Global $gahWnd[3]
For $i = 0 To 2
$gahWnd[$i] = GUICreate("Example " & $i)
GUISetState(#SW_SHOW, $gahWnd[$i])
Next
Global $gaExample = _WinGetByProc(#AutoItPID)
If #error Then Exit 2
Sleep(3000) ; so you can at least see the windows were created
; windows are returned in the "last z-order"
; so they'll be returned "Example 2, Example 1, Example 0"
; This makes it easy to close all but the first one
; use -1 to keep the first window created
For $i = 1 To $gaExample[0] - 1
ConsoleWrite("Closing: " & $gaExample[$i] & ":" & WinGetTitle($gaExample[$i]) & #CRLF)
WinClose($gaExample[$i])
Next
Global $gaMsg
While 1
$gaMsg = GUIGetMsg(1)
Switch $gaMsg[1]
Case $gahWnd[0]
Switch $gaMsg[0]
Case -3
Exit
EndSwitch
Case $gahWnd[1]
Switch $gaMsg[0]
Case -3
GUIDelete($gahWnd[1])
EndSwitch
Case $gahWnd[2]
Switch $gaMsg[0]
Case -3
GUIDelete($gahWnd[2])
EndSwitch
EndSwitch
WEnd
#EndRegion - Example
; pass the exe or the process id
Func _WinGetByProc($vExe)
; will return pid if exe name sent or validate if pid is sent
Local $iPID = ProcessExists($vExe)
If Not ProcessExists($iPID) Then
Return SetError(1, 0, 0)
EndIf
; enum desktop window only (top-level-windows)
Local $ahWnds = _WinAPI_EnumDesktopWindows(_WinAPI_GetThreadDesktop( _
_WinAPI_GetCurrentThreadId()))
If #error Or Not IsArray($ahWnds) Then
Return SetError(2, 0, 0)
EndIf
Local $aExeContainer[11], $iDim
For $iwnd = 1 To $ahWnds[0][0]
; compare windows pid with our pid
If (WinGetProcess(HWnd($ahWnds[$iwnd][0])) = $iPID) Then
$iDim += 1
; sanity check, be sure the array has the right number of indexes
If (Mod($iDim, 10) = 0) Then
ReDim $aExeContainer[$iDim + 10]
EndIf
$aExeContainer[$iDim] = HWnd($ahWnds[$iwnd][0])
EndIf
Next
; if there were no matches return
If Not $iDim Then
Return SetError(3, 0, 0)
EndIf
; trim array and set number found in the zero index
ReDim $aExeContainer[$iDim + 1]
$aExeContainer[0] = $iDim
Return $aExeContainer
EndFunc

AutoIT WinWaitActive doesn't uderstands that window is active

I want to get pixel color from a game and react.
So I have this sript:
#include <Color.au3>
Local $pause = False;
$WinName = "Game" ; Let's say there is a game with this name =)
$hwnd = WinGetHandle($WinName) ; Checked handle with powershell and Au3Info, handle is correct
local $res
Opt("PixelCoordMode", 2);
HotKeySet("{F10}", "exitNow");
HotKeySet("{F11}", "Pause");
While 1
;WinWaitActive($hwnd) ; The script stops here if it is uncommented no matter if window is active or not
if ( $pause ) Then
$res = GetPos();
ConsoleWrite ( StringFormat ("Result color: %s %s", $res[0], $res[1] ) )
Sleep (1000)
EndIf
WEnd
Func exitNow()
Exit
EndFunc
Func Pause()
$pause = Not $pause
EndFunc
Func GetPos()
local $var = Hex(PixelGetColor(5, 5, $hwnd)) ; Only works in windowed mode, FullScreen return some random colors like 00FFFFFF or 00AAAAAA
$var = StringTrimLeft($var,2) ; Removing first 2 numbers they r always 00
local $var1 = Hex(PixelGetColor(15, 5, $hwnd)) ; Only works in windowed mode, FullScreen return some random colors like 00FFFFFF or 00AAAAAA
$var1 = StringTrimLeft($var1,2) ; Removing first 2 numbers they r always 00
local $result[2] = [ $var, $var1 ]
return $result
EndFunc
Main script should before window is active and only then should try to GetPixelColor but that never happens, no matter what I do, i've tried WindowActivate still no result.
a) - What am I doing wrong ? Or may be there is another way to check if window is currently active ?
So at the moment I start script disabled, and when I activate window manually I press F11 to enable.
b) - PixelGetColor only works if game is running in Windowed mode, if it's a fullscreen mode result is unpredictable. Is there a way to make PixelGetColor work in fullscreen.
I've tried to run game x32, x64, DX9 and DX11 in different combinations Fullscreen result is just wrong.
ADDED:
Now While looks like this and that works :)
Thanks to Xenobeologist!!!
While 1
$hwnd = WinGetHandle('[Active]');
If ( $pause ) Then
If WinGetTitle($hwnd) <> $WinName Then
Pause()
ContinueLoop
EndIf
$res = GetPos();
ConsoleWrite ( StringFormat ("Result color: %s %s", $res[0], $res[1] ) )
Sleep (1000)
Else
If WinGetTitle($hwnd) = $WinName Then
Pause()
ContinueLoop
EndIf
EndIf
WEnd
a) is now solved
b) is still not solved. One more thing, topic of this question doesn't say anything bout this question, should add info bout this into the topic or it's better to start a new thread? a) was my main question, it would be prefect to solve b) as well but I can live without it. As far as I understood it's much more complicated. What do you think?
ADDED2:
As far as I understand problem b) can be solved by using more complex code. Here http://www.autohotkey.com/board/topic/63664-solved-imagesearch-failure-wdirectx-fullscreen-gamewin7/ was discussed pretty same problem. It's AHK and ImageSearch function, but im pretty sure that the reason I get wrong colours in fullscreen is the same. I don't want to complicate code that much and PrintScreen is too slow so I'll use windowed mode and wont be bothering with b).
Does this help?
#include <MsgBoxConstants.au3>
$handle = WinGetHandle('[Active]')
ConsoleWrite('!Title : ' & WinGetTitle($handle) & #CRLF)
ConsoleWrite('!Process : ' & WinGetProcess($handle) & #CRLF)
ConsoleWrite('!Text : ' & WinGetText($handle) & #CRLF)
Sleep(Random(10, 3000, 1))
If WinActive($handle) Then MsgBox($MB_SYSTEMMODAL, "", "WinActive" & #CRLF & "Scite ")

Autoit dead loop problem

In SSMS (SQL Server Management Studio), you have to middle-click the tab or press Ctrl+F4 to close the current editor tab. I want to use Autoit to make a shortcut Ctrl+w do the same thing. But I have problem with it. The following is the code. What I thought is, when the user press Ctrl+w, check if the user is in SSMS, if so, send Ctrl+F4 to close the current tab, if not, send Ctrl+w to let it go as normal. But the point is, if you send Ctrl+w, it will be captured again by Autoit, so dead loop occurs. I can't find a way to solve this problem. Anyone can help me with it?
Thanks.
HotKeySet("^w", "close_ssms_editor")
While 1
Sleep(200)
WEnd
; using Ctrl + w to close
; * editors in SSMS
; * editors in SSMS through Royal TS
Func close_ssms_editor()
$window_class_name = get_window_class_name(WinGetHandle(""))
If $window_class_name = "wndclass_desked_gsk" or $window_class_name = "WindowsForms10.Window.8.app.0.218f99c" Then
Send("^{F4}")
Else
Send("^w")
EndIf
EndFunc
Func get_window_class_name($nCtrl)
If Not IsHWnd($nCtrl) then $nCtrl = HWnd($nCtrl)
Local $struct = DllStructCreate("char[128]"),$classname = 0
$ret = DllCall("user32.dll","int","GetClassName","hwnd",$nCtrl,"ptr",DllStructGetPtr($struct),"int",DllStructGetSize($struct))
If IsArray($ret) Then
$classname = DllStructGetData($struct,1)
While (StringIsDigit(StringRight($classname,1)))
$classname = StringTrimRight($classname,1)
WEnd
EndIf
$struct =0
Return $classname
EndFunc
I found the solution.
; using Ctrl + w to close
; * editor in SSMS
; * editor in SSMS through Royal TS
Func close_ssms_editor()
$window_class_name = get_window_class_name(WinGetHandle(""))
If $window_class_name = "wndclass_desked_gsk" or $window_class_name = "WindowsForms10.Window.8.app.0.218f99c" Then
Send("^{F4}")
Else
HotKeySet("^w")
Send("^w")
HotKeySet("^w", "close_ssms_editor")
EndIf
EndFunc

ASP.NET: Execute an external executable doesn't work

I need help with the code below.
I try to convert a AutoCAD file from the format dwg to the format dwf.
Then, the dwf file is downloaded and opened on the client computer using a java applet.
The command used to convert the dwg file on the command-line is:
C:\inetpub\wwwroot\COR-Basic\cadviewer\converter\ax2008.exe -i="C:\inetpub\wwwroot\test\container\DU38_EG00_070116.dwg" -o="C:\inetpub\wwwroot\COR-Basic\cadviewer\files\DU38_EG00_070116.dwf" -f=dwf -model -text
this works when I enter the command text in cmd.exe.
But when I call it from my asp.net application, it only starts the process, but the process never ends...
I've tried adding an additional user, have given this user full permission, and full permissions on wwwroot, but it still doesn't work.
Anybody knows what I'm doing wrong, or how I could do it in another way?
If System.IO.File.Exists(strDWGlocation) Then
Dim psiProcessSettings As Diagnostics.ProcessStartInfo = New Diagnostics.ProcessStartInfo
psiProcessSettings.FileName = strApplicationPath
psiProcessSettings.Arguments = " -i=""" & strDWGlocation & """ -o=""" & strOutputLocation & """ -f=dwf -model -text"
'ST-LAPTOP\converter
psiProcessSettings.UserName = "converter"
psiProcessSettings.Password = secureString
'StefanSteiger.Debug.MsgBox("Input location:" + strDWGlocation)
'StefanSteiger.Debug.MsgBox("Output location:" + strOutputLocation)
Response.Write("<h1>Argument1: " + psiProcessSettings.Arguments + "</h1>")
Response.Write("<h1>Pfad1: " + psiProcessSettings.FileName + "</h1>")
'psiProcessSettings.RedirectStandardInput = True
psiProcessSettings.RedirectStandardError = True
psiProcessSettings.RedirectStandardOutput = True 'Redirect output so we can read it.
psiProcessSettings.UseShellExecute = False 'To redirect, we must not use shell execute.
'psiProcessSettings.CreateNoWindow = True ' don't create a window
Dim pConverterProcess As Diagnostics.Process = New Diagnostics.Process
pConverterProcess = Diagnostics.Process.Start(psiProcessSettings) 'Create the process.
pConverterProcess.Start() 'Execute the process.
'Response.Write("<h1>" + Replace(pConverterProcess.StandardOutput.ReadToEnd(), vbCrLf, "<BR />") + "</h1>") 'Send whatever was returned through the output to the client.
'pConverterProcess.CancelOutputRead()
'pConverterProcess.CancelErrorRead()
'pConverterProcess.StandardInput.Close()
'Wait for the process to end.
'pConverterProcess.WaitForExit()
pConverterProcess.Close()
'Dim iExitCode As Integer = pConverterProcess.ExitCode()
pConverterProcess.Dispose()
Else
MyNamespace.Debug.MsgBox("No such file.")
End If
This is my code that does a similar thing, and it works!
process.StartInfo.FileName = toolFilePath;
process.StartInfo.Arguments = parameters;
process.StartInfo.UseShellExecute = false; // needs to be false in order to redirect output
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardInput = true; // redirect all 3, as it should be all 3 or none
process.StartInfo.WorkingDirectory = Path.GetDirectoryName(toolFilePath);
process.StartInfo.Domain = domain;
process.StartInfo.UserName = userName;
process.StartInfo.Password = decryptedPassword;
process.Start();
output = process.StandardOutput.ReadToEnd(); // read the output here...
process.WaitForExit(); // ...then wait for exit, as after exit, it can't read the output
returnCode = process.ExitCode;
process.Close(); // once we have read the exit code, can close the process
Why have you commented out the WaitForExit()?
You could try setting EnableRaisingEvents to true as well.
In my experience, the Process class is quite difficult to work with when reading the standard output, try removing any code that attempts to redirect and read output

Resources