Войти

Показать полную графическую версию : [Архив - Часть 1.3] AutoIt скрипты


Страниц : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [20] 21 22 23 24 25 26

Creat0R
05-05-2007, 00:51
TERMINAL
нужно скриптом определить эти диски и отформатить D,E
Что значит определить? по каким параметрам их определять?

Чтобы отформатировать диск, можно использовать ком. строку:


$DriveToFormat = 'Z:'
$Confirm = 'no'; 'yes' для подтверждения удаления

$FOpen = FileOpen(@TempDir & '\Answer.tmp', 2)
FileWrite($FOpen, $Confirm)
FileClose($FOpen)

$CmdPid = Run(@ComSpec & ' /c formart ' & $DriveToFormat & ' < "' & @TempDir & '\Answer.tmp"')

While Not ProcessExists($CmdPid)
Sleep(10)
WEnd

FileDelete(@TempDir & '\Answer.tmp')


На всякий случай я специально подставил переменной $DriveToFormat значение буквы диска Z, и переменной $Confirm значениие 'no' (не подтверждать форматирование), запускать этот скрипт очень осторожно, если у переменной $Confirm поставить значение 'yes', то следует полагать что диск будет отформатирован без подтверждения - сам не проверял :) (проверял метод на реестре).

Системны диск отформатировать из запущенной Windows не получится :no:.

amel27
05-05-2007, 08:53
Creat0Rвроде в функции уже есть возможность автоотключения кнопки ОК в нужный момент (если использовать $flag=1)
это в качестве примера использования SendMessage... кстати, с помощью этого сообщения можно ограничить возможность выбора файлов по определенному признаку - имени, типу, etc. Но для этого придется наладить "диалог" с окном выбора, а без CallBack-функций этого не осуществить.
какой код у параметраНа оффсайте есть очень полезная тулза, возвращающая коды по всем (или почти всем) GUI-сообщениям:
http://www.autoitscript.com/forum/index.php?showtopic=32691BFFM_SETEXPANDED (или может нужен BFFM_SETSELECTION?)Естественно BFFM_SETSELECTION... BFFM_SETEXPANDED служит для раскрытия определенной ветки (+) без перемещения курсора. С сообщением BFFM_SETSELECTION есть одна тонкость - дело в том, что оно на самом деле передает не строку пути, а указатель на эту строку, т.е. адрес... но у разных процессов разные адресные пространства, если управляющий скрипт создаст строку и передаст ее адрес, то главный скрипт при попытке обращения по этому адресу скорее всего вывалится с ошибкой доступа памяти или типа того. Поэтому строку должен создать главный скрипт, сообщить ее адрес управляющему скрипту, а тот уже отправит корректное сообщение BFFM_SETSELECTION. Вот один из вариантов реализации, главный скрипт:#include <GUIConstants.au3>
Global Const $BFFM_SETSELECTION = $WM_USER + 102 ; BFFM_SETSELECTION

$initDir = "C:\Windows\System32" ; Стартовый каталог
; Создаем и заполняем структуру для $initDir
$str = DllStructCreate ("char[260]")
DllStructSetData ($str, 1, $initDir)
; Ищем окно управляющего скрипта
$hOpenDialogControl = WinGetHandle ("_FileOpenDialogControl")
; Если найдено, отправляем сообщение с указателем
If Not @error Then
$ret = DllCall ("user32.dll", "int", "SendMessage", _
"hwnd", $hOpenDialogControl, _
"int", $BFFM_SETSELECTION, _
"int", 1, _
"ptr", DllStructGetPtr ($str) )
EndIf
; Открываем главное окно выбора
$files = _FileSelectFolder ('Тестирование выбора каталога')Управляющий скрипт:#include <GUIConstants.au3>
Global Const $BFFM_SETSELECTION = $WM_USER + 102 ; BFFM_SETSELECTION

Global $arrMsgSend [1][4]=[[0,0,0,0]] ; Массив сообщений для отправки
; Создаем фиктивное окно (для приема сообщений)
$hWndMain = GUICreate("_FileOpenDialogControl")
; Регистрируем наше пользовательское сообщение
GUIRegisterMsg ($BFFM_SETSELECTION, "_SaveMsgParms")
; Ждем открытия главного окна
WinWait ("Обзор папок")
; Обработка полученных сообщений
If $arrMsgSend[0][0] Then
$hMsgWnd = WinGetHandle ("Обзор папок")
For $i=1 To $arrMsgSend[0][0]
$ret = DllCall ("user32.dll", "int", "SendMessage", _
"hwnd",$hMsgWnd, _
"int", $arrMsgSend[$i][1], _
"int", $arrMsgSend[$i][2], _
"ptr", $arrMsgSend[$i][3] )
Next
EndIf
; Функция обработки входящих сообщений
Func _SaveMsgParms($hWnd, $iMsg, $WParam, $LParam)
Switch $iMsg
Case $BFFM_SETSELECTION
$arrMsgSend[0][0]+=1
ReDim $arrMsgSend[$arrMsgSend[0][0]+1][4]
$arrMsgSend[$arrMsgSend[0][0]][1] = $BFFM_SETSELECTION
$arrMsgSend[$arrMsgSend[0][0]][2] = $WParam
$arrMsgSend[$arrMsgSend[0][0]][3] = $LParam
EndSwitch
EndFunc

amel27
05-05-2007, 09:15
Creat0RКак можно средставми RegExp осуществлять массовую замену в переменной?RegExp подерживает только одну заменяющую строку (3-й параметр), причем она даже не является регулярным выражением (за исключением групповых подстановок)... а в чем собственно проблема?.. неужели так существенна одна лишняя строка кода?

Creat0R
05-05-2007, 11:52
amel27
На оффсайте есть очень полезная тулза, возвращающая коды по всем (или почти всем) GUI-сообщениям:
Класс, именно это я давно(?) и искал, спасибо.

Поэтому строку должен создать главный скрипт, сообщить ее адрес управляющему скрипту, а тот уже отправит корректное сообщение BFFM_SETSELECTION
А обязательно создавать фиктивное окно, пмещать в массив данные и передавать обратно в окно выбора каталога? :wacko:
Может можно как то передавать нужные данные через ком. строку? (в этот же скрипт к примеру).

Но вообще, оно работает, огромнейшее спасибо за пример - спустя полтора часа колдования над ним, мне наконец удалось поместить всё это в более или менее юзабельные UDF'ы :biggrin: (см. ниже пример).

Правда есть один момент - Не получается нормально определить заголовок окна выбора каталога (Обзор папок), хотелось сделать универсально, но даже при попытке использовать класс имени окна ("classname=#32770"), почему то вместо окна обзора папок находит окно диспетчера задач... и кстати, интересно, в английской версии Windows как это окно называется, я предположил что Select folder, но не уверен.

Вот собственно адаптированные функции и пример использования:

Пример:


#include <GUIConstants.au3>
#NoTrayIcon

Global Const $BFFM_SETSELECTION = $WM_USER + 102

_FileSelFolderHandler()

$hWnd = WinGetHandle(WinGetTitle(""))
$InitDir = @WindowsDir
$FileNeeded = "Notepad.exe"

