Sign in to follow this  
Followers 0
centralpressure

DriveGetDrive as variable

12 posts in this topic

Newbie hacking his way through life...

I am trying to run a script saved to CD on different computers (upwards of 90). Some have the CD-ROM as D: and others as E:.

I tried:

$drive = DriveGetDrive( "CDROM" )

run($drive & '\installscor.exe')

Nothing happens when I run the script. Obviously I am making this too simple and am missing something. Do I have to declare the variable in order to make this work?

Thanks for the help.

Share this post


Link to post
Share on other sites



DriveGetDrive returns an array, incase there are several drives, if you don't specify the element in the array, it won't know what to do.

$drive = DriveGetDrive( "cdrom" )
If NOT @error Then
     For $i = 1 to $drive[0]    ;$drive[0] has the number of drives
    If FileExists($drive[$i]&'\installscor.exe') = 1 Then 
        ExitLoop
    Else If $i= $drive[0] Then
        MsgBox(16,"Error","Could not find CD drive with installscor.exe")
        Exit
    EndIf
    
    Next
EndIf

run($drive[$i] & '\installscor.exe')

If you're running our script right off the CD, look at @scriptdir

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Here is some code from scriptomatic (search this it rocks) that will pull what you need from WMI

; Generated by AutoIt Scriptomatic

$wbemFlagReturnImmediately = 0x10
$wbemFlagForwardOnly = 0x20
$colItems = ""
$strComputer = "localhost"

$Output=""
$Output = $Output & "Computer: " & $strComputer  & @CRLF
$Output = $Output & "==========================================" & @CRLF
$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
$colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_CheckCheck", "WQL", _
                                          $wbemFlagReturnImmediately + $wbemFlagForwardOnly)

If IsObj($colItems) then
   For $objItem In $colItems
      $Output = $Output & "Check: " & $objItem.Check & @CRLF
      $Output = $Output & "Location: " & $objItem.Location & @CRLF
      if Msgbox(1,"WMI Output",$Output) = 2 then ExitLoop
      $Output=""
   Next
Else
   Msgbox(0,"WMI Output","No WMI Objects Found for class: " & "Win32_CheckCheck" )
Endif

you would just need to make $drive = $objItem.Location (assuming that the computer only has one optical drive)

Edited by dot45

Share this post


Link to post
Share on other sites

DriveGetDrive returns an array, incase there are several drives, if you don't specify the element in the array, it won't know what to do.

$drive = DriveGetDrive( "cdrom" )
If NOT @error Then
     For $i = 1 to $drive[0]    ;$drive[0] has the number of drives
    If FileExists($drive[$i]&'\installscor.exe') = 1 Then 
        ExitLoop
    Else If $i= $drive[0] Then
        MsgBox(16,"Error","Could not find CD drive with installscor.exe")
        Exit
    EndIf
    
    Next
EndIf

run($drive[$i] & '\installscor.exe')

If you're running our script right off the CD, look at @scriptdir

Thanks for response! I am still trying to understand exactly what is going on.

What is the $i = 1 to $drive[0] accomplishing? Is this just declaring that there is a CD drive and the active location is [0]?

I rather learn this and have the "AH-HA" moment than continually badger people on forums.

Thanks.

Share this post


Link to post
Share on other sites

The quickest and easiest way to do what you are trying to do:

Thanks to SmOke_N for this one Posted Image

$drive = _ScriptDrive()

Func _ScriptDrive()
    Return StringRegExpReplace(@ScriptDir, "^(\w+:)(.*?\z)|^((?:\\\\|//).*?)([\\/].*?\z)", "\1\3")
EndFunc

noted, and saved :D

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

The quickest and easiest way to do what you are trying to do:

Thanks to SmOke_N for this one :D

$drive = _ScriptDrive()

Func _ScriptDrive()
    Return StringRegExpReplace(@ScriptDir, "^(\w+:)(.*?\z)|^((?:\\\\|//).*?)([\\/].*?\z)", "\1\3")
EndFunc

I found this to be 10x quicker:

$scriptdrive=StringLeft(@ScriptDir,2)

And of course this will only work if the program you're looking for is on the same disc as the autoit script.

