Что нового

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

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 319
Или так:
Код:
$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 471
Репутация
2 401
Автор
A

avmir

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

avmir

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

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


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