Jump to content

Transfer information fom batch into AutoIT


Go to solution Solved by sg08234,

Recommended Posts

I have to transfer information from a batchfile into an AutoIT-EXE.

My current work via a text file. Setting an environment variable in batch via SET ... and using EnvUpdate / EnvGet in AutoIT does not work: EnvGet always returns the value at start of the EXE.

Is there an "elegant" way of transferring information from a batchfile into AutoIT?

Many thanks
Michael

Link to post
Share on other sites

Many thanks! In the meantime I already found your solution and started testing. But the batch (started as admin)

set TEST=Start
".....\EnvVar.exe"

with

Local $result1
    Local $result2

    _EnvVarRefresh()
    $result1=EnvGet("TEST")
    $result2=_EnvVarGet("TEST", 0)
    MsgBox ($MB_OK,"_R_TEST", "EnvGet: " & $result1 & " - _EnvVarGet: " & $result2)

    plus your code

in EnvVar.au3 only gives me "EnvGet: Start - _EnvVarGet: <empty>".

What's wrong? Many thanks again - Michael

Link to post
Share on other sites

With _EnvVarGet ("xxx", 0) you're going to return an array not a string, try using one of the following instead:

;~ If this is a machine environment variable
 $result2=_EnvVarGet("TEST", 2)
 
 ;~ If this is a user environment variable
  $result2=_EnvVarGet("TEST", 3)

 

Link to post
Share on other sites

Thanks again - but neither 1,2,3,or 4 work ($result2 stays empty):

  • What can be wrong?
  • Do I need _EnvVarRefresh()?
  • To be honest: I feel familiar with Process Environment Variables (type 1 - DOS SET-command) and System Environment Variables (type 2 - Set by system control). How can I manage type 3 and 4?

My mini test-bat (started as admin):
 

set TEST=Start
"D:\Documentation\roc-k-IT - Allgemein\Software\EnvVar\EnvVar.exe"

pause

My complete EnvVar.au3:

; Environment-Variable lesen, schreiben, löschen sowie Refresh Environment
; https://www.autoitscript.com/forum/topic/206921-windows-environment-variables/?tab=comments
;~ #RequireAdmin ;~ Required when writing to System Environment Variable

#RequireAdmin ;~ Required when writing to System Environment Variable
#include <Array.au3>
#include <MsgBoxConstants.au3>


; #VARIABLES# ===================================================================================================================
Global $MAX_VALUE_NAME = 1024
Global $HWND_BROADCAST = 0xffff
Global $WM_SETTINGCHANGE = 0x001A
Global $SMTO_ABORTIFHUNG = 0x0002
Global $SMTO_NORMAL = 0x0000
Global $MSG_TIMEOUT = 5000
Local $result1
Local $result2

;~ ============================== Begin Example ===============================
; While 1
    _EnvVarRefresh()
    $result1=EnvGet("TEST")
    $result2=_EnvVarGet("TEST", 4)
    MsgBox ($MB_OK,"TEST", "EnvGet: " & $result1 & " - _EnvVarGet: " & $result2)
;   Sleep (3000)
; WEnd
;~ If Machine Environment Variable "LSFORCEHOST" = "192.168.1.189" Then Change it to "license01.local"
    If _EnvVarGet("LSFORCEHOST", 2) = "192.168.1.189" Then _EnvVarSet("LSFORCEHOST", "license01.local", 2)
;~ If Machine Environment Variable "LSHOST" = "192.168.1.189" Then Change it to "license01.local"
    If _EnvVarGet("LSHOST", 2) = "192.168.1.189" Then _EnvVarSet("LSFORCEHOST", "license01.local", 2)
;~ If Machine Environment Variable "SPSS_LMHOST" = "192.168.1.189" Then Change it to "license01.local"
    If _EnvVarGet("SPSS_LMHOST", 2) = "192.168.1.189" Then _EnvVarSet("LSFORCEHOST", "license01.local", 2)
;~ =============================== End Example ================================

;~ $_iEnvType = 0 - Returns Enviroment Variables from all profiles
;~ $_iEnvType = 1 = Process Enviornment Variable
;~ $_iEnvType = 2 = System Enviornment Variable
;~ $_iEnvType = 3 = User Enviornment Variable
;~ $_iEnvType = 4 = Volatile Enviornment Variable

