Nicht wirklich neu, aber nachdem in diesem Thread meine etwas in die Jahre gekommene Ersatzfunktion für subst hervorgewühlt wurde, habe ich mich nochmals damit beschäftigt und etwas aufgeräumt und erweitert.
ACHTUNG:
Die Parameterreihenfolge habe ich im Vergleich zur Funktion _PartialDrive geändert. Da das Ziellaufwerk (wenn nicht angegeben) automatisch den nächsten freien Buchstaben (ab E) verwendet, ist es sinnvoller diesen hinter der Pfadangabe zu platzieren. Diese ist im Normalfall zwingend, kann aber auch ohne Angabe genutzt werden und verweist dann auf @MyDocumentsDir.
Im Gegensatz zur Vorgängerfunktion verzeiht diese auch Falscheingaben (Pfad mit abschließendem Backslash oder Laufwerksangabe ohne Doppelpunkt) und korrigiert das automatisch.
ERFORDERLICH:
Stable 3.3.16.1 (Verwendung von Map)
#include <Array.au3>
#include "DefineDosDevice"
_Erstellen()
Func _Erstellen()
Local $drive = _DefineDosDevice() ; erstes freies Lw mit @MyDocumetsDir
Local $iErr = @error, $iExt = @extended
If Not $iErr Then
ConsoleWrite('+> CREATED: ' & $drive & @CRLF)
Else
ConsoleWrite('!> ERROR: ' & $iErr & ' EXTENDED: ' & $iExt & @CRLF)
EndIf
Local $aDrives = _DefineDosDevice('', '', 2)
_ArrayDisplay($aDrives)
If Not $iErr Then Return _Loeschen($drive)
EndFunc
Func _Loeschen($_drive)
Local $drive = _DefineDosDevice('', $_drive, 1)
If Not @error Then
ConsoleWrite('+> DELETED: ' & $drive & @CRLF)
Else
ConsoleWrite('!> ERROR: ' & @error & @CRLF)
EndIf
Local $aDrives = _DefineDosDevice('', '', 2)
_ArrayDisplay($aDrives)
EndFunc
Alles anzeigen
;-- TIME_STAMP 2022-12-29 14:15:44 v 0.1
;===================================================================================================
; Function Name .: _DefineDosDevice($_sTargetPath='', $_sDeviceName='', $_iActionFlag=0)
; Description ...: Creates or removes a Virtual Drive or lists existing drives. The Drive will be romved automatically on shutdown.
; Parameter(s) ..: $_sTargetPath Path to link the driveletter to
; Create: with "" link to @MyDocumentsDir (default)
; $_sDeviceName Driveletter of the Drive to create / delete,
; Create: with "" the first free drive letter - starts with "E:" - is used (default)
; Delete: pass "" - the path connected with the driveletter will be found automatically.
; $_iActionFlag 0 = Creation (default)
; 1 = Deletion of the Drive
; 2 = Return an array of dos drives, if available; [0][0]=counter, [['drive','path']]
; Return Value(s): Success Driveletter of the created/deleted virtual Drive or array with found dos drives
; Failure 0 @error=1 wrong action flag
; @error=2 wrong drive letter @extended: 1=no free drive letter available; 2=drive letter already exists
; @error=3 no valid path to link to
; @error=4 action failed
; @error=5 no valid drive to delete
; Author(s) : BugFix (autoit@bug-fix.info)
; Note : The function corrects incorrect entries for drive and path specifications.
; Thus "c:\folder1\folder2\" and "f" are evaluated as correct entries.
; Requires : AutoIt stable min. 3.3.16.1
;===================================================================================================
Func _DefineDosDevice($_sTargetPath='', $_sDeviceName='', $_iActionFlag=0)
If $_iActionFlag < 0 Or $_iActionFlag > 2 Then Return SetError(1,0,0)
$_sTargetPath = $_sTargetPath = '' ? @MyDocumentsDir : StringRegExpReplace($_sTargetPath, '\\$', '')
$_sDeviceName = $_sDeviceName <> '' ? (StringRegExpReplace(StringLower($_sDeviceName), ':*$', '') & ':') : ''
Local $aDrives, $ret
Switch $_iActionFlag
Case 0 ; create new dos device
If $_sDeviceName = '' Then ; get next free drive letter
$aDrives = DriveGetDrive("ALL")
Local $mDrives[]
For $i = 1 To UBound($aDrives) -1
$mDrives[StringLeft($aDrives[$i],1)] = 1
Next
For $j = 101 To 122
If Not MapExists($mDrives, Chr($j)) Then
$_sDeviceName = Chr($j) & ':'
ExitLoop
EndIf
Next
If $_sDeviceName = '' Then Return SetError(2,1,0)
Else ; check if passed drive letter exists
If FileExists($_sDeviceName) Then Return SetError(2,2,0)
EndIf
If Not FileExists($_sTargetPath) Then Return SetError(3,0,0)
$ret = DllCall('kernel32.dll', 'long', 'DefineDosDeviceA', _
'long', 0x0, 'str', $_sDeviceName, 'str', $_sTargetPath)
Return SetError(($ret[0]=0?4:0), 0, ($ret[0]<>0?$_sDeviceName:0))
Case 1 ; determine the path associated with the drive to be deleted
$ret = DllCall("kernel32.dll", "long", "QueryDosDeviceA", "str", $_sDeviceName, "str", "", "long", 260)
If $ret[0] = 0 Then
Return SetError(4,0,0)
Else
$_sTargetPath = StringRegExpReplace($ret[2], '(\W*)([a-zA-Z].*)', '$2')
If Not FileExists($_sTargetPath) Then Return SetError(5,0,0)
$ret = DllCall('kernel32.dll', 'long', 'DefineDosDeviceA', _
'long', 0x2, 'str', $_sDeviceName, 'str', $_sTargetPath)
Return SetError(($ret[0]=0?4:0), 0, ($ret[0]<>0?$_sDeviceName:0))
EndIf
Case 2 ; array of existing dos devices, [0][0]=counter, [['drive','path']]
$aDrives = DriveGetDrive('FIXED')
Local $aOut[27][2] = [[0]]
For $i = 1 To UBound($aDrives) - 1
$ret = DllCall("kernel32.dll", "long", "QueryDosDeviceA", "str", $aDrives[$i], "str", "", "long", 260)
Local $path = StringRegExpReplace($ret[2], '(\W*)([a-zA-Z].*)', '$2')
If StringRegExp($path, '[a-zA-Z]:.*') Then
$aOut[0][0] += 1
$aOut[$aOut[0][0]][0] = $aDrives[$i]
$aOut[$aOut[0][0]][1] = $path
EndIf
Next
ReDim $aOut[$aOut[0][0]+1][2]
Return $aOut
EndSwitch
EndFunc
Alles anzeigen
EDIT:
Bei administrativer Tätigkeit ist es als Kommandozeilentool sicher besser anwendbar.
EDIT 2:
Habe jetzt mehrfach damit gearbeitet - auf der Kommandozeile Leerparameter zu übergeben ist unpraktisch. Hier werde ich noch Änderungen vornehmen.
EDIT 3:
Ist geändert - Parameterreihenfolge ist egal. Man übergibt nur die erforderlichen Parameter. Zusätzlich ergänzt um eine Hilfe.
;-- TIME_STAMP 2022-12-30 12:54:04 v 0.2
#AutoIt3Wrapper_Change2CUI=y
#cs CMD Line
Syntax: "Path to DefineDosDeviceCMD.exe" [Switch] [Full Target Path] [Drive Letter]
The parameters can be specified in any order.
The search for free drive letters starts at "E:". However, if not occupied, "A:" or "B:" can also be specified.
"Path to DefineDosDeviceCMD.exe" Compiled program path
[Switch] /c Create drive (default, omit this parameter)
/d Delete drive
/l Listing of Dos devices and their paths, if any
/? Shows the help
[Full Target Path] /target="Path to link the drive letter to"
[Drive Letter] /drive=F: or /drive=x Drive letter of the drive to create or delete - omit this, to create with next free letter
#ce
If $CMDLINE[0] = 0 Then Exit ConsoleWrite('"' & @ScriptName & '"' & @CRLF & 'The program was called without parameters! Call the help (/?)!' & @CRLF)
Global $sHelp = 'Creates or removes a Virtual Drive or lists existing drives. The Drive(s) will be removed automatically on shutdown.' & @CRLF & @CRLF
$sHelp &= '"Path to DefineDosDeviceCMD.exe" [Switch] [Full Target Path] [Drive Letter]' & @CRLF
$sHelp &= 'The parameters can be specified in any order.' & @CRLF
$sHelp &= 'The search for free drive letters starts at "E:". However, if not occupied, "A:" or "B:" can also be specified.' & @CRLF & @CRLF
$sHelp &= '"Path to DefineDosDeviceCMD.exe" Compiled program path' & @CRLF
$sHelp &= '[Switch] /c Create drive (default, omit this parameter)' & @CRLF
$sHelp &= ' /d Delete drive' & @CRLF
$sHelp &= ' /l Listing of Dos devices and their paths, if any' & @CRLF
$sHelp &= ' /? Shows the help' & @CRLF
$sHelp &= '[Full Target Path] /target="Path to link the drive letter to"' & @CRLF
$sHelp &= '[Drive Letter] /drive=F: or /drive=x Drive letter of the drive to create or delete - omit this, to create with next free letter' & @CRLF
Global $aMatch, $sSwitch, $iFlag, $sTarget, $sDrive, $sOut
; check for switch
$aMatch = StringRegExp(StringLower($CMDLINERAW), '(\/[cdl\?])(?!\w)', 1)
If @error Then
$sSwitch = '/c'
Else
$sSwitch = $aMatch[0]
EndIf
If $sSwitch = '/?' Then Exit ConsoleWrite($sHelp & @CRLF)
If $sSwitch = '/c' Then $iFlag = 0
If $sSwitch = '/d' Then $iFlag = 1
If $sSwitch = '/l' Then $iFlag = 2
; check for target path
$aMatch = StringRegExp(StringLower($CMDLINERAW), '\/target=(?:"|\x27)(.+)(?:"|\x27)', 1)
If @error Then
$sTarget = ""
If $iFlag = 0 Then Exit ConsoleWrite('[CREATION] ERROR The creation requires the specification of a target path!' & @CRLF)
Else
$sTarget = $aMatch[0]
EndIf
; check for drive letter
$aMatch = StringRegExp(StringLower($CMDLINERAW), '\/drive=([a-z]:?)', 1)
If @error Then
$sDrive = ""
Else
$sDrive = $aMatch[0]
EndIf
Global $vResult = _DefineDosDevice($sTarget, $sDrive, $iFlag)
Global $iErr = @error, $iExt = @extended
Switch $iFlag
Case 0
If $iErr = 2 And $iExt = 1 Then
$sOut = '[CREATION] ERROR No free drive letter available!' & @CRLF
ElseIf $iErr = 2 And $iExt = 2 Then
$sOut = '[CREATION] ERROR The passed drive letter already exists!' & @CRLF
ElseIf $iErr = 3 Then
$sOut = '[CREATION] ERROR The path to link to is not valid!' & @CRLF
Else
$sOut = '[CREATION] SUCCESS Drive "' & StringUpper($vResult) & '" has been created.' & @CRLF
EndIf
Case 1
If $iErr = 4 Then
$sOut = '[DELETION] ERROR The action has failed!' & @CRLF
Else
$sOut = '[DELETION] SUCCESS Drive "' & StringUpper($vResult) & '" has been deleted.' & @CRLF
EndIf
Case 2
If $vResult[0][0] = 0 Then
$sOut = '[LISTING] No DOS devices defined!' & @CRLF
Else
$sOut = '[LISTING] DRIVE LINKED_TO' & @CRLF
For $i = 1 To $vResult[0][0]
$sOut &= ' ' & StringUpper($vResult[$i][0]) & ' ' & $vResult[$i][1] & @CRLF
Next
EndIf
EndSwitch
ConsoleWrite($sOut)
;===================================================================================================
; Function Name .: _DefineDosDevice($_sTargetPath='', $_sDeviceName='', $_iActionFlag=0)
; Description ...: Creates or removes a Virtual Drive or lists existing drives. The Drive will be removed automatically on shutdown.
; Parameter(s) ..: $_sTargetPath Path to link the driveletter to
; Create: with "" link to @MyDocumentsDir (default)
; $_sDeviceName Driveletter of the Drive to create / delete,
; Create: with "" the first free drive letter - starts with "E:" - is used (default)
; Delete: pass "" - the path connected with the driveletter will be found automatically.
; $_iActionFlag 0 = Creation (default)
; 1 = Deletion of the Drive
; 2 = Return an array of dos drives, if available; [0][0]=counter, [['drive','path']]
; Return Value(s): Success Driveletter of the created/deleted virtual Drive or array with found dos drives
; Failure 0 @error=1 wrong action flag
; @error=2 wrong drive letter @extended: 1=no free drive letter available; 2=drive letter already exists
; @error=3 no valid path to link to
; @error=4 action failed
; @error=5 no valid drive to delete
; Author(s) : BugFix (autoit@bug-fix.info)
; Note : The function corrects incorrect entries for drive and path specifications.
; Thus "c:\folder1\folder2\" and "f" are evaluated as correct entries.
; Requires : AutoIt stable min. 3.3.16.1
;===================================================================================================
Func _DefineDosDevice($_sTargetPath='', $_sDeviceName='', $_iActionFlag=0)
If $_iActionFlag < 0 Or $_iActionFlag > 2 Then Return SetError(1,0,0)
$_sTargetPath = $_sTargetPath = '' ? @MyDocumentsDir : StringRegExpReplace($_sTargetPath, '\\$', '')
$_sDeviceName = $_sDeviceName <> '' ? (StringRegExpReplace(StringLower($_sDeviceName), ':*$', '') & ':') : ''
Local $aDrives, $ret
Switch $_iActionFlag
Case 0 ; create new dos device
If $_sDeviceName = '' Then ; get next free drive letter
$aDrives = DriveGetDrive("ALL")
Local $mDrives[]
For $i = 1 To UBound($aDrives) -1
$mDrives[StringLeft($aDrives[$i],1)] = 1
Next
For $j = 101 To 122
If Not MapExists($mDrives, Chr($j)) Then
$_sDeviceName = Chr($j) & ':'
ExitLoop
EndIf
Next
If $_sDeviceName = '' Then Return SetError(2,1,0)
Else ; check if passed drive letter already exists
If FileExists($_sDeviceName) Then Return SetError(2,2,0)
EndIf
If Not FileExists($_sTargetPath) Then Return SetError(3,0,0)
$ret = DllCall('kernel32.dll', 'long', 'DefineDosDeviceA', _
'long', 0x0, 'str', $_sDeviceName, 'str', $_sTargetPath)
Return SetError(($ret[0]=0?4:0), 0, ($ret[0]<>0?$_sDeviceName:0))
Case 1 ; determine the path associated with the drive to be deleted
$ret = DllCall("kernel32.dll", "long", "QueryDosDeviceA", "str", $_sDeviceName, "str", "", "long", 260)
If $ret[0] = 0 Then
Return SetError(4,0,0)
Else
$_sTargetPath = StringRegExpReplace($ret[2], '(\W*)([a-zA-Z].*)', '$2')
If Not FileExists($_sTargetPath) Then Return SetError(5,0,0)
$ret = DllCall('kernel32.dll', 'long', 'DefineDosDeviceA', _
'long', 0x2, 'str', $_sDeviceName, 'str', $_sTargetPath)
Return SetError(($ret[0]=0?4:0), 0, ($ret[0]<>0?$_sDeviceName:0))
EndIf
Case 2 ; array of existing dos devices, [0][0]=counter, [['drive','path']]
$aDrives = DriveGetDrive('FIXED')
Local $aOut[27][2] = [[0]]
For $i = 1 To UBound($aDrives) - 1
$ret = DllCall("kernel32.dll", "long", "QueryDosDeviceA", "str", $aDrives[$i], "str", "", "long", 260)
Local $path = StringRegExpReplace($ret[2], '(\W*)([a-zA-Z].*)', '$2')
If StringRegExp($path, '[a-zA-Z]:.*') Then
$aOut[0][0] += 1
$aOut[$aOut[0][0]][0] = $aDrives[$i]
$aOut[$aOut[0][0]][1] = $path
EndIf
Next
ReDim $aOut[$aOut[0][0]+1][2]
Return $aOut
EndSwitch
EndFunc
Alles anzeigen
So sieht es aus: