Jump to content

About extracting content from strings


Go to solution Solved by Nine,

Recommended Posts

Posted

I have a string that looks like this:

C:\>for /f %1 in ( a.txt ) do @dir %1Recovery /a 2> nul
 Volume in drive \\?\Volume{eea3b237-18e9-4572-a656-ba4f3c6030a6} has no label.
 Volume Serial Number is F4E6-FD70

 Directory of \\?\Volume{eea3b237-18e9-4572-a656-ba4f3c6030a6}\Recovery

2023/08/27  19:47    <DIR>          .
2023/08/27  19:47    <DIR>          ..
2023/08/27  19:47    <DIR>          OEM
               0 File(s)              0 bytes
               3 Dir(s)  165,001,043,968 bytes free
 Volume in drive \\?\Volume{1aafebf5-8d4b-487e-8ad8-754c15d8ed07} has no label.
 Volume Serial Number is 9624-8F9F

 Directory of \\?\Volume{1aafebf5-8d4b-487e-8ad8-754c15d8ed07}\Recovery

2023/07/25  21:44    <DIR>          .
2023/07/25  21:44    <DIR>          ..
2023/07/25  21:50    <DIR>          Logs
2023/07/25  21:49    <DIR>          WindowsRE
               0 File(s)              0 bytes
               4 Dir(s)      88,928,256 bytes free

My Function

Func _GetRecoveryPartition()
    Local $GUID_TMP, $iPid
    $GUID_TMP = Run(@ComSpec & ' /C mountvol | find "\\?" >' & @TempDir & '\GUID.TMP','','', $STDOUT_CHILD+$STDERR_CHILD)
    ProcessWaitClose($GUID_TMP)
    $iPid = Run(@ComSpec & ' /C for /f %1 in ( ' & @TempDir & '\GUID.TMP' & ') do @dir %1Recovery /a 2> nul' ,'','', $STDOUT_CHILD+$STDERR_CHILD)
    Local $line0, $line1
    While ProcessExists($iPid)
        $line0 = StdoutRead($iPid)
        ConsoleWrite($line0)
      ...
        $line1 = StringRegExpReplace($line0, .)
      ConsoleWrite($line1)
    WEnd
EndFunc

With the above function, I don't know how to extract the desired result.

The end result I want to achieve is : $GUID = \\?\Volume{eea3b237-18e9-4572-a656-ba4f3c6030a6}\

Can you help me? Thank you so much!

Posted (edited)

Something like this?

#include <Array.au3>

$sData = ' Volume in drive \\?\Volume{eea3b237-18e9-4572-a656-ba4f3c6030a6} has no label.' & @CRLF
$sData &= ' Volume Serial Number is F4E6-FD70' & @CRLF
$sData &= '' & @CRLF
$sData &= ' Directory of \\?\Volume{eea3b237-18e9-4572-a656-ba4f3c6030a6}\Recovery' & @CRLF
$sData &= '' & @CRLF
$sData &= '2023/08/27  19:47    <DIR>          .' & @CRLF
$sData &= '2023/08/27  19:47    <DIR>          ..' & @CRLF
$sData &= '2023/08/27  19:47    <DIR>          OEM' & @CRLF
$sData &= '               0 File(s)              0 bytes' & @CRLF
$sData &= '               3 Dir(s)  165,001,043,968 bytes free' & @CRLF
$sData &= ' Volume in drive \\?\Volume{1aafebf5-8d4b-487e-8ad8-754c15d8ed07} has no label.' & @CRLF
$sData &= ' Volume Serial Number is 9624-8F9F' & @CRLF
$sData &= '' & @CRLF
$sData &= ' Directory of \\?\Volume{1aafebf5-8d4b-487e-8ad8-754c15d8ed07}\Recovery' & @CRLF
$sData &= '' & @CRLF
$sData &= '2023/07/25  21:44    <DIR>          .' & @CRLF
$sData &= '2023/07/25  21:44    <DIR>          ..' & @CRLF
$sData &= '2023/07/25  21:50    <DIR>          Logs' & @CRLF
$sData &= '2023/07/25  21:49    <DIR>          WindowsRE' & @CRLF
$sData &= '               0 File(s)              0 bytes' & @CRLF
$sData &= '               4 Dir(s)      88,928,256 bytes free'

$aMatches = StringRegExp($sData, 'Volume in drive \K(?:.+){[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12}}', 3)

_ArrayDisplay($aMatches)

I assumed $sData is your console output. The result is in $aMatches and you can simply prefix each match with $GUID = or anything you want.

Edited by Andreik
Posted

FWIW, instead of going thru external program like you did, you could use WMI to get the volumes:

#include <Array.au3>

Local $aVolume = GetVolumes()
_ArrayDisplay($aVolume)

Func GetVolumes()
  Local Const $Class = "Win32_Volume"
  Local $objWMI = ObjGet('Winmgmts:\\' & @ComputerName & '\root\CIMV2')
  If Not IsObj($objWMI) Then Exit MsgBox($MB_SYSTEMMODAL, "Error", "Winmgmts unavailable")
  Local $oVolume = $objWMI.InstancesOf($Class)
  If Not $oVolume.count Then Exit MsgBox($MB_SYSTEMMODAL, "Error", "No volume defined")
  Local $aVol[$oVolume.count][2], $iCount = 0
  For $oVol In $oVolume
    $aVol[$iCount][0] = $oVol.DeviceId
    $aVol[$iCount][1] = $oVol.Name = $oVol.DeviceId ? "" : $oVol.Name
    $iCount += 1
  Next
  Return $aVol
EndFunc

 

Posted
4 hours ago, Andreik said:

Something like this?

#include <Array.au3>

$sData = ' Volume in drive \\?\Volume{eea3b237-18e9-4572-a656-ba4f3c6030a6} has no label.' & @CRLF
$sData &= ' Volume Serial Number is F4E6-FD70' & @CRLF
$sData &= '' & @CRLF
$sData &= ' Directory of \\?\Volume{eea3b237-18e9-4572-a656-ba4f3c6030a6}\Recovery' & @CRLF
$sData &= '' & @CRLF
$sData &= '2023/08/27  19:47    <DIR>          .' & @CRLF
$sData &= '2023/08/27  19:47    <DIR>          ..' & @CRLF
$sData &= '2023/08/27  19:47    <DIR>          OEM' & @CRLF
$sData &= '               0 File(s)              0 bytes' & @CRLF
$sData &= '               3 Dir(s)  165,001,043,968 bytes free' & @CRLF
$sData &= ' Volume in drive \\?\Volume{1aafebf5-8d4b-487e-8ad8-754c15d8ed07} has no label.' & @CRLF
$sData &= ' Volume Serial Number is 9624-8F9F' & @CRLF
$sData &= '' & @CRLF
$sData &= ' Directory of \\?\Volume{1aafebf5-8d4b-487e-8ad8-754c15d8ed07}\Recovery' & @CRLF
$sData &= '' & @CRLF
$sData &= '2023/07/25  21:44    <DIR>          .' & @CRLF
$sData &= '2023/07/25  21:44    <DIR>          ..' & @CRLF
$sData &= '2023/07/25  21:50    <DIR>          Logs' & @CRLF
$sData &= '2023/07/25  21:49    <DIR>          WindowsRE' & @CRLF
$sData &= '               0 File(s)              0 bytes' & @CRLF
$sData &= '               4 Dir(s)      88,928,256 bytes free'

$aMatches = StringRegExp($sData, 'Volume in drive \K(?:.+){[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12}}', 3)

_ArrayDisplay($aMatches)

I assumed $sData is your console output. The result is in $aMatches and you can simply prefix each match with $GUID = or anything you want.

 @AndreikThank you very much for your reply, but it did not meet my needs. In fact, I am not an English operating system, ConsoleWrite($line0) outputs the following:

 ǽ¶¯Ʒ \\?\Volume{eea3b237-18e9-4572-a656-ba4f3c6030a6} ֐µľ탻Ӑ±ꇩ¡£
 ¾�вÁкŊǠF4E6-FD70

 \\?\Volume{eea3b237-18e9-4572-a656-ba4f3c6030a6}\Recovery µĄ¿¼