Func _EnvVarGet($_sEnvVarGet, $_iEnvVarType = 3, $_bExpVarValue = True)
    Local $iExpandEnvStrings = Opt("ExpandEnvStrings")
    Local $sEnvVarValue, $aEnvVarValue[5] = [4]
    Local $oEnvVarType, $aEnvVarType[5] = [4, "PROCESS", "SYSTEM", "USER", "VOLATILE"]
    Local $oWshShell = ObjCreate("WScript.Shell")
    Switch $_iEnvVarType
        Case 0
            If $_bExpVarValue == True Then Opt("ExpandEnvStrings", 1)
            For $i = 1 To $aEnvVarType[0]
                $oEnvVarType = $oWshShell.Environment($aEnvVarType[$i])
                $aEnvVarValue[$i] = $oEnvVarType($_sEnvVarGet)
            Next
            Opt("ExpandEnvStrings", $iExpandEnvStrings)
            Return $aEnvVarValue
        Case 1 To 4
            If $_bExpVarValue == True Then Opt("ExpandEnvStrings", 1)
            $oEnvVarType = $oWshShell.Environment($aEnvVarType[$_iEnvVarType])
            $sEnvVarValue = $oEnvVarType($_sEnvVarGet)
            Opt("ExpandEnvStrings", $iExpandEnvStrings)
            Return $sEnvVarValue
        Case Else
            Return SetError(1, 0, "")
    EndSwitch
EndFunc

;~ $_iEnvType = 0 - Sets Enviroment Variable for all profiles
;~ $_iEnvType = 1 = Set Process Enviornment Variable
;~ $_iEnvType = 2 = Set System Enviornment Variable
;~ $_iEnvType = 3 = Set User Enviornment Variable
;~ $_iEnvType = 4 = Set Volatile Enviornment Variable
Func _EnvVarSet($_sEnvVarName = "", $_sEnvVarValue = "", $_iEnvVarType = 3)
    Local $oEnvVarType, $aEnvVarType[5] = [4, "PROCESS", "SYSTEM", "USER", "VOLATILE"]
    Local $oWshShell = ObjCreate("WScript.Shell")
    Switch $_iEnvVarType
        Case 0
            For $i = 1 To $aEnvVarType[0]
                $oEnvVarType = $oWshShell.Environment($aEnvVarType[$i])
                $oEnvVarType($_sEnvVarName) = $_sEnvVarValue
            Next
        Case 1 To 4
            $oEnvVarType = $oWshShell.Environment($aEnvVarType[$_iEnvVarType])
             $oEnvVarType($_sEnvVarName) = $_sEnvVarValue
        Case Else
            Return SetError(1)
    EndSwitch
    _EnvVarRefresh()
    If @error Then Return SetError(1)
EndFunc

;~ $_iEnvType = 0 - Returns Enviroment Variables from all profiles
;~ $_iEnvType = 1 = Process Enviornment Variable
;~ $_iEnvType = 2 = System Enviornment Variable
;~ $_iEnvType = 3 = User Enviornment Variable
;~ $_iEnvType = 4 = Volatile Enviornment Variable

Func _EnvVarDelete($_sEnvVarName = "", $_iEnvVarType = 3)
    Local $oEnvVarType, $aEnvVarType[5] = [4, "PROCESS", "SYSTEM", "USER", "VOLATILE"]
    Local $oWshShell = ObjCreate("WScript.Shell")
    Switch $_iEnvVarType
        Case 0
            For $i = 1 To $aEnvVarType[0]
                $oEnvVarType = $oWshShell.Environment($aEnvVarType[$i])
                $oEnvVarType.Remove($_sEnvVarName)
            Next
        Case 1 To 4
            $oEnvVarType = $oWshShell.Environment($aEnvVarType[$_iEnvVarType])
             $oEnvVarType.Remove($_sEnvVarName)
        Case Else
            Return SetError(1, 0, "")
    EndSwitch
    _EnvVarRefresh()
    If @error Then Return SetError(1)
EndFunc

Func _EnvVarRefresh()
    ; http://msdn.microsoft.com/en-us/library/ms644952%28VS.85%29.aspx
    $iRet2 = DllCall("user32.dll", "lresult", "SendMessageTimeoutW", _
            "hwnd", $HWND_BROADCAST, _
            "dword", $WM_SETTINGCHANGE, _
            "ptr", 0, _
            "wstr", "Environment", _
            "dword", $SMTO_ABORTIFHUNG, _
            "dword", $MSG_TIMEOUT, _
            "dword_ptr*", 0)

    If $iRet2[0] = 0 Then Return SetError(1)
EndFunc


 

Link to post
Share on other sites
On 10/12/2022 at 8:10 AM, sg08234 said:

Setting an environment variable in batch via SET ... and using EnvUpdate / EnvGet in AutoIT does not work: EnvGet always returns the value at start of the EXE.

EnvGet() works fine in the example below.  Maybe I don't understand what you mean by "EnvGet always returns the value at start of the EXE".  Is an external process changing the value of the environment variable(s) during the execution of the AutoIt script?  If so, please show a working example script, with EnvGet() not working, that includes the actual output and describe what the expected output should be.

Example (compiled to a3_temp.exe):

#pragma compile(Console, true)

ConsoleWrite('EnvGet("TEST") = ' & EnvGet("TEST") & @CRLF)
ConsoleWrite('EnvGet("TEMP") = ' & EnvGet("TEMP") & @CRLF)

MsgBox(0, "", 'EnvGet("TEST") = ' & EnvGet("TEST") & @CRLF & 'EnvGet("TEMP") = ' & EnvGet("TEMP"))

Batch file:

@echo off

Set test=
a3_temp.exe

set test=This is a test
a3_temp.exe

set test=This is a different value
a3_temp.exe

Output: (StdOut generated by a3_temp, from 3 executions in the batch script, after setting environment variable "TEST" 3 times)

EnvGet("TEST") =
EnvGet("TEMP") = C:\Temp
EnvGet("TEST") = This is a test
EnvGet("TEMP") = C:\Temp
EnvGet("TEST") = This is a different value
EnvGet("TEMP") = C:\Temp

 

On 10/12/2022 at 8:10 AM, sg08234 said:

Is there an "elegant" way of transferring information from a batchfile into AutoIT?

No, there's not an "elegant" solution, there are probably many.

A better question is why try to integrate batch scripts AND AutoIt scripts?  What are you doing in your batch script that can't be done in an AutoIt script?  That's a rhetorical question.  The obvious answer is nothing.  My point is that, in general, there's no need to pass info from a batch script to an AutoIt script when you can do it all in an AutoIt script.  Just convert that batch script to an AutoIt script.

If you must pass info from batch scripts to AutoIt scripts, then you could pass the information in numerous ways: flat file (plain text, xml, json, custom format), INI file, database, environment variables, or command line parameters (to name a few).  What types of information need to be passed (binary, text, arrays, groups or sequences of data), how much information needs to be passed, and whether you need to keep and maintain the passed data, are all questions that will help you determine what may be the best or most "elegant" solution.  Only you can answer what is "elegant" to you.

Elegance, like beauty, is in the eye of the beholder.  What one person considers elegant, another may consider crude and unrefined .  ;)

Edited by TheXman
Link to post
Share on other sites

Thanks!

To complete the desription of me problem: I have a  complex system for checking clients and managing backups. For historical reasons this system is batch-based and I can't imagen the effort of migrating it to AutoIt (or Powershell). One of the functions of this system is informing the user about running backup-jobs; I implemented this with an  AutoIT-msgbox-skript running parallel as a task.

Thus I need transformation of information (e.g. status of backup) from the batch into AutoIT. Currently I use plain text files for this purpose but this does not seems to be an elegant (better: smooth) way of implementation and it creates possible locking problems (access via two unsynchronized processes).

My idea was to use environment variables set by the batch system but the AutoIT-task does not recognize any changes of the values of the environment variables.

Thus I though I might need EnvUpdate (not tested yet) or system environment variables (not tested yet). For whatever reasons I also did not succeed in using Subz' UDF (see above).

Michael

Link to post
Share on other sites

I solved my "problem" this way:

  • Using setx <var> <value> /M in my batch system
  • Using EnvVarGet("<var>", 2) in the AutoIT-task
  • REG delete "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /F /V <var> for deleting the system variable

For me this seems to be a smooth enough way of transferring information between different tasks.

Many thanks to all who helped - especially to Subz for his UDF.
Michael

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...