Что нового

Возможность адресации с использованием имени тома

avmir

Новичок
Сообщения
28
Репутация
1
Версия AutoIt: 3.3.6.0

Описание: Допустим имеется несколько съемных дисков с уникальными именами томов ("Имя_01", "Имя_02", "Имя_03" и т.д.), причем практически все диски имеют зеркало (например: 'содержимое диска "Имя_01"'='содержимому диска "Имя_02"').
Необходимо, открыв ярлык проверить не подключен ли один из необходиых дисков (по имени).
Если подключен, то открыть в проводнике местонахождение (файла (или папки) на который(ую) ссылается ярлык).
Если не подключен, то выдать сообщение о необходимости подключить к системе один из двух дисков с кнопками "Да" "Нет". Если "Да", то все сначала, если "Нет" - выход из скрипта.

Как я понимаю, ярлык должен запускать скрипт с тремя параметрами: "1-ое Имя Тома", "2-ое Имя Тома", "Имя файла или папки".

Как это написать я не знаю... :(
Помогите пожалуйста.

P.S. Нужно, чтобы скрипт работал и в XP и в Win7
 
Автор
A

avmir

Новичок
Сообщения
28
Репутация
1
Господа! Неужели никто не знает как это сделать? Может это вообще невозможно?
 

SyDr

Сидра
Сообщения
651
Репутация
158
Код:
If $CMDLine[0] <> 3 Then Exit MsgBox(4096, "Ошибка", "Неверно указаны параметры") * 0 + 1
$bFound = False

While True
	$Drives = DriveGetDrive("REMOVABLE")
	For $i = 0 To UBound($Drives) - 1
		If DriveGetLabel($Drives[$i]) = $CMDLine[1] Or DriveGetLabel($Drives[$i]) = $CMDLine[2] Then $bFound = True
	Next

	If $bFound Then
		ShellExecute($CMDLine[3])
		Exit
	EndIf

	If 2 = MsgBox(4097, "Ошибка", "Подключите хотя бы один из необходимых дисков:" & @CRLF & $CMDLine[1] & @CRLF & $CMDLine[2]) Then Exit
WEnd
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Или так:
Код:
$sLabel_1 = 'Имя_01' ;имя первого диска, который ищем
$sLabel_2 = 'Имя_02' ;имя второго диска, который ищем
$sLabel = ''
$sPath = '\Папка\файл' ;папка или файл, который ищем
$fYes = False
$fWork = True

While $fWork
	$aDrives = DriveGetDrive('all')
	If Not @error Then
		For $i = 1 To $aDrives[0]
			$sLabel = DriveGetLabel($aDrives[$i])
			If $sLabel = $sLabel_1 Or $sLabel = $sLabel_2 Then
				$fYes = True
				$sPath = $aDrives[$i] & $sPath
				ExitLoop
			EndIf
		Next
	Else
		MsgBox(16, 'Error', 'Error')
		$fWork = False
	EndIf
	If $fYes Then
		If FileExists($sPath) Then
			If StringInStr(FileGetAttrib($sPath), 'D') Then
				ShellExecute($sPath)
				$fWork = False
			Else
				$sPath = StringRegExpReplace($sPath, '\\[^\\]*$', '')
				ShellExecute($sPath)
				$fWork = False
			EndIf
		Else
			MsgBox(16, 'Error', 'Отсутствует файл(папка) ' & $sPath)
			$fWork = False
		EndIf
	Else
		If MsgBox(37, 'Error', 'Диски ' & $sLabel_1 & ', ' & $sLabel_2 & ' не подключены.' & _
				@CRLF & 'Подключите один из них и нажмите "Повтор",' & @CRLF & _
				'или нажмите "Отмена" для выхода.') = 4 Then
			ContinueLoop
		Else
			$fWork = False
		EndIf
	EndIf
WEnd
 
Автор
A

avmir

Новичок
Сообщения
28
Репутация
1
madmasles сказал(а):
Код:
$sPath = StringRegExpReplace($sPath, '\\[^\\]*$', '')
            ShellExecute($sPath)
            $fWork = False

А можно, при открытии папки назначения, еще и перевести фокус на нужный файл?

Да, и кстати после выполнения ShellExecute($sPath) процесс скрипта остается. Как его закрыть?
Заметил, что если запустить после него MsgBox (видимо фокус возвращается приложению) процесс скрипта завершается...


Немного изменил требования к скрипту.
Сократил количество параметров до 1-го - "Том1:Том2\Каталог1\Подкатлог\Файл.txt"
Добавил возможность не указывать зеркало - "Том1\Каталог1\Подкатлог\Файл.txt"
Добавил краткую справку по параметру /?.
Расширил варианты различных проверок.
Вот что у меня получилось:

Код:
; Параметр передаваемый скрипту должен иметь вид
; Имя_диска_Х:Имя_диска_зеркала\Путь к файлу или папке
; Под "Имя_диска_Х" и "Имя_диска_зеркала" подразумевается имя тома
; При указании зеркала, после Имя_диска_Х обязательно ставится двоеточие!
; Если файл хранится только на одном диске, двоеточие и "Имя_диска_зеркала" - опускаются
;
; Скрипт применим не только для USB устройств, но и для E-SATA

$sLabel_1 = '' ;имя первого диска, который ищем
$sLabel_2 = '' ;имя второго диска, который ищем
$sLabel = ''
$sTempLabel = ''
$sPath = '' ; путь к папке или файлу, который ищем
$sTempPath = ''
$fYes = False
$fWork = True
$fExistOnFirstDrive = True
$iPass = 0
$iFirstPos = 0
$iSecondPos = 0

; здесь парсим параметр командной строки
If $CMDLine[0] <> 1 Then
	Exit MsgBox(4096, "Ошибка", 'Неверно указан параметр!' & @LF & 'Проверьте, возможно в пути к папке(файлу) имеются пробелы...'  & @LF & 'Тогда заключите параметр в кавычки.')
ElseIf  $CMDLine[0] = 1 Then
	If $CMDLine[1] = "/?" Then
		MsgBox(32, "Справка", 'Параметр передаваемый скрипту должен иметь вид:' & @LF & @LF & _
		'"Имя_диска_Х:Имя_диска_зеркала\Путь к файлу или папке."' & @LF & @LF & _
		'Заключать параметр в кавычки обязательно, так как в пути к папке(файлу) могут встречаться пробелы' & @LF & _
		'Под "Имя_диска_Х" и "Имя_диска_зеркала" подразумевается имена томов где нужно икать папку (файл).' & @LF & _
		'При указании зеркала, после Имя_диска_Х обязательно ставится двоеточие!' & @LF & @LF & _
		'Например:' & @LF & @LF & _
		'"Том1:Том2\Каталог1\Подкатлог\Файл.txt"'  & @LF & @LF & _
		'Если файл хранится только на одном диске, двоеточие и "Имя_диска_зеркала" - опускаются' & @LF & @LF & _
		'Например:' & @LF & @LF & _
		'"Том1\Каталог1\Подкатлог\Файл.txt"')
		Exit
	ElseIf $CMDLine[1] <> "/?" Then
		$iFirstPos = StringInStr($CMDLine[1], ":")
		$iSecondPos = StringInStr($CMDLine[1], "\")


		; указан зеркальный диск
		IF $iFirstPos <> 0 Then
			$sLabel_1 = StringLeft($CMDLine[1], $iFirstPos - 1)
			$sLabel_2 = StringMid($CMDLine[1], $iFirstPos + 1, $iSecondPos - ($iFirstPos + 1))

			; если в параметре указано два одинаковых имени тома, считаем, что второго нет
			If $sLabel_2 = $sLabel_1 Then
				$sLabel_2 = "Зеркала нет"
			EndIf
			$sPath = StringRight($CMDLine[1], StringLen($CMDLine[1]) - ($iSecondPos - 1))

		; не указан зеркальный диск
		ElseIf $iFirstPos = 0 Then
 			$sLabel_1 = StringLeft($CMDLine[1], $iSecondPos - 1)
			$sLabel_2 = "Зеркала нет"
			$sPath = StringRight($CMDLine[1], StringLen($CMDLine[1]) - ($iSecondPos - 1))
		EndIf
	EndIf
EndIf

$sTempLabel = $sLabel_1

While ($fWork)
    $aDrives = DriveGetDrive('all')
    If Not @error Then
        For $i = 1 To $aDrives[0]
            $sLabel = DriveGetLabel($aDrives[$i])
            If $sLabel = $sTempLabel Then
                $fYes = True
                $sTempPath = $aDrives[$i] & $sPath
                ExitLoop
			Else
				$fYes = False
            EndIf
        Next
    Else
        MsgBox(16, 'Ошибка', 'Ошибка')
        $fWork = False
    EndIf

	If $fYes Then ; нашли диск
        If FileExists($sTempPath) Then
            If StringInStr(FileGetAttrib($sTempPath), 'D') Then
                ShellExecute($sTempPath)
                $fWork = False
            Else
                $sTempPath = StringRegExpReplace($sTempPath, '\\[^\\]*$', '')
                ShellExecute($sTempPath)
                $fWork = False
            EndIf
        Else
			If ($iPass = 0 And $sLabel_2 = "Зеркала нет") Then
				MsgBox(16, 'Внимание', 'Единственный указанный диск "' & $sTempLabel & '" подключен, но на нем отсутствует папка(файл):' & @LF & @LF & $sTempPath)
				$fWork = False
			ElseIf ($iPass = 0 And $sLabel_2 <> "Зеркала нет") Then
				MsgBox(48, 'Внимание', 'Первый указанный диск "' & $sTempLabel & '" подключен, но на нем отсутствует папка(файл):' & @LF & @LF & $sTempPath)
				$fExistOnFirstDrive = False ; на первом диске папка(файл) не найдена
				$iPass += 1 ; если на первом диске папка(файл) не найдена делаем второй проход и ищем на зеркале
				$sTempLabel = $sLabel_2
				ContinueLoop
			ElseIf ($fExistOnFirstDrive  And $iPass = 1 And $sLabel_2 <> "Зеркала нет") Then
				If MsgBox(37, 'Внимание', 'Первый указанный диск "' & $sLabel_1 & '" не был подключен.' & @LF & _
					'Зеркальный диск "' & $sLabel_2 & '" подключен, но на нем отсутствует папка(файл):' & @LF & @LF & $sTempPath & @LF & _
					@CRLF & 'Попробуйте подключить первый диск "' & $sLabel_1 & '" и нажмите "Повтор",' & @CRLF & _
					'или нажмите "Отмена" для выхода.') = 4 Then
					$iPass = 0
					$sTempLabel = $sLabel_1
					$fYes = false
					ContinueLoop
				Else
					$fWork = False
				EndIf
			ElseIf ((Not $fExistOnFirstDrive)  And $iPass = 1 And $sTempLabel = $sLabel_2) Then
				MsgBox(16, 'Внимание', 'Ни на первом диске "' & $sLabel_1 & '",' & @LF & 'ни на втором диске "'  & $sLabel_2 & '"' & @LF & _
					'нет папки(файла):' & @LF & @LF & $sPath & @LF & @CRLF & 'Проверьте правильность заданного параметра.')
					$fWork = False
			EndIf
        EndIf
	ElseIf ((Not $fYes) And $iPass = 0 And $sLabel_2 <> "Зеркала нет") Then ; первого диска не нашли, ищем второй (если он есть)
		MsgBox(48, 'Внимание', 'Первый указанный диск "' & $sTempLabel & '" не подключен')
		$sTempLabel = $sLabel_2
		$iPass += 1
		ContinueLoop
	ElseIf ((Not $fYes) And $iPass = 0 And $sLabel_2 = "Зеркала нет") Then ; единственного диска не нашли
		If MsgBox(37, 'Внимание', 'Указанный диск "' & $sTempLabel & '" не подключен, а зеркала нет' & @LF & _
			@CRLF & 'Попробуйте подключить этот диск "' & $sLabel_1 & '" и нажмите "Повтор",' & @CRLF & _
			'или нажмите "Отмена" для выхода.') = 4 Then
			$iPass = 0
			$sTempLabel = $sLabel_1
			ContinueLoop
		Else
			$fWork = False
		EndIf
	ElseIf ((Not $fExistOnFirstDrive) And $iPass = 1 And $sLabel_2 <> "Зеркала нет") Then
		If MsgBox(37, 'Внимание', 'Первый указанный диск "' & $sLabel_1 & '" подключен, но на нем отсутствует папка(файл):' & @LF & @LF & $sTempPath & @LF & @LF & _
			'Зеркальный диск "' & $sLabel_2 & '" не был подключен.' & @LF & _
			@CRLF & 'Попробуйте подключить зеркальный диск "' & $sLabel_2 & '" и нажмите "Повтор",' & @CRLF & _
			'или нажмите "Отмена" для выхода.') = 4 Then
			$iPass = 1
			$sTempLabel = $sLabel_2
			$fYes = false
			ContinueLoop
		Else
			$fWork = False
		EndIf

    Else ; не нашли ни одного диска
        If MsgBox(37, 'Внимание', 'Диски "' & $sLabel_1 & '" и "' & $sLabel_2 & '" не подключены.' & _
                @CRLF & 'Подключите один из них и нажмите "Повтор",' & @CRLF & _
                'или нажмите "Отмена" для выхода.') = 4 Then
			$iPass = 0
			$sTempLabel = $sLabel_1
            ContinueLoop
        Else
            $fWork = False
        EndIf
    EndIf
WEnd
 
Автор
A

avmir

Новичок
Сообщения
28
Репутация
1
avmir сказал(а):
А можно, при открытии папки назначения, еще и перевести фокус на нужный файл?

Да, и кстати после выполнения ShellExecute($sPath) процесс скрипта остается. Как его закрыть?
Заметил, что если запустить после него MsgBox (видимо фокус возвращается приложению) процесс скрипта завершается...

Гуру отзовитесь...
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Автор
A

avmir

Новичок
Сообщения
28
Репутация
1
Ставил. Как-то странно работает. При одном и том же параметре то завершается процесс, то нет...
Причем вроде в ситуации: "когда первый диск не подключен, а второй подключен и файл там есть" :wacko:
 
Автор
A

avmir

Новичок
Сообщения
28
Репутация
1
Небольшая поправочка. В строку кода
Код:
Run("Explorer.exe /select,"' & $sFile & '"')

нужно записать как
Код:
Run('Explorer.exe /select,"' & $sFile & '"')


А так... Судари и сударыни огромное всем спасибо за науку! Все работает как нужно :laugh:
 
Верх