Jump to content

About extracting content from strings


i2i8
 Share

Go to solution Solved by Nine,

Recommended Posts

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!

Link to comment
Share on other sites

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

When the words fail... music speaks.

Link to comment
Share on other sites

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

 

Link to comment
Share on other sites

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}\

Link to comment
Share on other sites

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}\

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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

 

 

 

Link to comment
Share on other sites

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}}\\

 

When the words fail... music speaks.

Link to comment
Share on other sites

  • Solution

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

 

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...