Что нового

Массив командной строки

rolatipov

Новичок
Сообщения
25
Репутация
0
Здраствуйте.У меня вот такой скрипт:
Код:
FileOpen('C:\1.txt', 2)
FileWriteLine('C:\1.txt', $CmdLine[1])

где $CmdLine[1] в данном случае путь к выделенному файлу.Если выделен один файл то все понятно.Но если больше одного тогда записывается последний.А как правильно записать массив файлов с переходом на новую строку пока не представляю.Подскажите, кто знает
 

madmasles

Модератор
Глобальный модератор
Сообщения
7 790
Репутация
2 319
rolatipov,
Попробуйте так.
Код:
$sText = ''

$hFile = FileOpen('C:\1.txt', 2)
If $hFile <> -1 Then
	For $i = 1 To $CmdLine[0]
		$sText &= $CmdLine[$i] & @CRLF
	Next
	FileWrite($hFile, StringTrimRight($sText, 2))
	FileClose($hFile)
EndIf
 
Автор
R

rolatipov

Новичок
Сообщения
25
Репутация
0
madmasles,все равно только один записывает
 
Автор
R

rolatipov

Новичок
Сообщения
25
Репутация
0
Пример массива приведите
ну если например записать вот так:
Код:
MsgBox(0, '', $CmdLine[1])

и выделишь три файла то получишь сразу три окна
 
Автор
R

rolatipov

Новичок
Сообщения
25
Репутация
0
madmasles, у меня в контекстном меню есть свой пункт.В реестре для этого пункта прописана команда:
c:\script.exe "%1".Когда я выделяю файл(файлы) и нажимаю на этот пункт я получаю путь(пути) к этому файлу(файлам).Далее мне этот путь(пути) надо записать в txt.C одним файлом проблем нет,а вот как записать для более одного файла(каждый путь в строку) я не знаю
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 713
rolatipov

Для этого есть механизм DDE, но это муторно. Более простой, но менее надежный вариант - Mutex + WM_COPYDATA.

Код:
#NoTrayIcon

#Include <APIConstants.au3>
#Include <Array.au3>
#Include <WinAPIEx.au3>

Opt('MustDeclareVars', 1)
Opt('WinTitleMatchMode', 3)
Opt('WinWaitDelay', 0)

If Not $CmdLine[0] Then
	Exit
EndIf

Global $tCOPYDATA, $hReceiver, $hMutex, $Ret, $Lenght, $Count = 1
Global $Path[101] = [1, $CmdLine[1]]

$hMutex = _WinAPI_CreateMutex('{3891B756-85A2-4274-9226-5E66967E60A4}')
If _WinAPI_GetLastError() = 183 Then
	$hReceiver = WinWait('{A257F21D-D0BF-4CE9-A6C9-84C7D258C91B}', '', 3)
	If @error Then
		Exit
	EndIf
	$Lenght = StringLen($CmdLine[1]) + 1
	$tCOPYDATA = DllStructCreate('ulong_ptr;dword;ptr;wchar[' & $Lenght & ']')
	DllStructSetData($tCOPYDATA, 1, 0x1000)
	DllStructSetData($tCOPYDATA, 2, 2 * $Lenght)
	DllStructSetData($tCOPYDATA, 3, DllStructGetPtr($tCOPYDATA, 4))
	DllStructSetData($tCOPYDATA, 4, $CmdLine[1])
	$Ret = DllCall('user32.dll', 'uint', 'SendMessage', 'hwnd', $hReceiver, 'uint', $WM_COPYDATA, 'ptr', 0, 'ptr', DllStructGetPtr($tCOPYDATA))
	If (@error) Or (Not $Ret[0]) Then
		; Nothing
	EndIf
	Exit
EndIf

$hReceiver = GUICreate('{A257F21D-D0BF-4CE9-A6C9-84C7D258C91B}')
GUIRegisterMsg($WM_COPYDATA, 'WM_COPYDATA')

While 1
	Sleep(200)
	If $Path[0] = $Count Then
		ExitLoop
	EndIf
	$Count = $Path[0]
WEnd

GUIRegisterMsg($WM_COPYDATA, '')
GUIDelete($hReceiver)

_WinAPI_CloseHandle($hMutex)

ReDim $Path[$Path[0] + 1]

_ArrayDisplay($Path)

Func WM_COPYDATA($hWnd, $iMsg, $wParam, $lParam)
	Switch $hWnd
		Case $hReceiver
			Local $tCOPYDATA = DllStructCreate('ulong_ptr;dword;ptr', $lParam)
			Switch DllStructGetData($tCOPYDATA, 1)
				Case 0x1000
					$Path[0] += 1
					If $Path[0] > UBound($Path) - 1 Then
						ReDim $Path[$Path[0] + 100]
					EndIf
					$Path[$Path[0]] = DllStructGetData(DllStructCreate('wchar[' & (DllStructGetData($tCOPYDATA, 2) / 2) & ']', DllStructGetData($tCOPYDATA, 3)), 1)
					Return 1
			EndSwitch
	EndSwitch
	Return 0
EndFunc   ;==>WM_COPYDATA


Здесь узкое место - задержка в цикле. Если она будет слишком маленькая, то скрипт может раньше времени вывести результат, а последующие сообщения придутся на другой экземпляр программы. Если слишком большая, то долго (относительно) ждать придется. У меня прекрасно работает с задержкой 100 мс, но поставил 200 мс. Поэкперементируй.
 
Автор
R

rolatipov

Новичок
Сообщения
25
Репутация
0
AZJIO я понял о чем ты говоришь.Есть такая функция:
Код:
#Include<WinAPIEx.au3>
$path = _WinAPI_GetCurrentDirectory ( )

которая и должна вернуть путь до файла(файлов)-активную директорию.Таким образом полный путь вместе с файлом будет выглядеть так:
Код:
$file = $path&'\'&'text'
где text и есть имя файла взятое из списка ControlListView.Но здесь есть один большой недостаток-скрытые расширения(а у меня они скрыты),которые не "увидит" ControlListView.Как с этим бороться?


Добавлено:
Сообщение автоматически объединено:

Yashied, командная строка это самый верный способ получить путь(пути) к файлу(файлам) так чтобы с ними можно было спокойно работать(поочередно с каждым значением массива) или есть альтернативный способ?Такой,при котором не нужны будут такие громоздкие скрипты?
Спасибо, скрипт работает.
 

Zaramot

I ♥ AutoIt
Сообщения
1 160
Репутация
658
Yashied,
У меня даже c задержкой в 3000, всё равно показывает 1 файл.

PS. Система Windows XP SP3...
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 713
Zaramot сказал(а):
У меня даже c задержкой в 3000, всё равно показывает 1 файл.
Значит ты что-то не так делаешь.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 713
Как ты его запускал?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 713
Нужно добавить в реестр

Код:
HKEY_CLASSES_ROOT\*\shell\Enum\command
путь к скомпилированному скрипту

Код:
"...\Script.exe" "%1"
После этого выбрать "Enum" в контекстном меню выделенных файлов. "Open with..." я не могу проверить, в Windows 7 этот диалог можно вызвать только для одного файла.
 
Верх