While 1
$Ret = _FileSelectFolder('Select Folder', 0, 1, $InitDir, $hWnd)
If @error Then ExitLoop
If FileExists($Ret & "\" & $FileNeeded) Then ExitLoop

MsgBox(48, "Error", "Please select folder that contain " & $FileNeeded, 3)
$InitDir = $Ret
WEnd

If Not @error Then MsgBox(64, "Results", "File <" & $FileNeeded & "> was found in selected directory (" & $Ret & ")")


На заметку - В начале примера присутствие функции _FileSelFolderHandler() жизнено необходимо, иначе вас ждёт весьма неприятная учесть (которая постигла меня) - скрипт “начнёт запускать себя” бесконечно, я наверно минут 5 боролся с его процессами вооружившись ProcessKiller'ом :moderator

Функции:


Func _FileSelectFolder($title, $root = 0, $flags = 0, $InitDir = '', $hwnd = 0)
Local $ret, $pidl, $res = ''
; Создание структур данных
Local $ubi = DllStructCreate ("hwnd;ptr;ptr;ptr;int;ptr;ptr;int") ; управляющая структура BROWSEINFO
Local $utl = DllStructCreate ("char[512],char") ; заголовок окна
Local $urs = DllStructCreate ("char[260]") ; буфер для возвращаемого пути (длиной MAX_PATH)
Local $ulf = BitOR (BitShift(BitAnd ($flags,1),-9), _ ; 1: не позволять создавать новые каталоги
BitShift(BitAnd ($flags,2),-5), _ ; 2: использовать новый стиль диалога
BitShift(BitAnd ($flags,4),-2), 1) ; 4: включить cтроку редактирования ;Последняя единица для деактивирования кнопки OK.
; Заполнение структур данных
DllStructSetData ($utl, 1, $title)
DllStructSetData ($ubi, 1, $hwnd)
DllStructSetData ($ubi, 3, DllStructGetPtr($urs))
DllStructSetData ($ubi, 4, DllStructGetPtr($utl))
DllStructSetData ($ubi, 5, $ulf)
$ret = DllCall ("shell32.dll", "ptr", "SHGetSpecialFolderLocation", _
"int", 0 , _
"int", $root , _
"ptr", DllStructGetPtr($ubi, 2))
If $ret[0] Then Return $res

;Запуск управляющего скрипта
Local $RunLine = '"' & @ScriptFullPath
If Not @Compiled Then $RunLine = @AutoItExe & ' "' & @ScriptFullPath
Run($RunLine & '" /SetInitDir')

WinWait("_FileOpenDialogControl", "", 3)

; Создаем и заполняем структуру для $initDir
$str = DllStructCreate ("char[260]")
DllStructSetData ($str, 1, $initDir)
; Ищем окно управляющего скрипта
$hOpenDialogControl = WinGetHandle("_FileOpenDialogControl")
; Если найдено, отправляем сообщение с указателем
If Not @error Then
$ret = DllCall ("user32.dll", "int", "SendMessage", _
"hwnd", $hOpenDialogControl, _
"int", $BFFM_SETSELECTION, _
"int", 1, _
"ptr", DllStructGetPtr ($str) )
EndIf

; Открытие окна выбора каталога
$pidl = DllCall ("shell32.dll", "ptr", "SHBrowseForFolder", "ptr", DllStructGetPtr ($ubi))
If $pidl[0] Then
$ret = DllCall ("shell32.dll", "int", "SHGetPathFromIDList", _
"ptr", $pidl[0], _
"ptr", DllStructGetPtr ($urs))
If $ret[0] Then $res = DllStructGetData ($urs, 1)
DllCall ("ole32.dll", "int", "CoTaskMemFree", "ptr", $pidl[0]) ; чистим за собой
Else
Return SetError(1)
EndIf
DllCall ("ole32.dll", "int", "CoTaskMemFree", "ptr", DllStructGetData ($ubi, 2))
Return $res ; Вывод результата
EndFunc

Func _FileSelFolderHandler()
If $CmdLine[0] > 0 And $CmdLine[1] = "/SetInitDir" Then
Local $FSFTitle = "Обзор папок", $hMsgWnd
If @OSLang <> 0419 Then $FSFTitle = "Select Folder"
Global $arrMsgSend [1][4]=[[0,0,0,0]]

Local $hWndMain = GUICreate("_FileOpenDialogControl")
GUIRegisterMsg ($BFFM_SETSELECTION, "_SaveMsgParms")

WinWait($FSFTitle, "", 3)

If $arrMsgSend[0][0] Then
$hMsgWnd = WinGetHandle($FSFTitle)
For $i=1 To $arrMsgSend[0][0]
DllCall ("user32.dll", "int", "SendMessage", _
"hwnd",$hMsgWnd, _
"int", $arrMsgSend[$i][1], _
"int", $arrMsgSend[$i][2], _
"ptr", $arrMsgSend[$i][3] )
Next
EndIf
Exit
EndIf
EndFunc

Func _SaveMsgParms($hWnd, $iMsg, $WParam, $LParam)
Switch $iMsg
Case $BFFM_SETSELECTION
$arrMsgSend[0][0]+=1
ReDim $arrMsgSend[$arrMsgSend[0][0]+1][4]
$arrMsgSend[$arrMsgSend[0][0]][1] = $BFFM_SETSELECTION
$arrMsgSend[$arrMsgSend[0][0]][2] = $WParam
$arrMsgSend[$arrMsgSend[0][0]][3] = $LParam
EndSwitch
EndFunc

Creat0R
05-05-2007, 12:37
amel27
в чем собственно проблема?.. неужели так существенна одна лишняя строка кода?
Эх, если-бы одна... иногда такие замены приходится делать по 10, а то и 20 раз...

В общем решил я эту задачку UDF'ным путём ;) ...


$String = 'file://localhost/%22c:/my%20test/test.zip%22'
$Patern = 'file://localhost/|/|%20|%22'
$Replace = '|\\| |"'

$Results = _StringRexExpReplaceEx($String,

MsgBox(64, "Results", $Results) ;На выходе имеем это: "c:\my test\test.zip"

Func _StringRexExpReplaceEx($String, $Patern, $Replace)
If StringInStr($Patern, '|') And StringInStr($Replace, '|') Then
Local $PaternArr = StringSplit($Patern, '|')
Local $ReplaceArr = StringSplit($Replace, '|')
Local $Ret = $String
Local $Ubound = UBound($ReplaceArr)
If UBound($PaternArr) <= UBound($ReplaceArr) Then $Ubound = UBound($PaternArr)
For $i = 1 To $Ubound-1
$Ret = StringRegExpReplace($Ret, $PaternArr[$i], $ReplaceArr[$i])
Next
Return $Ret
Else
Return StringRegExpReplace($String, $Patern, $Replace)
EndIf
EndFunc


Правда не удаётся сделать замену по ссимволу | - но мне пока что это не нужно :)

amel27
06-05-2007, 09:02
Creat0RА обязательно создавать фиктивное окно, пмещать в массив данные и передавать обратно в окно выбора каталога?- Без GUI-окна некому будет отправлять GUI-сообщение... Конечно, в Windows есть и другие способы межпроцессного обмена, просто я не мудрствуя использовал тот же метод доставки, что и для окна "Обзор папок" (через SendMessage). Альтернативный способ - расшарить именованный кусок памяти, но для этого придется опять колдовать с API-функциями... Через консоль наверно тоже можно, но без "извращений" не обойдется, так как строго говоря AutoIT-приложения не являются консольными;
- для одного сообщения массив понятно не нужен, это я с запасом на обработку нескольких сообщений зарядил SWITCH, ну и соответственно массив;Не получается нормально определить заголовок окна выбора каталога (Обзор папок)ну да, проблематично определить HWID окна, которое еще не создано :) ... тем более, что класс у него вполне стандартный, как вариант - использовать для идентификации кроме заголовка - текст окна, переданный первым параметром функции.

ADD:помнится, я еще практиковал межскриптовый обмен через ключи рееестра... скажем, один меняет значение извеcтного параметра, а второй в цикле отслеживает эти значения и делает свои выводы (по SWITH)... хотя это было вызвано совсем другими причинами - оба скрипта крутились под разными учетками, один под SYSTEM, а второй под рядовым пользователем.

amel27
07-05-2007, 11:30
Creat0R

Вроде разобрался с DLL-кой, проблема была не в GUIRegisterMsg (она-то как раз работает), а в самой DLL-ке... Нашел где подправить чтобы запустилась, осталось только состыковаться с автором и перекомпилить как надо. :)

Все-таки через CallBack все выглядит намного круче - можно по ходу получать инфу о выбранных файлах/каталогах, фильтрах, контролировать правильность ввода в Edit-Boxе и на основании этого менять подстветку, текст кнопок или текст статус-бара.

mrak1990
07-05-2007, 16:30
Покопался я насчёт этого вопроса. Но только начал копать в сторону меню у папок и файлов и пришёл к выводу, что такие пункты как "WinRAR", "Проверить на вирусы" (Kaspersky) добавляются из .dll-файлов. Потом даже открыл какой-то из файлов WinRAR,а и нашёл там строки из контекстного меню.
А у меня на рабочем столе в меню есть пункт "Панель управления NVIDIA", которую можно убирать через настройки. Я думаю с этим пунктом таже история, что и с WinRAR - как-то через DLL. Короче на данном этапе врядли что-то получится сделать.

Я в общем покопался ещё с этой всей фигнёй. И у меня получилось всё ьаки добавить свой пункт в меню. Проблема в том что на неё нельзя повесить команду, а только ID.
MENUITEM "Мой пункт", 29640
Где можно узнать или где содержится этот список команд и соответствующих им ID?

Нашёл ссылку, вроде бы относящуюся к делу: http://msdn2.microsoft.com/en-us/library/aa381023.aspx

amel27
10-05-2007, 13:00
Creat0R

Автор DLL-ки подкинул идею, как можно попробовать реализовать средствами AutoIT... К сожалению, фокус прокатил только с классическим интерфейсом, но это уже большой плюс!.. Для окна в стиле Explorer без сторонних модулей видимо не обойтись.#include <GUIConstants.au3>

Global Const $BFFM_SETSELECTION = $WM_USER + 102

Global Const $BIF_BROWSEFORCOMPUTER = 0x1000 ; Выбирать только компьютеры в сетевом окружении
Global Const $BIF_BROWSEFORPRINTER = 0x2000 ; Выбирать только принтеры в сетевом окружении
Global Const $BIF_BROWSEINCLUDEFILES = 0x4000 ; Позволить выбирать файлы
Global Const $BIF_DONTGOBELOWDOMAIN = 0x2 ; Не открывать домены в сетевом окружении
Global Const $BIF_EDITBOX = 0x10 ; Включить строку редактирования
Global Const $BIF_RETURNONLYFSDIRS = 0x1 ; Выбирать только объекты файловой системы

Global Const $BIF_OLDSTYLEFLAGS = BitOR ($BIF_BROWSEFORCOMPUTER, $BIF_BROWSEFORPRINTER, $BIF_BROWSEINCLUDEFILES, _
$BIF_DONTGOBELOWDOMAIN, $BIF_EDITBOX, $BIF_RETURNONLYFSDIRS)

; Примитивный ГУИ для примера
$hWndMain = GUICreate ("Тест", 200, 45, -1, -1)
$Button_1 = GUICtrlCreateButton ("Выбрать папку", 55, 10)
GUISetState()
While 1
$msg = GUIGetMsg()
Select
Case $msg = $GUI_EVENT_CLOSE
ExitLoop
Case $msg = $Button_1
$res = _FileSelectFolderOldStyle ('Выбор объекта:', 0, $BIF_RETURNONLYFSDIRS, 'C:\Windows', $hWndMain)
MsgBox (0, "Выбран объект:", $res)
EndSelect
Wend

; Процедура инициализации стартового каталога
Func _FileSelectFolderOldStyleProc ($hWnd, $Msg, $wParam, $lParam)
$ret = DllCall ("user32.dll", "int", "SendMessage", _
"hwnd",$hWnd, _
"int", $BFFM_SETSELECTION, _
"int", 1, _
"ptr", $lParam )
EndFunc

Func _FileSelectFolderOldStyle ($text = '', $root = 0, $flags = 0, $iniDir = '', $hwnd = 0)
Local $ret, $pidl, $res = ''
; Создание структур данных
Local $ubi = DllStructCreate ("hwnd;ptr;ptr;ptr;int;ptr;ptr;int") ; управляющая структура BROWSEINFO
Local $utl = DllStructCreate ("char[512],char") ; текст окна
Local $urs = DllStructCreate ("char[260]") ; буфер для возвращаемого пути (длиной MAX_PATH)
Local $ulf = BitAnd ($flags, $BIF_OLDSTYLEFLAGS) ; фильтруем только разрешенные флаги
; Заполнение структур данных
DllStructSetData ($utl, 1, $text)
DllStructSetData ($ubi, 1, $hwnd)
DllStructSetData ($ubi, 3, DllStructGetPtr($urs))
DllStructSetData ($ubi, 4, DllStructGetPtr($utl))
DllStructSetData ($ubi, 5, $ulf)
If ($iniDir <> '') And ($hwnd <> 0) Then
Local $udr = DllStructCreate ("char[" & StringLen ($iniDir)+1 & "]")
DllStructSetData ($udr, 1, $iniDir)
$ret = DllCall ("user32.dll", "ptr", "GetWindowLong", "hwnd", $hwnd, "int", -4)
DllStructSetData ($ubi, 6, $ret[0])
DllStructSetData ($ubi, 7, DllStructGetPtr($udr))
EndIf
$ret = DllCall ("shell32.dll", "ptr", "SHGetSpecialFolderLocation", _
"int", 0 , "int", $root , "ptr", DllStructGetPtr($ubi, 2) )
If $ret[0] Then Return $res
GUIRegisterMsg (1, "_FileSelectFolderOldStyleProc") ; регистрируем событие для перехвата
; Открытие окна выбора каталога
$pidl = DllCall ("shell32.dll", "ptr", "SHBrowseForFolder", "ptr", DllStructGetPtr ($ubi))
GUIRegisterMsg (1, "") ; разрегистрируем событие
If $pidl[0] Then
$ret = DllCall ("shell32.dll", "int", "SHGetPathFromIDList", _
"ptr", $pidl[0], "ptr", DllStructGetPtr ($urs))
If $ret[0] Then $res = DllStructGetData ($urs, 1)
DllCall ("ole32.dll", "int", "CoTaskMemFree", "ptr", $pidl[0]) ; чистим за собой
EndIf
DllCall ("ole32.dll", "int", "CoTaskMemFree", "ptr", DllStructGetData ($ubi, 2))
Return $res ; Вывод результата
EndFunc

Creat0R
10-05-2007, 14:45
amel27
К сожалению, фокус прокатил только с классическим интерфейсом, но это уже большой плюс!
Это огромный плюс!!! а зачем больше, классика есть классика :) - Тем более что строка состояния есть, возможность выбора только объектов файловой системы есть, "родительский/дочерний статус" есть :), и даже есть опция выбора не только каталогов, но и файлов!!! (о чём я лично, вообще и не подозревал в подобном диалоге)... что ещё нужно?

Большое спасибо тебе, и автору идеи!

Diamond
11-05-2007, 03:20
Завершение процессов и служб
Некоторые процессы невозможно завершить с помощью ProcessClose() т.к. они имеют отношение к службам.
А если такой просесс завершить принудительно, (например с помощью консольной команды TASKKILL) то в журнал системных событий записывается сообщение об ошибке, и потом что либо найти в нём с каждым разом становится всё труднее...
Всё это навело меня на мысль написать скрипт:

$ProcessName="oodag.exe" ; имя завершаемого процесса
;~ Подключаемся к WMI:
$WMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\.\root\CIMV2")
$PID = ProcessExists($ProcessName) ;Определяем PID
If $PID Then ProcessClose($PID) ; Если существует - пытаемся убить
If ProcessExists($PID) Then ; Если процесс всё ещё существует тогда
$OutputName=CheckService($PID) ; проверяем принадлежность процесса к службам (проверку можно пропусить!!!)
If Not $OutputName=0 Then ; Если является службой тогда
$Pressed=MsgBox(262144+32+4,"", "Не удалось завершить процесс поскольку"& @CR & _
"он является запущенной службой: " & $OutputName & @CR & _
"Остановить службу?")
If $Pressed=6 Then KillService($PID) ; Если "Да" - останавливаем службу
EndIf
EndIf

;~ ==================================================
;~ Определяет, является ли процесс запущенной службой (Эту функцию можно исключить!!!)
;~ Если является службой - возвращает "Выводное имя" службы, в противном случае 0
Func CheckService($PrPid)
;~ Формируем текст запроса:
$QueryText = "SELECT * FROM Win32_Service WHERE ProcessId = '" & $PrPid & "'"
;~ Создаём объект-коллекцию:
$CollectionServices = $WMI.ExecQuery($QueryText)
If $CollectionServices.Count > 0 Then ; Если элементов коллекции > 0 Тогда
;~ Цикл по элемент(у)ам коллекции:
For $objItem In $CollectionServices
Return $objItem.DisplayName
Next
Else
Return 0
EndIf
EndFunc

;~ ==================================================
;~ Останавливает службу, в случае успеха возвращает: 0
Func KillService($PrPID)
;~ Формируем текст запроса:
$QueryText = "SELECT * FROM Win32_Service WHERE ProcessId = '" & $PrPid & "'"
;~ Создаём объект-коллекцию:
$CollectionServices = $WMI.ExecQuery($QueryText)
If $CollectionServices.Count > 0 Then ; Если элементов коллекции > 0 Тогда
;~ Цикл по элемент(у)ам коллекции:
For $objItem In $CollectionServices
Return $objItem.StopService()
Next
EndIf
EndFunc

Diamond
11-05-2007, 04:34
mrak1990
А с чем это связано? Как я понял, при запуске скрипа он первым делом обрабатывается интерпретатором и висит в памяти. И он уже не обращается к файлу. Возможно, что я и не прав. У кого есть мысли по этому поводу - пишите.
При запуске, скрипт действительно обрабатывается интерпретатором и загружается в память, после чего может быть переименован или удалён.
Я думаю единственным препятствием может быть "блокирующий дескриптор" - а откуда ему там взятся, если только в момент переименования, файл не открыт для записи каким либо другим процессом (естественно, такое "открытие" может произойти только с ведома пользователя).

mrak1990
11-05-2007, 20:56
DiamondПри запуске, скрипт действительно обрабатывается интерпретатором и загружается в память, после чего может быть переименован или удалён.
Я думаю единственным препятствием может быть "блокирующий дескриптор" - а откуда ему там взятся, если только в момент переименования, файл не открыт для записи каким либо другим процессом (естественно, такое "открытие" может произойти только с ведома пользователя).
К счастью скрипт такой, что на выполнение не требуется особого времени. Тем более, я им сейчас активно пользуюсь. Вроде всё без глюков.
Единственное, что надо будет дописать, чтобы он обновлял не только открытые окна, рабочий стол, но и диалог выбора\открытия файла. Но в этом нет ничего трудного, к счастью.

VelDmi
13-05-2007, 12:06
Почему вот такой батник работает:
fsum.exe -c -r -d%inputdir% %mdfile% > fsum.err
а автоит нет:
RunWait (@ScriptDir& '\fsum.exe -c -r -d' &$inputdir& ' ' &$mdfile& ' > ' &@ScriptDir& '\fsum.err', @ScriptDir)
пробовал так-же
RunWait (@COMSPEC & ' /c fsum.exe -c -r -d' &$inputdir& ' ' &$mdfile& ' > ' &@ScriptDir& '\fsum.err', @ScriptDir)

Как привильно запустить команду?

Creat0R
13-05-2007, 16:31
VelDmi
Как привильно запустить команду?
А в чём проявляется проблема с данным примером?

Возможно путь к скрипту содержит пробелы, или служебные символы, в таком случае надёжнее заключать пути в кавычки:


RunWait ('"' & @ScriptDir & '\fsum.exe" -c -r -d' & $inputdir & ' ' & $mdfile & ' > "' & @ScriptDir & '\fsum.err"', @ScriptDir)

VelDmi
13-05-2007, 17:45
не работает > fsum.err, то есть при вызове из автоит не пишет в файл fsum.err

amel27
14-05-2007, 06:20
VelDmi
проверил - с @COMSPEC все работает, попробуй вместо /c поставить /k и отследить сообщения

VelDmi
14-05-2007, 09:39
amel27
Посмотри пожалуйста пример вживую. http://rapidshare.com/files/31198773/1.rar.html
Батником у меня создается файл, а автоитом нет.

amel27
14-05-2007, 12:36
VelDmi
CMD ругался на кавычки после ">", так с кавычками вроде работает:$CutDir = '"' &@ScriptDir& '\CutDir' & '"'
$exfile = '"' &@ScriptDir& '\fsum.exe' & '"'
$mdfile = '"' &@ScriptDir& '\sums.md5' & '"'
$erfile = '"' &@ScriptDir& '\fsums.err' & '"'

RunWait (@COMSPEC & ' /c ' & '(' & $exfile & ' -c -r -d' & $CutDir & ' ' & $mdfile & ' >' & $erfile & ')', @ScriptDir)

Creat0R
15-05-2007, 06:06
Вышла новая версия - AutoIt v3.2.4.1 (http://www.autoitscript.com/autoit3/downloads.php)...

Из глобальных изменении:

*AutoIt теперь скомпилирован для Unicode, AutoIt3.exe для Unicode - AutoIt3A.exe для ANSI. Для более подробной информации смотрите эту страницу (http://www.autoitscript.com/autoit3/docs/intro/unicode.htm).
*Переписан инструмент для работы с окнами (Au3Info tool).
*Функции бинарных данных полностью переписаны - скрипты использующие эти функции будет необходимо изменить.

Справка на русском для AutoIt v3.2.4.0 (http://www.autoitscript.com/cgi-bin/getfile.pl?autoit3/russian-v3.2.4.0.zip).




© OSzone.net 2001-2012