Edited by TurionAltec

Share this post


Link to post
Share on other sites

I found this to be 10x quicker:

$scriptdrive=StringLeft(@ScriptDir,2)

And of course this will only work if the program you're looking for is on the same disc as the autoit script.

The problem with that is if you are running from a file share like UNC. The one from SmOke_N will work in all scenarios.

If I ran the script from "\\machine\folder\file.exe", your script would say the script drive is "\\"

Share this post


Link to post
Share on other sites

Thanks for response! I am still trying to understand exactly what is going on.

What is the $i = 1 to $drive[0] accomplishing? Is this just declaring that there is a CD drive and the active location is [0]?

I rather learn this and have the "AH-HA" moment than continually badger people on forums.

Thanks.

DriveGetDrive() will create an array, and store it in the variable $drive. An array is several different pieces of data grouped into the same variable, where the number in the square brackets can be thought of as the "address", or more commonly "subscript" or "index". DriveGetDrive only has a 1 dimensional array (one subscript), but 2, and 3 dimensional arrays exist.

The size of the array depends on the number of optical drives found:

1 drive, 2 items will be in the array,

$drive[0]= 2

$drive[1]="d:"

3 drives, 2 items will be in the array.

$drive[0]=3

$drive[1]="d:"

$drive[2]="e:"

$drive[3]="f:"

DriveGetDrive will set the value of $drive[0] to equal the number of drives found, which makes it easier to process later, because we know how many drives it found.

"For $i = 1 to $drive[0]" is a For next loop (check help: For...To...Step...Next )

In this loop, it will check every CD drive for the file. Once it finds the drive with the file, it will exit the loop (using Exitloop)

The variable $i will be set to 1, it will run the commands in the loop until it reaches "Next", increment the value of $i and run it again.

Notice we use the value of $i in the subscript of the array.

The loop will terminate at "Next" if $i is equal to $drive[0] (once we have checked all the drives).

For-next loops makes it easy to process the same commands on every element in an array.

If your script is in the same directory as the file you're looking for you won't need any of this, but be better off with @scriptdir, but this is good background information on arrays.

Share this post


Link to post
Share on other sites

The problem with that is if you are running from a file share like UNC. The one from SmOke_N will work in all scenarios.

If I ran the script from "\\machine\folder\file.exe", your script would say the script drive is "\\"

The code you gave seems to return \\server in that scenario, which may or may not be of any use depending on the purpose of the code. I'd think it'd be more useful if it at least gave \\server\share because that's the root of the share.

Of course if everything is supposed to be in the same directory (or subdir there of) as the scriptfile, you can just use @scriptdir, and it will work in all cases.

Share this post


Link to post
Share on other sites

Good point, though I think SmOke_N made it return "\\server" on purpose since that would be the closest equivalent to the root of the drive.

Share this post


Link to post
Share on other sites

Here is some code from scriptomatic (search this it rocks) that will pull what you need from WMI

; Generated by AutoIt Scriptomatic

$wbemFlagReturnImmediately = 0x10
$wbemFlagForwardOnly = 0x20
$colItems = ""
$strComputer = "localhost"

$Output=""
$Output = $Output & "Computer: " & $strComputer  & @CRLF
$Output = $Output & "==========================================" & @CRLF
$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
$colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_CheckCheck", "WQL", _
                                          $wbemFlagReturnImmediately + $wbemFlagForwardOnly)

If IsObj($colItems) then
   For $objItem In $colItems
      $Output = $Output & "Check: " & $objItem.Check & @CRLF
      $Output = $Output & "Location: " & $objItem.Location & @CRLF
      if Msgbox(1,"WMI Output",$Output) = 2 then ExitLoop
      $Output=""
   Next
Else
   Msgbox(0,"WMI Output","No WMI Objects Found for class: " & "Win32_CheckCheck" )
Endif

you would just need to make $drive = $objItem.Location (assuming that the computer only has one optical drive)

Be careful recommending code that involves the use of WMI.

WMI runs as a service and it's a service that is often disabled in a business environment. It's okay if the service is installed AND you know how to start it at the beginning of the script and then set it to it's previous status when you are finished.


George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

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  
Followers 0