2023/08/27  19:47    <DIR>          .
2023/08/27  19:47    <DIR>          ..
2023/08/27  19:47    <DIR>          OEM
               0 ¸ö΄¼þ              0 ז½ڍ
               3 ¸öĿ¼ 164,650,033,152 ¿ɓ×ֽڍ
 ǽ¶¯Ʒ \\?\Volume{1aafebf5-8d4b-487e-8ad8-754c15d8ed07} ֐µľ탻Ӑ±ꇩ¡£
 ¾�вÁкŊǠ9624-8F9F

 \\?\Volume{1aafebf5-8d4b-487e-8ad8-754c15d8ed07}\Recovery µĄ¿¼

2023/07/25  21:44    <DIR>          .
2023/07/25  21:44    <DIR>          ..
2023/07/25  21:50    <DIR>          Logs
2023/07/25  21:49    <DIR>          WindowsRE
               0 ¸ö΄¼þ              0 ז½ڍ
               4 ¸öĿ¼     88,928,256 ¿ɓ×ֽڍ

My Function

Func _GetRecoveryPartition()
    Local $GUID_TMP, $iPid
    $GUID_TMP = Run(@ComSpec & ' /C mountvol | find "\\?" >' & @TempDir & '\GUID.TMP','','', $STDOUT_CHILD+$STDERR_CHILD)
    ProcessWaitClose($GUID_TMP)
    $iPid = Run(@ComSpec & ' /C for /f %1 in ( ' & @TempDir & '\GUID.TMP' & ') do @dir %1Recovery /a 2> nul' ,'','', $STDOUT_CHILD+$STDERR_CHILD)
    Local $line0, $line1, $line2
    While ProcessExists($iPid)
        $line0 = StdoutRead($iPid)
        ConsoleWrite($line0)
    WEnd
EndFunc

The end result I want to achieve is : $GUID = \\?\Volume{eea3b237-18e9-4572-a656-ba4f3c6030a6}\

Posted
38 minutes ago, Nine said:

FWIW, instead of going thru external program like you did, you could use WMI to get the volumes:

#include <Array.au3>

Local $aVolume = GetVolumes()
_ArrayDisplay($aVolume)

Func GetVolumes()
  Local Const $Class = "Win32_Volume"
  Local $objWMI = ObjGet('Winmgmts:\\' & @ComputerName & '\root\CIMV2')
  If Not IsObj($objWMI) Then Exit MsgBox($MB_SYSTEMMODAL, "Error", "Winmgmts unavailable")
  Local $oVolume = $objWMI.InstancesOf($Class)
  If Not $oVolume.count Then Exit MsgBox($MB_SYSTEMMODAL, "Error", "No volume defined")
  Local $aVol[$oVolume.count][2], $iCount = 0
  For $oVol In $oVolume
    $aVol[$iCount][0] = $oVol.DeviceId
    $aVol[$iCount][1] = $oVol.Name = $oVol.DeviceId ? "" : $oVol.Name
    $iCount += 1
  Next
  Return $aVol
EndFunc

 

Thank you very much for your beautiful script, although all partition GUids are listed,But I don't know which GUID is the recovery partition. I am going to assign a drive letter to the recovery partition by its GUID. For example:
MountVol R:  \\?\Volume{eea3b237-18e9-4572-a656-ba4f3c6030a6}\

Posted (edited)

Very sorrry, in this case, I didn't write it right. the GUID of my recovery partition is:

\\?\Volume{1aafebf5-8d4b-487e-8ad8-754c15d8ed07}\

The end result I want to achieve is : $GUID = \\?\Volume{1aafebf5-8d4b-487e-8ad8-754c15d8ed07}\

Now that I have a GUID, I want to be able to assign a drive letter to the recovery partition with the following command:

MountVol R: \\?\Volume{1aafebf5-8d4b-487e-8ad8-754c15d8ed07}\

Edited by i2i8
Posted

In the loop you can test if a specific folder exists with FileExists.  Something like this :

Func GetVolumes()
  Local Const $Class = "Win32_Volume"
  Local $objWMI = ObjGet('Winmgmts:\\' & @ComputerName & '\root\CIMV2')
  If Not IsObj($objWMI) Then Exit MsgBox($MB_SYSTEMMODAL, "Error", "Winmgmts unavailable")
  Local $oVolume = $objWMI.InstancesOf($Class)
  If Not $oVolume.count Then Exit MsgBox($MB_SYSTEMMODAL, "Error", "No volume defined")
  For $oVol In $oVolume
    If FileExists($oVol.DeviceId & "Recovery") Then Return $oVol.DeviceId
  Next
EndFunc

 

 

 

Posted
59 minutes ago, i2i8 said:

 @AndreikThank you very much for your reply, but it did not meet my needs. In fact, I am not an English operating system, ConsoleWrite($line0) outputs the following:

 ǽ¶¯Ʒ \\?\Volume{eea3b237-18e9-4572-a656-ba4f3c6030a6} ֐µľ탻Ӑ±ꇩ¡£
 ¾�вÁкŊǠF4E6-FD70

 \\?\Volume{eea3b237-18e9-4572-a656-ba4f3c6030a6}\Recovery µĄ¿¼

2023/08/27  19:47    <DIR>          .
2023/08/27  19:47    <DIR>          ..
2023/08/27  19:47    <DIR>          OEM
               0 ¸ö΄¼þ              0 ז½ڍ
               3 ¸öĿ¼ 164,650,033,152 ¿ɓ×ֽڍ
 ǽ¶¯Ʒ \\?\Volume{1aafebf5-8d4b-487e-8ad8-754c15d8ed07} ֐µľ탻Ӑ±ꇩ¡£
 ¾�вÁкŊǠ9624-8F9F

 \\?\Volume{1aafebf5-8d4b-487e-8ad8-754c15d8ed07}\Recovery µĄ¿¼

2023/07/25  21:44    <DIR>          .
2023/07/25  21:44    <DIR>          ..
2023/07/25  21:50    <DIR>          Logs
2023/07/25  21:49    <DIR>          WindowsRE
               0 ¸ö΄¼þ              0 ז½ڍ
               4 ¸öĿ¼     88,928,256 ¿ɓ×ֽڍ

My Function

Func _GetRecoveryPartition()
    Local $GUID_TMP, $iPid
    $GUID_TMP = Run(@ComSpec & ' /C mountvol | find "\\?" >' & @TempDir & '\GUID.TMP','','', $STDOUT_CHILD+$STDERR_CHILD)
    ProcessWaitClose($GUID_TMP)
    $iPid = Run(@ComSpec & ' /C for /f %1 in ( ' & @TempDir & '\GUID.TMP' & ') do @dir %1Recovery /a 2> nul' ,'','', $STDOUT_CHILD+$STDERR_CHILD)
    Local $line0, $line1, $line2
    While ProcessExists($iPid)
        $line0 = StdoutRead($iPid)
        ConsoleWrite($line0)
    WEnd
EndFunc

The end result I want to achieve is : $GUID = \\?\Volume{eea3b237-18e9-4572-a656-ba4f3c6030a6}\

Try with this regex:

\\\\\?\\Volume{[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12}}\\

 

  • Solution
Posted

Modified version to get the unassigned volume...

Func GetVolumes()
  Local Const $Class = "Win32_Volume"
  Local $objWMI = ObjGet('Winmgmts:\\' & @ComputerName & '\root\CIMV2')
  If Not IsObj($objWMI) Then Exit MsgBox($MB_SYSTEMMODAL, "Error", "Winmgmts unavailable")
  Local $oVolume = $objWMI.InstancesOf($Class)
  If Not $oVolume.count Then Exit MsgBox($MB_SYSTEMMODAL, "Error", "No volume defined")
  For $oVol In $oVolume
    If $oVol.DeviceId <> $oVol.Name Then ContinueLoop
    If FileExists($oVol.DeviceId & "Recovery") Then Return $oVol.DeviceId
  Next
EndFunc

 

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