Jump to content

Recommended Posts

Inspired by this topic, the ability to execute any line of AutoIt3 code.

You can even make calculations!

Requirements:

- AutoIt v3.1.0.0

Edit:

- Added _Calc UDF

- Recreated the _Calc UDF because it only returned integers

- _Execute now wraps the Exit function around the code (Thanks, Sven)

- Added example of an advanced math expression

- optimized _Execute function; Reduced code from 7 lines to 3 to 2

- added optional "delete temp file" parameter in the _Calc UDF

- Added RunAsSet so you can run AutoIt3 functions with Admin credentials. Cases: RegWrite, FileDelete, INIWrite

In previous versions I converted quotes. Won't do that anymore.

I now only double the double quotes.

The syntax for the _Execute function:

_Execute(<Line of code>, [<Username>, [<Domain>, [<Password>, [<Options>]]]]
<Line of code>   AutoIt3 function. You can put functions in functions. For instance: 'MsgBox(64, "Test", StringTrimLeft(@UserName, 3) )'
<Username>   [optional] (Default is current username) Username of an (domain) admin account to run the function with. Useful for running under restricted accounts.
<Domain>     [optional] (Default is current computername) Domain or computername.
<Password>   [optional] Password of specified user account.
<Options>    [optional] Options:
0 = profile not loaded (HKEY_CURRENT_USER not changed)
1 = profile loaded (and loaded into HKEY_CURRENT_USER)
2 = the credentials are NOT used locally and are only used when accessing the network.

Dim $val

;Example 1
$val = _Execute("5 + (5 * 5)")            ;Only integers. I recommend _Calc for math exp[b][/b]ressions
MsgBox(64, "Example 1", "$Val: " & @CRLF & $Val)

;Example 2
_Execute('MsgBox(64, "Example 2", "5 + (5 * 5) = " & ' & 5 + (5 * 5) & ')')

;Example 3
_Execute('MsgBox(64, "Example 3", "Just some text, y''know.")')

;Example 4
_Execute("MsgBox(64, 'Example 4', 'He shouted: ""What''s going on here?!""')")

;Example 5
_Execute('MsgBox(64, "Example 5", "He shouted: ''What''s going on here?!''")')

;Example 6
_Execute('MsgBox(64, "Example 6", "@UserName: " & @UserName)', "Administrator")

;Finished...

$val = 0
Exit

Func _Execute($LineofCode, $rUsername = "", $rDomain = "", $rPassword = "", $rOpts = 1)
   Local $PrevSett, $RetVal, $RunAs = 0
   $LineofCode = StringReplace($LineofCode, '"', '""')
   If @NumParams > 1 Then
      If @OSVersion = "WIN_XP" Or @OSVersion = "WIN_2000" Then $RunAs = 1
   EndIf
   If $RunAs Then
      If $rUsername = "" Then $rUsername = @UserName
      If $rDomain = "" Then $rDomain = @ComputerName
      If $rPassword = "" Then
         $rPassword = InputBox('_Execute', 'Enter the password for username "' & $rUsername & '"')
         If @error Then Return 1
      EndIf
      $PrevSett = Opt ("RunErrorsFatal", 0)
      RunAsSet($rUsername, $rDomain, $rPassword, $rOpts)
   EndIf
   If StringLeft($LineofCode, 2) = "If" And StringInStr($LineofCode, "Then") Then
      $RetVal = RunWait(@AutoItExe & ' /c "' & $LineofCode & '"', @WorkingDir)
   Else
      $RetVal = RunWait(@AutoItExe & ' /c "Exit(' & $LineofCode & ')"', @WorkingDir)
   EndIf
   If @error Then
      MsgBox(16, "_Execute Error", "Error: Incorrect password or unknown username.")
      Return 1
   ElseIf $RunAs Then
      RunAsSet()
      Opt ("RunErrorsFatal", $PrevSett)
   EndIf
   Return $RetVal
EndFunc  ;==>_Execute

Dim $val, $Formula

$val = _Calc("100 / 3")
MsgBox(64, "Example 1", "$val: " & $val)

$val = _Calc("1 / 2")
MsgBox(64, "Example 2", "$val: " & $val)

$val = _Calc("30 * 2 / (8 - 4) / 2")
MsgBox(64, "Example 3", "$val: " & $val)

$Formula = "(Log(1000+5*6)*Exp(ACos(5))/Sqrt(8))*(Sin(1)*Cos(1)*Tan(1))/(5*(20-7+Mod(20,35)))"

; calculate using _Calc (regular style)
$val = _Calc((Log(1000+5*6)*Exp(ACos(5))/Sqrt(8))*(Sin(1)*Cos(1)*Tan(1))/(5*(20-7+Mod(20,35))))
MsgBox(64, "Example 4", "calculate using _Calc (regular style)" & @CRLF & $Formula & " = " & @CRLF & $val)

; calculate using _Calc (as a string)
$val = _Calc("(Log(1000+5*6)*Exp(ACos(5))/Sqrt(8))*(Sin(1)*Cos(1)*Tan(1))/(5*(20-7+Mod(20,35)))")
MsgBox(64, "Example 5", "calculate using _Calc (as a string)" & @CRLF & '"' & $Formula & '" = ' & @CRLF & $val)

;Finished...

$val = 0
$Formula = 0
EXIT

Func _Calc($Expr, $Del = 0)
   Local $Result
   _Execute('INIWrite(@TempDir & "\Calc.tmp", "Calculation", "Result", ' & $Expr & ')')
   $Result = IniRead(@TempDir & "\Calc.tmp", "Calculation", "Result", 0)
   If $Del Then FileDelete(@TempDir & "\Calc.tmp")
   Return $Result
EndFunc  ;==>_Calc

Func _Execute($LineofCode, $rUsername = "", $rDomain = "", $rPassword = "", $rOpts = 1)
   Local $PrevSett, $RetVal, $RunAs = 0
   $LineofCode = StringReplace($LineofCode, '"', '""')
   If @NumParams > 1 Then
      If @OSVersion = "WIN_XP" Or @OSVersion = "WIN_2000" Then $RunAs = 1
   EndIf
   If $RunAs Then
      If $rUsername = "" Then $rUsername = @UserName
      If $rDomain = "" Then $rDomain = @ComputerName
      If $rPassword = "" Then
         $rPassword = InputBox('_Execute', 'Enter the password for username "' & $rUsername & '"')
         If @error Then Return 1
      EndIf
      $PrevSett = Opt ("RunErrorsFatal", 0)
      RunAsSet($rUsername, $rDomain, $rPassword, $rOpts)
   EndIf
   If StringLeft($LineofCode, 2) = "If" And StringInStr($LineofCode, "Then") Then
      $RetVal = RunWait(@AutoItExe & ' /c "' & $LineofCode & '"', @WorkingDir)
   Else
      $RetVal = RunWait(@AutoItExe & ' /c "Exit(' & $LineofCode & ')"', @WorkingDir)
   EndIf
   If @error Then
      MsgBox(16, "_Execute Error", "Error: Incorrect password or unknown username.")
      Return 1
   ElseIf $RunAs Then
      RunAsSet()
      Opt ("RunErrorsFatal", $PrevSett)
   EndIf
   Return $RetVal
EndFunc  ;==>_Execute
Edited by SlimShady
Link to post
Share on other sites

I love this rec. functions, they are something special, no end for an script,

SUPPERRR REALLY

Autoit.es - Foro Autoit en EspaƱol Word visitors Image Clustrmap image: - Football Spanish team - Spanish team: Casillas, Iniesta, Villa, Xavi, Puyol, Campdevilla, etc..Programando en Autoit+Html - Coding Autoit-Html - Arranca programas desde Internet - Preprocesador de Autoit a http
Link to post
Share on other sites

Sure, why not. But AFAIK you can't use any formula. This IS a problem.

<{POST_SNAPBACK}>

Yes, you can!

I added my version to the example "pacman" made.

My _Calc can solve any Math expression that AutoIt can.

My _Calc uses AutoIt to solve the Math expression.

That's why it's smaller and faster.

Attached is the updated test/compare script.

Link to post
Share on other sites

I don't care that a 26 byte file is left behind.

If you really care, you change it.

Here's an example of formula.

$x = 5
$y = 6
$z = 8
$Exp[b][/b]ression = "3*x+y+z"
$Exp[b][/b]ression = StringReplace($Exp[b][/b]ression, "x", $x)
$Exp[b][/b]ression = StringReplace($Exp[b][/b]ression, "y", $y)
$Exp[b][/b]ression = StringReplace($Exp[b][/b]ression, "z", $z)

$val = _Calc($Exp[b][/b]ression)
MsgBox(64, "Example 1", "$val: " & $val)

Func _Calc($Expr)
   _Execute('INIWrite(@TempDir & "\Calc.tmp", "Calculation", "Result", ' & $Expr & ')')
   Return INIRead(@TempDir & "\Calc.tmp", "Calculation", "Result", 0)
EndFunc

Func _Execute($LineofCode)
   Local $RetVal
   Local $NewLineofCode = $LineofCode
   $NewLineofCode = StringReplace($NewLineofCode, '""', '"')
   $NewLineofCode = StringReplace($NewLineofCode, "'", "''")
   $NewLineofCode = StringReplace($NewLineofCode, '"', "'")
   $RetVal = RunWait(@AutoItExe & ' /c "' & $NewLineofCode & '"', @SystemDir)
   Return $RetVal
EndFunc
Link to post
Share on other sites

I meant my own operators. Like the factorial or ArcCoTan() or Catalan()

About don't caring because the file is small I think is a deprecable attitude. would you happy if someone leave some ash in you home just because it is small and harmless?

Link to post
Share on other sites

Hello SlimShady,

Very good work!

Just a suggestion, you could incorporate the Exit() statement INSIDE your _Execute function, so the users don't have to think whether they want a value immediately returned or using INIwrite. It won't affect the existing results:

Func _Execute($LineofCode)
;
; _Execute function written by: SlimShady
; See: http://www.autoitscript.com/forum/index.php?showtopic=7607

   Local $RetVal
   Local $NewLineofCode = $LineofCode
   $NewLineofCode = StringReplace($NewLineofCode, '""', '"')
   $NewLineofCode = StringReplace($NewLineofCode, "'", "''")
   $NewLineofCode = StringReplace($NewLineofCode, '"', "'")
   $RetVal = RunWait(@AutoItExe & ' /c "Exit(' & $NewLineofCode & ')"', @SystemDir)
   Return $RetVal
EndFunc

Now both the _Execute("1+2+3") for integers and the _Execute("INIWrite...) for floats will work.

Just a sidenote: I had a similar problem with my scripts requiring a 'sort of' _Execute() or Eval() function. But I couldn't use the 'call-AutoIT.exe-again' solution because I had an average of 210 evaluations to resolve.

So I rewrote my version AutoIt.EXE; now it can do Eval("expression") :-)

Regards,

-Sven

Link to post
Share on other sites

I see your point! Good idea.

Yesterday I was searching for a new editor.

While I was testing the editors I discovered that AutoIt also accepts functions in a function using the /C switch.

What I didn't know:

- Return and Exit both work as functions. eg: Exit(), Return()

Link to post
Share on other sites

I meant my own operators. Like the factorial or ArcCoTan() or Catalan()

About don't caring because the file is small I think is a deprecable attitude. would you happy if someone leave some ash in you home just because it is small and harmless?

<{POST_SNAPBACK}>

1. If we could run an AutoIt script using /C switch...

I'll try this out in a moment.

Nope doesn't work.

This is what I used:

$TestScript = @TempDir & "\File.au3"
FileWrite($TestScript, 'MsgBox(64, "Test", "Yes! AutoIt runs scripts using the /C switch!")')
Run(@AutoItExe & ' /c ' & $TestScript, @WorkingDir)
FileDelete($TestScript)

I get "Unable to parse line".

2. I understand what you mean. BUT there's a difference.

Many installers don't clean up the %TEMP% directory.

I just accept it. Because the installers don't talk back, unlike anyone who leaves ash on my floor.

Edit:

- Updated the functions. See first post.

Edited by SlimShady
Link to post
Share on other sites

I knew I could shorten my _Execute function.

- I removed all the StringReplace functions

- Did some tests with single quotes and double quotes

Discovery:

When using double quotes in the function call, it would delete them on run.

Solution:

I double the "double quotes" in the _Execute function.

I added two function calls I used, as examples in the 1st post.

Link to post
Share on other sites

2. I understand what you mean. BUT there's a difference.

Many installers don't clean up the %TEMP% directory.

<{POST_SNAPBACK}>

There is no difference. If they do wrong I think it is not a good idea doing the same. Many programs install malwares, do yours should too?

Anyway, it is becomed very nice! :idiot: Good work.

Link to post
Share on other sites

Well... I still use PacMan algorithm because I need multibase calculations. So I need formulas like

ToHex(255) that brings back FF or FrHex(FF) that returns 255 and some calculation that are not made by Autoit automatically like calculation of the Catalan number or the ArcCoTan() of an angle.

Link to post
Share on other sites

You didn't gave me an example of an expression (that's what I meant).

So I made a small thing.

Something like the following?

If not then give me an example formula.

$val1 = 255
$angle = 35;degrees. Not sure what kind of value you'll use
$res = _Execute(_CalcRPN('ToHex('& $val1 & ')') - ArcCoTan($angle))
MsgBox(64, "Test", "$res: " & $res)

Func _Execute ($LineofCode)
   $LineofCode = StringReplace($LineofCode, '"', '""')
   Return RunWait(@AutoItExe & ' /c "Exit(' & $LineofCode & ')"', @WorkingDir)
EndFunc
Edited by SlimShady
Link to post
Share on other sites

Here an example

Func Fact($iNum)
   Local $c, $iO = 1
   $iNum = Abs(Int($iNum))
   
   For $c = 2 to $iNum
      $iO = $iO * $c
   Next
   
   Return $iO
EndFunc

This little function return the Factorial of the number called. Since AutoIt automatically can't calculate this operation. It won't understand a line that keeps Factorial() inside... Can it? I am missing something?

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
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...