Компьютерный форум OSzone.net

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Автоматическая установка приложений (http://forum.oszone.net/forumdisplay.php?f=61)
-   -   [Архив] AutoIt скрипты - автоматическая установка приложений (http://forum.oszone.net/showthread.php?t=46951)

EgOrus 20-03-2005 18:12

[Архив] AutoIt скрипты - автоматическая установка приложений
 


Внимание! Вы читаете версию для печати архивной темы по Autoit.
Все темы по Autoit, включая текущее обсуждение, можно найти по этой ссылке.

Руководство к действию по работе c AutoIt.

Ну во превых, к моему удивлению, утилита (и компонента activeX) уже успела обновиться до версии 3.1.0 (7 фев 2005) и заполучить множество дополнительных функций (появилась возможность создавать граф. интерфейс к своим скриптам :). К сожалению русскоязычной справки пока нет.
Скачать можно здесь

Почему лишь руководство? Потомучто к программе прилагается обширная справка с описанием самой программы и команд, в т.ч. и на русском языке. Основные команды используемые в нашем случае в новой версии не поменялись. Я рассмотрю лишь самые азы, кот. необходимы для создания самого простого скрипта, в принципе этого достаточно для установки практически любой программы, просто знание дополнительных команд позволят сделать скрипт более компактным и красивым.

На сегоднящний день имеется 2 распространненых способа по автоматизации установки
1. Использование утилиты AutoIt и файлов скриптов au3, кот. в последствии можно компилировать в исполнимые файлы exe, не требующие утилиты AutoIt.exe
2. Использование VBS и JS скриптов, этот способ можно расширить за счет использования activeX компоненты - autoitX (к слову сказать - я пользуюсь именно этим методом).

Для примера создадим скрипт по установки Alcohol120%. Самое неприятное в его установки это окно с подтверждением установки SCSI драйвера. Это мы и поправим.
Цитата:
Сообщение от Скрипт alc120.au3
'Блокировка клавы и мышки
BlockInput(1)

'Ожидание окна установки SCSI адаптера
WinWait ("Мастер нового оборудования","", 0)

'Пауза на 500 мс на всякий случай, для слабых машин, чтобы окно успело обновиться
Sleep(500)

'Послать в активное окно нажатие клавиши ENTER
send("{ENTER}")

WinWait ("Мастер нового оборудования","Для закрытия мастера", 0)

Sleep(1000)

'Послать в указанное окно ControlClick для кнопки с назв. класса Button9
ControlClick ("Мастер нового оборудования","Для закрытия мастера", "Button9")

'Снятие блокировка клавы и мышки
BlockInput(0)

Скрипт и утилита autoit3.exe будет лежать рядом с дистром, и будет запускаться перед запуском дистрибутива.
Создадим файл с названием alc120.au3 в win1251 кодировке
Теперь нужно заблокировать клавиатуру и мышь чтобы наглый пользователь не нажал что-нибудь или не сменил случайно фокус с активного окна во время работы скрипта.

'Блокировка клавы и мышки (многие команды предназначены для посыла в активное окно)
BlockInput(1)

Скрипт запустился и теперь ожидает запуска инсталяра и появление сигнального окна, кот. сообщит скрипту что программа запущена и можно продолжать выполнение скрипта. Для того чтобы узнать название окна нужно использовать спец. утилитку AU3Info.exe, кот. входит в комплект дистрибутива autoit. Запускаем ее, после чего запускаем дистрибутив Alcohol120% и доходим до того места где вылазит окно Мастер нового оборудования с вопросом об установке SCSI адаптера. Активируем его кликнув по заголовку мышкой и жмем CTRL+ALT+F, в результате в окне AU3Info информация о текущем окне зафиксируется:
Цитата:
>>>>>>>>>>>> Window Details <<<<<<<<<<<<<
Title: Мастер нового оборудования
Class: #32770

копируем название этого заголовка, там же можно посмотреть текст наличествующий в этом окне, если необходимо.
Цитата:
>>>>>>>>>>> Visible Window Text <<<<<<<<<<<
Завершение работы мастера нового оборудования
Мастер завершил установку программ для:
SCSI/RAID хост-контроллер
Для закрытия мастера нажмите кнопку "Готово".
< &Назад
Готово
Отмена

'Ожидание окна установки SCSI адаптера (в зависимости от языка винды заголовок будет разным)
WinWait ("Мастер нового оборудования","", 0)

WinWait ( "title" [, "text" [, timeout]] )
title - название окна кот. ожидает скрипт для продолжения работы,
text - любой текст в этом окне, нужен если последующее окно после нажатия кнопки, имеет такой же заголовок
timeout - таймаут, время через кот. ожидание прекратиться, 0 - никогда


'Пауза на 500 мс на всякий случай, для слабых машин, чтобы окно успело обновиться
Sleep (500)

После того как окно с нужнымм заголовком появилось, скрипт должен послать активному окну клавишу ENTER, в результате будет нажата кнопка по умолчанию (в нашем случае "далее"). Список клавиатурных нажатий см. в справке.

'Послать в активное окно нажатие клавиши ENTER
Send ("{ENTER}")

Далее продолжится устанока SCSI адаптера вплоть до появление последнего окна с предложением закрыть мастер.
'Ожидание окна окончания установки SCSI адаптера
WinWait ("Мастер нового оборудования","Для закрытия мастера", 0)

'Ждем 600 мс. для того чтобы окно успело обновиться
Sleep (600)

Теперь нам нужно нажать клавишу готово, можно воспользоваться тем же методом что и выше Send ("{ENTER}"), но для разнообразия воспользуемся другим, не всегда ведь нам нужна будет кнопка по умолчанию кот. нажимается клавшей ввод. Используем метод ControlClick, кот. позволяет кликнуть по определенному объекту в окне исходя из его идентификатора (Control ID) или Названия Класса (ClassName). Чтобы узнать то или другое используем вышеупомянутую утилитку AU3Info, только теперь подводим курсор на нужную кнопку и смотрим на параметр "ClassNameNN", копируем значение Button9, и используем в скрипте.
Цитата:
>>>>>>>>>>> Control Under Mouse <<<<<<<<<<<
Size: X: 327 Y: 327 W: 75 H: 23
Control ID: 12325
ClassNameNN: Button9
Text: Готово

'Послать в указанное окно ControlClick для кнопки с назв. класса Button9
ControlClick ("Мастер нового оборудования","Для закрытия мастера", "Button9")

ControlClick ( "title", "text", controlID [, button] [, clicks]] )
title - название окна кот. ожидает скрипт для продолжения работы,
text - любой текст в этом окне, нужен если последующее окно после нажатия кнопки, имеет такой же заголовок
controlID - собственно идентификатор
button - какую кнопку использовать "left", "right" или "middle
clicks - количество кликов


Последнее что нужно сделать - снять блокировку с клавы и мышки.
'Снятие блокировка клавы и мышки
BlockInput(0)

После этого скрипт завершается, а алкоголик заканчивает установку.

Теперь нужно проверить работу скрипта.
Cоздаем бат-файл:
Цитата:
Сообщение от alc.bat
start C:\Test\AutoIt3.exe alc120.au3
msiexec.exe /passive /norestart /i "C:\Test\setup.msi"

В процессе выполнения скрипта в трэе появится занчок с буквой A, кот. показыает что скрипт выполняется, после отработки он исчезнет, если в процессе установки возникли проблеммы жмем CTRL+ALT+DEL (даже если клава заблокирована) и снимаем процесс autoit3.exe.

Если скрипт отлажен и проблем не возникает, для удобства можно скомпилировать его в .exe файл (содержит в себе утилиту autoit3.exe и скрипт .au3, кот. исполняется).
Для этого можно воспользоваться утлитой Aut2Exe.exe (входит в комплект с дистрибутивом autoit3).
Если нужно будет в последствии что-то изменить в скрипте, то полученный .exe файл можно будет конвертнуть назад в .au3 с помощью другой утилиты Exe2Aut.exe

Что касается 2го способа установки, то просто приведу пример, установки Alcohol120%, кот. использую я
Цитата:
Сообщение от alc120.vbs

Dim WshShell, fso, objArgs, AutoIt, dir

Set WshShell = WScript.CreateObject("WScript.Shell")
Set fso = CreateObject("Scripting.FileSystemObject")
Set AutoIt = WScript.CreateObject("AutoItX.Control")
On Error Resume Next

' Path to current vbs folder to successfully launch script in WPI
dir = fso.GetParentFolderName(WScript.ScriptFullName)

WshShell.Run ("msiexec.exe /passive /norestart /i" & dir & "\setup.msi")

'Блокировка клавы и мышки
AutoIt.BlockInput "on"
'Ожидание окна установки SCSI адаптера
AutoIt.WinWait "Мастер нового оборудования", "", 0
AutoIt.Sleep 500
AutoIt.Send "{ENTER}"
'Ожидание окна окончания установки SCSI адаптера
AutoIt.WinWait "Мастер нового оборудования", "Для закрытия мастера", 0
AutoIt.Sleep 600
AutoIt.Send "{ENTER}"
AutoIt.BlockInput "off"

WshShell.Run ("REGEDIT /S" & dir & "\sets.reg")

Wscript.Quit

В заключение хочу сказать что AutoIt это не только и не столько средство для автоматизации установки различных приложений, это скриптовый язык для автоматизации работы с приложениями, окнами, файлами и реестром с помощью него вполне реально создать небольшую програмку.

---------------------------------------------------------------------------------------------------

Разобранный здесь скрипт тестировался в vmware 4.5 на WinXP.rus SP2, если кто-то заметит ошибки пишите. Кстати потестите кто-нить этот скрипт, я давно уже этим делом не пользовался мог где-то напутать.

D@nil 20-03-2005 20:55

Статья Клас :)
Только я непонял чем лучше autoitX

D@nil 20-03-2005 21:26

Думаю ешё надо добавить про Переменные и настройки AutoIt.

Переменная должна начинаться с символа $ и может содержать буквы, цифры и символы подчеркивания _.
Цитата:
$exe_1 = "Setup.exe /S"
$exe_2 = "Rusian.exe /S"
RunWait( $Exe_1 )
run( $Exe_2 )


Продолжительность паузы между последовательными симуляциями нажатий клавиатуры. Время в миллисекундах.
Цитата:
AutoItSetOption("SendKeyDelay", 10)


Отображать или нет текущую строку сценария с помощью индикатора системной панели в режиме отладки. Полезно для отладки скриптов
Цитата:
AutoItSetOption("TrayIconHide", 0) ;0=не выводить строку (Стандартное значение), 1=отображать строку


Отображать/Скрыть в системной панели индикатор AutoIt.
Цитата:
AutoItSetOption("TrayIconDebug", 0) ;0 = отображать(Стандартное значение), 1 = скрыть

EgOrus 20-03-2005 21:28

D@nil
Сам по себе autoitX ничем не лучше, скорей даже наоборот по функционалу уступает, а у меня он используется как расширение функций vbs-cкриптов. При использовании такой связки чуть меньше гемора и чуть больше возможностей.

Т.е. если рассмотреть по шагам то получится
Использование Autoit3.exe через CMD-файл или например WPI:
1. команда запуска скрипта через Autoit3.exe или компилированный скрипт
2. команда запуска устанавливаемого приложения
3. команда запуска возможных reg файлов
4. копирование дополнительных файлов
По идее все это можно сделать через .au3, но как-то это некрасиво получится и громоздко :)

Использование vbs, все 4 шага легко делаются в пределах одного VBS-файла, при этом не нужно использовать autoit3.exe или тем более компилить скрипт, этот же vbs можно использовать для обычной установке вне CD или DVD.

Ага, переменные я оставил на потом, а про дебаг сам не знал :)

D@nil 20-03-2005 21:45

EgOrus
Где тогда должна лежать утилитка autoitX Т.К. файл alc120.vbs ссылается на AutoIt
AutoIt.Sleep 600
AutoIt.Send "{ENTER}"

EgOrus 20-03-2005 22:23

autoit - это не утилитка, это объект ActiveX
Set AutoIt = WScript.CreateObject("AutoItX.Control") - объявление объекта Autoit
AutoIt.Sleep 600 - использование функции объекта Autoit, в данном случае функции sleep





Sanja Alone 20-03-2005 23:14

как ПРАВИЛЬНО отличить 2 "одинаковых" окна средствами AutoIt?
 
Вопрос: как ПРАВИЛЬНО отличить 2 "одинаковых" окна средствами AutoIt?
Т.е., они конечно не одинаковые, одинаковы только все параметры окон отображаемые с пом. AutoIt Reveal Mode.
Реально текст в окнах разный, но AutoIt Reveal Mode показывает только одинаковые строки.

Я нашел в хелпе по AutoIt вот такую штуку:
DetectHiddenText, <on | off>
но, даже если она действительно определяет скрытый текст,
непонятно как добраться до результата сией операции...
Через
WinGetActiveStats, <Title Var>, <Width Var>, <Height Var>, <Xpos Var>, <Ypos Var>
не выйдет, т.к. эта функция не извлекает текст окна.


Сначала я сделал так, но здесь те самые два окна с одинаковыми заголовками и текстом застопорили скрипт:
(проблемный фрагмент я выделил красным цветом)

Код:
Run, %ProgramFiles%\\Sonic Foundry\\Sound Forge 6.0\\forge60.exe %systemdrive%\\install\\test.mpg WinWaitActive, Sonic Foundry Sound Forge 6.0,Purchase... Send, {ENTER} WinWaitActive, Sonic Foundry - MPEG Plug-In,Progress1 LeftClick, 400, 340 WinWaitActive, Sonic Foundry,Progress1 LeftClick, 120, 240 WinWaitActive, Sonic Foundry,Progress1 LeftClick, 100, 273 Send, %Serial2% Send, {ENTER} WinWaitActive, MainConcept MPEG-1,2 Pro Plug-In,Thank you for purchasing MainConcept MPEG-1&2 Pro Plug-In. Send, {ENTER} WinWaitClose, MainConcept MPEG-1,2 Pro Plug-In,Thank you for purchasing MainConcept MPEG-1&2 Pro Plug-In. WinClose, Sonic Foundry Sound Forge 6.0 WinWaitClose, Sonic Foundry Sound Forge 6.0 Sleep, 50


Т.е. второе окно появилось и на этом все, а клик для активизации поля ввода серийника уже не проходит.


Затем я таки поборол эту каку,
но явно неправильным методом (3 сек. задержка + 2 двойных клика),
т.к. в конце приходится убивать процесс (иначе он вызывает крит.ошибку).
Правда, при этом информация о регистрации сохраняется.

Код:
Run, %ProgramFiles%\\Sonic Foundry\\Sound Forge 6.0\\forge60.exe %systemdrive%\\install\\test.mpg WinWaitActive, Sonic Foundry Sound Forge 6.0,Purchase... Send, {ENTER} WinWaitActive, Sonic Foundry - MPEG Plug-In,Progress1 LeftClick, 400, 340 WinWaitActive, Sonic Foundry,Progress1 LeftClick, 120, 240 Sleep, 3000 LeftClick, 100, 273 LeftClick, 100, 273 LeftClick, 100, 273 LeftClick, 100, 273 Send, %Serial2% Send, {ENTER} WinWaitActive, MainConcept MPEG-1,2 Pro Plug-In,Thank you for purchasing MainConcept MPEG-1&2 Pro Plug-In. Send, {ENTER} WinWaitClose, MainConcept MPEG-1,2 Pro Plug-In,Thank you for purchasing MainConcept MPEG-1&2 Pro Plug-In. WinWaitActive, Sonic Foundry Sound Forge 6.0 RunWait, taskkill.exe /F /IM forge60.exe Sleep, 2000


Какие буду идеи?

EgOrus 20-03-2005 23:38

Sanja Alone
надо было в существующую тему добавлять.
А какая у тебя версия autoit? reveal mode был в версии 2.x на сколько я помню

Opt("WinDetectHiddenText", 0)
и потом используешь WinWait ( "title" [, "text" [, timeout]] , но вместо text попробуй использовать hiddentext из второго окна

Sanja Alone 21-03-2005 17:40

Цитата:
надо было в существующую тему добавлять.

Ну не посмотрел я, каюсь.

Цитата:
А какая у тебя версия autoit? reveal mode был в версии 2.x на сколько я помню

Да, ты прав: версия 2.64. Когда-то скачал и не юзал, а теперь понадобилась.

Сейчас качаю 3.1.0 - посмотрю, может там что-то придумали.
Надеюсь, там уже есть определение окна по идентификатору.

type 22-03-2005 22:54

Установил, AutoIt v3.
пытаюсь запустить что нить комадндой
Цитата:
Run("adbacrob6.exe", "C:\Install\Graphic", @SW_HIDE)

не прокатывает и все((
говорит, что "Unable to execute the external program"
но все лежит именно по этому пути.
может есь какой секре, хотя в хелпе ясно сказано как запускать exe и cmd файлы.

EgOrus 22-03-2005 23:18

type
на сколько я помню, надо уазывать полный путь к программе, т.е. что-то типа c:\Install\adbacrob6.exe, можно использовать переменные окружения н-р: Run(@ProgramFilesDir & "\Alcohol Soft\Alcohol 120\Alcohol.exe")
что касается твоего пути, то это рабочая папка, а не путь до программы

type 22-03-2005 23:29

ОО!!!!....зарабоооталааа))))
я Вам благодарен!)

Debby 23-03-2005 09:15

Вопрос из области флейма

Блин такая дилемма - с одной стороны, можно с помощью AutoIt забабахать конкретный диск с кучей софта и не мучиться, а с другой стороны, охота все-таки взять, помучиться и все-таки заставить приложение ставиться в "тихом" режиме с "родными" ключами. Что делать?

EgOrus 23-03-2005 10:02

Debby
Искать ключи на msfn'е, если нет пробовать самому исходя из инстолятора, а если уж и это не помогло то все равно придется мучиться пока скрипты составлять будешь :)

Sanja Alone 23-03-2005 18:27

Короче, обошел я эту гадость с одинаковыми окнами (они оказались абсолютно одинаковы даже для AutoIt Window Info).
Обошел опять не совсем правильно, но влазить в функции с указателями мне не хотелось (уж сильно мутно):

Код:
... Run ( '"' & @ProgramFilesDir & '\Sonic Foundry\Sound Forge 6.0\forge60.exe" ' & EnvGet('systemdrive') & '\install\test.mpg' ) WinWaitActive ( 'Sonic Foundry Sound Forge 6.0', 'Purchase...' ) Send ( '{ENTER}' ) WinWaitActive ( 'Sonic Foundry - MPEG Plug-In' ) MouseClick( "left", 400, 340, 1, 0 ) WinWaitActive ( 'Sonic Foundry' ) ;переименовываем окно, чтобы скрипт не завис WinSetTitle ( 'Sonic Foundry', '', "SF" ) WinWaitActive ( 'SF' ) MouseClick( "left", 120, 240, 1, 0 ) ;это окно - причина переименования предыдущего, т.к. окна по ВСЕМ параметрам идентичны (AutoIt Window Info) WinWaitActive( 'Sonic Foundry' ) ;активизируем поле ввода серийника (через ControlSetText к полю не достучаться - его не видно) MouseClick( "left", 100, 273, 1, 0 ) ;3-й шаг регистрации "MainConcept MPEG-1&2 Pro Plug-In" - вводим серийник Send ( $Serial2 ) Send ( '{ENTER}' ) WinWaitActive ( 'MainConcept MPEG-1,2 Pro Plug-In', 'Thank you for purchasing' ) Send ( '{ENTER}' ) WinWaitClose ( 'MainConcept MPEG-1,2 Pro Plug-In', 'Thank you for purchasing' ) ;дожидаемся окна Sound Forge, чтобы сохранились данные регистрации WinWaitActive ( 'Sonic Foundry Sound Forge 6.0' ) ;здесь (при нормальном закрытии Sound Forge с пом. WinClose) происходит крит.ошибка, ;поэтому просто убиваем процесс (все рег. данные уже сохранены) ;(для красоты спрячем процесс убийства с пом. флага @SW_HIDE) RunWait ( 'taskkill.exe /F /IM forge60.exe', '', @SW_HIDE ) Sleep ( 1000 ) ;снимаем блокировку мыши и клавы BlockInput ( 0 )


Жаль, что в новой версии AutoIt нельзя работать с элементами:
  • TreeView
  • CheckListBox
Пример первого - выбор компонент в установщике WinAmp
Пример последнего - выбор компонент в установщиках K-Lite Codec Pack
(по идее, можно применить silent.inf файл, но у меня параметр components=... игнорируется напрочь)

D@nil 23-03-2005 22:28


Спасиб Sanja Alone метод WinSetTitle удобный, Возьму на заметку

type 23-03-2005 22:58

Как можно в текстовое поле ввести значение.
а то ввожу
WinWait("AutoCAD 2002 Setup","&Serial Number:")
Send("{4}")
Send("{0}")
Send("{0}")
Send("{TAB}")
Send("{1}")
Send("{2}")
Send("{3}")
Send("{4}")
Send("{5}")
Send("{6}")
Send("{7}")
Send("{8}")
Send("{TAB}")
Send("{T}")
......
ну и в таком духе, как можно ввести в поле сразу все значение?

D@nil 23-03-2005 23:48

type Можно.
WinWait("AutoCAD 2002 Setup","&Serial Number:")
Send("400" & {TAB} & "12345678" & "{TAB}" & "T")
А вобще смотри справку к AutoIt3 :beer:

type 24-03-2005 00:33

точно точно....D@nil так есть...надо читать хелп...
Цитата:
Send("400" & {TAB} & "12345678" & {TAB} & "T")

ток у меня без кавычек для {TAB} не нработает т.е. надо так
Send("400" & "{TAB}" & "12345678" & "{TAB}" & "T")
Но ты выручил...спасибо.!!))

Aspirine 25-03-2005 13:35

Ребята у меня проблема!!
Устанавливаю скриптом VirtulСD, пробую без компиляции все ок работает. Потом кампилирую как написано к руководстве. После кампиляции у меня получается вместо 29мбайтного файла установки 100кб? В чём проблема подскажте??


Sanja Alone 25-03-2005 19:46

Aspirine
При компиляции, получается *.exe файл с тем же, что и у *.au3 именем.
В твоем случае итоговое имя совпадает с именем файла-установщика самой проги VirtualCD и он перезаписывается поверх.
Просто смени имя *.au3 файла, скажем на autoit_vcd.au3, тогда при компиляции получишь autoit_vcd.exe.

А вообще, на кой тебе этот VirtualCD? Тот же Alcohol прекрасно монтирует его файлы *.vcd и *.000 (только при их добавлении, в списке нужно выбрать "все файлы", а не "все поддерживаемые образы")
А если нужно создавать образы CD/DVD самостоятельно добавляя/удаляя файлы/каталоги, то можно воспользоваться UltraISO. К тому же, UltraISO понимает наверное все форматы образов, и может их конвертировать в iso, nrg, ccd, bin.

P.S. Я когда-то тоже юзал VCD (v4 и немного v5), но тогда это был чуть-ли не единственный нормальный эмулятор.
Все течет, все меняется... (C) не мое


----------------------------


type
В твоем варианте посылки строкой символов, на слабой машине TAB может просто не успеть перевести фокус (если не увеличить "SendKeyDelay") на другое поле и будет бяка.
IMHO, правильнее (и быстрее) будет не симулировать нажатия клавиш, а непосредственно ввести данные в соотв. поле. В какое? - посмотри с пом. AutoIt Window Info.
Вот, как пример (установка Ultra ISO v7.5.1.965):

Код:
;скрыть в системной панели индикатор AutoIt AutoItSetOption("TrayIconHide", 1) ;блокируем мышь и клаву BlockInput ( 1 ) ;запуск установки в тихом режиме RunWait ( 'uiso75me-s.exe /VERYSILENT /SP-' ) ;запуск проги для появления диалога регистрации Run ( @ProgramFilesDir & '\UltraISO\UltraISO.exe' ) WinWait ( 'Добро пожаловать' ) WinActivate ( 'Добро пожаловать' ) ControlClick ( 'Добро пожаловать', '', 'TButton4' ) WinActivate ( 'Регистрация' ) ;ввод рег. данных ControlSetText ( 'Регистрация', '', 'TEdit4', 'Имя регистрации' ) ControlSetText ( 'Регистрация', '', 'TEdit5', 'хххх' ) ControlSetText ( 'Регистрация', '', 'TEdit3', 'хххх' ) ControlSetText ( 'Регистрация', '', 'TEdit2', 'хххх' ) ControlSetText ( 'Регистрация', '', 'TEdit1', 'хххх' ) ControlClick ( 'Регистрация', '', 'TButton2' ) WinWaitActive ( 'Подсказка' ) Send ( '{ENTER}' ) WinWaitClose ( 'Подсказка' ) Sleep ( 50 ) ;удаление с раб. стола, и перенос ярлыков в более удобный каталог FileDelete ( EnvGet("USERPROFILE") & '\Рабочий стол\UltraISO.lnk' ) DirCopy ( EnvGet("ALLUSERSPROFILE") & '\Главное меню\Программы\UltraISO', EnvGet("ALLUSERSPROFILE") & '\Главное меню\Программы\CD и DVD утилиты\UltraISO', 1 ) DirRemove ( EnvGet("ALLUSERSPROFILE") & '\Главное меню\Программы\UltraISO', 1 ) ;снимаем блокировку мыши и клавы BlockInput ( 0 )


Есть еще один плюс такого подхода - никакие автопереключатели раскладки (Punto Switcher и т.п.) не испортят ввод серийников.

Aspirine 26-03-2005 13:20

Sanja Alone
Огромное спасибо!!!!!
Всё прекрасно заработало. Я сам нелавно начал изучать autoit крипты, поэтому ошибаюсь на лёгком и часто...
Насчёт VirtualCD. Я диск другу делаю, котрый в компах ни буи-бум, и не желает учиться работать с другими прогами(он до сизх пор пользуется v4.3 если не ошиюбаюсь..) Сам я ЮЗАЮ АЛКОГОЛЬЧИК.

Sanja Alone 26-03-2005 17:27

Aspirine

Всегда рад помочь.
А юзать Autoit я тоже недавно начал - около недели назад (да еще сдуру с версии 2.64). Потом пришлось по-быстрому переписать готовые скрипты под версию 3.1.0. Правда, конвертер немного помог :-) Сегодня поеду знакомому винду ставить - посмотрю на работу своего unattended-сидюка на реальной, а не вирт. машине...

Vadikan 03-05-2005 18:18

Вопрос к специалистам по AutoIt. Допустим, мне нужно изменить некую настройку в программе. Настройка выставляется при помощи чекбокса. Я не знаю отмечен чекбокс или нет, т.к. некоторые юзеры могли его отметить. Можно ли при помощи AutoIt выполнить проверку (отмечен или нет) и соответственно отметить чекбокс только в случае, если он не отмечен?

piterpen 04-05-2005 05:49

вышла в прошлом месяце AutoIt v3.1.1
http://www.autoitscript.com/cgi-bin/getfile.pl?autoit3/autoit-v3-setup.exe

русская справка
http://www.autoitscript.com/cgi-bin/getfile.pl?autoit3/russian-v3.0.102.zip

jurikorn 05-05-2005 11:14

Vadikan.
Можно. Autoit Это позволяет

ControlCommand ( "title", "text", controlID, "command", "option" )

option:
IsChecked, "" (вернуть 1, если Button отмечена)
Check, "" (отметить radio или Button)
UnCheck, "" (снять отметку radio или Button)

Vadikan 05-05-2005 14:07

jurikorn
Спасибо! Видимо придется мне разбираться с AutoIt (а так лень было это делать ;-), если не найду другого решения своей задачи...

Vadikan 06-05-2005 19:48

Вникнув в проблему детальнее я не вижу как мне определить ControlID в моем окне. Это Word 2002, окно Tools | Options. Похоже все эти чекбоксы не имеют индивидуальных ControlID.

Через реестр, похоже, тоже не вариант, т.к. regshot отслеживает такой ключ
Код:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\9040210900063D11C8EF00054038389C\Usage]
на разных машинах скорее всего набор цифр будет другим... Вообще, это не столько автоматическая установка, сколько автоматизация процесса настройки после установки, которую проводил не я.

VelDmi 06-06-2005 01:54

Как определить Имя компьютера или его IP адрес?
С помощью _GetIP из справки возвращается значение -1.

jurikorn 06-06-2005 04:49

Существуют макрокомманды:
@IPAddress1
IP адрес первого сетевого адаптера. Может вернуть и просто 127.0.0.1.
@IPAddress2
IP адрес второго сетевого адаптера. Равен 0.0.0.0, если отстутствует.
@IPAddress3
IP адрес третьего сетевого адаптера. Равен 0.0.0.0, если отстутствует.

@ComputerName
Сетевое название ПК.

Sanja Alone 11-06-2005 21:00

Тут кто-то интересовался автоустановкой Lingvo. Я иногда юзаю этот словарик, ну и решил замутить скрипт автоустановки для своего Unattended DVD-юка.

Для автоустановки потребуются:
1. Образ первого сидюка Lingvo 10 Multilingual - LV10ML.iso (тупо скопировать содержимое сидюка в какой-либо каталог на автоустановочном CD/DVD и запустить setup.exe не получится - потребует вставить родной диск; с образа все работает)
2. Образ установочной дискеты Lingvo - ling10me_flp.ima (в zip-е всего-то 2Кб, но немогу прикрепить - меня назовут пиратом и заклеймят позором :( )
3. Virtual Floppy Driver некоего Kenji Kato - (нужны 2 файла vfd.exe и vfd.sys)
4. Предварительно установленный и 1 раз запускавшийся Alcohol 120% или DaemonTools с хотя бы одним вирт. приводом в системе
5. Нижеприведенный скрипт
(Все файлы должны лежать в одном каталоге, 2 файла vfd - в подкаталоге vfd)
Код:
;Перед запуском этого скрипта, даже если Алкоголь уже установлен, его (Алкоголь) ;нужно один раз запустить для применения параметров виртуального привода ;В сл. применения DT, также требуется его запуск и установка в систему хотя бы одного вирт. привода ;(нажать ПКМ на иконке DT в трее и выбрать "set number of devices" - "1 drive") ; ;скрыть в системной панели индикатор AutoIt AutoItSetOption("TrayIconHide", 1) AutoItSetOption("SendKeyDelay", 20) ;блокируем мышь и клаву BlockInput ( 1 ) ;Объявление переменных ;$i - счетчик, используемый в цикле определения буквы виртуального привода ;$virtdrv - маркер (будем устанавливать в 0, если исп-ся DaemonTools и в 1 в случае применения Alcohol-я) ;$daemondir - каталог, куда установлен DaemonTools (без обратного слэша в конце) ;(присваиваем переменной значение, к-рое соотв. пути Демона по умолчанию) ;$alcoholdir - каталог, куда установлен Алкоголь (без обратного слэша в конце) ;(присваиваем переменной значение, к-рое соотв. пути Алкоголя по умолчанию) Local $i, $virtdrv, $alcoholdir=@ProgramFilesDir & '\Alcohol Soft\Alcohol 120', $daemondir=@ProgramFilesDir & '\D-Tools' ;Проверяем какой эмулятор установлен и монтируем образ Lingvo в первый привод установленного эмулятора ;Если не один не установлен - выходим из скрипта с сообщением о необходимости установки эмулятора If FileExists ( $daemondir & '\daemon.exe' )=1 Then $virtdrv=0 ;Демонтируем текущий образ из первого вирт. привода Демона. ;(это необязательно) RunWait ( $daemondir & '\daemon.exe -noicon -unmount 0' ) ;Монтируем образ Lingvo на первый виртуальный CD/DVD-привод Run ( $daemondir & '\daemon.exe -noicon -mount 0,"' & @ScriptDir & '\LV10ML.iso"' ) ElseIf FileExists ( $alcoholdir & '\AxCmd.exe' )=1 Then $virtdrv=1 ;Демонтируем текущий образ из первого вирт. привода Алкоголя. ;(это необязательно) RunWait ( $alcoholdir & '\AxCmd.exe 1: /U' ) ;Монтируем образ Lingvo на первый виртуальный CD/DVD-привод Run ( $alcoholdir & '\AxCmd.exe 1: /M:' & @ScriptDir & '\LV10ML.iso' ) Else BlockInput ( 0 ) MsgBox ( 0, '', 'Для установки Lingvo требуется DaemonTools или Alcohol 120%.' & @LF & 'Сейчас установка Lingvo будет прекращена.' ) Exit EndIf ;Ждем процесс "autorun.exe" не более 10 сек., если появится - закрываем ;(даже если диск без авторана, все равно нужна пауза на монтирование iso-файла) If ProcessWait ( "autorun.exe", 10 )=1 Then ProcessClose ( "autorun.exe" ) ProcessWaitClose ( "autorun.exe" ) EndIf Sleep ( 100 ) ;Определение буквы виртуального CDROM-а (67 - ASCII-код символа "C", 90 - "Z") ;(в качестве маркерного файла используем "ABBYY Lingvo 10 Multilingual Dictionary.msi") $i = 67 While FileExists( Chr($i) & ':\ABBYY Lingvo 10 Multilingual Dictionary.msi' )=0 AND $i<=90 $i = $i + 1 WEnd Sleep ( 50 ) ;Запускаем установку Lingvo ;(/L1049 - русский язык диалоговых окон, SERIALNUMBER=сюда введите свой серийный номер) Run ( Chr($i) & ':\setup.exe /L1049 /v"SERIALNUMBER=XXXX-XXXX-XXXX-XXXX-XXXX"' ) WinWaitActive ( 'ABBYY Lingvo 10 Multilingual Dictionary', 'Лицензионный договор' ) ;Я принимаю условия лицензионного договора ControlClick ( 'ABBYY Lingvo 10 Multilingual Dictionary', 'Лицензионный договор', 'Button3' ) Send ( '{ENTER}' ) WinWaitActive ( 'ABBYY Lingvo 10 Multilingual Dictionary', 'Укажите сведения о себе' ) Send ( '{ENTER}' ) WinWaitActive ( 'ABBYY Lingvo 10 Multilingual Dictionary', 'При установке вы можете использовать установочную дискету' ) ;Копируем с CD/DVD образ установочной дискеты Lingvo во временный каталог ;(установщик Lingvo будет производить запись на эту "дискету" в процессе ;инсталляции, следовательно, он должен быть доступен для записи) FileCopy( @ScriptDir & '\ling10me_flp.ima', @TempDir & '\ling10me_flp.ima', 1 ) Sleep ( 500 ) ;Снимаем с образа установочной дискеты Lingvo атрибут Read-Only ;(файл копировался с CD, и явно не Far-ом :), а значит недоступен для записи) FileSetAttrib( @TempDir & '\ling10me_flp.ima', "-R" ) Sleep ( 500 ) ;Монтируем в виртуальном флопповоде (vfd - Virtual Floppy Driver) образ установочной дискеты Lingvo RunWait ( @ScriptDir & '\vfd\vfd.exe MOUNT ' & @TempDir & '\ling10me_flp.ima /L:B', '', @SW_HIDE ) Sleep ( 500 ) ;продолжаем установку WinActivate ( 'ABBYY Lingvo 10 Multilingual Dictionary', 'При установке вы можете использовать установочную дискету' ) Send ( '{ENTER}' ) WinWaitActive ( 'ABBYY Lingvo 10 Multilingual Dictionary', 'Выберите режим установки и укажите папку' ) ;Выборочная установка ;(для Стандартной сразу жать ENTER (удалив ControlClick) и перейти к STD) ControlClick ( 'ABBYY Lingvo 10 Multilingual Dictionary', 'Выберите режим установки и укажите папку', 'Button3' ) Send ( '{ENTER}' ) WinWaitActive ( 'ABBYY Lingvo 10 Multilingual Dictionary', 'Выберите компоненты программы' ) ;отключение ger-ru-ger словаря Send ( '{DOWN}' ) Send ( '{RIGHT}' ) Send ( '{DOWN}' ) Send ( '{DOWN}' ) Send ( '!{DOWN}' ) Send ( '{UP}' ) Send ( '{ENTER}' ) ;отключение fr-ru-fr словаря Send ( '{DOWN}' ) Send ( '!{DOWN}' ) Send ( '{UP}' ) Send ( '{ENTER}' ) ;отключение it-ru-it словаря Send ( '{DOWN}' ) Send ( '!{DOWN}' ) Send ( '{UP}' ) Send ( '{ENTER}' ) ;отключение esp-ru-esp словаря Send ( '{DOWN}' ) Send ( '!{DOWN}' ) Send ( '{UP}' ) Send ( '{ENTER}' ) ;отключить "озвученные немецкие слова" Send ( '{DOWN}' ) Send ( '{DOWN}' ) Send ( '{DOWN}' ) Send ( '{RIGHT}' ) Send ( '{DOWN}' ) Send ( '{DOWN}' ) Send ( '!{DOWN}' ) Send ( '{UP}' ) Send ( '{ENTER}' ) Sleep ( 50 ) ;продолжить установку Send ( '{ENTER}' ) ;STD WinWaitActive ( 'ABBYY Lingvo 10 Multilingual Dictionary', 'Хранение настроек словарей' ) Send ( '{ENTER}' ) WinWaitActive ( 'ABBYY Lingvo 10 Multilingual Dictionary', 'Начало установки' ) Send ( '{ENTER}' ) WinWaitActive ( 'ABBYY Lingvo 10 Multilingual Dictionary', 'Установка ABBYY Lingvo 10 Multilingual Dictionary успешно завершена' ) Send ( '{ENTER}' ) Sleep ( 70 ) ;Демонтируем образ уст. дискеты Lingvo и отрубаем вирт. дисковод RunWait ( @ScriptDir & '\vfd\vfd.exe UMOUNT', '', @SW_HIDE ) Sleep ( 30 ) RunWait ( @ScriptDir & '\vfd\vfd.exe STOP', '', @SW_HIDE ) Sleep ( 30 ) RunWait ( @ScriptDir & '\vfd\vfd.exe REMOVE', '', @SW_HIDE ) Sleep ( 30 ) ;Переносим ярлыки Lingvo в более удобное (мне) место ;(я не люблю беспорядка в меню "Программы" и делаю это для всех устанавливаемых прог) DirCopy ( @ProgramsCommonDir & '\ABBYY Lingvo 10', @ProgramsCommonDir & '\Переводчики\ABBYY Lingvo 10', 1 ) DirRemove ( @ProgramsCommonDir & '\ABBYY Lingvo 10', 1 ) ;Удаляем образ уст. дискеты Lingvo (он больше не понадобится) FileDelete ( @TempDir & '\ling10me_flp.ima' ) Sleep ( 50 ) ;Убиваем процесс Lvagent ProcessClose ( "Lvagent.exe" ) ProcessWaitClose ( "Lvagent.exe" ) Sleep ( 50 ) ;Демонтируем образ CD-диска Lingvo из вирт. привода If $virtdrv=0 Then RunWait ( $daemondir & '\daemon.exe -noicon -unmount 0' ) Else RunWait ( $alcoholdir & '\AxCmd.exe 1: /U' ) EndIf Sleep ( 50 ) ;Удаляем Lingvo из автозапуска (кому хочется, чтобы Lingvo висело в трее - удалите следующие 2 строки) RegDelete("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", "Lingvo Launcher") RegDelete("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", "LingvoTraining") ;Может выскочить эта ошибка ;(окно "setup.exe - Диск отсутствует", сообщение "В устройстве нет диска. Вставьте диск в устройство X:") ;Если да - закрываем процесс setup.exe If ProcessWait ( "setup.exe", 7 )=1 Then ProcessClose ( "setup.exe" ) ProcessWaitClose ( "setup.exe" ) EndIf Sleep ( 50 ) ;снимаем блокировку мыши и клавы BlockInput ( 0 )
Пользуйтесь, кому нужно.

P.S. Устанавливается Lingvo долго (до 10 мин.), самый тормозной этап - "установка индекса" на образ дискеты. А когда индикатор "установки индекса" доходит почти до конца, может показаться, что комп (или мой скрипт) завис. Так и должно быть.
Эх, где-то я такое уже видел... :)

Solitude 28-06-2005 17:51

Возникла такая проблема:
при установке программы необходмо импортировать данные из reg файла
делаю так
Код:
Run("regedit.exe /s Fail.reg", "")

Установка производится до первой загрузки Windows(RunOnceEx.cmd), но почему то запись в реестр не происходит ?
Самое интересное то, что если уже когда Windows загрузилась запусить этот же файл установки то данные в реестр экспортируются. Может кто подскажет решение этой проблемы ?

Sanja Alone 28-06-2005 18:54

Solitude
Попробуй так:
Код:
RunWait ( "regedit /S Fail.reg", "", @SW_HIDE )
И правильно будет и незаметно благодаря @SW_HIDE.

Solitude 29-06-2005 14:10

Sanja Alone
Не работает... :-((

Sanja Alone 29-06-2005 18:16

Solitude
Ну можешь еще так попробовать:
Код:
RunWait ( 'regedit /S ' & @ScriptDir & '\Fail.reg', '', @SW_HIDE ) ;или так: RunWait ( @Comspec & ' /C regedit /S ' & @ScriptDir & '\Fail.reg', '', @SW_HIDE )
Если не катит, значит ты пытаешься писать в изменяемые при загрузке ветки/ключи реестра.

Чуть не забыл - все эти варианты работают только если reg-файл и скрипт находятся в одном каталоге. В противном случае, нужно писать полный путь. И еще одно - пробелы внутри кавычек (' ') стоят все по делу, а не для красоты - не удали случайно.

P.S. С моего автоустановочного диска все ставящиеся проги (с пом. WPI, к-рый действует также через RunOnceEx) вносят изменения в реестр именно первым способом (см. предыдущий пост) - все данные импортируются.

Solitude 30-06-2005 12:54

Sanja Alone
Вот этот спопсоб
Код:
RunWait ( 'regedit /S ' & @ScriptDir & '\Fail.reg', '', @SW_HIDE )

сработал
Спасибо!!

Madcap 04-07-2005 07:40

2 all

Возникла проблемка с Некоторыми комбинациями клавиш:

Код:
... WinWait ("CDCheck - 3.0.1.43 [Personal non profit use]","", 0) Sleep (300) ;Послать в активное окно комбинацию нажатий клавиш Send ("!a") ; alt+a ...


Эта комбинация (Впрочем ALT+[любая другая буква]) отлично выполняется в 2000 и ХР. А в 98, такое впечатление, игнорируется.
Кто нибудь с таким сталкивался? С чем это связано? Какие еще команды глючат? И как с этим бороться
Прога качана по ссылке piterpen

godoo 05-07-2005 02:53

2 all

Здравствуйте, всем!
Помогите решить такую проблему: при установке приложения нужно изменить путь установки, так, чтобы не прописывать точный путь, а указать текущую системную папку Program Files (т.е. как-то указать не C:\Program Files\... , а %systemdrive% или %programs%). Ну никак не хочет :(

Madcap 05-07-2005 05:57

godoo

так
Код:
@ProgramFilesDir

пробовал?

Madcap 06-07-2005 00:38

2 all
Вопрос про комбинации клавиш снимается.
Как оказалось в Win98 команда Send некоректно отрабатывает при заблокированной клавиатуре и мышке (BlockInput(1))
Если клавиатуру не блокировать - все комбинации клавиш работают нормально

2 godoo

Скачай хелп - там описаны все переменные понимаемые AutoIT.
Раздел Указатель Макро

godoo 06-07-2005 01:07

Madcap, спасибо за совет, но это я пробовал и хелп прочитал...
Вся проблема в том, при такой замене пути установки:
WinWaitActive ( '', 'Выбор директории установки...' )
ControlSetText ( '', 'Выбор директории установки...', 'Edit2', '@ProgramFilesDir\Software\' )
вылезает окно:
Директория @ProgramFilesDir\Software не может быть создана. Укажите другой путь.

Работает только с полным заданием пути.:(



Madcap 07-07-2005 09:02

godoo

Сегодны экспериментировал с тоталом, получилось вот так:

Код:
;Ввод пути установки проги ControlSend ( "Installation Total Commander 6.0", "", "Edit1", @ProgramFilesDir & "\totalcmd")

ched3n 08-07-2005 00:23

пример скрипта
скрипт сравнивается с часами другого компьютера и каждые два часа качает фаил в заведомо созданую папку. как можно грамотно урезать , а то через чур большой
Код:
Opt('TrayIconHide', 0) ;Установка эталоного времени #include <Process.au3> $rc = _RunDos("net use file:///comp /user:user password") $rc = _RunDos("net time file:///comp /set /yes") TrayTip("Time", "Установка эталоного времени", 1, 1) Sleep(1000) TrayTip("clears any tray tip","",0) ;Скачка прайс листа InetGet("http://www.name.ru/files.rar", "c:\files\files.rar", 1, 1) While @InetGetActive TrayTip("Price", "Обновление прайса", 5, 1) Sleep(250) Wend Opt('TrayIconHide', 1) Sleep(7200000) Opt('TrayIconHide', 0) ;Скачка прайс листа InetGet("http://www.name.ru/files.rar", "c:\files\files.rar", 1, 1) While @InetGetActive TrayTip("Price", "Обновление прайса", 5, 1) Sleep(250) Wend Opt('TrayIconHide', 1) Sleep(7200000) Opt('TrayIconHide', 0) ;Установка эталоного времени #include <Process.au3> $rc = _RunDos("net use file://comp/ /user:user password") $rc = _RunDos("net time file:///comp /set /yes") TrayTip("Time", "Установка эталоного времени", 2, 1) Sleep(1000) TrayTip("clears any tray tip","",0) ;Скачка прайс листа InetGet("http://www.name.ru/files.rar", "c:\files\files.rar", 1, 1) While @InetGetActive TrayTip("Price", "Обновление прайса", 5, 1) Sleep(250) Wend Opt('TrayIconHide', 1) Sleep(7200000) Opt('TrayIconHide', 0) ;Скачка прайс листа InetGet("http://www.name.ru/files.rar", "c:\files\files.rar", 1, 1) While @InetGetActive TrayTip("Price", "Обновление прайса", 5, 1) Sleep(250) Wend ;завершение скрипта Exit

godoo 08-07-2005 02:00

Madcap, при таком способе перед тем путем, который стоит появляется вот это:
:\Ё ЁЁЁ Ё\Ё Ё ЁЁ ЁЁ\

Madcap 08-07-2005 04:48

На счет удаления предыдущего пути - можно послать в это окно кучу {DEL}ов.
На счет
Цитата:
:\Ё ЁЁЁ Ё\Ё Ё ЁЁ ЁЁ\
незнаю.

Madcap 08-07-2005 05:36

2 all
Скажите, плс, есть ли в этой проге какой нибудь аналог команды GO TO ?

Sanja Alone 08-07-2005 23:23

Madcap
В хелпе написано такое (FAQ - 4. Where is the "goto" command?):
Цитата:
Just to get you started, the most basic use of Goto in version 2.64 was an infinite loop like:
Код:
:mylabel ...do something... ...and something else... goto, mylabel
A simple v3 version of that is a While loop that is always "true".
Код:
While 1 = 1 ...do something... ...do something else... Wend
If there is a massive outcry about this after the launch of v3 then I may add it back in, but only to help people convert scripts.


Короче говоря, что-то подобное есть, а если goto требуется не в бесконечном цикле, то нужно (imho) использовать маркерную переменную как-то вот так:
Код:
$your_variable = "исходное значение" ; ;какой-то код, к-рый может повлиять на $your_variable ; While $your_variable = "исходное значение" ...do something... ...do something else... Wend
А еще посмотри в сторону Select...Case...EndSelect

Sanja Alone 09-07-2005 00:09

godoo
Цитата:
Код:
WinWaitActive ( '', 'Выбор директории установки...' ) ControlSetText ( '', 'Выбор директории установки...', 'Edit2', '@ProgramFilesDir\Software\' )

Ты все правильно в хелпе прочитал, но недочитал... Макросы (@ProgramFilesDir и т.п.) не берутся в кавычки, а объединяются со строками с пом. оператора объединения строк - &

Т.о., приведи код к такому виду:
Код:
WinWaitActive ( '', 'Выбор директории установки...' ) ControlSetText ( '', 'Выбор директории установки...', 'Edit2', @ProgramFilesDir & '\Software' )
и все будет ОК.

И еще один момент: ты используешь директиву ControlSetText, и, следовательно, никаких del-ов посылать не нужно, т.к. в этом случае значение элемента Edit2 будет перезаписано новым и тебе не нужно беспокоиться о его начальном значении)

Sanja Alone 09-07-2005 17:07

ched3n
Красивее будет сделать так:
1. Заменяешь #include и _RunDos на RunWait(@ComSpec & ' /C твоя_команда', '', @SW_HIDE);
2. Приводишь скрипт к виду:
Код:
;устанавливаем выход из скрипта по хоткею (в данном сл. это Ctrl+Alt+Z; выбор за тобой) HotKeySet("^!z", "my_exit") ;запускаем основной бесконечный цикл While 1 = 1 Opt('TrayIconHide', 0) time_sync() dl_price() Opt('TrayIconHide', 1) Sleep(7200000) Wend ;функция синхронизации времени Func time_sync() RunWait(@ComSpec & ' /C net use file:///comp /user:user password', '', @SW_HIDE) RunWait(@ComSpec & ' /C net time file:///comp /set /yes', '', @SW_HIDE) TrayTip("Time", "Установка эталоного времени", 1, 1) Sleep(1000) TrayTip("clears any tray tip","",0) EndFunc ;функция закачки прайса Func dl_price() InetGet("http://www.name.ru/files.rar", "c:\files\files.rar", 1, 1) While @InetGetActive TrayTip("Price", "Обновление прайса", 5, 1) Sleep(250) Wend EndFunc ;функция завершения скрипта Func my_exit() Exit EndFunc
Ес-но, можно бесконечный цикл заменить на конечный (используя переменную-счетчик или какое-то условие), дополнить функции закачки и синхронизации времени проверками (удаленный комп ведь может быть и недоступен). Но это уже будет украшательством. Захочешь - сделаешь. А приведенный выше скрипт будет выполняться бесконечно (до нажатия хоткея) независимо от доступности удаленной машины (функции пользователя по ум. всегда возвращают 0, ес-но, если это не переопределить с пом. директивы Return.

P.S. Синтаксис команд net use/time я оставлю на твоей совести, но на правильный он непохож; к тому-же, net use к синхронизации времени не имеет никакого отношения.

ched3n 10-07-2005 04:40

спасибо за помощь
net use \\comp /user:user password авторизируется на удаленном компьютере
net time \\comp /set /yes синхронизирует время локального компьютера с удаленным

Madcap 11-07-2005 00:32

Sanja Alone

Большое спасибо.

godoo 12-07-2005 03:37

Ребята, все получилось!!!
ОГРОМНОЕ ВАМ СПАСИБО!!!

Izvr 12-07-2005 06:58

Мой первый скрипт!
Установка FAR Manager, можете меня поздравить. И не говорите, что Фар можно как то проще поставить. Если просто разархивировать его в соответствующию директорию получится, во-первых, отсутствие ярлыков, во-вторых, в путях его системных не будет... В общем этот вариант самый оптимальный.
Вот текст:
BlockInput(1)
Run("Far1705.exe")
WinWait("FAR version 1.70 beta 5","",0)
Sleep(1000)
Send("{TAB}")
Send("{ENTER}")
WinWait("The FAR manager SETUP","&Folder to install FAR",0)
Send("{ENTER}")
WinWait("The FAR manager SETUP","Done",0)
Send("{ENTER}")
WinClose("FAR manager")
BlockInput(0)

ched3n 12-07-2005 10:01

молодца

Sanja Alone 12-07-2005 18:37

Izvr
Цитата:
во-первых, отсутствие ярлыков

Я этот вопрос решил просто - у меня Far со всеми плагинами ставится из rarsfx-архива. Т.о., можно создавать стандартные ярлыки и запускать до/после извлечения команду/файл на выполнение (в данном сл. - импорт настроек в реестр regedit /S settings.reg, где settings.reg=FarSave1.reg+FarSave2.reg).

Цитата:
во-вторых, в путях его системных не будет...

Это ты о чем? ВСЕ свои настройки Far хранит в реестре. Файлы SaveSettings.bat и RestoreSettings.bat в каталоге Far-а ты видел? Эти файлики сохраняют и восстанвливают настройки Far-а (в/из файлы/файлов FarSave1.reg и FarSave2.reg). А в системную переменную Path Фар себя вообще не пишет, да и новых переменных не создает.

Теперь по сути.
В скриптах, вместо WinWait лучше использовать WinWaitActive или связку WinWait + WinActivate. Во-первых, это избавляет от необходимости угадывания времени Sleep-а, и, во-вторых, позволяет избежать проблем с последующим несвоевременным нажатием клавиш.
И еще одно замечание: не нужно в функциях ожидания окон задавать нулевые таймауты. Смысл таймаута такой - ждать X окно не более Y секунд и в любом сл. идти дальше. При таймауте=0 будет сделана одна проверка на наличие искомого окна и сразу будет выполнена следующая функция, что также может вызвать проблемы, т.к. посылаемая комбинация клавиш передастся не в активный элемент окна, а х.з. куда (по ум. пауза для оконных операций у AutoIt составляет всего 250 мс). Для окон установщика Фара этого с головой хватает, но ведь может попасться приложение и с загаженными всяким мусором, медленно появляющимися окнами.

Установка Far-а:
Код:
AutoItSetOption("TrayIconHide", 1) BlockInput ( 1 ) Run ( 'Far1705.exe' ) WinWaitActive ( 'FAR version' ) ControlClick ( 'FAR version', '', 'Button2' ) WinWaitActive ( 'The FAR manager SETUP', '&Folder to install FAR' ) ;поставить галку "Associate FAR with RAR, ARJ, LZH, ZIP, HA, CAB and TGZ" ControlClick ( 'The FAR manager SETUP', '&Folder to install FAR', 'Button4' ) ;начать установку ControlClick ( 'The FAR manager SETUP', '&Folder to install FAR', 'Button8' ) WinWaitActive ( 'The FAR manager SETUP', 'Installation completed' ) Send ( '{ENTER}' ) ;перенос ярлыков в более удобное место DirCopy ( @ProgramsCommonDir & '\FAR manager', @ProgramsCommonDir & '\Файл-менеджеры\FAR manager', 1 ) DirRemove ( @ProgramsCommonDir & '\FAR manager', 1 ) BlockInput ( 0 )

Izvr 13-07-2005 11:09

Sanja Alone
Цитата:
Это ты о чем? ВСЕ свои настройки Far хранит в реестре. Файлы SaveSettings.bat и RestoreSettings.bat в каталоге Far-а ты видел? Эти файлики сохраняют и восстанвливают настройки Far-а (в/из файлы/файлов FarSave1.reg и FarSave2.reg). А в системную переменную Path Фар себя вообще не пишет, да и новых переменных не создает.

Ну а как тогда объяснить то, что я могу набрать в Run far и он у меня откроется? Я, конечно, допускаю возможность положить одноименный ярлык куда-нибудь в C:\windows, но мы не знаем всего того, что вшили разработчики в свой installer(так как они его к примеру залочили), так что SFX как то не очень надежно получается...
Цитата:
В скриптах, вместо WinWait лучше использовать WinWaitActive или связку WinWait + WinActivate. Во-первых, это избавляет от необходимости угадывания времени Sleep-а, и, во-вторых, позволяет избежать проблем с последующим несвоевременным нажатием клавиш.

Спасибо, учту...
Цитата:
И еще одно замечание: не нужно в функциях ожидания окон задавать нулевые таймауты. Смысл таймаута такой - ждать X окно не более Y секунд и в любом сл. идти дальше. При таймауте=0 будет сделана одна проверка на наличие искомого окна и сразу будет выполнена следующая функция, что также может вызвать проблемы, т.к. посылаемая комбинация клавиш передастся не в активный элемент окна, а х.з. куда (по ум. пауза для оконных операций у AutoIt составляет всего 250 мс). Для окон установщика Фара этого с головой хватает, но ведь может попасться приложение и с загаженными всяким мусором, медленно появляющимися окнами.

а "0" по моему бесконечность означает!? так что это вполне оправдано, но может быть я и не прав...

Sanja Alone 13-07-2005 18:45

Izvr
Цитата:
Ну а как тогда объяснить то, что я могу набрать в Run far и он у меня откроется?

Да уж, давно я дедовским способом Far не ставил... Сейчас проверил на вирт. машине - действительно он добавляет свой путь в Path. Мне только не ясно одно - зачем? Ведь если запустить Фар из Run-а, то на него без боли смотреть просто невозможно и все юзеры (любящие комформ) запускают Фар с пом. ярлыка, к-рый редактируют "под себя". Но если ты экстремал, то можешь добавлять путь Far-а к Path-у с пом. включения в архив маленькой утилки setenv.exe (35 328 байт) и батника примерно такого содержания:
Код:
@echo off copy /y Far.lnk "%AllUsersProfile%\Application Data\Microsoft\Internet Explorer\Quick Launch\Far.lnk" > nul regedit /S settings.reg setenv -m PATH %PATH%;"%ProgramFiles%\Far" exit
(Far.lnk - "настроенный" ярлык, к-рый также нужно положить в архив).
У меня из подобного файлика (ес-но, без setenv) еще и шрифт в Винду добавляется для понимания Фаром укр. буковок.
И пусть тебя не беспокоят "лишние" файлы в каталоге установленного Фара. Если Фар придется когда-нибудь удалять (в сязи с острым приступом тоталкоммандеризма или еще чего-то пострашнее) то заставить Фар удалить и эти файлы можно просто дописав их имена в файл Uninstall.lst в каталоге Фара.

Цитата:
а "0" по моему бесконечность означает!?

Бесконечность означает отсутствие данного параметра, а 0 означает именно то, что я написал выше.

Madcap 14-07-2005 03:39

Sanja Alone
Ты неправ, 0 означает бесконечность.
Попробуй запусти 2 нехитрых скрипта:

Код:
WinWait ("Название окна","Текст", 1) Sleep (300) MsgBox ( 0, "12345", "12345")


и

Код:
WinWait ("Название окна","Текст", 0) Sleep (300) MsgBox ( 0, "12345", "12345")

Izvr 14-07-2005 09:37

Цитата:
Да уж, давно я дедовским способом Far не ставил... Сейчас проверил на вирт. машине - действительно он добавляет свой путь в Path. Мне только не ясно одно - зачем? Ведь если запустить Фар из Run-а, то на него без боли смотреть просто невозможно и все юзеры (любящие комформ) запускают Фар с пом. ярлыка, к-рый редактируют "под себя". Но если ты экстремал, то можешь добавлять путь Far-а к Path-у с пом. включения в архив маленькой утилки setenv.exe (35 328 байт) и батника примерно такого содержания:

Я создаю решение не для себя, а для работы. Так что мне пофиг, кому надо настроят. А вообще я пользуюсь консолькой, поэтому набрать far для меня проще, чем тыкаться в ярлык. За утилитку спасибо.

Sanja Alone 14-07-2005 17:36

Madcap
Да, так и есть: WinWait ("Название окна","Текст", 0) дает такой же результат, как и WinWait ("Название окна","Текст"). Ну что тут сказать - такие выкрутасы должны быть описаны в справке. А там только сказано, что это "Timeout in seconds" и никаких ремарок (Remarks - None). Камень в огород писателей :) справки к AutoIt.

ched3n 15-07-2005 03:55

могет совместно над чем нить поработаем
хотя .... о чем это я

Madcap 15-07-2005 06:25

to all

Такая командочка:
Код:
if WinWaitActive ( "Окно1", "") or ( "Окно2", "") then ...

Неработает оператор or. Если появляется "Окно1" - все ОК скрипт продолжает выполняться.
Если появляется "Окно2" - то скрипт висит.
Что я делаю неправильно?

Sanja Alone 15-07-2005 20:03

Madcap
Цитата:
Что я делаю неправильно?

Почти все :) Ты пытаешься связать логическим условием функцию и текст в скобках. А нужно делать так:
Код:
if WinWaitActive ( "Окно1", "") or WinWaitActive ( "Окно2", "") then
P.S. Все директивы AutoIt - это функции, а в скобки заключаются передаваемые им параметры.

Madcap 18-07-2005 02:47

Sanja Alone
Все равно не работает :( тоже самое что и раньше - второе окно не хочет искать.
Вот у меня маленький скриптик который, по идее, должен определить какое из двух видов окошек открылось

Код:
if WinWaitActive ( "Калькулятор", "") or WinWaitActive ( "Безымянный - Блокнот", "") then if WinExists ( "Калькулятор", "") then MsgBox ( 0, "1", "Калькулятор") else MsgBox ( 0, "1", "блокнот") endif endif

но он не хочет работать. Может у меня руки кривые? Ткни пжлста пальцем где я еще обшибся.

Sanja Alone 18-07-2005 19:56

Madcap
Гм, а тут ничего и не может работать - у функций ожидания окон таймауты равны бесконечности :)
Рабочий вариант должен использовать другие функции (мгновенной проверки):
Код:
While 1=1 if WinExists ( "Калькулятор" ) and WinExists ( "Безымянный - Блокнот" ) then MsgBox ( 0, "1", "Оба окна существуют" ) ElseIf WinExists ( "Калькулятор" ) and Not WinExists ( "Безымянный - Блокнот" ) then MsgBox ( 0, "1", "Калькулятор" ) ElseIf Not WinExists ( "Калькулятор" ) and WinExists ( "Безымянный - Блокнот" ) then MsgBox ( 0, "1", "Блокнот" ) Else ;если убрать это сообщение, то скрипт будет вести себя тихо при отсутствии окон MsgBox ( 0, "1", "Нет ни одного окна" ) endif WEnd
Или тоже самое, но другим способом:
Код:
While 1=1 Select Case WinExists ( "Калькулятор" ) and WinExists ( "Безымянный - Блокнот" ) MsgBox ( 0, "1", "Оба окна существуют") Case WinExists ( "Калькулятор" ) and Not WinExists ( "Безымянный - Блокнот" ) MsgBox ( 0, "1", "Калькулятор") Case WinExists ( "Безымянный - Блокнот" ) and Not WinExists ( "Калькулятор" ) MsgBox ( 0, "1", "Блокнот") Case Else ;если убрать это сообщение, то скрипт будет вести себя тихо при отсутствии окон MsgBox ( 0, "1", "Нет ни одного окна") EndSelect WEnd
В обоих примерах важен порядок условий, т.к. каждый последующий ElseIf или Case выполняется только когда все предыдущие ложные.

Madcap 19-07-2005 00:47

Sanja Alone
Честно говоря я думал что оператор or позволяет сделать проверку и с бесконечными таймаутами.
Огромное спасибо.

ЗЫ: Все таки это были кривые руки :)

bogomolv 19-07-2005 04:10

Рад приветствовать единомышленников!

Уже более двух лет автоматизирую AutoIt'ом все, что можно и не можно.
Начинал, естественно, с "автокликанья" по окошкам программ-установщиков. Но сейчас мне обидно за любимый AutoIt, когда его используют исключительно в этих целях.
Мои скрипты отвечают за весь процесс установки системы, а также выполняют ряд полезных функций в текущей работе. Главное, что дал AutoIt, это более мощные и разнообразные инструменты, по сравнению с обычными батниками, и логику, по сравнению с обычными inf- и reg-файлами.

Поделюсь несколькими фирменными приемчиками.

Проверка на стадии cmdlines наличия железки и установка дров для нее:
Код:
Opt('ExpandVarStrings', 1); default = 0 ..... $iDir= '@ScriptDir@\Up\' $iDirDr= '@ScriptDir@\I386\$$oem$$\$$1\drivers\' If DriveGetFileSystem(StringLeft(@ScriptDir,3))='CDFS' Then $iDirDr='@ScriptDir@\$$1\drivers\' ..... $hwid='PCI\VEN_1002' ;ati If hwidtest($hwid) Then $Dr='$iDirDr$1_ati\' RunWait('$Dr$driver\Setup.exe -s -f1"$Dr$driver\setup.iss"') RunWait('$Dr$cpanel\Setup.exe -s -f1"$Dr$cpanel\setup.iss"') RegDelete('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run','ATIPTA') RegWrite('HKLM\SOFTWARE\ATI Technologies\Desktop','EnableIcon','REG_SZ','0') $f='$iDirDr$4_s910t\nast_color.au3' If FileExists($f) Then StartupDrivers("RunWait('AutoIt3.exe $f$')") EndIf ..... Exit ..... Func hwidtest($hwid) ;проверка наличия железки по ID return NOT RunWait('@ComSpec@ /C devcon.exe hwids "$hwid$" | find "$hwid$"','',0) EndFunc

Доустановка после первой загрузки Windows дров, которые "не любят" стадию cmdlines:
Код:
..... $hwid='PCI\VEN_8086' ;INTEL If hwidtest($hwid) Then $hwid='PCI\VEN_8086&DEV_24DF' ;INTELSATA If hwidtest($hwid) Then StartupDrivers("RunWait('$iDirDr$0_intel_sata\iaar47_multi.exe -A -S','',0)") StartupDrivers("DirRemove('@ProgramsCommonDir@\Intel(R) Application Accelerator',1)") Manager','$aMenuPSS$',1)") Else RunWait('$iDirDr$0_intel\iaa23_enu.exe -A -S','', 0) DirRemove('@ProgramsCommonDir@\Intel Application Accelerator',1) EndIf EndIf ..... Exit ..... Func StartupDrivers($l) $file = FileOpen('C:\startupdrivers.au3', 1) FileWriteLine($file, $l) FileClose($file) EndFunc

Создание Подключений и соответствующих Учетных записи OutLook через IPS-файл на основе данных пользователя (файл internet.ini)
Код:
..... $ini= 'ПУТЬ\internet.ini' $ins= '%temp%\ispcnfg.ins' $con= IniReadSectionNames($ini) For $i=1 to $con[0] IspCnfg_ins() Run(@ComSpec&' /C Start %temp%\ispcnfg.ins','',0) WinWaitActive('Мастер подключения к Интернету') Send('{ENTER}') WinWaitActive('Мастер подключения к Интернету','Завершена подготовка') Send('{ENTER}') Next ..... Exit ..... Func IspCnfg_ins() ;создание ispcnfg.ins, создающего соединение $f = FileOpen($ins, 2) FileWriteLine($f, '[Entry]') FileWriteLine($f, 'Entry_Name='& $con[$i]) FileWriteLine($f, '') FileWriteLine($f, '[Phone]') FileWriteLine($f, 'Dial_As_Is=yes') FileWriteLine($f, 'Phone_Number='& IniRead($ini, $con[$i],'Phone_Number','')) FileWriteLine($f, 'Area_Code=8452') FileWriteLine($f, 'Country_Code=7') FileWriteLine($f, 'Country_ID=7') FileWriteLine($f, '') FileWriteLine($f, '[Device]') FileWriteLine($f, 'Type=modem') FileWriteLine($f, '') FileWriteLine($f, '[Server]') FileWriteLine($f, 'Type=PPP') FileWriteLine($f, 'SW_Compress=yes') FileWriteLine($f, 'Network_Logon=no') FileWriteLine($f, 'Negotiate_TCP/IP=yes') FileWriteLine($f, 'Negotiate_NetBEUI=No') FileWriteLine($f, 'Negotiate_IPX/SPX=No') FileWriteLine($f, '') FileWriteLine($f, '[TCP/IP]') FileWriteLine($f, 'Specify_IP_Address=no') FileWriteLine($f, 'Specify_Server_Address=yes') FileWriteLine($f, 'IP_Header_Compress=yes') FileWriteLine($f, 'Gateway_On_Remote=yes') FileWriteLine($f, 'DNS_Address='& IniRead($ini, $con[$i],'DNS_Address','')) FileWriteLine($f, 'DNS_Alt_Address='& IniRead($ini, $con[$i],'DNS_Alt_Address','')) FileWriteLine($f, '') FileWriteLine($f, '[User]') FileWriteLine($f, 'Name='& IniRead($ini, $con[$i],'Name','')) FileWriteLine($f, 'Password='& IniRead($ini, $con[$i],'Password','')) FileWriteLine($f, 'Display_Password=no') FileWriteLine($f, '') FileWriteLine($f, '[ConnectionSettings]') FileWriteLine($f, 'ApplyInsToConnection='&$con[$i]) FileWriteLine($f, '') If IniRead($ini, $con[$i],'Email_Name','')<>'' Then FileWriteLine($f, '[Internet_Mail]') FileWriteLine($f, 'SMTP_Server='& IniRead($ini, $con[$i],'SMTP_Server','')) FileWriteLine($f, 'POP_Server='& IniRead($ini, $con[$i],'POP_Server','')) FileWriteLine($f, 'Domain=') ;sample.net FileWriteLine($f, 'Install_Mail_16=0') FileWriteLine($f, 'Email_Name='& IniRead($ini, $con[$i],'Email_Name','')) FileWriteLine($f, 'Email_Address='& IniRead($ini, $con[$i],'Email_Address','')) FileWriteLine($f, 'POP_Logon_Name='& IniRead($ini, $con[$i],'POP_Logon_Name','')) FileWriteLine($f, 'POP_Logon_Password='&IniRead($ini, $con[$i],'POP_Logon_Password','')) FileWriteLine($f, '') EndIF FileClose($f) EndFunc

Где файл internet.ini имеет следующий вид
Код:
[ИМЯ_СОЕДИНЕНИЯ1] Phone_Number= Phone_Number2= Name= Password= DNS_Address= DNS_Alt_Address= SMTP_Server= POP_Server= Email_Name= Email_Address= POP_Logon_Name= POP_Logon_Password= [ИМЯ_СОЕДИНЕНИЯ2] .....



Для перевода reg-файлов в коды AutoIt написал простенький макрос для Word:
Код:
Sub ОбработкаREG() With Selection If .Start = .End Then ActiveDocument.Select Set myRange = .Range 'удаление лишнего Замена "( ){1;}", "\1", True Замена "^p ", "^p", False Замена "\^p", "", False Замена "\\", "\", False Замена "HKEY_CURRENT_USER", "HKCU", False Замена "HKEY_LOCAL_MACHINE", "HKLM", False 'обработка строк For Each aPara In myRange.Paragraphs aPara.Range.Select: .End = .End - 1 If Left(.Text, 1) = ";" Then ElseIf Left(.Text, 1) = "[" Then hkey = Mid(.Text, 2, InStr(.Text, "]") - 2) .End = .End + 1 .Text = "" ElseIf InStr(.Text, "=") Then kkey = Mid(.Text, 2, InStr(2, .Text, Chr(34)) - 2) If InStr(.Text, "dword") Then tkey = "REG_DWORD" zkey = Mid(.Text, InStr(.Text, "=") + 7) zkey = Trim(Str(Val("&h" + zkey))) ElseIf InStr(.Text, "hex") Then tkey = "REG_BINARY" zkey = Mid(.Text, InStr(.Text, "=") + 5) zkey = Replace(zkey, ",", "") zkey = UCase(zkey) Else tkey = "REG_SZ" zkey = Mid(.Text, InStr(.Text, "=") + 2) zkey = Replace(zkey, Chr(34), "") End If .Text = "RegWrite('" + hkey + "','" + kkey + "','" + tkey + "','" + zkey + "')" End If Next myRange.Select End With End Sub Sub Замена(a, b, s) Set SRange = Selection.Range With Selection.Find .ClearFormatting .Replacement.ClearFormatting .Execute FindText:=a, ReplaceWith:=b, Replace:=wdReplaceAll, Wrap:=wdFindStop, MatchWildcards:=s End With SRange.Select End Sub


Буду рад, если что-нибудь кому-нибудь пригодится...

boss911 19-07-2005 11:57

Всем привет! У меня вопрос, так как нехотел создавать еще одну тему! У меня есть скрипт "Lan XP SP2.vbs". Что он делает: запускает "Мастер настройки сети" и настраивает локальную сеть, но после настройки лок. сети открывает автоматом общий доступ к папке "Общие документы" (SharedDocs)
Код:
Set WshShell = WScript.CreateObject("WScript.Shell") On Error Resume Next WshShell.Run ("%SystemRoot%\system32\rundll32.exe hnetwiz.dll,HomeNetWizardRunDll") WScript.Sleep 1000 WshShell.SendKeys "{ENTER 2}" WScript.Sleep 100 WshShell.SendKeys "{DOWN}" WScript.Sleep 100 WshShell.SendKeys "{ENTER}" WScript.Sleep 100 WshShell.SendKeys "{DOWN 2}" WScript.Sleep 100 WshShell.SendKeys "{ENTER}" WScript.Sleep 100 WshShell.SendKeys "Sergey" WScript.Sleep 20 WshShell.SendKeys "{ENTER}" WScript.Sleep 100 WshShell.SendKeys "MSHOME" WScript.Sleep 20 WshShell.SendKeys "{ENTER}" WScript.Sleep 100 WshShell.SendKeys "{UP}" WScript.Sleep 100 WshShell.SendKeys "{ENTER 2}" WScript.Sleep 12000 WshShell.SendKeys "{DOWN 3}" WScript.Sleep 100 WshShell.SendKeys "{ENTER 2}" WScript.Sleep 100

Так вот можно ли в этот скрипт прописать такую вещь с командной строки, котороя закрывает общий доступ к ней - "net share SharedDocs %userprofile%\Документы /delete". Как должна эта команда выглядеть в моем скрипте? И можно ли этот скрипт выполнить с cmdlines.txt, сработает ли он на 13-12 минуте до окончания установки Windows XP SP2? Спасибо!!!
Код:
[COMMANDS] useraccounts.cmd "Lan XP SP2.vbs"

DenchikK 21-07-2005 04:42

Не выходит установить Agnitum Outpost 2.7 через AutoIt: не закрывается последнее окно, где спрашивается
про перезагрузку компа. На это окно вообще ничего не действует. Подскажите пожалуйста, как же с этим можно справиться.
Вот мой скрипт:

Код:
Run('setup.exe') WinWaitActive ('Select Language') Send('{TAB 3}{DOWN 5}') ControlClick ('Select Language','','Button2') WinWaitActive ('Приветствуем') ControlClick ('Приветствуем','','Button1') WinWaitActive ('Лицензионное соглашение') ControlClick ('Лицензионное соглашение','','Button3') ControlClick ('Лицензионное соглашение','','Button1') WinWaitActive ('Read Me файл') ControlClick ('Read Me файл','','Button1') WinWaitActive ('Выберите папку для установки') ControlClick ('Выберите папку для установки','','Button1') WinWaitActive ('Начало копирования файлов') ControlClick ('Начало копирования файлов','','Button1') WinWaitActive ('Создать новую конфигурацию') ControlClick ('Создать новую конфигурацию','','Button6') WinWaitActive ('Мастер конфигурации') ControlClick ('Мастер конфигурации','','Button6') WinWaitActive ('Ручная настройка') ControlClick ('Ручная настройка','','Button8') WinWaitActive ('Установка','Необходимо перезагрузить компьютер для завершения установки.') ControlClick ('Установка','Необходимо перезагрузить компьютер для завершения установки.','Button3') Exit

bogomolv 21-07-2005 10:54

DenchikK

Попробуй "WinKill" или "ProcessClose".

Sanja Alone 21-07-2005 18:24

DenchikK
Рабочий скрипт для установки Agnitum Outpost 2.7
Код:
AutoItSetOption("TrayIconHide", 1) BlockInput ( 1 ) AutoItSetOption ( "SendKeyDelay", 15 ) Run ( 'OutpostProInstall.exe' ) WinWaitActive ( 'Select Language' ) ControlCommand ( 'Select Language', '', 'ListBox2', 'SelectString', 'Russian' ) If @error=1 Then ControlCommand ( 'Select Language', '', 'ListBox1', 'SelectString', 'Russian' ) EndIf Send ( '{ENTER}' ) WinWaitActive ( 'Приветствуем' ) Send ( '{ENTER}' ) WinWaitActive ( 'Лицензионное соглашение' ) ControlClick ( 'Лицензионное соглашение', '', 'Button3' ) Send ( '{ENTER}' ) WinWaitActive ( 'Read Me файл' ) Send ( '{ENTER}' ) WinWaitActive ( 'Выберите папку для установки' ) Send ( '{ENTER}' ) WinWaitActive ( 'Начало копирования файлов' ) ;Создать программную группу для текущего пользователя Send ( '{ENTER}' ) ;выбрать вариант "Создать программную группу для всех пользователей" ;ControlClick ( 'Начало копирования файлов', '', 'Button5' ) WinWaitActive ( 'Создать новую конфигурацию' ) ;Автоматическая настройка Send ( '{ENTER}' ) ;или Ручная настройка ;ControlClick ( 'Создать новую конфигурацию', '', 'Button2' ) WinWait ( 'Мастер конфигурации' ) AutoItSetOption("MouseCoordMode", 2) ;без этой паузы не хочет работать дальше (реально нужно 20-30 сек., но для тестов на VMWare пришлось поставить больше) Sleep ( 60000 ) WinActivate ( 'Мастер конфигурации' ) ;Далее MouseClick( "left", 400, 330, 1, 0 ) WinWaitActive ( 'Ручная настройка' ) Send ( '{ENTER}' ) WinWaitActive ( 'Установка' ) Send ( '{ESC}' ) Sleep ( 50 ) ;лекарство и настройки RunWait ( 'opst_ui.exe' ) RunWait ( 'settings.exe' ) Sleep ( 50 ) ;перенос ярлыков DirCopy ( @ProgramsDir & '\Agnitum\Outpost Firewall', @ProgramsCommonDir & '\Сеть\Agnitum Outpost Firewall', 1 ) DirRemove ( @ProgramsDir & '\Agnitum', 1 ) ;если имеете рабочий ключ, то введите его сюда ;RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Agnitum\Outpost Firewall","Key","REG_SZ","XXX...XX") ;отключить Автообновление RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Agnitum\Outpost Firewall\General","AutoUpdate","REG_DWORD","00000000") ;убрать Аутпост из автозапуска (кому нужно) ;RegDelete("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", "Outpost Firewall") BlockInput ( 0 )

DenchikK 27-07-2005 12:49

bogomolv
Sanja Alone
Спасибо огромное! Я, кстати, разобрался, отчего у меня не работал скрипт - в окне Создать Конфигурацию я нажимал - автоматическая, и при установке AutoIT'ом почему-то сразу пропускался мастер и сразу выдавалось последнее окно. С этим то я разобрался.
Родился новый вопрос, может быть подскажете: для автоматизации работы нужно запустить несколько приложений и брать оттуда некоторые данные. добавлять в другие и.т.д. Проблема в том, что прочитав справку и форум по AI, я так и не нашёл, возможно ли точно переходить в конкретнозаданное запущенное окно. А то метод Alt+Tab не всегда срабатывает.
Заранее спасибо.

Sanja Alone 27-07-2005 17:12

DenchikK
Цитата:
я так и не нашёл, возможно ли точно переходить в конкретнозаданное запущенное окно

Activates (gives focus to) a window - WinActivate ( "title" [, "text"] )

bogomolv 28-07-2005 00:08

DenchikK
Sanja Alone

Без "WinActivate()", конечно, не обойтись.
Но можно оперировать вводом-выводом, и не активируя соответствующие окна:
Код:
$GetSN=ControlGetText('keygen', 'RU', 'Edit1') ControlSetText('ABBYY', 'Введите серийный номер', 'Edit1', $GetSN)

vserd 28-07-2005 07:40

bogomolv
Цитата:
ABBYY

Ну ты и монстр!!!! :)))) Давно думал как можно автоматизировать это безобразие, а ты как фокусник слона из кармана вытянул.
СПАСИБО!!!


UncleGluk 28-07-2005 10:00

Все супер! И AutoIt просто не заменимая вещь! Как я до него жил - ума не приложу.. :) Так же не могу понять как собственно мне получить код возврата кнопки "ОК" или "Cancel" при использовании функции MsgBox???
Допустим, что-то типа:

MsgBox (1, "", "Запускать? ")

и необходимо обработать нажатие кнопки, и дальше отправить по условию, как это можно сделать, кто нибудь подскажет?
Спасибо!

bogomolv 28-07-2005 14:48

vserd

Рабочий скрипт немного сложнее:
Код:
While Not WinExists('Мастер Активации') ControlClick('keygen', 'RU', 'Button4') $GetSN=ControlGetText('keygen', 'RU', 'Edit1') ControlSetText('ABBYY', 'Введите серийный номер', 'Edit1', $GetSN) ControlClick('ABBYY', 'Введите серийный номер', 'Button1') WinWait('Мастер Активации','',5) WinClose('ABBYY', 'Проверьте правильность') Wend


UncleGluk

Если кто-то:) открыл бы AutoIt.chm, то без труда там нашел:
Код:
If MsgBox (1, "", "Запускать? ")<>1 Then Exit

Sanja Alone 28-07-2005 18:15

bogomolv
Цитата:
можно оперировать вводом-выводом, и не активируя соответствующие окна

Спрашивали не об этом - я отвечал на прямой вопрос.
А о том, что ты говоришь - я знаю, но без активации оно не всегда должным образом работает :(
Да, ты мне напомнил - я пару месяцев назад для знакомого делал автоустановку ABBYY FineReader 7.
Выкладываю для народа:
Код:
AutoItSetOption("TrayIconHide", 1) BlockInput ( 1 ) Global $InstPath, $Serial, $InstID, $FFCode, $ActCode, $ACStr AutoItSetOption ( "SendKeyDelay", 20 ) ;запуск кейгена Run ( 'keygen.exe' ) WinWaitActive ( 'Abbyy FineReader Professional v7.0 keygen' ) ;страна - UA (для RU - удалить один ControlClick) ControlClick ( 'Abbyy FineReader Professional v7.0 keygen', '', 'Button3' ) ControlClick ( 'Abbyy FineReader Professional v7.0 keygen', '', 'Button3' ) ControlClick ( 'Abbyy FineReader Professional v7.0 keygen', '', 'Button3' ) ControlClick ( 'Abbyy FineReader Professional v7.0 keygen', '', 'Button3' ) Sleep ( 600 ) $Serial = ControlGetText ( 'Abbyy FineReader Professional v7.0 keygen', '', 'Edit1' ) Sleep ( 70 ) ;установка программы Run ( 'setup.exe /L1049' ) WinWait ( 'ABBYY FineReader 7.0 Professional Edition - ', 'Лицензионный договор' ) WinActivate ( 'ABBYY FineReader 7.0 Professional Edition - ', 'Лицензионный договор' ) ControlCommand ( 'ABBYY FineReader 7.0 Professional Edition - ', 'Лицензионный договор', 'Я &принимаю условия лицензионного договора', "Check", "" ) Send ( '{ENTER}' ) WinWait ( 'ABBYY FineReader 7.0 Professional Edition - ', 'Режим установки' ) WinActivate ( 'ABBYY FineReader 7.0 Professional Edition - ', 'Режим установки' ) $InstPath = ControlGetText ( 'ABBYY FineReader 7.0 Professional Edition - ', 'Режим установки', 'RichEdit20W1' ) ;по ум., путь = C:\Program Files\ABBYY FineReader 7.0 Professional Edition\ Выборочная установка. Выбрана только для подключения еще и англ. языка интерфейса - мужик хотел совсем "полную" установку. Кому нужно, на этом этапе можно отключить FormFiller (после получения фокуса элементом SysTreeView321 нажать {DOWN 5}, !{DOWN}, {UP} и {ENTER} ). Для обычной установки сразу жать Button1 и идти к STD ControlClick ( 'ABBYY FineReader 7.0 Professional Edition - ', 'Режим установки', 'Button5' ) ;Далее ControlClick ( 'ABBYY FineReader 7.0 Professional Edition - ', 'Режим установки', 'Button1' ) WinWait ( 'ABBYY FineReader 7.0 Professional Edition - ', 'Выборочная установка' ) WinActivate ( 'ABBYY FineReader 7.0 Professional Edition - ', 'Выборочная установка' ) ControlFocus ( 'ABBYY FineReader 7.0 Professional Edition - ', 'Выборочная установка', 'SysTreeView321' ) Send ( '{DOWN}' ) Send ( '{RIGHT}' ) Send ( '{DOWN}' ) Send ( '!{DOWN}' ) Send ( '{DOWN}' ) Send ( '{ENTER}' ) Sleep ( 70 ) ;Далее Send ( '{ENTER}' ) ;STD WinWaitActive ( 'ABBYY FineReader 7.0 Professional Edition - ', 'Подключение к каналу новостей ABBYY' ) ControlCommand ( 'ABBYY FineReader 7.0 Professional Edition - ', 'Подключение к каналу новостей ABBYY', 'H&ет', "Check", "" ) Sleep ( 50 ) Send ( '{ENTER}' ) WinWaitActive ( 'ABBYY FineReader 7.0 Professional Edition - ', 'Установка программы' ) Send ( '{ENTER}' ) WinWaitActive ( 'ABBYY FineReader 7.0 Professional Edition - ', 'Установка ABBYY FineReader 7.0 завершена' ) Send ( '{ENTER}' ) Sleep ( 50 ) ;регистрация программы Run ( $InstPath & 'FineReader.exe' ) WinWaitActive ( 'ABBYY FineReader 7.0 Professional Edition Try&Buy', 'Вы работаете с испытательной версией программы' ) ControlCommand ( 'ABBYY FineReader 7.0 Professional Edition Try&Buy', 'Вы работаете с испытательной версией программы', '&Ввести серийный номер', "Check", "" ) Send ( '{ENTER}' ) WinWaitActive ( 'ABBYY FineReader 7.0 Professional Edition Try&Buy', '&Введите серийный номер' ) ControlSetText ( 'ABBYY FineReader 7.0 Professional Edition Try&Buy', '&Введите серийный номер', 'Edit1', $Serial ) Send ( '{ENTER}' ) WinWaitActive ( 'Мастер Активации ABBYY FineReader 7.0 Professional Edition', 'Мастер активации последовательно проведет Вас по всему процессу' ) ControlCommand ( 'Мастер Активации ABBYY FineReader 7.0 Professional Edition', 'Мастер активации последовательно проведет Вас по всему процессу','по &факсу или телефону', "Check", "" ) Send ( '{ENTER}' ) WinWaitActive ( 'Мастер активации ABBYY FineReader 7.0 Professional Edition', 'Активация по факсу или телефону' ) ;для России Ukraine замените на Russia ControlCommand ( 'Мастер активации ABBYY FineReader 7.0 Professional Edition', 'Активация по факсу или телефону', 'ComboBox1', "SelectString", 'Ukraine' ) $InstID = ControlGetText ( 'Мастер активации ABBYY FineReader 7.0 Professional Edition', 'Активация по факсу или телефону', 'Edit2' ) ;переход в окно кейгена WinActivate ( 'Abbyy FineReader Professional v7.0 keygen' ) Sleep ( 30 ) ControlSetText ( 'Abbyy FineReader Professional v7.0 keygen', '', 'Edit3', $InstID ) Sleep ( 70 ) ;Generate ControlClick ( 'Abbyy FineReader Professional v7.0 keygen', '', 'Button8' ) Sleep ( 50 ) $FFCode = ControlGetText ( 'Abbyy FineReader Professional v7.0 keygen', '', 'Edit2' ) $ActCode = ControlGetText ( 'Abbyy FineReader Professional v7.0 keygen', '', 'Edit4' ) Sleep ( 50 ) WinClose ( 'Abbyy FineReader Professional v7.0 keygen' ) WinWaitClose ( 'Abbyy FineReader Professional v7.0 keygen' ) Sleep ( 20 ) WinActivate ( 'Мастер активации ABBYY FineReader 7.0 Professional Edition', 'Активация по факсу или телефону' ) ;из кейгена код получен одной строкой вида x-x-x..., а вводить нужно по частям в разные поля - разделяем. $ACStr = StringSplit ( $ActCode, "-" ) Sleep ( 350 ) ControlSetText ( 'Мастер активации ABBYY FineReader 7.0 Professional Edition', 'Активация по факсу или телефону', 'Edit4', $ACStr[1] ) ControlSetText ( 'Мастер активации ABBYY FineReader 7.0 Professional Edition', 'Активация по факсу или телефону', 'Edit5', $ACStr[2] ) ControlSetText ( 'Мастер активации ABBYY FineReader 7.0 Professional Edition', 'Активация по факсу или телефону', 'Edit6', $ACStr[3] ) ControlSetText ( 'Мастер активации ABBYY FineReader 7.0 Professional Edition', 'Активация по факсу или телефону', 'Edit7', $ACStr[4] ) ControlSetText ( 'Мастер активации ABBYY FineReader 7.0 Professional Edition', 'Активация по факсу или телефону', 'Edit8', $ACStr[5] ) ControlSetText ( 'Мастер активации ABBYY FineReader 7.0 Professional Edition', 'Активация по факсу или телефону', 'Edit9', $ACStr[6] ) ControlSetText ( 'Мастер активации ABBYY FineReader 7.0 Professional Edition', 'Активация по факсу или телефону', 'Edit10', $ACStr[7] ) Sleep ( 30 ) Send ( '{ENTER}' ) WinWaitActive ( 'Мастер активации ABBYY FineReader 7.0 Professional Edition', 'Активация успешно завершена' ) Send ( '{ENTER}' ) Sleep ( 500 ) ;это окно иногда появляется, а иногда нет. (Тестил и на VMWare и на 2 реальных ПК - закономерности найти не пытался, а просто впаял эту проверку. Работает... и ладушки.) If WinExists ( 'Регистрация FineReader 7.0 Professional Edition', 'Пожалуйста' ) Then WinActivate ( 'Регистрация FineReader 7.0 Professional Edition', 'Пожалуйста' ) Send ( '{SPACE}' ) ControlClick ( 'Регистрация FineReader 7.0 Professional Edition', 'Пожалуйста', 'Button4' ) WinWaitActive ( 'Регистрация', 'Внимание!' ) Send ( '{ENTER}' ) EndIf WinWait ( 'Добро пожаловать!' ) WinActivate ( 'Добро пожаловать!' ) ;&Закрыть ControlClick ( 'Добро пожаловать!', '', 'Button5' ) ;активировать и закрыть основное окно программы WinActivate ( 'Пакет без имени - ABBYY FineReader 7.0 Professional Edition' ) WinClose ( 'Пакет без имени - ABBYY FineReader 7.0 Professional Edition' ) WinWaitClose ( 'Пакет без имени - ABBYY FineReader 7.0 Professional Edition' ) Sleep ( 50 ) ;активация FormFiller-а Run ( $InstPath & 'FormFiller.exe' ) WinWaitActive ( 'Активация' ) ControlSetText ( 'Активация', '', 'Edit1', $FFCode ) Sleep ( 70 ) ;&Активация ControlClick ( 'Активация', '', 'Button1' ) WinWait ( 'Форма - ABBYY FormFiller' ) WinActivate ( 'Форма - ABBYY FormFiller' ) WinClose ( 'Форма - ABBYY FormFiller' ) WinWaitClose ( 'Форма - ABBYY FormFiller' ) Sleep ( 20 ) ;перенос ярлыков DirCopy ( @ProgramsCommonDir & '\ABBYY FineReader 7.0', @ProgramsCommonDir & '\Офис\ABBYY FineReader 7.0', 1 ) DirRemove ( @ProgramsCommonDir & '\ABBYY FineReader 7.0', 1 ) ;Поддержка украинского языка для FineReader 7.0 ;(пакет перепакован в winrar-sfx архив для тихой установки) ;команды SFX-сценария (для winrar-архива): ; Setup=setup.exe /L1049 ; TempMode ; Silent=1 ; Overwrite=1 RunWait ( 'ukr.exe' ) $FFCode = 0 $InstPath = 0 $Serial = 0 $InstID = 0 $ActCode = 0 $ACStr = 0 BlockInput ( 0 )
P.S. Возможно, здесь не все оптимально, но работает без проблем.
Сама прога бралась отсюда (43 749 965 байт)
Укр. язык (1 639 936 байт) - может кому и нужен :)

bogomolv 29-07-2005 01:57

Sanja Alone

С интересом познакомился с использованием функции StringSplit(). Даже не знал о ее существовании.

По оптимизации кода:
а) пару десятков строк можно сэкономить, используя вместо Run('setup.exe /L1049') команду RunWait('setup.exe /L1049 /v/qb');
б) в одном случае из 10 введенный серийник оказывается неверным. Поэтому "зацикливаю" его ввод (см. пример);
в) для настройки установленного FineRеader можно включить в скрипт RunWait('regedit /s FineRеader.reg') и FileCopy($iDir&'Untitled.fbt', $pDir, 1).

Общие вопросы:
б) зачем обнулять переменные на выходе из скрипта?
в) категорически не согласен с использованием BlockInput(). Отлаженный скрипт может быть неожиданно прерван на чужой машине выскочившим окошком какого-либо сообщения Windows об отсутствующих дровах и т.п. Что делать в этом случае? То же самое относится и к Opt('TrayIconHide',1). Наоборот всегда включаю Opt('TrayIconDebug',1), чтобы можно было понять, чего ждет "зависший" скрипт.

UncleGluk 29-07-2005 04:49

bogomolv

Ой! :blush: да я не думал что все так просто! Начал чего то выдумывать и совсем потерялся, уйдя от правильной мыслишки!

Спасибо!

Sanja Alone 29-07-2005 20:07

bogomolv
Цитата:
С интересом познакомился с использованием функции StringSplit()
Мне приятно, что мои 5 месяцев зканомства с AutoIt не прошли уж совсем зря...

Цитата:
пару десятков строк можно сэкономить
Угу, но я ведь делал установку НЕ с параметрами по умолчанию.

Цитата:
в одном случае из 10 введенный серийник оказывается неверным
Ни разу такого не было - FR7 за все время раз 20 ставил, а SoundForge6 (там вообще привязка ключа к аппаратной конфигурации) уже раз 40-50 (причем, с BatchConverter-ом и регистрацией MPEG1/2-плагина). Наверное, хорошие кейгены попадались :)

Цитата:
для настройки установленного FineRеader
Если не затруднит - пришли мне на мыло FineRеader.reg и Untitled.fbt и расшифруй смысл переменных $iDir и $pDir (у меня своего сканера нет, а последний FR, к-рый я юзал, был еще версии 4.х). Это не для себя делалось...

Цитата:
зачем обнулять переменные на выходе из скрипта?
Обнуляются для освобождения памяти, хотя при нынешних объемах ОЗУ в типичных ПК это и не актуально... И изначально это был не выход - там еще путь в Path добавлялся :)

Цитата:
Отлаженный скрипт может быть неожиданно прерван на чужой машине выскочившим окошком какого-либо сообщения Windows об отсутствующих дровах и т.п. Что делать в этом случае?
Ctrl+Alt+Del, открывается TaskManager и блокировка при этом снимается - не знал?

Цитата:
всегда включаю Opt('TrayIconDebug',1), чтобы можно было понять, чего ждет "зависший" скрипт.
Может я так и сделаю, просто не люблю я лишних иконок в трее :) И для многократно проверенных скриптов это излишество.

bogomolv 30-07-2005 08:24

Sanja Alone

Про установку не "по умолчанию".
А что не "по умолчанию" ты устанавливаешь? Как правило, все можно потом задействовать/отключить через реестр.
Например, новостной канал отключается удалением ключа "FineReader7NewsReaderPro" в ветке HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run.

Про FineRеader.reg и Untitled.fbt.
Эти файлы воспроизводят личные пользовательские настройки.
Настриваешь FR, сохраняешь через меню "Опции" в Untitled.fbt, копируешь.
Незапоминаемые Untitled.fbt настройки интерфейса находим в реестре (ветка HKCU\Software\ABBYY\FineReader\7.00) и сохраняем в FineRеader.reg.
Есть ли нужда пересылать их? Там все из разряда "мне так нравится".

Про переменные $iDir и $pDir.
Это имена папок "откуда и куда" идет установка. А ты что подумал?

Про серийник.
Иногда и 30 раз проходит с первого раза. А иногда через раз начинает ругаться, что неверный.
М.б. это проблема конкретной версии...

Про Ctrl+Alt+Del и BlockInput(0).
Я знаю. Знаю и то, что не надо трогать мышь и клавиатуру во время работы скрипта. Так от кого эта защита?
А вот людей, которые потом будут этим пользоваться, вряд ли стоит пугать зависшим компьютером.

Sanja Alone 30-07-2005 18:46

bogomolv
Про не "по ум." - англ. язык интерфейса, я это написал в комментариях к скрипту. И я не думаю, что тут поможет реестр, т.к. отсутствующий компонент посредством реестра не включится :)

Цитата:
Есть ли нужда пересылать их? Там все из разряда "мне так нравится".
Мне было бы интересно посмотреть пример, я же сказал, что последним активно используемым FR-ом для меня был еще 4.х.

Про переменные $iDir и $pDir - я понял что это, но не понял два момента:
- можно ведь просто написать FileCopy('Untitled.fbt', $pDir, 1), или у тебя скрипты лежат в каком-то отдельном каталоге?
- куда пихать тот самый Untitled.fbt. Это ведь может быть не только каталог проги, но и что-нить типа Doc&Set\Имя_юзера\AppData\Abbyyy_блаблабла или ты и это станешь оспаривать?

Цитата:
А вот людей, которые потом будут этим пользоваться, вряд ли стоит пугать зависшим компьютером.
Есть 2 больших категории юзеров - первые вообще боятся нажать случайно какую-нибудь кнопку (эти устанавливать проги сами не будут), а остальные знают про "комбинацию из трех пальцев".

Цитата:
Так от кого эта защита?
От тех, кто любит трогать :)

bogomolv 31-07-2005 04:57

Sanja Alone

Про установку не "по умолчанию".
Такие вещи, на мой вгляд, лучше задавать непсредственно в установщике, либо отредактировав msi-файл, либо создав для него mst-файл дополнительных настроек установки.
Использую для этого Orca (MSI Table Editor). С его помощью записал то, что тебе нужно, в full.mst (запускается FineReader.msi /qb TRANSFORMS=full.mst).
Вышлю вместе с другими файлами, когда ответишь по мылу.

Про пути.
$pDir=@ProgramFilesDir&'\ABBYY FineReader 7.0 Professional Edition\'
$iDir=@ScriptDir&'\'. Но это сейчас, когда пакую все файлы дистрибутива и настроек в SFX RAR архив. Раньше было по-другому.

Про 2 больших категории юзеров.
Так к какой категории относятся те, кто любит трогать?:)

DenchikK 01-08-2005 21:11

Наверное всё-таки напишу в эту тему, так как в теме об установке WinAmp обсуждается немного не то.

О наболевшем. Об установке WinAmp. Хочется сделать её универсальной - в том смысле, чтоб скрипт AutoIT срабатывал всегда, а не только в случае установки на чистую (или не чистую) систему. Загвоздка в том, что WinAmp при установке, в зависимости от системы, задаёт РАЗНЫЕ вопросы - и естественно скрипт может не сработать. Первая вещь, на которой иногда спотыкается установка - это вопрос о регистрации. Победилась просто - перед установкой reg файлом вносятся необходимые регистрационные данные. Но есть второй подводный камень - на чистой системе задаётся вопрос о перезапуске, на системе, в которой уже стоял WinAmp - этот вопрос не задётся. Как бы сделать обход этого - например оператором IF, чтоб скрипт, если не появилось окно с вопросом о регистрации, дальше продолжал свою работу, а если появится - отмнил бы перезагрузку ну и проч. по плану?

И ещё один вопрос, правда не очень в тему: на второй странице Sanja Alone сказал, что образы от Virtual CD монтируются Алкоголем. Я сам уже давно на Алкоголь перешёл, но есть куча образов от VCD. Обрадовался - попробовал - не вышло - Алкоголь правильно распознаёт размер, но не может считать информацию. Образы от VCD 4.5, Алкоголь: 3 последних.

Sanja Alone 02-08-2005 18:51

DenchikK
Цитата:
Как бы сделать обход этого - например оператором IF

А какие проблемы?
Код:
If WinExists ( 'Имя', 'Текст' ) Then ;код, выполняемый если окно появилось Else ;код, выполняемый если окна не было EndIf
(Тоже самое можно сделать и с пом. Select...Case...EndSelect)


По поводу регистрации - раз уж установка делается скриптом, то пусть и регистрация делается им же (и без "лишнего" reg-файла):
Код:
RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Nullsoft\Winamp", "regname", "REG_SZ", "xxxxxxxxxxxxx") RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Nullsoft\Winamp", "regkey", "REG_SZ", "xxxxxxxxxxxxxxxxxxxxxxxx")

Цитата:
Sanja Alone сказал, что образы от Virtual CD монтируются Алкоголем

Алкоголь у меня тогда был 1.4.8.1222, а более новые версии ведут себя так, как ты и описал. Выход есть - переконвертировать *.vcd/*.000-образы с пом. UltraISO во что-нибудь стандартное (например, iso). Но и здесь возможны проблемы. С былых времен у меня осталось только 3 образа VCD - два монтируются (но не дают считать содержимое) новым Алкоголем, при этом они не загружаются в UltraISO, но без лишних вопросов конвертируются последним в нормально читаемые iso. А третий образ vcd/000 вообще ничем кроме родного VirtualCD не монтируется и не конвертируется. Такие вот дела...

DenchikK 03-08-2005 18:22

Никак не могу всё-таки справиться с winamp : установка происходит нормально, только не в первый раз. Вот привожу пример того, что наваял:
Код:
Run('setup.exe') RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Nullsoft\Winamp", "regname", "REG_SZ", "***") RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Nullsoft\Winamp", "regkey", "REG_SZ", "***") WinWaitActive ('Winamp Setup','License Agreement') ControlClick ('Winamp Setup','License Agreement','I &Agree') WinWaitActive ('Winamp Setup','Choose Components') ControlSend ('Winamp Setup','Choose Components','SysTreeView321','{End}{Up 2}{Space}{UP 5}{Space}{Enter}') WinWaitActive ('Winamp Setup','Choose Install Location') ControlClick ('Winamp Setup','Choose Install Location','&Next >') WinWaitActive ('Winamp Setup','Choose Install Options') ControlClick ('Winamp Setup','Choose Install Options','&Next >') WinWaitActive ('Winamp Setup','Internet Connection and Language Settings') Send ('{Down 2}{Tab 5}{Enter}') WinWaitActive ('Winamp Setup','Interface and Skin Selection') ControlClick ('Winamp Setup','Interface and Skin Selection','&Install') ; Вот здесь и наступает непонятка: после нажатия на кнопку инстал (строчка выше) открывается следующее окно, где и идёт процесс установки, не закрывается, выскакивает новое окно с вопросом о перезагрузке. После нажатия “нет” – всё закрывается, winamp даже не запускается. Так вот, при выскакивании этого окна с запросом, ничего не происходит. Я явно не понял, как этот оператор работает. If WinExists ( 'Winamp Setup', 'A reboot is required to complete the installation' ) Then WinWaitActive ('Winamp Setup','A reboot is required to complete the installation.') ControlClick ('Winamp Setup','A reboot is required to complete the installation','Button2') ProcessWaitClose("winamp.exe") Run('ENHANCER.EXE') WinWaitActive ('Enhancer 0.17') ControlClick ('Enhancer 0.17','','Next >') Sleep ( 1000 ) ProcessWaitClose("'ENHANCER.exe") run ('rus.exe') Else sleep ( 3500 ) ;WinWaitActive ('Player Window') ;sleep ( 1000 ) WinWaitActive ('Add Media to Library') WinActivate ('Add Media to Library') Send ('{Tab 2}{Enter}') WinWaitClose("Add Media to Library", "", 5) sleep ( 1000 ) run ('taskkill.exe /F /IM winamp.exe') ProcessWaitClose("winamp.exe") Run('ENHANCER.EXE') WinWaitActive ('Enhancer 0.17') ControlClick ('Enhancer 0.17','','Next >') Sleep ( 1000 ) ProcessWaitClose("'ENHANCER.exe") run ('rus.exe') EndIf Exit

VelDmi 03-08-2005 23:13

DenchikK
А ты не пробовал версию winamp.msi? C ней таких проблем нет.

Madcap 04-08-2005 00:32

2 DenchikK
На сколько я понял оператор WinExists проверяет наличее окна только 1 раз, в твоем случае сразу после нажатия клавиши
Цитата:
ControlClick ('Winamp Setup','Interface and Skin Selection','&Install')
когда окно
Цитата:
'Winamp Setup'
еще не появилось.
Внимательно почитай посты на 4 странице, там Sanja Alone растолковывал мне как определить какое именно окно открылось. Это должно подойти и тебе.

DenchikK 04-08-2005 16:42

Слегка получилось со скриптом для winamp (и новый робоформ построил на его основе), только работает странно - скрипт не закрывается, приходится вызывать taskkill - что не есть гуд. И вторая неприятная вещь - я выставил таймаут для нормальной работы скрипта - боюсь что на других компах может и не сработать.

И заодно бы хотел спросить про функцию проверки отметки чекбокса. Примерно в половине программ она не срабатывает. Это нормально, или я что-то не так делаю? Там где не срабатывает, есть отличительная черта: не совпадение надписи на чекбоксе с тем, что выдаёт AutoIT

Пример: Offline Explorer 3.8, Recovery My Files 3.70.

А вот так например сработало для FastStone:
Код:
ControlCommand ( 'FastStone Image Viewer', 'Completing the FastStone Image', 'Button4', 'UnCheck', '' )

Sanja Alone 07-08-2005 19:16

DenchikK
Цитата:
Примерно в половине программ она не срабатывает. Это нормально, или я что-то не так делаю?
Почти со стопроцентной уверенностью могу сказать, что все несрабатывающие используют установщик Inno Setup. Ничего не поделаешь - подводи куда нужно курсор и Send('{SPACE}')

bogomolv 08-08-2005 14:19

DenchikK

Начну с самоцитаты из своего первого поста:
"Мне обидно за любимый AutoIt, когда его используют исключительно в этих [автокликанье] целях".

На другом ресурсе (где мы с тобой уже встречались) был предложен достаточно простой и быстрый(!) способ автоустановки WinAmp путем копирования свежеустновленной программы и ее данных в реестре.
Установка WinAmp (и большинства других программ) автокликаньем имеет огромный недостаток - зависит от версии программы. В результате с выходом каждой новой версии любимой программы, как правило, приходится переписывать autoit-скрипты , что со временем изрядно надоедает. Поэтому советую обращаться к AutoIt лишь тогда, когда другие средства установки неприменимы.
Способ установки копированием реестра также зависит от версии. Но все отличия, скорее всего, будут локализованы в одной-двух отвечающих за настройки программы ветках реестра, которые можно элементарно скопировать целиком и заменить в соответствующем reg-файле.
К тому же при этом способе часто удается использовать "скрытые" возможности самой программы. Например, простое копирование mplayerc.exe можно сопроводить RunWait(@ProgramFilesDir&'\Media Player Classic\mplayerc.exe /regvid') и зарегистристрировать таким образоом на Media Player Classic расширения видеофайлов. Остается добавить в реестр некоторые свои любимые настройки программы и - ву-аля.
Интересная комбинация может получаться при синтезе нескольких способов установки. Например, в папку $oem$\$Progs\WinRAR можно положить не развернутую копию программыных файлов, а только два из них - Settings.reg (сохраненные из самого WinRAR настройки) и rarreg.key (лицензионный ключ). Тогда для автоустановки WinRAR достаточно будет двух команд
RunWait ('regedit /s "@ProgramFilesDir@\WinRAR\Settings.reg"') и RunWait ('@ScriptDir@\wrar35b7ru.exe /S') (именно в этой последовательности!).

Относительно же твоих вопросов о том, почему в кокретном случае не срабатывает та или иная команды или не закрывается то или иное окно, на них ответить трудно. Для этого под рукой нужно иметь твою программу в той версии, которую ты мучаешь и т.д. Да и обсуждение, вряд ли для кого-нибудь, кроме тебя лично, будет представлять интерес. А раз так, тебе самому и решать возникающие проблемы - перебирай по очереди различные способы слежения за окнами в AutoIt (только параметром Opt('WinTitleMatchMode', 1-4) можно задать 4 таких способа), пробуй все известные способы нажимания на кнопки (различные Control, Send (особенно Send('горячая клавиша'), MouseClick), читай и перечитывай AutoIt.chm...

Sanja Alone
Цитата:
Почти со стопроцентной уверенностью могу сказать, что все несрабатывающие используют установщик Inno Setup.
А вот это уже значительно более интересный аспект темы, поднятой DenchikK.
В продолжение начатого с ним разговора могу напомнить, что у установщика INNO SETUP есть ключ /COMPONENTS="comma separated list of component names", так что можно вполне обойтись silent-установкой без чекбоксов.
При юзании устновщиков INNO SETUP можно также сохранить параметры ручной установки ключом /SAVEINF="filename", а потом воспроизводить их через /LOADINF="filename".

DenchikK 08-08-2005 17:15

bogomolv

Цитата:
Начну с самоцитаты из своего первого поста:
"Мне обидно за любимый AutoIt, когда его используют исключительно в этих [автокликанье] целях".
Может, вы и правы, но для меня пока нет задачи, кроме автокликанья, для которой мне мог бы понадобиться AutiIT. Появятся такие задачи – более полно раскроется для меня и AutoIT. Специально то я не буду искать такие задачи. Так что с этим всё очень просто.

Цитата:
На другом ресурсе (где мы с тобой уже встречались) был предложен достаточно простой и быстрый(!) способ автоустановки WinAmp путем копирования свежеустновленной программы и ее данных в реестре.
Знаю, но меня пока ни один из известных способов не устраивает, и этот метод меня не устраивает в первую очередь. Если посмотреть программой, отслеживающий изменения в системе, то можно увидеть, что изменений, относящихся к winamp насчитывается почти 2 тысячи! И каждый раз, как выходит новая версия опять заниматься отловом записей реестра, файлов и проч. (WinAmp ещё и кодаки ставит – и отдельно их отыскивать и регистрировать) – это полный геморрой. Хотя бы попробуйте экспортировать из реестра ключи, отвечающие за регистрацию расширений – обещаю – надоест очень быстро! Так что это способ отвергается сразу.

Цитата:
Поэтому советую обращаться к AutoIt лишь тогда, когда другие средства установки неприменимы.
Вот потому и пользуюсь AutoIT только в крайних случаях, мои приоритеты просты:
1. Ключи
2. Rar SFX
3. AutoIT

Цитата:
Да и обсуждение, вряд ли для кого-нибудь, кроме тебя лично, будет представлять интерес

C эти то же не согласен. Многим пользователям будет очень полезно
прочитать, как можно решить анологичную проблему. Программы меняются - а принцип решения может быть одинаковым.


Цитата:
пробуй все известные способы нажимания на кнопки (различные Control, Send (особенно Send('горячая клавиша'), MouseClick), читай и перечитывай AutoIt.chm...
Что я и делаю, прежде чем обратиться на форум.

Цитата:
В продолжение начатого с ним разговора могу напомнить, что у установщика INNO SETUP есть ключ
Далеко не все программы работают с этими 2 способами.

Madcap 09-08-2005 02:45

Цитата:
Многим пользователям будет очень полезно
прочитать, как можно решить анологичную проблему. Программы меняются - а принцип решения может быть одинаковым.
Полностью согласен. ИМХО после прочитывания данной темы у многих начинающих "писателей" скриптов :) отпадет большая часть вопросов.

Такой вопрос. Как можно кликнуть на скрытую кнопку?
Код:
Control ID: 12325 ClassNameNN: Button7 Text: Готово (Control is hidden)

send ("{enter}") нехочется, потому что долго подводить курсор, а можно ли ControlClick-ом?

bogomolv 09-08-2005 06:13

DenchikK
Во-первых, в интернете, как и в бане, все равны. Так что, не "выкай" (и тем более не делай это с маленькой буквы - я один!).
Во-вторых, ну и зачем ты это написал? Не хочешь слушать - не слушай. Я ж все равно не проверю, как ты реализушь мои бесценные наставления! А по содержанию твой пост - сугубо личное послание-оправдание. Для этого есть почтовый ящик.:)


DenchikK & Madcap

Цитата:
Многим пользователям будет очень полезно прочитать, как можно решить анологичную проблему. Программы меняются - а принцип решения может быть одинаковым.
Полностью согласен. ИМХО после прочитывания данной темы у многих начинающих "писателей" скриптов отпадет большая часть вопросов.
И я полностью согласен, что нужно обсуждать ПРИНЦИПЫ. Поэтому и пишу.
Вы же обсуждаете, "можно ли кликнуть на скрытую кнопку" или "как бы сделать обход этого - например оператором IF". Кто ж за вас это сделает? Вот и попробуйте кликнуть на скрытую кнопку или сделать обход оператором IF. А результаты доложите...:)

biork 13-08-2005 04:42

Всем привет.
Аналогичная проблемка. Иногда выскакивает окошко, иногда нет. В случае, когда оно есть - скрипт удачно доходит до конца. В случае, когда окошка нет - не происходит отработки ветки "Else". Что не так?

Код:
Run("ezAntivirus.exe") ;BlockInput(1) WinWaitActive("License Agreement", "") ControlClick("License Agreement", "", "CUST:BUTTON2") WinWaitActive("Installation Location", "") ControlClick("Installation Location", "", "CUST:BUTTON2") If WinExists ("Update Message", "") Then WinWaitActive ("Update Message", "") ControlClick("Update Message", "", "CUST:BUTTON2") WinWaitActive ("Scan", "") ControlClick("Scan", "", "CUST:BUTTON1") ControlClick("Scan", "", "CUST:BUTTON1") WinWaitActive("Restart Required", "") WinClose("Restart Required", "") Else WinWaitActive ("Scan", "") ControlClick("Scan", "", "CUST:BUTTON1") ControlClick("Scan", "", "CUST:BUTTON1") WinWaitActive("Restart Required", "") WinClose("Restart Required", "") EndIf Exit

biork 13-08-2005 05:05

Цитата:
Ничего не поделаешь - подводи куда нужно курсор и Send('{SPACE}')

Воспользовался этим нехитрым методом:

Код:
... WinWaitActive("Drive Image 2002 Setup", "Select the features you want to install") ControlFocus ( "Drive Image 2002 Setup", "", "SysTreeView321") MouseClick( "left", 443, 471, 1) ControlFocus ( "Drive Image 2002 Setup", "", "Button2") Send("!n") ...


Работает! Но... только на моём компе, когда тестирую скрипт.
При запуске на виртуальной машине или другом компьютере стрелка уезжает совсем не в то место, где нужно кликнуть

bogomolv 13-08-2005 17:56

biork

По MouseClick.
Вместо этой команды Tab'ом подведи к кусор к кнопке и кликни ее. Что-то вроде Send({Tab}{Enter}).

По неожиданным окошкам.
Не знаю конкретной проблемы, но в общем случае для неожиданных окон и любых других нежелательных оказий в AutiIt есть чудная процедура AdlibEnable('Имя функции').
Пример. На стадии cmdlines иногда выскакивает сообщение о заканчивающейся виртуальной памяти. Для его погашения в cmdlines.au3, отрабатывающем все действия на данной стадии, задаем функцию NonVMEM
Код:
AdlibEnable('NonVMEM') ... обычные действия ... Exit Func NonVMEM() If WinExists('Слишком мало виртуальной памяти') Then WinKill('Слишком мало виртуальной памяти') EndFunc

Sanja Alone 13-08-2005 19:01

biork
Если сильно хочется MouseClick-нуть, то сначала обрати внимание на опцию
Код:
Opt("MouseCoordMode", 1) ;1=absolute, 0=relative, 2=client
По умолчанию, привязка идет к левому верхнему углу экрана (1), а тебе нужно привязаться к активному окну (0) или к клиентской части активного окна (2). В AutoIt Window Info эти режимы находятся здесь: Options - Coord Mode.

Sanja Alone 14-08-2005 18:24

Я написал простенький конвертер для перевода reg-файлов в директивы AutoIt (RegWrite и RegDelete).
Конвертер понимает все типы параметров (известные AutoIt-у), поддерживает удаление веток/параметров.
Параметры типов REG_RESOURCE_LIST (hex(8)), REG_FULL_RESOURCE_DESCRIPTOR (hex(9)), REG_RESOURCE_REQUIREMENTS_LIST (hex(a)), REG_QWORD (hex(b)), а также неправильные параметры типа DWORD (hex(4)) пропускаются.

Ограничения: не понимает Unicode, т.е. исходные reg-файлы должны быть в DOS или Win кодировках (REGEDIT4).
Особенности: медленная работа с большими файлами (675Кб ветка HKLM\SYSTEM\CurrentControlSet\Services, выбранная для теста, обрабатывается 4,5 мин. на AXP-1500MHz). Я не считаю этот момент проблемой, т.к. конвертер предназначен не для преобразования реестра, а для дополнения AutoIt-скриптов установок прог их настройками из reg-файлов.

Кому нужен - прошу
Если при использовании столкнетесь с какими-то недоработками - мыльните.

Кроме того, скрипты установки н-рых программ находятся на этой странице.

P.S. Исправил проблемы с \\, \", одинарными кавычками внутри параметров ('), двоеточиями в названиях параметров, параметрами по умолчанию (@), символами равно внутри строковых параметров.

bogomolv 15-08-2005 11:03

Sanja Alone

Well job!

Geck 20-08-2005 02:07

Люди подскажите пожалуйста как можно из экселевской таблички скопировать данные (количество строк не фиксированное, столбцы фиксированные)?

bogomolv 21-08-2005 00:56

Geck

Обработать xls-файл вряд-ли удастся - слишком сложная структура файла.
А вот обработать окно с открытой таблицей легко - через Send('^{Ins}) или ControlGetText().

Geck 21-08-2005 02:31

bogomolv
Спасибо... А как можно определить когда данные закончатся?
Можно конечно вручную править количество повторов в цикле, но это не выход.


Geck 21-08-2005 02:32

bogomolv
Кстати через ControlGetText() не получается, только через Send

demo369 23-08-2005 09:30

Добрый вечер
Вопрос по поводу скрипта от Lingvo
Сдела папочку Lingvо, сложил туда все нужные файлики:
/vfd
AutoIt3.exe
ling10me_flp.IMA
lingvo.au3
lingvo.exe
LV10ML.iso
Запускаю
AutoIt3.exe lingvo.au3
Доходит до принятия лицензионного соглашения и виснет.
Причем стоит точка на отказе принятия лицензионного соглашения
Может где-нибудь в скрипте ошибка?

Я так понимаю ошибка должна быть здесь:
ControlClick ( 'ABBYY Lingvo 10 Multilingual Dictionary', 'Лицензионный договор', 'Button3' )
Такой функции не нашел в описании. AutoIT 3.1.1

Sanja Alone 29-08-2005 18:09

demo369
Цитата:
Запускаю AutoIt3.exe lingvo.au3
В принципе, так тоже должно работать, т.к. я применял макрос @ScriptDir в путях, но я всегда использую откомпилированные в exe скрипты, а данный вариант запуска установки Lingvo не тестировал вовсе.

Цитата:
Может где-нибудь в скрипте ошибка?
Пару десятков раз проверял на VMWare и 2 раза на реальных компах - все было ОК.
Почему скрипт может не работать:
1. Не выполнен пункт 4 оригинального поста - Alcohol или Daemon ни разу не запускались.
2. Другой дистрибутив Lingvo и, следовательно, отличные от приведенных в скрипте названия окон, текст в окнах, названия эл-тов (ну не Button3, а Button2, например), другое имя msi-файла в корне исошки Lingvo и т.п.

Для выяснения точной причины, добавь в начало скрипта строку Opt("TrayIconDebug",1), а также закомментируй AutoItSetOption("TrayIconHide", 1) и BlockInput ( 1 ). Запусти скрипт снова, и, когда он зависнет, наведи мышь на иконку AutoIt-а в трее и увидишь причину зависания.

Цитата:
Такой функции не нашел в описании. AutoIT 3.1.1
Плохо искал: ControlClick ( "title", "text", controlID [, button] [, clicks]] ). При просмотре chm-ки, для более удобного поиска, переключайся на закладку "Указатель" и там вводи то, что ищешь. При этом работает автодополнение и ты быстро найдешь искомую функцию.

P.S. Извини за неоперативный ответ - я только вчера купил новую интернет-карточку.

EgOrus 30-08-2005 09:13

Здравствуйте товарищи, радует что тема растет и множится.
Написал скрипт для автоматизации процесса скидывания CD и DVD дисков на HDD (мне нужно было скинуть большое количество фильмов).

Так вот вопрос такой, хотелось бы сделать прогрэсбар для наглядности, но каким образом обновлять его, что-то не представляю. Вернее есть решение, считывать объем инфы кот. уже скопировалась и сравнивать с общим объемом компакт диска, но это работает только в случае копирования мелких фалов, при копировании фильма индикатор с 1% будет прыгать на 100%. Есть ли какое-то решение?

Код:
; Скрипт полностью автоматизирует процесс копирования, от пользователя требуется ; только вставлять диски и задвигать лоток. Скипт написан для запуска из Total Commander, ; но можно использовать и самостоятельно. ; В верхнем левом углу выводит инф. о текущем действии скрипта. ; Пример запуска: ; cdcopy.exe [CD] [Destination] ; cdcopy.exe X: D:\Video или cdcopy X "D:\Video store" ; cdcopy.exe "%P" "%T" из TC ;----------------------------------------------------------- Opt('ExpandVarStrings', 1) Opt('TrayIconDebug',1) ;Назначение переменных из командной строки $cmd1 = $CmdLine[1] $cmd2 = $CmdLine[2] ;Приведение переменных к нужному виду If StringLen($cmd1) = 1 Then $cmd1 = "$cmd1$:" If StringLen($cmd2) = 1 Then $cmd2 = "$cmd2$:" If StringLen($cmd1) > 2 Then $cmd1 = StringLeft("$cmd1$", 2) If StringRight("$cmd2$", 1) = "\" Then $cmd2 = StringTrimRight("$cmd2$", 1) ;Завершение скрипта если нет параметров или первый параметр не явл. буквой CD(DVD)ROM'а If $CmdLine[0] = 0 Then MsgBox(4096,"CD-DVD Copy script", "No command-line arguments") Exit ElseIf DriveGetType("$cmd1$\") <> "CDROM" Then MsgBox(4096,"CD-DVD Copy script", "$cmd1$ is not a CD(DVD)ROM drive letter") Exit EndIf ;Начало цикла While 1 Sleep (1000) ;Если в приводе нет носителя, начинаем цикл сначала If DriveStatus("$cmd1$\") == "NOTREADY" Then ContinueLoop ToolTip(" CD mount.", 1, 1) Sleep (500) ;Получаем объем своб.места на диске назначения и конвертируем его в gb. в случае если места больше 1024 mb. $DestFree = DriveSpaceFree(StringLeft("$cmd2$", 2) & "\") if $DestFree > 1024 Then $DestFreeGB = round (($DestFree / 1024), 2) $siz = "gb." Else $DestFreeGB = round ($DestFree, 2) $siz = "mb." EndIf ;получаем объем носителя в mb. (CD или DVD) $SourceTotal = DriveSpaceTotal("$cmd1$\") If $SourceTotal > 801 Then $media = "DVD" Else $media = "CD" EndIf ;получаем Метку диска $CDlabel = DriveGetLabel("$cmd1$\") ;Завершение скрипта если недостаточно свободного места на диске назначения ToolTip(" Check free space.", 1, 1) Sleep (500) ToolTip(" Free space: $DestFreeGB$ $siz$", 1, 1) If $DestFree < $SourceTotal Then MsgBox(4096,"CD-DVD Copy script", "Not enough free space on Drive " & StringLeft("$cmd2$", 2) & " " & round($DestFree, 2) & " mb. free") Exit EndIf Sleep (1000) ;Создаем папку, куда затем будет скопирован диск DirCreate("$cmd2$\!new\$CDlabel$") ToolTip(" $media$ copy in progress :: $CDlabel$ :: [" & round($SourceTotal, 2) & " mb.]", 1, 1) DirCopy("$cmd1$\", "$cmd2$\!new\$CDlabel$",1) ToolTip(" $media$ copy complete", 1, 1) Sleep (500) SoundSetWaveVolume(50) SoundPlay ( "C:\WINDOWS\Media\chimes.wav") CDTray("$cmd1$", "open") ToolTip(" Please mount Media in Drive $cmd1$", 1, 1) Sleep (4000) WEnd

demo369 30-08-2005 10:24

demo369

Цитата:
Запускаю AutoIt3.exe lingvo.au3

В принципе, так тоже должно работать, т.к. я применял макрос @ScriptDir в путях, но я всегда использую откомпилированные в exe скрипты, а данный вариант запуска установки Lingvo не тестировал вовсе.

Сделал экзешник. Ситуация не поменялась ;)


Цитата:
Может где-нибудь в скрипте ошибка?

Пару десятков раз проверял на VMWare и 2 раза на реальных компах - все было ОК.
Почему скрипт может не работать:
1. Не выполнен пункт 4 оригинального поста - Alcohol или Daemon ни разу не запускались.

Пользуюсь Alcohol. Специально запускал. По идеи если его не запустить, то он и образ не должен примонтировать,а это он как раз делает.

2. Другой дистрибутив Lingvo и, следовательно, отличные от приведенных в скрипте названия окон, текст в окнах, названия эл-тов (ну не Button3, а Button2, например), другое имя msi-файла в корне исошки Lingvo и т.п.

LV10ML.iso - размер 650,170,368 байт
MSI файл как и в скрипте.
названия и кнопки такие же. смотрел через AutoIt Window Info и через IsoBuster.

Для выяснения точной причины, добавь в начало скрипта строку Opt("TrayIconDebug",1), а также закомментируй AutoItSetOption("TrayIconHide", 1) и BlockInput ( 1 ). Запусти скрипт снова, и, когда он зависнет, наведи мышь на иконку AutoIt-а в трее и увидишь причину зависания.

Просто выдает что скрипт остановлен (paused) lingvo.exe


Цитата:
Такой функции не нашел в описании. AutoIT 3.1.1

Плохо искал: ControlClick ( "title", "text", controlID [, button] [, clicks]] ). При просмотре chm-ки, для более удобного поиска, переключайся на закладку "Указатель" и там вводи то, что ищешь. При этом работает автодополнение и ты быстро найдешь искомую функцию.

Угу, нашел. Даже пробовал, добавить button и clicks. Рез-тов не дало.

P.S. Извини за неоперативный ответ - я только вчера купил новую интернет-карточку

Это не страшно ;) Спасибо что ответил.
Могу еще скриншот скинуть на окошко, на котором скрипт останавливается. Может что-нибудь прояснится.

Sanja Alone 31-08-2005 19:21

demo369
Очень неудобно читать твои посты - pls, пользуйся тэгами цитат quote.

Цитата:
Просто выдает что скрипт остановлен (paused) lingvo.exe
Не просто... Наведи мышку на иконку и не нажимай клавиш, появится всплывающая подсказка на 2 строки - в первой будет имя скрипта, а во второй строка на к-рой он застопорился (что-то вроде Line 5: WinWait("Name","Text")) Причем лучше запускать au3-файл, т.к. в случае с exe не будет показан номер строки скрипта.

Цитата:
Даже пробовал, добавить button и clicks. Рез-тов не дало.
Все, что в квадратных скобках - необязательные параметры.

Что я могу еще придумать:
1. Можно заменить
Код:
WinWaitActive ( 'ABBYY Lingvo 10 Multilingual Dictionary', 'Лицензионный договор' ) ; на WinWait ( 'ABBYY Lingvo 10 Multilingual Dictionary', 'Лицензионный договор' ) WinActivate ( 'ABBYY Lingvo 10 Multilingual Dictionary', 'Лицензионный договор' ) WinWaitActive ( 'ABBYY Lingvo 10 Multilingual Dictionary', 'Лицензионный договор' )

2. Заменить
Код:
ControlClick ( 'ABBYY Lingvo 10 Multilingual Dictionary', 'Лицензионный договор', 'Button3' ) Send ( '{ENTER}' ) ; на Send ( '{UP}' ) Send ( '{ENTER}' )

3. Мешать скрипту могут различные перехватывающие нажатия клавиш проги: автопереключатели раскладки, счетчики нажатий клавиш и т.п. Тут нужно или отказаться от BlockInput(1), или убивать процесс такого приложения в памяти, например, убийство Punto Switcher-а будет выглядеть так (поместить этот код нужно в начало скрипта):
Код:
If ProcessExists ( "ps.exe" )<>0 Then ProcessClose ( "ps.exe" ) ProcessWaitClose ( "ps.exe" ) EndIf

Sanja Alone 31-08-2005 20:37

EgOrus
Цитата:
Вернее есть решение, считывать объем инфы кот. уже скопировалась и сравнивать с общим объемом компакт диска
Два шага:
1. Перед началом копирования определять объем свободного места на целевом диске;
2. Разность (текущий объем свободного пространства - начальный) сравнивать с общим объемом компакта.
Данные на винт ведь не 700-метровыми кусками пишутся :)

EgOrus 31-08-2005 23:29

Цитата:
Сообщение от Sanja Alone
Два шага:
1. Перед началом копирования определять объем свободного места на целевом диске;
2. Разность (текущий объем свободного пространства - начальный) сравнивать с общим объемом компакта. Данные на винт ведь не 700-метровыми кусками пишутся

Не вижу принципиального отличия от моей схемы :) в моем варианте происходило так:
1. рассчет занимаемого места целевой папки куда ложится фильм (для диска создается отдельная папка с меткой диска)
2. сравнения полученного значения с общим объемом компакта.
Но вся заковырка в том, что данные именно 700 метровыми кусками и пишутся. Может конечно что-то в системе нужно изменить, но у меня именно так и происходит, под фильм сразу резервируется все 700 метров в самомом начале копирования, т.е. в целевой папке создается 700метровый файл.
Есть еще один вариант, копировать через @comspec copy , возможно в этом случае копирование происходит без резервирования.

Sanja Alone 01-09-2005 18:12

EgOrus
Цитата:
Есть еще один вариант, копировать через @comspec copy
Стандартные средства тут не катят - copy как и xcopy резервируют пр-во перед началом копирования.
Тебе нужна xxcopy (244 527 байт) - эта вариация на тему xcopy имеет массу возможностей и копирует без предварительного резервирования места. Но потом не ругайся на обрубки файлов, если прервешь процесс :)

EgOrus 02-09-2005 00:31

Sanja Alone
Да я знаю эту утилитку, но ни xxcopy ни robocopy меня не устраивают, лучше уж я пожертвую прогрессбаром, чем буду использовать сторонние утилитки. К моему удивлению на родном форуме также ничего по копированию больших файлов не придумали. Спасибо тебе за помощь.

Speed_Perm 02-09-2005 07:34

Здравствуйте.

Обращаюсь за помощью. Слепил скриптик для автоматической установки программы на компьютер W2000 pro SP4 под правами опытного пользователя. Но инсталляция просит наличие прав администратора. Как бы проблема решаема с помощью RunAsSet ( ["user", "domain", "password"] . Инсталяционный пакет находится на сететвом ресурсе. Но возникает проблема:



run(‘\\Maim\install\setup.exe’)

Инсталяция запускается, но сообщает об необходимости прав администратора



а если

RunAsSet ( "Admin", @Computername, "password" )

run('\\Maim\install\setup.exe')

то выдает ошибку

Error: Unable to execute the external program.

Системе не удается найти указанный путь



если

RunAsSet ( "Admin@Computername, "password" )

run('D:\install\setup.exe')

то запускается



Подскажите причина такого глюка? Или я не правильно делаю?

biork 02-09-2005 16:54

Всем привет!
В очередной раз прошу помощи у знающих и понимающих :-)
Совершенно ламерский вопрос. Как скопировать файл с CD диска на HDD в процессе выполнения скрипта?
Скрипт запускается из RunOnceEx.cmd. Оба файла, котырые нужно скопировать лежат в той же дирректории что и сам скрипт.
Вариант, приведённый ниже не срабатывает: папка создаётся, но файлы не копируются

Код:
DirCreate("D:\folder1\folder2") FileCopy("setup.exe", "D:\folder1\folder2\*.*") FileCopy("#readme.txt", "D:\folder1\folder2\*.*")


Однако, если запустить скрипт "вручную", непосредственно кликнув по нему, то всё ок - файлы копируются.
В чём косяк? (Все остальные команды из RunOnceEx.cmd, а так же сам скрипт, фрагмент которого приведён выше, выполняются нормально)

Sanja Alone 02-09-2005 17:56

biork
Код:
FileCopy( @ScriptDir & '\setup.exe', 'D:\folder1\folder2\' ) FileCopy( @ScriptDir & '\#readme.txt', 'D:\folder1\folder2\')

Sanja Alone 02-09-2005 19:01

Speed_Perm
Цитата:
run('\\Maim\install\setup.exe') то выдает ошибку Error: Unable to execute the external program.
afair, Run не понимает сетеых путей. Попробуй сначала примапить ресурс \\Maim\install при помощи функции
Код:
DriveMapAdd( "device", "remote share" [, flags [, "user" [, "password"]]] )
(фактически, это местный net use). А уже потом запускай setup.exe через
Код:
Run('X:\setup.exe')
(где X - это и есть тот самый "device").

Sanja Alone 04-09-2005 21:10

Добавил скрипт для автоустановки переводчика Pragma 4.xx.xxxx.
Да, можете посмотреть на применение функции AdlibEnable() на примере этого скрипта. Все комментарии (как всегда) внутри скрипта.

bogomolv 06-09-2005 01:39

Sanja Alone
Цитата:
Попробуй сначала примапить ресурс \\Maim\install при помощи функции DriveMapAdd

Недавно тоже обратил внимание на эту функцию. Понравилось, но, к сожалению, она НЕ работает под WinPE!
Там вообще с сетью постоянные заморочки. Как раз для простого и быстрого подключения из под WinPE ко второму компьютеру и пытался прикрутить эту функцию. Фиг-вам. Пришлось оставить скрипт, основанный на NET USE:
Код:
For $i=1 to 15 $err=RunWait('net use * \\note\c /user:Богомолов') If $err=0 Then MsgBox(0,'AutoIt3','Подключение установлено! ', 5) Exit Else If MsgBox(5,'AutoIt3','Попытка подключения '&$i&'. Ждите... ', 10)=2 Then ExitLoop EndIF Next MsgBox(16,'','Подключиться не удалось. Проверьте свою сеть! ', 10)


bogomolv 06-09-2005 16:46

Продолжим разговор об интересных функциях?

Очень понравилась функция StringSplit. Особенно одно ее практическое применение, которое подсмотрел в предлагаемом для include файле File.au3. Теперь одной строчкой считываю содержимое текстового файла в массив $list=StringSplit(FileRead($f,FileGetSize($f)),@CRLF) и делаю с ним, что хочу!

В частности, функция очень пригодилась для считывания структуры каталогов драйверов OEM-установки Windows (папка $oem$\$1\drivers). Раньше приходилось следить и жестко прописывать все пути к драйверам для их автоустановки на стадии CMDLINES (CMDLINES.TXT у меня запускает CMDLINES.AU3, в котором расписан сценарий установки дров и инициализации настроек системы).
Теперь в CMDLINES.AU3 вместо многостраничного перечня действий со всеми своими и чужими драйверами (с которыми когда-либо встречался и могу встретиться еще) у меня стоит красивая конструкция:
Код:
;Установка драйверов устройств $f= '%temp%\1.txt' RunWait ('%Comspec% /c dir /ad /s "c:\drivers" | find "c:\drivers\" > $f$','',0) $dr= StringSplit(StringReplace(FileRead($f,FileGetSize($f)),' ‘®¤Ґа¦Ё¬®Ґ Ї ЇЄЁ ',''),@CRLF) For $i=1 To $dr[0] $drr= $dr[$i] $srch= FileFindFirstFile('$drr$\*_1.au3') If $srch=0 Then RunWait('AutoIt3.exe "$drr$\'&FileFindNextFile($srch)&'"') FileClose($srch) Next

Данной процедурой считывается дерево каталога "c:\drivers" (куда копируются в процессе установки драйвера из $oem$\$1\drivers) и проверяется наличие скриптов с именем *_1.au3 с последующим их запуском. Файлы скриптов *_1.au3 - это мои автоустановщики дров и их настроек, которые я теперь храню вместе с дровами (а не в CMDLINES.AU3, как раньше). Не все дрова требуют наличия таких установщиков. И прекрасно! FileFindNextFile() не найдет *_1.au3 и перейдет к следующему каталогу. Есть и такие дрова, которые вообще не любят ставиться в процессе установки Windows (например, IAAraid). Обзываем скрипт их установки *_2.au3 и включаем те же девять строк в начало STARTUP.AU3, который стартует из Автозапуска при первом запуске свежеустановленной Windows (в этом файле у меня расписан сценарий автустановки программного обеспечения).
Теперь подготовка дистрибутива для установки системы на чужой машине сводится к простому копированию из архива заготовок драйверов для $oem$\$1\drivers и небольшой правке unattended.txt. Счастливому же владельцу машины достается комплект автопереустановки системы, похожий на те, что идут с ноутбуками…

Sanja Alone 06-09-2005 18:54

1. Подправил скрипт для Pragma 4.x: теперь можно посмотреть на применение функции AdlibEnable(), а также опции OnExitFunc - здесь она необязательна, но уместна в кач-ве демонстрации.
2. Переписал скрипт для ABBYY FineReader 7.0: теперь 3 варианта установки, две страны (Украина, Россия), зациклен ввод серийника (действительно иногда первый сгенерированный серийник не подходит).

bogomolv
Цитата:
Очень понравилась функция StringSplit
А ты думаешь какой функцией я воспользовался при чтении файла в массив в своем конвертере crta :)
Но тут есть заковырка: если массив у тебя уже объявлен, например как $Array[1], то элемент $Array[0] - это не длина массива, а всего лишь первое внесенное значение (у меня была необходимость в предопределенном массиве в кач-ве временного хранилища многострочных hex-параметров). Для дополнения такого массива новым элементом его нужно ресайзнуть ReDim $Array[UBound($Array) + 1],а в циклах вместо For $i=1 To $Array[0] писать For $i=1 To UBound( $Array, 1 )-1.
И еще одна особенность AutoIt-а в плане работы с массивами: когда я переписал конвертер так, чтобы он использовал 2 массива (вх. и рез.), а не добавлял построчно данные в файл, он (конвертер) стал работать более чем в 3 раза медленнее (~16 мин.). Вот тебе и ОЗУ :( Самое забавное, что я еще пробовал третий вариант: построчное чтение вх. файла с такой же построчной записью результирующих строк в вых. файл - выполняется 6 с небольшим минут (против 4,5 в исх. вар-те), правда исп-ся минимум памяти. (это время конвертации моего тестового 675Кб reg-файла - ветка HKLM\SYSTEM\CurrentControlSet\Services)
Пришлось оставить исходный вариант алгоритма: читаем все в массив - определяем тип строки - составляем выходную строку - пишем в файл - повторяем до конца массива (для многострочных параметров, как я уже сказал, исп-ем доп. динамический временный массив). Ух, удалился я от темы, ну да ладно...

К вопросу о драйверах: я использую метод установки с CD. Вполне себе нормально все ставится... и без скриптов. Правда, пока приходилось ставить Винду только на VIA и nForce2-based платформы, с другими может и не так все гладко. А у тебя создается некое подобие персонифицированного для конкретной машины набора дров, или как? Алгоритм? Ты бы статью написал на эту тему, что ли...

demo369 07-09-2005 06:41

Sanja Alone
Добрый день.
Не очень тут удобно редактировать письма, да не суть.
Спасибо за подсказку с функцией Opt() При ее помощи удалось найти проблему. Все дело оказалось в кодировке файла скрипта :( Русский язык не правильно воспринимался, поэтому дальше скрипт и не шел.
Прошу прощения, что отнял столько времени из-за такой глупости.

Цитата:
demo369
Очень неудобно читать твои посты - pls, пользуйся тэгами цитат quote.


Цитата:
Просто выдает что скрипт остановлен (paused) lingvo.exe

Не просто... Наведи мышку на иконку и не нажимай клавиш, появится всплывающая подсказка на 2 строки - в первой будет имя скрипта, а во второй строка на к-рой он застопорился (что-то вроде Line 5: WinWait("Name","Text")) Причем лучше запускать au3-файл, т.к. в случае с exe не будет показан номер строки скрипта.


Цитата:
Даже пробовал, добавить button и clicks. Рез-тов не дало.

Все, что в квадратных скобках - необязательные параметры.

Что я могу еще придумать:
1. Можно заменить

Код:
WinWaitActive ( 'ABBYY Lingvo 10 Multilingual Dictionary', 'Лицензионный договор' )
; на
WinWait ( 'ABBYY Lingvo 10 Multilingual Dictionary', 'Лицензионный договор' )
WinActivate ( 'ABBYY Lingvo 10 Multilingual Dictionary', 'Лицензионный договор' )
WinWaitActive ( 'ABBYY Lingvo 10 Multilingual Dictionary', 'Лицензионный договор' )

2. Заменить

Код:
ControlClick ( 'ABBYY Lingvo 10 Multilingual Dictionary', 'Лицензионный договор', 'Button3' )
Send ( '{ENTER}' )
; на
Send ( '{UP}' )
Send ( '{ENTER}' )

3. Мешать скрипту могут различные перехватывающие нажатия клавиш проги: автопереключатели раскладки, счетчики нажатий клавиш и т.п. Тут нужно или отказаться от BlockInput(1), или убивать процесс такого приложения в памяти, например, убийство Punto Switcher-а будет выглядеть так (поместить этот код нужно в начало скрипта):

Код:
If ProcessExists ( "ps.exe" )<>0 Then
ProcessClose ( "ps.exe" )
ProcessWaitClose ( "ps.exe" )
EndIf

ANGRO 11-09-2005 09:15

Господа помогите с InputBox, если жмут Cancel или закрывают окно на выходе должен быть путь установки проги по умолчанию, как написать?
Всё разобрался
Код:
$answer = InputBox("Путь установки", "Куда исталлировать программу?", @ProgramFilesDir & "\PRMT6\", "", -1, -1,400,300) If @error=1 Then $answer =@ProgramFilesDir & "\PRMT6\" EndIf FileWrite("Answer.txt",$answer)

Sanja Alone 12-09-2005 22:03

1. Переписал скрипт для Winamp 5.xx: теперь с исп-ем идентификатора окна и внесением н-рых настроек в winamp.ini
2. Добавил скрипты для Everest 2.xx (Ultimate/Corporate/Home) и DVD Identifier 3.x (4.x)

P.S. Таблица выбора скриптов на сайте теперь содержит инф. о версии скрипта, а также имеет возможность сортировки (применены xml+xsl+javascript). Если у кого-то не будет работать - напишите мне (указав свой браузер и его версию), т.к. тестировалось все это дело только на IE 6.0.

P.P.S. Если у Вас будет желание, то могу разместить эдесь и Ваши скрипты. Ес-но, добавив в таблицу ссылку на автора (пока в этом нет нужды, т.к. автор один - я :) )

Softwarez777 13-09-2005 07:41

А для Promt 7 Expert можно сделать ?

Sanja Alone 13-09-2005 18:04

Softwarez777
Цитата:
А для Promt 7 Expert можно сделать ?
Конечно, но у меня его нет, а качать с "двухбаксов" пролеченную версию на двух CD (прога + CD со словарями) мне на диалапе сложновато и оч-чень дороговато :(

SlavaS 13-09-2005 22:42

EgOrus
Расскажи пожалуйста поподробнее про alc120.vbs, что и куда ложить надо и что за объект ActiveX? И про alc120.au3 что-то я пробовал и ни чего у меня не получилось, тут наверное я один такой одаренный :) что ни чего не понимаю, когда просто запускаю start C:\Test\AutoIt3.exe alc120.au3 в трэе появляется значок, а когда при установке даже в VmWare выскакивает ошибка чтения файла alc120.au3, а Alcohol продолжает устанавливаться и вылазиет мастер нового оборудования, и ничего не происходит :(, делаю все как написано в руководстве подскажи плиз что я ни так делаю.

EgOrus 15-09-2005 02:13

SlavaS
во1ых, start C:\Test\AutoIt3.exe C:\Test\alc120.au3 (нужно указать путь к скрипту, иначе система ищет его в системных папках)
во2ых, какой язык системы у тебя? скрипт au3 дан для русской винды, для англ. нужно переписывать заголовки окон.
в3их, добавь в начало скрипта строку AutoItSetOption ("TrayIconDebug", 1) и если при появлении мастера нового оборудования ничего не происходит, наведи на значок "A" в трэе, он тебе покажет на какой строчке скрипт остановился, напиши эту информацию здесь, будем дальше думать (возможно что ты используешь последнюю версию Алкоголика и в нем что-то изменилось, хотя наврятли, пот. мастер нового оборудования это не алкоголиковское окно)

Кстати как ты запускаешь установку? Так:
msiexec.exe /passive /norestart /i c:\Test\setup.msi

По поводу vbs:
Сперва чтобы пользовать этим самым объектом ActiveX, нужно зарегить в системе библиотеку AutoItX.dll (есть в дистрибутиве AutoIt)
regsvr32 /s c:\Test\AutoItx.dll (предположим что ты dll'ку положил в С:\Test а вообще правильнее ложить ее в папку windows или windows\system32 - $OEM$\$$\system32)
после этого положить vbs данный на 1ой странице рядом с распакованным дистром (должен присутствовать файл setup.msi) и запустить его.

Sanja Alone 15-09-2005 19:02

SlavaS
Скрипт установки Alcohol 120% 1.9.5.3105 (установка/регистрация/настройки). Комментарии смотри внутри au3-файла (скрипт подходит для любых Алкоголиков, т.к. исп-ся тихая установка).

SlavaS 16-09-2005 01:23

У меня установка и регистрация проходит нормально, я не могу от мастера нового оборудования избавиться :(

EgOrus 16-09-2005 02:37

SlavaS
Проверь чтобы заголовок первого окна мастера нового оборудования совпадал с первой строчкой winwait (...).
Проверять установку лучше не на виртуальной машине, а на своей, устанавливаешь если и что-то не так в процессе, удалаешь его. Правишь скрипт, потом опять запускаешь и смотришь как прошла установка, так до победного конца.

DenchikK 16-09-2005 03:30

А можно ли с помощью AutoIT определить, какая винда (XP, ХP SP1, XP SP2) стоит на машине?
Идея вот в чём: в зависимости от того, какая винда стоит, подключать соответствующий BootScreen:
1. Переписать файл скрина на винт
2. Редактировать (добавить строчку) файл boot.ini (где-то я видел, как с помощью AutoIT можно редактировать файлы).

SlavaS 16-09-2005 08:49

EgOrus
что-то я ни как не могу победить этот мастер нового оборудования, или скрипт не доделанный или у меня XP не тот, но в заголовке окна все совпадает.
Я вот думаю почему в твоем скрипте как только появляется мастер нового оборудования и нажимается ENTER?
Цитата:
'Ожидание окна установки SCSI адаптера
AutoIt.WinWait "Мастер нового оборудования", "", 0
AutoIt.Sleep 500
AutoIt.Send "{ENTER}"

Он ведь сначала спрашивает разрешить подключение к узлу Windows update для поиска програмного обеспечения и нужно выбрать Да, только в этот раз или Нет, не в этот раз, т.к. кнопка далее не активна, а вот потом уже нужно этот самый ENTER.

EgOrus 16-09-2005 11:54

SlavaS
Понятно, у меня до устаноки софта применяются твики, в данном случае за НЕпоявление указанного тобой окна отвечает этот твик:
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DriverSearching]
"DontSearchWindowsUpdate"=dword:00000001
"DontPromptForWindowsUpdate"=dword:00000001

Поэтому у тебя и не выходит каменный цветок...
Можешь либо применить твик, либо просто добавить в скрипт действия по закрытию этого окна. С помощью AU3Info.exe узнать название класса кнопки "нет" и использовать конструкицю типа
WinWait ("нужное окно","", 0)
Sleep(500)
'Послать в указанное окно ControlClick для кнопки НЕТ (название класса этой кнопки например Button2)
ControlClick ("Нужное окно","", "Button2")

Sanja Alone 16-09-2005 19:07

DenchikK
Цитата:
А можно ли с помощью AutoIT определить, какая винда (XP, ХP SP1, XP SP2) стоит на машине?

Код:
@OSLang - Returns code denoting OS Language. See Appendix for possible values. @OSType - Returns "WIN32_NT" for NT/2000/XP/2003 and returns "WIN32_WINDOWS" for 95/98/Me @OSVersion - Returns one of the following: "WIN_2003", "WIN_XP", "WIN_2000", "WIN_NT4", "WIN_ME", "WIN_98", "WIN_95" @OSBuild - Returns the OS build number. For example, Windows 2003 Server returns 3790 @OSServicePack - Service pack info in the form of "Service Pack 3" or, for Windows 95, it may return "B"


Цитата:
...файл boot.ini (где-то я видел, как с помощью AutoIT можно редактировать файлы).
Для ini-файлов в AutoIt-е предусмотрены спец. функции:
Код:
IniDelete ( "filename", "section" [, "key"] ) - Deletes a value from a standard format .ini file. IniRead ( "filename", "section", "key", "default" ) - Reads a value from a standard format .ini file. IniReadSection ( "filename", "section" ) - Reads all key/value pairs from a section in a standard format .ini file. IniReadSectionNames ( "filename" ) - Reads all sections in a standard format .ini file. IniWrite ( "filename", "section", "key", "value" ) - Writes a value to a standard format .ini file.


Все вышеперечисленное можно найти просто почитав оригинальный файл AutoIt.chm (а не переведенный хелп к одной из старых версий AutoIt-а).

DenchikK 16-09-2005 22:56

Спасибо огромное! Просто с английским у меня дико плохо - вот и юзаю перевод, а он оказывается не полный.

Sanja Alone 17-09-2005 17:29

Добавил скрипты:
Adobe Photoshop CS (Photoshop 8.0)
BetterJPEG 1.4.1.2
DivX Pro 5.1.1 GAIN Bundle Codec
Foxit PDF Reader 1.3 (Build 0708)
Get File Size 2.2
Mozilla Thunderbird 1.0.6

Поправил/дописал:
DivX Pro 6.0 Bundle Codec (Create)
Image Dupeless 1.6.1 (ru/en)

bogomolv 18-09-2005 16:07

Sanja Alone

Ты памятник себе воздвигаешь себе нерукотворный?
К нему не зарастет народная тропа!

Маладес!

Хотел бы подмазаться. Но, блин, как же это тяжело думать о других...

Ну и типа - by the way!
Други, впервые встретился с проблемой, что НЕ МОГУ ввести латинскую "D"!
Всегда решал эту проблему "русского языка" Autoit (под WinXP Rus) с помощью ClipPut('D')... Send('+{INS}') или ControlSetText(''...','...','...','D'). Но DSKPROBE.EXE (этот Василий Алибабаевич!) не воспринимает ничего, прямого direct push!

bogomolv 18-09-2005 16:23

Sanja Alone
Сань, признавая и уважая... Но как же мы по-разному думаем!
Вместо autoit-foxitpdf.au3 у меня в ...\$oem$\$Progs\FoxitReader лежат FoxitReader.exe и foxitpdfreader.reg. В CmdLines.au3 при этом есть запись RunWait ('regedit /s "@ProgramFilesDir@\FoxitReader\foxitpdfreader.reg"')

Sanja Alone 18-09-2005 18:54

bogomolv
Цитата:
НЕ МОГУ ввести латинскую "D"!
Chr(68) пробовал?

Цитата:
Хотел бы подмазаться.
А какие проблемы, я же недавно предлагал всем желающим присоединяться. Если есть что-то, чего не жалко раздать всем и нашару - прошу. Авторства я себе присваивать не собираюсь, честность - мой порок :)

Цитата:
Но, блин, как же это тяжело думать о других...
Альтруизм - врожденная неизлечимая болезнь. Если с этим родился, с этим и помрешь. Я даже в игрушках всегда играю за хороших...

Цитата:
Но как же мы по-разному думаем!
Ес-но, одинаково мыслящие люди - это уже роботы :) На нашей Окраине политики любят называть таких биомассой. Ужасное, но предельно точное определение из уст мерзких лицемерных существ...
Цитата:
Вместо autoit-foxitpdf.au3 у меня в ...
У меня программы ставятся с отдельного DVD (на основе WPI), к тому же я не люблю установку прог через $oem$ - тогда уж лучше юзать sfx-архивы. Возьмем, например мой любимый Far - я никогда не буду его ставить скриптом, а только через sfx. Да и скрипты я стараюсь делать с расчетом на простых юзеров.

SlavaS 19-09-2005 01:21

EgOrus
Спасибо твик помог, все получилось :)

bogomolv 19-09-2005 14:33

Sanja Alone
Цитата:
Chr(68) пробовал?

Обижаешь, начальник!

bogomolv 19-09-2005 14:38

Sanja Alone
Цитата:
к тому же я не люблю установку прог через $oem$

"Какие Ваши доказательства?" (с) Красная жара

Sanja Alone 19-09-2005 18:25

bogomolv
Цитата:
"Какие Ваши доказательства?" (с) Красная жара
Жаль, что ты не можешь передать акцент, с к-рым была произнесена эта фраза :) А "доказательства" мои простые: опять же приведу в кач-ве примера Far. Что мы имеем: более тысячи файлов общим объемом в 16 с лишним мегабайт. Через $oem$ с CD/DVD это дело будет очень долго копироваться, постоянно дергая диск по причине большого к-ва мелких файлов, а из sfx-а ставится за несколько секунд. Хотя, метод $oem$ вполне приемлем для установки программ с малым к-вом файлов, таких, как упомянутый выше FoxitPDFReader. И ес-но, $oem$-метод лишен смысла при установке приложений НЕ с диска с Виндой - мой случай.
Цитата:
В огороде бузина, а в Киеве Sanja Alone?
Я продолжу: За те я тебе полюбив, що на руцi перстень маеш... Эта поговорка употребляется с целью показать человеку, что он говорит о несвязанных между собой вещах, порет чушь. Я же говорил о предпочитаемом мной способе установки, так же, как ты о способе $oem$. Ты бы лучше что-то по сути твоей нелюбви к sfx сказал, а не пытался меня обидеть.

P.S. На будущее: если хочется сказать мне какую-то гадость, то для этого есть e-mail. Иначе можно форум превратить в подобие одной известной fido-конференции, в к-рой от банальных перепалок перешли к межнациональным словесным войнам. Какое-то время это даже было забавно читать, потом стало скучно, а в рез-те эху снесли с бона...

VelDmi 19-09-2005 23:38

bogomolv
Цитата:
Вместо autoit-foxitpdf.au3 у меня в ...\$oem$\$Progs\FoxitReader лежат FoxitReader.exe и foxitpdfreader.reg

Хорошая программа да еще и установки не требует. А как ассоциировать файлы с расширением pdf с этой программой?

EgOrus 20-09-2005 01:58

VelDmi
добавь в свой foxitpdfreader.reg (не забудь поменять пути если у тебя другий):
Код:
; Foxit PDF Reader [HKEY_CLASSES_ROOT\.pdf] @="FoxitReader.Document" "Content Type"="application/pdf" [HKEY_CLASSES_ROOT\FoxitReader.Document] @="PDF Document" "BrowseInPlace"="1" [HKEY_CLASSES_ROOT\FoxitReader.Document\DefaultIcon] @="C:\\PROGRA~1\\PDFREA~1\\FOXITR~1.EXE,1" [HKEY_CLASSES_ROOT\FoxitReader.Document\DocObject] @="0" [HKEY_CLASSES_ROOT\FoxitReader.Document\protocol\StdFileEditing\server] @="C:\\PROGRA~1\\PDFREA~1\\FOXITR~1.EXE" [HKEY_CLASSES_ROOT\FoxitReader.Document\protocol\StdFileEditing\verb\0] @="&Edit" [HKEY_CLASSES_ROOT\FoxitReader.Document\shell\open\command] @="\"C:\\PROGRA~1\\PDFREA~1\\FOXITR~1.EXE\" \"%1\"" [HKEY_CLASSES_ROOT\FoxitReader.Document\shell\print\command] @="C:\\PROGRA~1\\PDFREA~1\\FOXITR~1.EXE /dde" [HKEY_CLASSES_ROOT\FoxitReader.Document\shell\print\ddeexec] @="[print(\"%1\")]" [HKEY_CLASSES_ROOT\FoxitReader.Document\shell\printto\command] @="C:\\PROGRA~1\\PDFREA~1\\FOXITR~1.EXE /dde" [HKEY_CLASSES_ROOT\FoxitReader.Document\shell\printto\ddeexec] @="[printto(\"%1\",\"%2\",\"%3\",\"%4\")]"

или сокращенный вариант
Код:
; Foxit PDF Reader [HKEY_CLASSES_ROOT\.pdf] @="FoxitReader.Document" "Content Type"="application/pdf" [HKEY_CLASSES_ROOT\FoxitReader.Document] @="PDF Document" "BrowseInPlace"="1" [HKEY_CLASSES_ROOT\FoxitReader.Document\DefaultIcon] @="C:\\PROGRA~1\\PDFREA~1\\FOXITR~1.EXE,1" [HKEY_CLASSES_ROOT\FoxitReader.Document\DocObject] @="0" [HKEY_CLASSES_ROOT\FoxitReader.Document\shell\open\command] @="\"C:\\PROGRA~1\\PDFREA~1\\FOXITR~1.EXE\" \"%1\""

bogomolv
Sanja Alone
стоит ли из-за таких пустяков ссориться, у каждого свои любимые методы и вкусы, а о вкусах как известно не спорят

bogomolv 20-09-2005 02:44

Sanja Alone
Цитата:
метод $oem$ вполне приемлем для установки программ с малым к-вом файлов

Золотые слова. Именно поэтому через \$oem$\$Progs у меня устанавливаются только 5 из 30 "автоустанавливаемых" программ. Установка остальных программ идет, как правило, через SFX-архив, содержащий дистрибутив программы, файлы ее настроек и скрипты автоустановки...
О чем спорим?

EgOrus
Считаю полезным также прописывать регистрацию pdf-файла на FineReader:
Код:
;Открыть с помощью FineReader [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\FoxitReader.Document\shell\Open With FineReader] @="Открыть с помощью FineReader" [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\FoxitReader.Document\shell\Open With FineReader\Command] @="\"C:\\Program Files\\ABBYY FineReader 7.0 Professional Edition\\FineReader.exe\" \"%1\"" [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\FoxitReader.Document\shell\Open With FineReader\ddeexec] @="Open(\"%1\")" [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\FoxitReader.Document\shell\Open With FineReader\ddeexec\Application] @="FineReader" [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\FoxitReader.Document\shell\Open With FineReader\ddeexec\Topic] @="System"


EgOrus 20-09-2005 03:00

bogomolv
не... это не мне это для VelDmi, наверное будет полезно :) я пользуюсь сокращенным вариантом и то лишь при создании WinPE
кстати сообщения лучше редактировать, если чего-то забыл дописать, чем плодить неск. подряд :)

bogomolv 20-09-2005 15:20

3 вложений
Автоматизация подготовки диска к установке системы.
Два скрипта NewDisk.au3 и Unattend.au3:
http://forum.oszone.net/attachment.php?attachmentid=997&stc=1
http://forum.oszone.net/attachment.php?attachmentid=998&stc=1
http://forum.oszone.net/attachment.php?attachmentid=999&stc=1
Блин, как сделать, чтобы были рисунки?
С их помощью процесс развертывания системы на новом компьютере (друзья, дети, дети друзей и друзья детей) сводится к загрузке с CD Windows PE и исполнению этих самых скриптов.

Первым скриптом готовится диск: разбиение диска, его форматирование, развертывание WinPE, создание типовых папок, сбрасывание дистрибутива WinXP.
Привязка дистрибутива к машине и пользователю осуществляется вторым скриптом. Им правится unattend.txt: пользователь, настройки экрана, oem-драйвера и т.п. Самое муторное в этой процедуре - правка OemPnPDriversPath. Чтобы максимально облегчить редактирование этого параметра, включил в скрипт дополнительные средства обработки папки $oem$\$1\drivers.
Единственное, что приходится делать ручками (вернее, головой), отбирать для дистрибутива заготовки драйверов (включающие при необходимости скрипты автоустановки и подстройки последних). Как уже писал, для этого имею базу таких заготовок, которую по мере обновления драйверов и знакомства с новым железом периодически пополняю.
После такой подготовки, занимающей в несложном случае полчаса, остается запустить автоустановку WinXP. Проследив результат и подкорректировав исходники, вручаю "клиенту" работающую машину с "ноутбучным" комплектом ПО для автопереустановки системы, о котором рассказывал раньше.

Конечно, установка типовой системы с CD проще и быстрее. Для подобных целей имею собственный "супер-диск" с набором основных драйверов и типовых программ. Но чтобы донастроить установленную таким образом систему требуется квалификация. Вариант с дистрибутивом, полностью привязанным к машине, позволяет самому неподготовленному пользователю самостоятельно поддерживать работоспособность системы самым эффективным способом - периодически вчистую ее переустанавливая.

В продолжение разговора об интересных функциях.
При отладке работы NewDisk.au3 столкнулся с необходимостью считывать результаты командной строки непосредственно в память: WinPE работает с CD, жесткий диск еще не размечен, создавать виртуальный диск, чтобы выполнить DiskPart.exe /S list.txt > 1.txt, не хотелось. Нашел красивую замену в лице CLIPCOPY.EXE (21Kb), считывающей выходные данные командной строки в clipboard. С помощью этой программульки считываю информацию о присутствующих в системе дисках следующим образом:
Код:
RunWait('%Comspec% /C DiskPart.exe /S $iDir$\dpartLIST$i$.txt | CLIPCOPY','',0) $dsk=StringSplit(ClipGet(),@CRLF)


Еще одна находка.
Раньше для развертывания WinPE на жестком диске (использую WinPE, в том числе, и при переустановке системы для автоудаления "замусоренных" системных папок) запускал установку Консоли восстановления, которая нужна была только для получения файловой копии загрузочного сектора BOOTSECT.DAT. Добрые люди подсказали, что в BartPE есть плагин, делающий это проще, быстрее и гибче. Позаимствовал оттуда MKBT.EXE (26Kb) и NT2PELDR.EXE (16Kb). Теперь создание загрузчика WinPE выглядит так:
Код:
RunWait(mailto:'@ScriptDir@mkbt.exe -x -c $ds$ $ds$\Peldr.dat') RunWait(mailto:'@ScriptDir@nt2peldr.exe $ds$\Peldr.dat') IniWrite('$ds$\Boot.ini','operating systems','C:\Peldr.dat','"Microsoft Windows PE" /MiniNT')


Последние находки позволили оптимизировать NewDisk.au3 так, что теперь можно подготовить чужой диск, просто подключив его к своей машине.

Sanja Alone 20-09-2005 18:39

bogomolv
Цитата:
Извини, конечно. Но зря ты так!
Просто у меня обострено чувство справедливости.
Цитата:
Давай-ка займемся самоцензурой и все подправим.
ОК, ты только поговорки подбирай не такие резкие и более уместные :)

VelDmi 20-09-2005 22:40

bogomolvEgOrus
Действительно огромное спасибо!
Не думал, что все так просто. Теперь буду ковырять другие программы в этом направлении, например XnView, который ставится unattend , но не забирает на себя графические форматы файлов. И Light Alloy тоже.

DenchikK 21-09-2005 06:58

Получился скриптик для bootscreen (спасибо огромное за разъяснение Sanja Alone (14 страница)):

Код:
If @OSVersion="WIN_XP" then if @OSServicePack="Service Pack 1" then IniWrite (@HomeDrive & "\boot.ini", "operating systems", "multi(0)disk(0)rdisk(0)partition(1)\WINDOWS", '"Microsoft Windows XP Professional" /noexecute=optin /fastdetect /Kernel=myboots1.exe') FileCopy("myboots1.exe", @WindowsDir & "\system32\") endif endif If @OSVersion="WIN_XP" then if @OSServicePack="Service Pack 2" then IniWrite (@HomeDrive & "\boot.ini", "operating systems", "multi(0)disk(0)rdisk(0)partition(1)\WINDOWS", '"Microsoft Windows XP Professional" /noexecute=optin /fastdetect /Kernel=myboots2.exe') FileCopy("myboots2.exe", @WindowsDir & "\system32\") endif endif exit


Всё вроде бы работает, но хотелось бы сделать ещё и проверку просто XP, без сервис пака. Ни у кого пока не нашёл винды такой, поэтому проверить, что возвращает макрос @OSServicePack на такой винде, не получилось. Может у кого есть такая винда?

Sanja Alone 21-09-2005 17:54

VelDmi
Цитата:
Теперь буду ковырять другие программы в этом направлении
Можно не ковырять, а при помощи RegShot-а сразу получить готовый reg-файл с вносимыми в реестр изменениями при ручной установке ассоциаций файлов в указанных тобой программах. Только используй RegShot в редакции ParaGlider-а

DenchikK
Цитата:
Всё вроде бы работает, но хотелось бы сделать ещё и проверку просто XP, без сервис пака
А что тебе мешает применить условие Else?
Код:
If @OSVersion="WIN_XP" then Select Case @OSServicePack="Service Pack 1" код 1 Case @OSServicePack="Service Pack 2" код 2 Case Else код 3 EndSelect EndIf

Sanja Alone 22-09-2005 20:28

Добавил скрипты:
GordianKnot RipPack 0.35.0
No1 Media Fixer Pro 4.4
No1 Video Converter 3.x.x

P.S. Для ускорения загрузки страницы со скриптами переписал ее на php (сортировка по прежнему на JavaScript). В связи с этим теперь страница crta такая, а au3 - вот.

bogomolv 23-09-2005 21:32

Свежий скрипт

Код:
Opt('ExpandEnvStrings', 1); default = 0 Opt('ExpandVarStrings', 1); default = 0 Opt('RunErrorsFatal', 0); default = 1 Opt('TrayIconDebug', 1); default = 0 $pDir='@ProgramFilesDir@\ABBYY FineReader 8.0 Professional Edition' DirCopy ('@ScriptDir@\Russian',$pDir,1) RunWait ('Regedit /S "@ScriptDir@\FineReader8.reg"') RunWait ('msiexec /i @ScriptDir@\FineReader8.msi /qb') FileCopy ('@ScriptDir@\Russian\FineReader.exe',$pDir,1) FileCopy ('@ScriptDir@\Russian\VerData.prt',$pDir,1) Exit


В папке \Russian лежат разархивированные файлы "русской морды" от FineReader (Russian UI.exe\Data1.cab: Tutorial1.chm, FineReader1.chm, fineui1.dll, screenshotreader1.dll, FRWordZoom1.dll, Shell1.dll, Enginel.dll, Russian.amd, Russian.amm, MorphoRes1.dll, Scan\ScanMan1.dll, Support\Ainfo.dll ) и пара файлов от установленного FineReader.
FineReader8.reg - копия нужных настроек из ветки HKCU\Software\ABBYY.

Проверял на 677 и 706 версиях.

Sanja Alone 24-09-2005 18:09

Добавил скрипты:
Videofixer 3.23
WinDVD 6.0
WinRAR 3.5x

biork 25-09-2005 21:01

У меня такая проблемка: не обрабатывается секция if - в любом случае (есть первое окно или нет) -
скрипт продолжает работу (или останавливается при наличии первого окна) со строчек после "Else"
В каком месте кривые руки? Где ошибка?

Код:
if WinExists ("Заголовок окна", "текст1") then WinWaitActive("Заголовок окна", "текст1") ControlClick ("Заголовок окна", "текст1", "button1") ... ... Else WinWaitActive("Заголовок окна", "текст2") ControlClick ("Заголовок окна", "текст2", "button1") ... ... endif

EgOrus 25-09-2005 23:20

biork
У тебя скрипт ждет пока окно не станет активным WinWaitActive("Заголовок окна", "текст2").
Может лучше использовать конструкции типа:
Код:
IF WinExists ("Заголовок окна", "текст1") then WinActivate("Заголовок окна", "текст1") ControlClick ("Заголовок окна", "текст1", "button1") ... ... ElseIf WinExists ("Заголовок окна", "текст2") then WinActivate("Заголовок окна", "текст2") ControlClick ("Заголовок окна", "текст2", "button1") ... ... EndIf


biork 26-09-2005 07:06

А зачем он ждёт активности второго окна, если появилось и активно первое?
Может я не прав, но по-моему логика скрипта такова, что при наличии первого окна ("Заголовок окна", "текст1")
должны выполняться строки после "then", при отсутствии оного или при появлении другого ("Заголовок окна", "текст2")
должны выполняться строки после "Else".
Если убрать условное выполнение, то каждая ветка скрипта выполняется нормально в своих условиях.

Твой вариант с WinActivate попробовал - не помогает. Причём, в моём варианте при наличии первого окна скрипт
ждёт на строке ожидания второго окошка, а в твоём - заканчивает работу

EgOrus 26-09-2005 10:20

biork
Правильно в примере, кот. предложил я, если ни одно из условий неверно, то продолжаем работу скрипта дальше. В твоем же как ты правильно сказал, если первое условие неправильно, то в любом случае ждем активное окно ("Заголовок окна", "текст2"), если оно по каким-то причинам не появляется, то придется прерывать скрипт вручную.
Приведи полный пример своего скрипта.

biork 27-09-2005 17:01

Вот весь скрипт с изменениями, как ты и рекомендовал в своём примере.
Часть, которая не хочет работать выделена курсивом

Код:
Opt("TrayIconDebug",1) Run("3dmark03_v360_setup.exe") WinWaitActive("3DMark03 - InstallShield Wizard", "Welcome to the InstallShield Wizard") ControlClick("3DMark03 - InstallShield Wizard", "Welcome to the InstallShield Wizard", "Button1") WinWaitActive("3DMark03 - InstallShield Wizard", "License Agreement") ControlClick("3DMark03 - InstallShield Wizard", "License Agreement", "Button5") ControlClick("3DMark03 - InstallShield Wizard", "License Agreement", "Button2") WinWaitActive("3DMark03 - InstallShield Wizard", "Destination Folder") ControlClick("3DMark03 - InstallShield Wizard", "Destination Folder", "Button1") WinWaitActive("3DMark03 - InstallShield Wizard", "Click Install to begin") ControlClick("3DMark03 - InstallShield Wizard", "Click Install to begin", "Button1") ;здесь может появиться окно ввода серийного номера, если программа ставится впервые IF WinExists ("3DMark03 - InstallShield Wizard", "Futuremark Registration") then WinActivate("3DMark03 - InstallShield Wizard", "Futuremark Registration") ControlSetText("3DMark03 - InstallShield Wizard", "Futuremark Registration", "Edit1", "18P2M-MY24M-39UK6-QAX2N") Sleep (1000) ControlClick("3DMark03 - InstallShield Wizard", "Futuremark Registration", "Button2") WinWaitActive("Congratulations!", "") ControlClick("Congratulations!", "", "Button1") WinWaitActive("3DMark03 - InstallShield Wizard", "InstallShield Wizard Complete") ControlCommand("3DMark03 - InstallShield Wizard", "InstallShield Wizard Complete", "Button1", "UnCheck", "") ControlCommand("3DMark03 - InstallShield Wizard", "InstallShield Wizard Complete", "Button2", "UnCheck", "") ControlClick("3DMark03 - InstallShield Wizard", "InstallShield Wizard Complete", "Button4") ElseIf WinExists ("3DMark03 - InstallShield Wizard", "InstallShield Wizard Complete") then WinActivate("3DMark03 - InstallShield Wizard", "InstallShield Wizard Complete") ControlCommand("3DMark03 - InstallShield Wizard", "InstallShield Wizard Complete", "Button1", "UnCheck", "") ControlCommand("3DMark03 - InstallShield Wizard", "InstallShield Wizard Complete", "Button2", "UnCheck", "") ControlClick("3DMark03 - InstallShield Wizard", "InstallShield Wizard Complete", "Button4") EndIf Exit


Насчёт логики. Дело то в том, что он почему то это первое окно не видит, хотя оно есть, ждёт и свиду вполне активно :). По мне, так условие выполнено, а вот с точки зрения AutoIt - почему то - нет :(
И что толку от продолжения работы скрипта, если дальнейшие действия связаны с кликаньями по окнам которые не появятся, пока не уйдёт текущее?

Я понимаю, что проблема выеденного яйца не стоит - можно сделать тихую инсталяшку или ввести серийный номер перед запуском установки с помощью рег-файла и исключить появление этого окна - дело в другом - хочу выяснить можно ли вообще бороться таким образом с "иногда появляющимися" окнами. У меня уже не первый случай когда нужно использовать функцию условного выполнения и всегда с этим проблемы. Что-то я тут не вкуриваю...

EgOrus 28-09-2005 01:59

biork
Чтобы понять почему не работает пришлось поставить 3DMark2001, ставится он почти также как 2003, так вот дело в том что, твое условие If WinExists проверяется на стадии копирования файлов и декомпрессии текстур, естественно такого окна нет, и переходим к следующему условию ElseIf WinExists такого окна тоже нет и завершаем скрипт.
Нужно добавить перед проверкой условий, ожидание завершения процесса копирования, чтобы в момент проверки условий либо то либо то окно успело появиться, сделать можно по разному например вот так:
Код:
ControlClick("InstallShield Wizard", "Start Copying Files", "Button1") ;здесь может появиться окно ввода серийного номера, если программа ставится впервые WinWait("Texture Conversion", "Setup Status") WinWaitClose("Texture Conversion", "Setup Status" , 180) sleep (1000) IF WinExists ("InstallShield Wizard", "MadOnion.com Registration") then WinActivate("InstallShield Wizard", "MadOnion.com Registration")

skylego 28-09-2005 09:01

Вот скрипт для Windows XP Manader

;Видим скрытый текст
Opt("WinTitleMatchMode",2)
Opt("WinDetectHiddenText",1)
;Уберем все с окна
WinMinimizeAll()
Sleep(1000)

$SF_1 = @ScriptDir & "\xpmanager.exe"

$SF_2 = StringLeft(@ProgramFilesDir,2) & '\PROGRA~1\YANICS~1\WinXPM~1\WinXPM~1.exe'

Run(@ComSpec & " /c " & "start " & $SF_1 , "", @SW_HIDE)

$Title_1 = "WinXP Manager Setup"
$Title_2 = "WinXP Manager"

WinWaitActive($Title_1)
sleep(1000)
SEND("{ENTER}")

WinWaitActive($Title_2,'The installer will guide you through the steps required to install WinXP Manager on your computer.')
sleep(1000)
SEND("{ENTER}")

WinWaitActive($Title_2,'Select Installation Folder')
sleep(1000)
controlclick('','','Button5')
SEND("{ENTER}")

WinWaitActive($Title_2,'Confirm Installation')
sleep(1000)
SEND("{ENTER}")

WinWaitActive($Title_2,'Installation Complete')
sleep(1000)
SEND("{ENTER}")


Run( @ComSpec & " /c " & "start " & $SF_2 , "", @SW_HIDE)
sleep(1000)

WinActivate("WinXP Manager V4.92.3")

;WinWaitActive('WinXP Manager V4.92.3','UnRegistered...')
WinWaitActive('WinXP Manager V4.92.3','Try It')
sleep(1000)
controlclick('WinXP Manager V4.92.3','','WindowsForms10.BUTTON.app31')

WinWaitActive('Purchase and Register WinXP Manager V4.92.3')
sleep(1000)
ControlSetText( "" , "", 'WindowsForms10.EDIT.app35','XXXX')
ControlSetText( "" , "", 'WindowsForms10.EDIT.app34','XXXX')
ControlSetText( "" , "", 'WindowsForms10.EDIT.app33','XXXX')
ControlSetText( "" , "", 'WindowsForms10.EDIT.app32','XXXX')
ControlSetText( "" , "", 'WindowsForms10.EDIT.app31','XXXX')
controlclick('','','WindowsForms10.BUTTON.app32')

WinWaitActive('Finis','Please restart this software')
sleep(1000)
SEND("{ENTER}")

EXIT

biork 28-09-2005 17:18

EgOrus
Ну ты монстр! :)
Всё заработало как часики. Оживил несколько заброшенных по подобной причине скриптов. Большущее тебе спасибо!
Вопрос на засыпку: зачем таймаут 3 минуты? А вдруг, диск плохо читается или комп 386-ой... я бы убрал этот параметр - пусть ждёт сколько ему надо.



EgOrus 29-09-2005 01:26

biork
по поводу 3х минут, вопрос спорный, теоретически это на тот как раз случай если диск нечитается вообще, на разных приводах может быть по разному, где-то начинает читать до посинения бывает и по 10-20 минут и все равно потом сбоит, бывает ошибку выдает, в любом случае скрипт встанет (скорей всего появится окно инстоляра об ошибке установки) и нужно будет вмешиваться. А так он на автомате через 3 минуты пойдет дальше. Вместо 3х можно побольше конечно поставить.

Sanja Alone 29-09-2005 20:47

Добавил скрипты:
Ad-Aware SE Personal 1.06r1
ListTV 3.8.6.1
MuxaSoft Dialer 4.1
O&O Defrag v8.0
RivaTuner v2.0 RC 15.x

Eralex 30-09-2005 14:48

Кто-нибудь помогите заавтоитить Outpost 3.0
Раньше (v. 2.0-2.7) скрипт прекрасно отрабатывался в том месте,
где идёт сбор об установленных программах и создаются для них правило.
Скрипт корректно дожидался, пока кнопка "Далее" не станет доступной
для нажатия. Вот это место

Код:
WinWaitActive("Мастер конфигурации") $e = ControlCommand("Мастер конфигурации", "Мастер конфигурации производит настройку Outpost Firewall Pro", "Button4", "IsEnabled", "") While $e=0 $e= ControlCommand("Мастер конфигурации", "Мастер конфигурации производит настройку Outpost Firewall Pro", "Button4", "IsEnabled", "") WEnd Send("{ENTER}")


Но почему-то в версии 3.0 этот трюк не срабатывает. Сразу появляется окошко о конце установки,
т.е. получается, что недоступная копка каким-то образом нажалась.

Sanja Alone 30-09-2005 18:17

Eralex
3.0 попробовать не довелось, но в 2.7 нормально работает такая конструкция:
Код:
... WinWaitActive ( 'Мастер конфигурации' ) While ControlCommand ( 'Мастер конфигурации', '', 'Button6', 'IsEnabled', '')=0 Sleep ( 1000 ) WEnd ;Далее ControlClick( 'Мастер конфигурации', '', 'Button6' ) ...

Eralex 01-10-2005 14:42

Цитата:
3.0 попробовать не довелось, но в 2.7 нормально работает такая конструкция:

Код:

Код:
... WinWaitActive ( 'Мастер конфигурации' ) While ControlCommand ( 'Мастер конфигурации', '', 'Button6', 'IsEnabled', '')=0 Sleep ( 1000 ) WEnd ;Далее ControlClick( 'Мастер конфигурации', '', 'Button6' ) ...


Не помогло!!!


biork 06-10-2005 18:03

Вот маленький скриптик. Работает.
Код:
Opt("TrayIconDebug",1) if FileExists("C:\Windows\System32\drivers\ati2mtag.sys") Then RunWait("Cpanel\Setup.exe /S") Else EndIf Exit


а так - нет. Почему?
Код:
Opt("TrayIconDebug",1) if FileExists("@SystemDir\drivers\ati2mtag.sys") Then RunWait("Setup.exe /S", "@ScriptDir\Cpanel") Else EndIf Exit

bogomolv 07-10-2005 00:25

biork
Патаму чта синтаксис :)
Код:
Opt('ExpandEnvStrings', 1); default = 0 Opt('ExpandVarStrings', 1); default = 0 if FileExists("@SystemDir@\drivers\ati2mtag.sys") Then RunWait("Setup.exe /S", "@ScriptDir@\Cpanel") Else EndIf Exit

И будь осторожен с RunWait ( "filename" [, "workingdir" [, flag]] ).
Чтобы задать рабочий каталог, лучше использовать FileChangeDir ( "path" )
Код:
FileChangeDir("@ScriptDir@\Cpanel") RunWait("Setup.exe /S")


All
Новый DrWeb433.
Установщик остался прежним. И также по-прежнему блокирует silent-установку. :(
Зато установщик разукрасили всеми цветами радуги. В результате, он перестал "понимать" ControlClick(...), ControlCommand(...,'Check') и т.д.!
Теперь приходится накручивать ControlSend('Внимание!!!',,'Button4','{+}{Enter}').

DenchikK 07-10-2005 12:59

А у меня во в новом инсталяторе DrWeb 2 раза заедало:
1. В месте "Выберите вид установки" (причём иногда только).
2. В месте "Настройки прокси сервера" - при их отсутствии. Нажатие на кнопку отмены мышкой, приводит к продолжени. установки DrWeb, нажатие на неё AutoIT'ом приводит к завершению инсталяции.
И там и там вывернулся использованием эмуляции нажатия мышки.

Ещё в догонку такая придумка. В установке Dr.Divx, вернее при работе keygen, надо вызывать из каталога с установленной программы регистрационный файл. А вдруг у пользователя прога стоит не на диске C и даже не в Program Files? Как это узнать? И вот что я придумал (главное - работает!).
Вкратце так: берём из реестра информацию об установленной программе, и вот мы уже имеем всегда правильный путь. В Dr.Divx чуть сложнее - пути как такого нет, есть путь вместе с .exe файлом. Этот самый .exe файл то мы и отрезаем (функция отрезать строку с конца).
Так что можно сделать инсталяторы чуточку более универсальными.

biork 07-10-2005 21:21

bogomolv
Мдя... Не очевидно (в справке, в описаниях макро об этом - ни слова...), но факт!
А зачем символ @ в конце каждого макро? Опять "синтаксис патаму чта"?
И почему осторожней с RunWait? Может надёжнее сам скрипт в нужную папку засунуть и вообще не указывать рабочий каталог?

VelDmi 13-10-2005 23:51

Есть прекрасные макро @ComputerName и @IPAddress1 чтобы узнать имя компьютера и его адрес.
А как можно изменить их? Мне нужно задать их не ползая по вкладкам свойств.

Sanja Alone 24-10-2005 21:09

bogomolv
Цитата:
Новый DrWeb433
Не качал - не скажу.
Цитата:
Установщик остался прежним. И также по-прежнему блокирует silent-установку
Как это блокирует? Вот у меня на автоустановочном диске лежит файлик drweb-432b-win-ru.exe. Ставится этим скриптом без всяких блокировок... Ес-но, для silent-установки нужно предварительно получить еще и файлик setup.iss (см. в том же архиве) установив один раз прогу командой drweb-432b-win-ru.exe -R.

VelDmi
Цитата:
Мне нужно задать их не ползая по вкладкам свойств.
Тогда придется поползать по реестру :)

CTEPBA 25-10-2005 15:43

Люди подскажите как мне с помощью AuotIt поставить Dr.Web 4.33 ( не ставиться командой setup.exe /s) только если по шагово.

EgOrus 25-10-2005 16:45

2Sanja Alone
Скачал у тебя скрипт на установку FoxitReader, к сожалению к новой версии он не подошел, посмотрев скрипт не понял зачем нужны условия на проверку Активности каждого окна? Практически во всех скриптовых языках условия несколько тормозят выполнение кода, легче сразу активировать окно без проверки его активности.
Цитата:
WinWait($Title,"Вас приветствует Мас")
If Not WinActive($Title,"Вас приветствует Мас") Then WinActivate($Title,"Вас приветствует Мас")
WinWaitActive($Title,"Вас приветствует Мас")
Send("{ENTER}")

Код:
;Установщик FoxitReader v1.3.909.exe #cs ---------------------- $Title - заголовок окна установки $file - установочный файл $programgroup - в какую программную группу положить ярлыки программы $rusfile - русифицированный исполнимы файл программы ---------------------- #ce Global $Title='Foxit Reader Install Wizard', $file='foxitreader.1_3_909.exe', $rusfile='rus\Foxit Reader.exe';, $programgroup='Офис\Foxit PDF Reader' Run($file) WinWait($Title,"Setup will install") WinActivate($Title,"Setup will install") Send("{ENTER}") WinWait($Title,"Please read the license") WinActivate($Title,"Please read the license") Send("{ENTER}") WinWait($Title,"Please select an installation type") WinActivate($Title,"Please select an installation type") ControlClick ($Title, '', 'Button2' ) WinWait($Title,"Please Choose the folder") WinActivate($Title,"Please Choose the folder") ControlSetText($Title, "", 'Edit1', @ProgramFilesDir & '\Foxit Reader\' ) Send("{ENTER}") WinWait($Title,"Desktop Settings") WinActivate($Title,"Desktop Settings") ControlClick ($Title, '', 'Button3') ControlClick ($Title, '', 'Button7') Send("{ENTER}") WinWait($Title,"Click Install to continue") WinActivate($Title,"Click Install to continue") Send("{ENTER}") WinWait($Title,"Setup has successfully") WinActivate($Title,"Setup has successfully") ControlClick ($Title, '', 'Button2') Send("{ENTER}") ;если есть FoxitRus, то заменяем им оригинальный англ. исполнительный файл If FileExists ( $rusfile ) Then FileCopy ( @ScriptDir & '\' & $rusfile, @ProgramFilesDir & '\Foxit Reader\', 1 ) EndIf

biork 25-10-2005 17:56

Всем привет. Вопрос на засыпку. Нужон такой скрипт:

- проверяем является ли диск D: разделом жёсткого диска (существует ли вообще и не является ли сменным или сетевым)
- если да, то копируем на него файл
- если нет, то - нет.

Есть идеи?

Sanja Alone 25-10-2005 18:20

Добавил скрипты:
ICE ECC 2.1
Sateira CD&DVD Burner 2.xx
WinImage 8.0 (и 7.0)


EgOrus
Цитата:
зачем нужны условия на проверку Активности каждого окна
1. Я мог бы придумать умный ответ, но скажу прямо - эти условия являются результатом использования ScriptWriter-а, входящего в состав редактора SciTE. Но ты конечно прав, условия спокойно можно убрать (оставив в соотв. стороках только функцию WinActivate).
2. Ты используешь странное сочетание функций при ожидании окон:
Код:
WinWait("Окно","Текст") WinWaitActive("Окно","Текст")
Функция WinWait здесь лишняя, т.к. для нажатия ENTER-а функцией Send окно должно быть активным. Я же всегда юзаю вот такую связку:
Код:
WinWait("Окно","Текст") WinActivate("Окно","Текст") WinWaitActive("Окно","Текст")
(здесь можно опустить WinWaitActive, т.к. активация проходит очень быстро и эта функция является всего лишь дополнительным гарантом). А можно вообще использовать одну функцию WinWaitActive("Окно","Текст"), если есть уверенность, что окно при любом раскладе будет активировано.


CTEPBA
Скрипт для DrWeb 4.32b - попробуй, может и для 4.33 подойдет.


biork
Цитата:
Есть идеи?
Всего одна строка:
Код:
If DriveGetType ('d:\')='Fixed' Then FileCopy ( 'Откуда\файл', 'd:\' )

Sanja Alone 25-10-2005 19:35

Меня по мылу уже неоднократно спаршивали как предотвратить множественный запуск одного и того же скрипта. Ответ вроде бы где-то на форуме встречался, но приведу его здесь еще раз. Все очень просто - в начало скрипта нужно добавить такую конструкцию:
Код:
If WinExists(@ScriptName) Then Exit AutoItWinSetTitle(@ScriptName)

EgOrus 26-10-2005 00:39

Sanja Alone
да, ты прав WinWaitActive("Окно","Текст" там абсолютно не нужен, видимо сказалось позднее время и нежелание писать что-то свое, когда есть готовое, отсюда и невнимательность, конечно же везде должно быть просто WinActivate.

По поводу скрипта для Sateira CDDVD Burner, можно нескромный вопрос? :) а почему скрипт сделан через работу с окнами, а не ключами установки?
/SILENT
/DIR="path"
/GROUP="folder name"
/TASKS="desktop,quicklaunch" (или /NOICONS)


Sanja Alone 26-10-2005 01:29

EgOrus
Цитата:
а почему скрипт сделан через работу с окнами, а не ключами установки?
Я уже ранее писал о своем отношении к Inno Setup - он не всегда корректно отрабатывает эти самые ключи... А так все ОК.

EgOrus 26-10-2005 02:32

Sanja Alone
Цитата:
он не всегда корректно отрабатывает эти самые ключи...

Это из личного опыта? в каких условиях не отрабатывает?
Странно, очень давно пользуюсь этой программой, сам постоянно делаю свои инстоляторы, ниразу не было чтобы что-то некоректно установилось. Единственный случай когда такое возможно, это если в скрипте жестко заданы пременные, и то отрабатывается все нормально просто поменять нельзя.
АвтоИт же наоборот только расширяет возможности InnoSetup, добавляя возможность использования переменных окружения при указании путей установки (при установке из комстроки требуется указание полновесных путей).

Спасибо за скрипт Gknot, я с тоской думал о том моменте когда придется его автоматизировать, жутко не люблю выписывать заголовки с окон, особенно когда их много

bogomolv 26-10-2005 07:22

Sanja Alone

Цитата:
Как это блокирует? Вот у меня на автоустановочном диске лежит файлик drweb-432b-win-ru.exe. Ставится этим скриптом без всяких блокировок... Ес-но, для silent-установки нужно предварительно получить еще и файлик setup.iss (см. в том же архиве) установив один раз прогу командой drweb-432b-win-ru.exe -R.


Обнаружив, что DrWeb в 432 версии лишился старых ключей автоустановки (кажется, это делалось через ini-файл), в первую очередь опробовал именно комбинацию setup.exe -R + setup.exe -s -f1"путь\setup.iss". Файл setup.iss создавался нормально. Но обрабатываться он у меня никак не хотел (и не хочет!). В форуме на drweb.ru нашел подтверждение своим смутным подозрениям - кто-то из приближенных к разработчикам авторитетно утверждал, что такая возможность заблокирована, и автоматическая установка поддерживается только в Enterprise Suite.
Если это не так, то это здорово!
Но у меня установка не проходит ни с моими, ни с твоими файлами. Чтобы проверить твой скрипт, разыскал drweb-432b-win-ru.exe. Результат тот же. Только в моем случае в setup.log значится ResultCode=-3, в твоем - ResultCode=-5.
Кстати, а почему в твоем скрипте в строке запуска drweb-432b-win-ru.exe нет ключа -f1"путь\setup.iss"? Что, если не указывать на setup.iss явно, он должен "подхватится" автоматом?

Давай разбираться!

CTEPBA 26-10-2005 13:46

Я сделал такой скрипт для Dr.Web 4,33 который работает по действиям, но у меня были проблемы с появление блокнота в конце, вроде я их решил, но еще проверял.
Код:
Run("setup.exe") WinWaitActive("Dr.Web - InstallShield Wizard") Send("{ENTER}") WinWaitActive("Установка Dr.Web", "Программа InstallShield® Wizard установит Dr.Web (4.33.0.09290) на компьютер") Send("{ENTER}") WinWaitActive("Внимание!!!") Send("{Space}") Send("{ENTER}") WinWaitActive("Установка Dr.Web", "ЛИЦЕНЗИОННЫЙ ДОГОВОР ОБ ИСПОЛЬЗОВАНИИ") Send("{UP}") Send("{ENTER}") WinWaitActive("Установка Dr.Web", "Программа установки установит Dr.Web в следующую папку") Send("{ENTER}") WinWaitActive("Установка Dr.Web", "Выберите вид установки") Send("{ENTER}") WinWaitActive("Установка Dr.Web", "Программа установки добавит значки программ в папку, указанную ниже") Send("{ENTER}") WinWaitActive("Установка Dr.Web", "Программа установки располагает всеми данными для начала копирования программных файлов") Send("{ENTER}") WinWaitActive("Установка Dr.Web", "Если Вы не используете прокси сервер, нажмите") Send("{Tab}") Send("{Tab}") Send("{Tab}") Send("{ENTER}") WinWaitActive("Вопрос") Send("{Tab}") Send("{ENTER}") WinWaitActive("Установка Dr.Web", "Сейчас будет проведена экспресс-проверка Вашей системы") Send("{ENTER}") WinWaitActive("Вопрос") Send("{Tab}") Send("{ENTER}") WinWaitActive("Установка Dr.Web", "Да, перезагрузить компьютер сейчас") Send("{DOWN}") Send("{ENTER}") ProcessWait("notepad") ProcessClose("notepad")

Sanja Alone 26-10-2005 18:18

Я написал скрипт для Dr.Web 4.33 через клацанье по окнам, добавил в zip-ку к скрипту для 4.32b. Пока можно юзать и такой вариант.


EgOrus
Цитата:
Это из личного опыта? в каких условиях не отрабатывает?
Да, больше всего трабл вызывают /SAVEINF и /LOADINF - проще сразу написать скрипт, чем думать почему настройки не сохранились или не загрузились.

Цитата:
жутко не люблю выписывать заголовки с окон, особенно когда их много
А вот тут упомянутый мной выше ScriptWriter будет весьма кстати.


bogomolv
Цитата:
автоматическая установка поддерживается только в Enterprise Suite
Вот Пик... пик... пик... редиски. И чего они хотят этим способом добиться? Бабок? - ничего не выйдет, народ у нас закаленный :)

Цитата:
разыскал drweb-432b-win-ru.exe. Результат тот же. Только в моем случае в setup.log значится ResultCode=-3, в твоем - ResultCode=-5
А у меня как раз для версии 4.33 в логе значится ResultCode=-5, а 4.32b ставится как миленькая.

Цитата:
Что, если не указывать на setup.iss явно, он должен "подхватится" автоматом?
Угу, конечно, если он будет лежать в том же каталоге, где и установщик.

Цитата:
Давай разбираться!
Я обнаружил, что при запуске файла drweb-433-win-ru.exe в память загружается 2 процесса - один "правильный" (с указанными мной ключами -s -f2c:\drweb.log), а второй с теми же ключами, но перед ними стоит еще ключ -deleter. Вот если бы убить этот паразитный процесс не затронув полезного, то, возможно, проблема и решилась бы... Но вот как это сделать?

EgOrus 27-10-2005 00:53

Sanja Alone
/SAVEINF и /LOADINF очень ограничены по использованию переменных окружения, все строчки из него дублируются обычными ключами.
Слегка видоизменил скрипт на Gknot, отменил установку AviSynth если есть более новый в этой же папке, добавил копирование плагинов к нему (к слову сказать - плаги ависинта работают на порядок быстрее VirtualDub'овских). В версии 2.56 появилась русская справка. Людям с толстыми каналами будет проще скачать новую версию GknotRipPack'a чем качать отдельно новый ависинт, тогда из скрипта нужно будет вырезать лишнее и переместить скрипт на установку ависинта.
Код:
If WinExists(@ScriptName) Then MsgBox(0, "Warning!", "Закрой предыдущую копию скрипта") Exit EndIf AutoItWinSetTitle(@ScriptName) Opt('TrayIconDebug',1) Opt('SendKeyDownDelay', 50) ToolTip("Installing in progress. Please wait.", 1, 1) #cs ---------------------- объявление переменных ---------------------- $file - имя инсталляционного файла $avsfile - новая версия AviSynth $AviSynthFolder - в какой подкаталог GKnot-а установить AviSynth $VobSubFolder - в какой подкаталог GKnot-а установить VobSub $vdubmodplug - rarsfx-архив с плагинами к VirtualDubMod команды SFX-сценария (положите каталог PLUGINS целиком внутрь архива, в противном сл. задайте Path=GordianKnot\VirtualDubMod\Plugins): Path=GordianKnot\VirtualDubMod SavePath Silent=1 Overwrite=1 ---------------------- #ce Global $file='GordianKnot.RipPack.0.35.0.Setup.exe', $avsfile='AviSynth\AviSynth_256_040905.exe', $AviSynthFolder='\AviSynth', $VobSubFolder='\Vobsub', $vdubmodplug='vdubmod_plugins.exe' Run ( $file ) WinWaitActive ( 'Gordian Knot', 'License Agreement' ) Send ( '{ENTER}' ) WinWaitActive ( 'Gordian Knot', 'Choose Components' ) Send ( '{ENTER}' ) WinWaitActive ( 'Gordian Knot', 'Choose Install Location' ) $InstPath = ControlGetText ( 'Gordian Knot', 'Choose Install Location', 'Edit1') Send ( '{ENTER}' ) WinWaitActive ( 'Installer Language' ) Send ( '{ENTER}' ) AutoItSetOption("WinTitleMatchMode", 2) WinWaitActive ( 'VobSub', 'Welcome to the VobSub Setup Wizard' ) Send ( '{ENTER}' ) WinWaitActive ( 'Installation Options' ) Send ( '{ENTER}' ) WinWaitActive ( 'Installation Folder' ) ControlSetText( 'Installation Folder', '', 'Edit1', $InstPath & $VobSubFolder ) Send ( '{ENTER}' ) WinWaitActive ( 'Completed' ) Send ( '{ENTER}' ) AutoItSetOption("WinTitleMatchMode", 1) If FileExists ( @ScriptDir & '\' & $avsfile ) Then ; Отказ от установки AviSynth 2.5.5 WinWaitActive ( 'AviSynth', 'License Agreement' ) ControlClick( 'AviSynth', 'License Agreement', 'Button3') Send ( '{ENTER}' ) Else ; Установка AviSynth из пакета Gknot WinWaitActive ( 'AviSynth', 'License Agreement' ) Send ( '{ENTER}' ) WinWaitActive ( 'AviSynth', 'Choose Components' ) Send ( '{ENTER}' ) WinWaitActive ( 'AviSynth', 'Choose Install Location' ) ControlSetText( 'AviSynth', 'Choose Install Location', 'Edit1', $InstPath & $AviSynthFolder ) Send ( '{ENTER}' ) WinWaitActive ( 'AviSynth', 'Completing the AviSynth Setup Wizard' ) Send ( '{ENTER}' ) EndIf WinWait ( 'Gordian Knot', 'Installation Complete' ) WinClose ( 'Gordian Knot', 'Installation Complete' ) WinWaitClose ( 'Gordian Knot', 'Installation Complete' ) If FileExists ( @ScriptDir & '\' & $avsfile ) Then ; Установка новой версии AviSynth Run ( $avsfile ) WinWaitActive ( 'AviSynth', 'License Agreement' ) Send ( '{ENTER}' ) WinWaitActive ( 'AviSynth', 'Choose Components' ) ; Отметка русской справки Send ('{TAB}{DOWN}{RIGHT}r{SPACE}') ControlClick( 'AviSynth', '', 'Button2') WinWaitActive ( 'AviSynth', 'Choose Install Location' ) ControlSetText( 'AviSynth', 'Choose Install Location', 'Edit1', $InstPath & $AviSynthFolder ) Send ( '{ENTER}' ) WinWaitActive ( 'AviSynth', 'Completing the AviSynth Setup Wizard' ) Send ( '{ENTER}' ) EndIf ;запуск программы для внесения в реестр базовых настроек Run ( $InstPath & '\GordianKnot.exe' ) WinWait ( 'Choose Language' ) WinActivate ( 'Choose Language' ) Send ( '{ENTER}' ) AutoItSetOption("WinTitleMatchMode", 2) WinWait ( '(gordianknot.sourceforge.net)' ) WinClose ( '(gordianknot.sourceforge.net)' ) WinWaitClose ( '(gordianknot.sourceforge.net)' ) Sleep ( 50 ) ;путь к DVDDecrypter почему-то не вносится в реестр в отличие от других (глюк наблюдается в версии GKnot 0.35.0) RegWrite('HKEY_CURRENT_USER\Software\GordianKnot',"DvdDecrypterExe","REG_SZ",FileGetShortName($InstPath)&'\DVDDecrypter\dvddecrypter.exe') ;н-рые настройки RegWrite('HKEY_CURRENT_USER\Software\GordianKnot',"DvdDecrypterNotUsed","REG_DWORD","00000000") RegWrite('HKEY_CURRENT_USER\Software\GordianKnot',"ActivePage","REG_DWORD","00000000") RegWrite('HKEY_CURRENT_USER\Software\GordianKnot',"Language","REG_SZ",'Russian') RegWrite('HKEY_CURRENT_USER\Software\GordianKnot\Slot0',"Bitrate","REG_DWORD","00000421") RegWrite('HKEY_CURRENT_USER\Software\GordianKnot\Slot0',"DivXMode","REG_DWORD","00000005") RegWrite('HKEY_CURRENT_USER\Software\GordianKnot\Slot0',"CalculateAVIOverhead","REG_DWORD","00000001") Sleep ( 50 ) ;Распаковка дополнительных плагинов к VirtualDubMod If FileExists ( @ScriptDir & '\' & $vdubmodplug ) Then RunWait ( @ScriptDir & '\' & $vdubmodplug ) ;Копирование дополнительных плагинов AviSynth DirCopy ( @ScriptDir & '\AviSynth\plugins', $InstPath & '\AviSynthPlugins', 1 ) ;перенос ярлыков ;DirCopy ( @ProgramsCommonDir & '\Gordian Knot', @ProgramsCommonDir & '\CD и DVD утилиты\Gordian Knot', 1 ) DirCopy ( @ProgramsCommonDir & '\AviSynth 2.5', @ProgramsCommonDir & '\Gordian Knot\AviSynth', 1 ) DirCopy ( @ProgramsDir & '\AviSynth 2.5', @ProgramsCommonDir & '\Gordian Knot\AviSynth', 1 ) DirCopy ( @ProgramsDir & '\VobSub', @ProgramsCommonDir & '\Gordian Knot\VobSub', 1 ) ;DirRemove ( @ProgramsCommonDir & '\Gordian Knot', 1 ) DirRemove ( @ProgramsCommonDir & '\AviSynth 2.5', 1 ) DirRemove ( @ProgramsDir & '\AviSynth 2.5', 1 ) DirRemove ( @ProgramsDir & '\VobSub', 1 )

bogomolv 27-10-2005 12:21

Sanja Alone
Цитата:
Вот если бы убить этот паразитный процесс не затронув полезного, то, возможно, проблема и решилась бы... Но вот как это сделать?

С помощью ProcessWait(), ProcessList(), ProcessClose(). Но не помогает!

Sanja Alone 27-10-2005 21:55

EgOrus
1. Ошибка
Код:
... If FileExists ( @ScriptDir & '\' & $avsfile ) Then ; Отказ от установки AviSynth 2.5.5 WinWaitActive ( 'AviSynth', 'License Agreement' ) ControlClick( 'AviSynth', 'License Agreement', 'Button3') Send ( '{ENTER}' ) ElseIf ...
Здесь должно быть просто Else. Советую юзать редактор SciTe ( Ctrl+F5 - проверка синтаксиса ) - помогает при отлове подобных опечаток.

2. А зачем Opt('SendKeyDownDelay', 50) если в моем скрипте и так все работало?


bogomolv
Цитата:
С помощью ProcessWait(), ProcessList(), ProcessClose(). Но не помогает!
Я уже успел попробовать. Тестовый код:
Код:
Global $file='drweb-433-win-ru.exe' Run ( $file & ' -s -f2' & EnvGet("SYSTEMDRIVE") & '\drweb.log' ) Sleep ( 200 ) $list = ProcessList($file) If $list[1][1] > $list[2][1] Then ProcessClose ( $list[1][1] ) msgbox(64, 'Процесс с PID = '&$list[1][1]&' был закрыт', 'Процессы drweb в памяти:'&@LF&@LF&$list[1][0] &' '& $list[1][1] &@LF& $list[2][0] &' '& $list[2][1],8) Else ProcessClose ( $list[2][1] ) msgbox(64, 'Процесс с PID = '&$list[2][1]&' был закрыт', 'Процессы drweb в памяти:'&@LF&@LF&$list[1][0] &' '& $list[1][1] &@LF& $list[2][0] &' '& $list[2][1],8) EndIf
Причем независимо от того, какой процесс убивается - с большим или меньшим PID (это определяется знаком "<" или ">" в If-е) в памяти все равно остается тот, у к-рого есть паскудный ключ -deleter. Вот такая кака :(

EgOrus 27-10-2005 23:30

Sanja Alone
да, все правильно, благодарю, такие вот гадкие ошибки потом всплывают в самый неподходящий момент.
Opt('SendKeyDownDelay', 50) пришло в скрипт вместе с шапкой, это у меня в каждом скрипте, особой пользы не несет, также как и вреда.

Petya V4sechkin 28-10-2005 02:18

Вчера почти весь день убил на активацию AutoCAD 2005. Пришлось извратиться пару раз :)
Никому не надо? Если надо, скажите.

skylego 28-10-2005 03:17

Цитата:
Вчера почти весь день убил на активацию AutoCAD 2005. Пришлось извратиться пару раз :)
Никому не надо? Если надо, скажите.


Если можно, то надо.
Отправь мне на skylego@mail.ru

garbals 28-10-2005 12:38

как написать скрипт для
Цитата:
  1. включения гостя в XP
  2. разрешить доступ к комьпьютеру из сети гостям
  3. отклонить локальный вход гостю
  4. авто логон имеющегося пользователя (не известно какого)

помогите с написанием скрипта :)

EgOrus 28-10-2005 13:23

garbals
это все делается батником
Код:
1. net user Гость /active:yes 2 и 3 secedit /configure /cfg %SystemRoot%\Security\Templates\netaccess.inf /db %SystemRoot%\Security\Database\netaccess.db /overwrite /log %SystemRoot%\Security\logs\netaccess.log /quiet 4. set UserN=%UserName% set Password= set regpath="HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" :: Setting User %UserN% to Autologon. REG ADD %regpath% /v DefaultUserName /t REG_SZ /d %UserN% /f REG ADD %regpath% /v DefaultPassword /t REG_SZ /d %Password% /f REG ADD %regpath% /v AutoAdminLogon /t REG_SZ /d 1 /f
данный тэмплэйт политик безопасности netaccess.inf, можно подправить (напрмер если нужен пользователь не Гость а какой нибудь другой/ие)

garbals 28-10-2005 18:20

запустил батник не работает всё в политике на своих местах

EgOrus 29-10-2005 00:40

garbals
подробности отправил в ПМ, оффтоп получается

Sanja Alone 31-10-2005 17:36

Я получил на мейл такой вопрос:
Цитата:
Возможно ли в AutoIt v3 сделать цикл, который бы проверял открыт или
закрыт CD-ROM - если открыт, то его закрыть и наоборот.

Тут есть одна загвоздка - функция DriveStatus("Z:\")="NOTREADY" в двух случаях:
1. лоток выдвинут
2. лоток задвинут, но без диска.

Я вижу преодоление данной неоднозначности только с пом. начальных условий и дополнительной переменной и предложил такой вариант:
Код:
;задаем букву диска при пом. переменной для удобства написания кода Global $d="Z:" ;начальные условия: ;нужно предварительно закрыть лоток, чтобы убрать неопределенность CDTray($d, "closed") ;переменная, определяющая положение лотка (1 - выдвинут, 0 - задвинут) Global $t=0 ;цикл для демонстрации работы (любой код) For $i=1 To 4 ;вызов функции открытия/закрытия лотка независимо от наличия/отсутствия ;в нем диска (если открыт - закроется, и наоборот) mycd($t, $d) Next ;определяем возможность модификации функцией переменной $t (с пом. ключевого ;слова ByRef), чтобы потом можно было многократно в нужные моменты вызывать ;функцию mycd() и ей передавалось правильное состояние лотка. Func mycd(ByRef $tray, $drive) Local $status = DriveStatus($drive&"\") Select Case $status = "READY" CDTray($drive, "open") msgbox (64,'case1','$status = '&$status& @LF &'$tray = '&$tray& @LF &'action = "open"',3) $tray=1 Case $status = "NOTREADY" and $tray=1 CDTray($drive, "closed") msgbox (64,'case2','$status = '&$status& @LF &'$tray = '&$tray& @LF &'action = "closed"',6) $tray=0 Case $status = "NOTREADY" and $tray=0 CDTray($drive, "open") msgbox (64,'case3','$status = '&$status& @LF &'$tray = '&$tray& @LF &'action = "open"',6) $tray=1 EndSelect EndFunc
Скорее всего, это неоптимальный вариант решения поставленной задачи, но он работоспособен. MsgBox-ы я поставил для наглядности - в рабочем варианте здесь должны быть Sleep-ы, достаточные для распознавания диска в приводе (при задвигании лотка) и поменьше (при выдвигании).

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

fox_sly 01-11-2005 03:24

Во первых строках огромный сенькс за труды Sanja Alone, bogomolv и другим участникам форума, за их подробные описания и толкования...
Изучив труды набросал для знакомого скриптик для установки Photoshop CS2, может кому пригодится?

Sanja Alone
- может подредактируешь и выложишь более оптимальный вариант у себя на сайте?

регистрациооные данные вбиты в файле Abcpy.ini
Код:
[OEM Install] SERIALNUMBER=XXXX-XXXX-XXXX-XXXX-XXXX-XXXX USERNAME=Fox Sly COMPANYNAME=Fox Sly System


сам скрипт

Код:
;предотвращение возможности множественного запуска скрипта добавлено Sanja Alone If WinExists(@ScriptName) Then Exit AutoItWinSetTitle(@ScriptName) ;Отображать текущую строку сценария с помощью индикатора системной панели в режиме отладки. AutoItSetOption("TrayIconDebug", 1) ; Установка переменных Global $file='setup.exe', $key='keygen.exe', $rus='PhotoshopCS2RU.exe', $AvtCode, $ACStr Run ( $file ) WinWaitActive ( 'Adobe Photoshop CS2 - Setup' ) ControlClick ( 'Adobe Photoshop CS2 - Setup', '', 'Button1' ) ; окно лицензионного соглашения, я думаю Не согласных нет? -) WinWaitActive ( 'Adobe Photoshop CS2 - License Agreement' ) ControlClick ( 'Adobe Photoshop CS2 - License Agreement', '', 'Button5' ) ; ввод информации о пользователе, в моем примере данные прописаны в файле Abcpy.ini WinWaitActive ( 'Adobe Photoshop CS2 - Setup','Customer Information' ) ControlClick ( 'Adobe Photoshop CS2 - Setup', 'Customer Information', 'Button1' ) ; выбор пути установки - по умолчанию WinWaitActive ( 'Adobe Photoshop CS2 - Setup','Destination Folder' ) ControlClick ( 'Adobe Photoshop CS2 - Setup', 'Destination Folder', 'Button1' ) ; ассоциация файлов - по умолчанию WinWaitActive ( 'Adobe Photoshop CS2 - Setup','File Association' ) ControlClick ( 'Adobe Photoshop CS2 - Setup', 'File Association', 'Button1' ) ; рапорт инсталятора о готовности к установки WinWait ( 'Adobe Photoshop CS2 - Setup','Ready to Install the Program' ) WinWaitActive ( 'Adobe Photoshop CS2 - Setup','Ready to Install the Program' ) ControlClick ( 'Adobe Photoshop CS2 - Setup', 'Ready to Install the Program', 'Button1' ) ; активация - начало WinWait ( 'Adobe Photoshop Installer','Activation Options' ) ;это окно иногда появляется, а иногда нет. Закономерность появления не найдена. If WinExists ( 'Adobe Photoshop Installer', 'Activate Using the Internet' ) Then WinActivate ( 'Adobe Photoshop Installer', 'Activate Using the Internet' ) WinWaitActive ( 'Adobe Photoshop Installer', 'Activate Using the Internet' ) ControlClick ( 'Adobe Photoshop Installer', 'Activate Using the Internet', 'Button3' ) EndIf ; продолжение активации - выбираем активировать по телефону WinWaitActive ( 'Adobe Photoshop Installer','Activation Options' ) Sleep ( 500 ) ControlClick ( 'Adobe Photoshop Installer','Activation Options', 'Button2' ) Sleep ( 500 ) ControlClick ( 'Adobe Photoshop Installer','Activation Options', 'Button7' ) ; Запуск кейгена Run ( $key ) WinWaitActive ( 'Keygen by PARADOX', 'Serial Number') ; Активация окна регистрации, получение серийника и вставка в кейген WinActivate ( 'Adobe Photoshop Installer', 'Phone Activation' ) WinWaitActive ( 'Adobe Photoshop Installer', 'Phone Activation' ) $GetSN1=ControlGetText('Adobe Photoshop Installer', 'Phone Activation', 'Edit3') ControlSetText('Keygen by PARADOX', 'Serial Number', 'Edit1', $GetSN1) ; Получение активационного номера и вставка в кейген $GetSN2=ControlGetText('Adobe Photoshop Installer', 'Phone Activation', 'Edit4') ControlSetText('Keygen by PARADOX', 'Serial Number', 'Edit2', $GetSN2) ; Активация кейгена и генерация кода авторизации WinActivate ( 'Keygen by PARADOX', 'Serial Number' ) WinWaitActive ( 'Keygen by PARADOX', 'Serial Number') ControlClick ( 'Keygen by PARADOX', 'Serial Number', 'Button2' ) Sleep ( 500 ) ; Получение кода авторизации $AvtCode = ControlGetText ( 'Keygen by PARADOX', 'Serial Number', 'Edit3' ) ; Код авторизации получен в виде xxxx xxxx xxxx xxxx xxxx разбиваем его на блоки $ACStr = StringSplit ( $AvtCode, ' ' ) Sleep ( 500 ) ; вставка кода авторизации WinActivate ( 'Adobe Photoshop Installer', 'Phone Activation' ) WinWaitActive ( 'Adobe Photoshop Installer', 'Phone Activation' ) ControlSetText ( 'Adobe Photoshop Installer', 'Phone Activation', 'Edit6', $ACStr[1] ) ControlSetText ( 'Adobe Photoshop Installer', 'Phone Activation', 'Edit7', $ACStr[2] ) ControlSetText ( 'Adobe Photoshop Installer', 'Phone Activation', 'Edit8', $ACStr[3] ) ControlSetText ( 'Adobe Photoshop Installer', 'Phone Activation', 'Edit9', $ACStr[4] ) ControlSetText ( 'Adobe Photoshop Installer', 'Phone Activation', 'Edit10', $ACStr[5] ) ; закрываем кейген WinActivate ( 'Keygen by PARADOX', 'Serial Number' ) WinWaitActive ( 'Keygen by PARADOX', 'Serial Number') ControlClick ( 'Keygen by PARADOX', 'Serial Number', 'Button3' ) ; продолжаем установку WinActivate ( 'Adobe Photoshop Installer', 'Phone Activation' ) WinWaitActive ( 'Adobe Photoshop Installer', 'Phone Activation' ) ControlClick ( 'Adobe Photoshop Installer', 'Phone Activation', 'Button3' ) WinWait ( 'Adobe Photoshop Installer', 'Thank You!' ) WinWaitActive ( 'Adobe Photoshop Installer', 'Thank You!' ) ControlClick ( 'Adobe Photoshop Installer', 'Thank You!', 'Button2' ) ; основная установка закончена, ждем установки Adobe Brige и прочей ерунды WinWait ( 'Adobe Photoshop CS2 - Setup', 'InstallShield Wizard Completed' ) WinWaitActive ( 'Adobe Photoshop CS2 - Setup', 'InstallShield Wizard Completed' ) ControlClick ( 'Adobe Photoshop CS2 - Setup', 'InstallShield Wizard Completed', 'Button4' ) Sleep ( 50 ) ControlClick ( 'Adobe Photoshop CS2 - Setup', 'InstallShield Wizard Completed', 'Button3' ) ; Запуск руссификатора, для тех кому он нужен Run ( $rus ) WinWaitActive ( 'Adobe Photoshop CS2 Russian - InstallShield Wizard') ControlClick ( 'Adobe Photoshop CS2 Russian - InstallShield Wizard', '', 'Button1' ) WinWaitActive ( 'Adobe Photoshop CS2 Russian - InstallShield Wizard', 'Select folder where setup will install files' ) ControlClick ( 'Adobe Photoshop CS2 Russian - InstallShield Wizard', 'Select folder where setup will install files' , 'Button6' ) WinWaitActive ( 'Adobe Photoshop CS2 Russian - InstallShield Wizard', 'The wizard is ready to begin installation.' ) ControlClick ( 'Adobe Photoshop CS2 Russian - InstallShield Wizard', 'The wizard is ready to begin installation.' , 'Button8' ) WinWaitActive ( 'Adobe Photoshop CS2 Russian - InstallShield Wizard', 'InstallShield Wizard Complete' ) ControlClick ( 'Adobe Photoshop CS2 Russian - InstallShield Wizard', 'InstallShield Wizard Complete' , 'Button15' ) exit


Проверил на паре машин - вроде работает

Sanja Alone 01-11-2005 21:22

Petya V4sechkin
Цитата:
Вчера почти весь день убил на активацию AutoCAD 2005. Пришлось извратиться пару раз :)
Никому не надо? Если надо, скажите.
Если не будешь возражать, то я размещу твой скрипт на соотв. странице своего сайта (дав ссылку на тебя как автора). В сл. твоего согласия - кинь свой скрипт мне на мыло.

fox_sly
Цитата:
может подредактируешь и выложишь более оптимальный вариант у себя на сайте?
Спасибо, уже выложил. А подредактировать я не смогу, т.к. Photoshop CS2 у меня нет - проверить будет не на чем :)

DenchikK 02-11-2005 11:21

Есть такая задача - с помощью AutoIT вставлять пароли в определённое
поле программы. Проблемма в том, что если скрипт .exe
раскомпилировать, то легко можно прочитать эти пароли. Понятно, что
нет ничего не взламываемого. Но от обычных пытливых юзеров хотелось бы
всё-таки пароли скрыть. Можно ли как то осуществить это с помощью
AutoIT?

AlikPan 02-11-2005 11:49

Гуру от Autoit?
Необходимо установить в переменные SET (для старых DOS задач)
в Autoit 2.64 использовал такие строки:

IfEqual,AUsername,L4305,Run,WinSet LOG_ST=F32,,hide

решил опробовать в Autoit 3.01.02, но WinSet как бы ругается
может есть провереное и более надежное решение ?
Да и не хочется использовать внешние утилиты.


Sanja Alone 02-11-2005 18:30

DenchikK
Цитата:
Но от обычных пытливых юзеров хотелось бы всё-таки пароли скрыть.
Aut2Exe.exe /? (см. в сторону ключа /nodecompile).


AlikPan
Цитата:
Необходимо установить в переменные SET
Непонятно что ты хочешь. Если установить системную переменную, то вот примеры:
1. Дописывание пути к 7-zip в переменную Path:
Код:
$cur = RegRead ( "HKEY_LOCAL_MACHINE\SYSTEM\Select", "Current" ) $smcur = 'HKEY_LOCAL_MACHINE\SYSTEM\ControlSet00' & $cur & '\Control\Session Manager\Environment' $syscurpath = RegRead ( $smcur, "Path" ) $sysnewpath = $syscurpath & Chr (59) & '%ProgramFiles%\7-Zip' RegWrite ( $smcur, "Path", "REG_EXPAND_SZ", $sysnewpath )


2. Создание новой системной переменной new строкового типа:
Код:
$newsysvarname = 'new' $newsysvartype='REG_SZ' $newsysvarvalue='value' $cur = RegRead ( "HKEY_LOCAL_MACHINE\SYSTEM\Select", "Current" ) $smcur = 'HKEY_LOCAL_MACHINE\SYSTEM\ControlSet00' & $cur & '\Control\Session Manager\Environment' RegWrite ( $smcur, $newsysvarname, $newsysvartype, $newsysvarvalue )
Можешь на основе этих обособленных неоптимизированных примеров написать функции соотв-но для изменения и создания системных переменных.

Цитата:
IfEqual,AUsername,L4305,Run,WinSet LOG_ST=F32,,hide
Если AUsername=L4305, тогда запустить некую утилиту WinSet с параметрами LOG_ST=F32 в скрытом окне (функции WinSet в автоите нет). К чему это?

DenchikK 02-11-2005 20:32

Sanja Alone
Спасибо большое, всё получилось.

Sanja Alone 03-11-2005 17:03

В скрипте для Winamp 5.xx исправил косяк с записью параметров в winamp.ini. На момент записи файл был недоступен для этой самой записи :) - добавил проверку.

fox_sly 05-11-2005 12:31

Тут на днях наводил порядок на винте и попался один из первых скриптов для создания Dial Up соединения
- так что может кому пригодится, единственное ограничение на сколько я помню, это то, что дрова для модема уже должны быть установлены и в системе должен быть только один модем, для двух и более прийдется подредактировать :)
Код:
;Запуск Мастера подключения к интернету Run ("rundll32.exe netshell.dll,StartNCW") WinWaitActive ( "Мастер новых подключений" ) ControlClick ( "Мастер новых подключений", "", "&Далее >" ) WinWaitActive ( "Мастер новых подключений" ) ControlClick ( "Мастер новых подключений", "", "&Подключить к Интернету" ) ControlClick ( "Мастер новых подключений", "", "&Далее >" ) WinWaitActive ( "Мастер новых подключений" ) ControlClick ( "Мастер новых подключений", "", "&Установить подключение вручную" ) ControlClick ( "Мастер новых подключений", "", "&Далее >" ) WinWaitActive ( "Мастер новых подключений" ) ControlClick ( "Мастер новых подключений", "", "Через &обычный модем" ) ControlClick ( "Мастер новых подключений", "", "&Далее >" ) WinWaitActive ( "Мастер новых подключений" ) Send ( "Demo Инфотекс" ) ControlClick ( "Мастер новых подключений", "", "&Далее >" ) WinWaitActive ( "Мастер новых подключений") Send ( "313003" ) ControlClick ( "Мастер новых подключений", "", "&Далее >" ) WinWaitActive ( "Мастер новых подключений") Send ( "demo" ) Send ( "{tab}" ) Send ( "demo" ) Send ( "{tab}" ) Send ( "demo" ) ControlClick ( "Мастер новых подключений", "", "Сделать &это подключение подключением к Интернету по умолчанию" ) ControlClick ( "Мастер новых подключений", "", "&Далее >" ) WinWaitActive ( "Мастер новых подключений") ControlClick ( "Мастер новых подключений", "", "Готово" ) Exit

Sanja Alone 06-11-2005 22:30

Добавил скрипт для Exact Audio Copy v0.95 beta 3
Переписал/дополнил/изменил ВСЕ скрипты на сайте:
- "шапки" теперь содержат инфу о версиях приложений на к-рых скрипты тестировались
- вписал те самые две строчки для предотвращения возможности множественного запуска скриптов
- все-таки решил перейти на вариант TrayIconDebug; TrayIconHide/BlockInput-вариант закомментировал
- везде, где нужно приписал макрос @ScriptDir для возможности запуска любого скрипта в неоткомпилированном вар-те без необходимости ложить его рядом с Autoit3.exe
- дописал тихие варианты установки там, где это было уместно
- еще что-то, сам не помню :)

Jangle 07-11-2005 17:36

Панель инструментов "МОЙ КОМПЬЮТЕР"
 
Доброго времени суток, уважаемые!

Вот какой вопрос мучает:
Все вы знаете что в винде есть панель инструментов быстрого запуска, языковая панель и т.д.
Так же сть возможность создание своей панели.
Вот что я делаю:
1 кликаю провой кнопкой на панели задач (на ней кнопка ПУСК)
2 снимаю галочку "закрепить панель задач"
3 см 1 --> панель инструментов --> создать панель инструментов
4 В окне "создать панель инструментов" выбераю папку "МОЙ КОМПЬЮТЕР" и жму ОК
после чего на панели задачь появляеться панель инструментов "МОЙ КОМПЬЮТЕР"
5 хватаю мышкой область этой панели помеченной вертикальной линией из точек и перетаскиваю до упора вверх (мышка тянет прямоугольник)
где эта панель прилипает к верху экрана
6 теперь кликая на этой панели правой кнопкой настраиваю ее - снимаю галочку показать заголовок,
ставлю галочки - поверх остальных окон и автоматически уберать с экрана
7 - настраиваю размер панели (так же как и с окнами)
8 возвращаю галочку п.2


это я так подробно описал для того что бы можно было бы посмотреть результат.

А ВОТ ТЕПЕРЬ САМ ВОПРОС:

как можно сделать эту панель не прописывая в AUTOIT эти все пошаговые действия
утраивает 2 варианта
1 - это делаеться с помощью реестра или системных файлов или файлов настройки explorer
2 - может возможно это сделать с помощью GUI

еще интересует где находяться настройки "поверх остальных окон", "автоматически уберать с экрана", размер панели и т.д

Буду признателен за любые предложения и мысли.
Спасибо всем

Jangle 07-11-2005 17:45

В догонку
 
в догонку Dial_up
как запустить соединение так что бы вышло стондартное окно И
ка запустить соединение бе этого окна.

bogomolv 07-11-2005 23:49

Jangle

За показ Панели быстрого запуска и поведение Панели Пуск отвечают ключи
;QStart - настройки
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Streams\Desktop]
"TaskbarWinXP"=
;STARTUP - настройки: автоскрывать, маленькие кнопки и т.д.
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\StuckRects2]
"Settings"=

Но сочетание параметров, отраженных в этих ключах сложное. Их работоспособность зависит от других настроек Explorer'a. Кроме того, при установке WinXP некторые настроенные параметры будут сбрасываться и забиваться дефолтными настройками.

С помощью AutoIt Панель быстрого запуска не настроишь.
Фантастика, но если не перетащить хотя бы одну иконку "ручками", то после перезапуска иконки "перетасуются" в нужном и понятном только им порядке. Так происходит, даже если перетаскивать иконки с помощью AutoIt.
Самое простое - устанавливать приложения, иконки которых тебе нужны в Панели быстрого запуска, именно в строго заданной последовательности.



ags 08-11-2005 07:29

Help!

Как АвтоИтом послать программе установки нажатие клавиши "+" на NumPade. Конструкция Send ("{+}") не работает. Там вообщето меню раскрывающееся (такое же как при выборе компонентов Office). Оно внутри окна и по-отдельности пункты не активизируются, только все меню целиком. Остается два способа: по координатам мышом (но ИМХО не надежно, вдруг на другом компе координаты не совпадут...) и стрелками, но чтобы попасть в подменю нужен этот "+". Иначе слишком много ненужного барахла установится:(


Сорри, не могу удалить... Сработала стрелка вправо (как я эту клавишу упустил из виду, ума не приложу...) Еще раз сорри за пустой пост...

AlikPan 08-11-2005 10:02

Sanja Alone
Цитата:
2. Создание новой системной переменной new строкового типа:

Код:
$newsysvarname = 'new'
$newsysvartype='REG_SZ'
$newsysvarvalue='value'
$cur = RegRead ( "HKEY_LOCAL_MACHINE\SYSTEM\Select", "Current" )
$smcur = 'HKEY_LOCAL_MACHINE\SYSTEM\ControlSet00' & $cur & '\Control\Session Manager\Environment'
RegWrite ( $smcur, $newsysvarname, $newsysvartype, $newsysvarvalue )


пожалуй это именно то, что нужно, СПАСИБО

Цитата:
IfEqual,AUsername,L4305,Run,WinSet LOG_ST=F32,,hide

Если AUsername=L4305, тогда запустить некую утилиту WinSet с параметрами LOG_ST=F32 в скрытом окне (функции WinSet в автоите нет). К чему это?


Всё правильно, нет такой функции. Но есть сторонняя утилита WinSet.exe (кажется от MIcrosoft), которую
я и вызываю. Устаналивает переменные SET в среде WINDOWS

Jangle 08-11-2005 12:40

2 bogomolv - огромное спасибо за информацию!!!
Буду думать :sorry:

Sanja Alone 08-11-2005 17:17

1. Добавил скрипт для Teleport Pro 1.38

2. Исправил ошибку в конвертере crta - неправильно импортировались в реестр параметры типа REG_DWORD (значения интерпретировались как десятичные). Кавычки заменил на дописывание к значению префикса "0x" - теперь все правильно (значения считаются шестнадцатиричными).

Эта ошибка также касается следующих скриптов:
7-Zip
Agnitum Outpost
DivX 5
DivX 6
DVDIdle
GordianKnot
ImageDupeless
ISOBuster
O&O Defrag
Pragma

Если кто-то скачал - извините. Можете скачать еще раз или исправить вручную. Я сам случайно заметил данную недоработку, т.к. большинство DWORD параметров были или 0 или 1, а эти цифры одинаковы во всех системах счисления.

DenchikK 09-11-2005 09:59

fox_sly
Практически так же сделано и у меня, только бы я Вам посоветовал заменить Send на ControlSetText - так оно и лучше и надёжнее будет.

Как то вот так:

Код:
Run("rundll32.exe netshell.dll,StartNCW") WinWaitActive ('Мастер новых подключений','Мастер новых подключений') Send('{Enter}') Sleep ('500') WinWaitActive ('Мастер новых подключений','Подключить к Интернету для просмотра веб-узлов и чтения электронной почты.') ControlClick ('Мастер новых подключений','Подключить к Интернету для просмотра веб-узлов и чтения электронной почты.','Button1') Sleep ('500') Send('{Enter}') WinWaitActive ('Мастер новых подключений','Каким образом подключиться к Интернету') ControlClick ('Мастер новых подключений','Каким образом подключиться к Интернету','Button2') Sleep ('500') Send('{Enter}') WinWaitActive ('Мастер новых подключений','Данное подключение использует модем и обычную телефонную линию или телефонную линию ISDN.') ControlClick ('Мастер новых подключений','Данное подключение использует модем и обычную телефонную линию или телефонную линию ISDN.','Button1') Sleep ('500') Send('{Enter}') WinWaitActive ('Мастер новых подключений','Им&я поставщика услуг') ControlSetText ( 'Мастер новых подключений', '', 'Edit1', 'Peterstar' ) Sleep ('500') Send('{Enter}') WinWaitActive ('Мастер новых подключений','Номер &телефона:') ControlSetText ( 'Мастер новых подключений', '', 'Edit1', '3203370,,,' ) Sleep ('500') Send('{Enter}') WinWaitActive ('Мастер новых подключений','&Имя пользователя:') sleep (100) ControlSetText ( 'Мастер новых подключений', '', 'Edit1', 'Login') sleep (100) ControlSetText ( 'Мастер новых подключений', '', 'Edit2', 'Password') Send('{tab}') sleep (100) ControlSetText ( 'Мастер новых подключений', '', 'Edit3', 'Password') Sleep ('500') ControlCommand ( 'Мастер новых подключений', '', 'Button13', 'Check', '' ) ControlCommand ( 'Мастер новых подключений', '', 'Button2', 'Check', '' ) Sleep ('500') Send('{Enter}') WinWaitActive ('Мастер новых подключений','Завершение работы мастера новых подключений') ControlCommand ( 'Мастер новых подключений', '', 'Button20', 'UnCheck', '' ) Send('{Enter}') Exit

fox_sly 09-11-2005 12:19

to DenchikK
С заменой согласен, просто как писал выше это была одна из первых попыток написать скрипт для соединения,
насколько я помню там была другая проблема, что не удалось в свое время уйти от Send('{Enter}'),
по крайней мере у меня строка типа
Код:
WinWaitActive ('Мастер новых подключений','Мастер новых подключений') Send('{Enter}')
срабатывала, а вот замена через ControlClick
Код:
WinWaitActive ('Мастер новых подключений','Мастер новых подключений') ControlClick ('Мастер новых подключений','Мастер новых подключений','Button3')

не работала, окно вообще закрывалось

CTEPBA 09-11-2005 12:31

Люди обэясните пожалуйста почему когда с ставлю Alcohol 120% при помощи какого сктрипта:
Код:
AutoItSetOption("TrayIconHide", 1) If @OSType="WIN32_NT" Then BlockInput ( 1 ) AutoItSetOption ( "SendKeyDelay", 10 ) Global $file='setup.exe', $patchfile='patch_3105.exe', $alcoholdir=@ProgramFilesDir & '\Alcohol Soft\Alcohol 120\' ;запуск установки в тихом режиме Run( $file & ' /qn REBOOT=Suppress' ) ProcessWait ( "rundll32.exe" ) ProcessClose ("rundll32.exe") Sleep ( 50 ) If FileExists ( $alcoholdir & '\Alcohol.exe' )=1 Then FileCopy ( @ScriptDir & '\' & $patchfile, $alcoholdir & $patchfile, 1 ) FileChangeDir ( $alcoholdir ) Run ( $alcoholdir & $patchfile, $alcoholdir ) WinWait ( 'Patch','Alcohol 120% v1.9.5.3105 Retail') WinActivate ( 'Patch' ) ControlClick ( 'Patch', '', 'Button1' ) Sleep ( 4000 ) WinClose ( 'Patch', 'Alcohol 120% v1.9.5.3105 Retail' ) WinWaitClose ( 'Patch','Alcohol 120% v1.9.5.3105 Retail' ) EndIf ;н-рые настройки RegWrite('HKEY_CURRENT_USER\Software\Alcohol Soft\Alcohol 120%\Options\Display',"AutostartWhenWindowsStartup","REG_SZ",'0') RegWrite('HKEY_CURRENT_USER\Software\Alcohol Soft\Alcohol 120%\Options\Display',"ExecuteInFullScreen","REG_SZ",'0') RegWrite('HKEY_CURRENT_USER\Software\Alcohol Soft\Alcohol 120%\Options\Display',"ListPhysicalDevicesFirst","REG_SZ",'0') RegWrite('HKEY_CURRENT_USER\Software\Alcohol Soft\Alcohol 120%\Options\General',"AutoCheckCurrentVersionViaInternetAtStart","REG_SZ",'0') RegWrite('HKEY_CURRENT_USER\Software\Alcohol Soft\Alcohol 120%\Options\Virtual drive',"MountImageTo1stDeviceOnDblClickingImageFile","REG_SZ",'1') RegWrite('HKEY_CURRENT_USER\Software\Alcohol Soft\Alcohol 120%\Options\Recording',"OverBurnDisc","REG_SZ",'1')


У меня закрывается WPI, а установка Alcohol продолжается?

DenchikK 09-11-2005 13:16

CTEPBA
Рискну предположить причину:

Алкоголь ставиться примерно так:
msiexec /qn /quiet /i setup.msi DRIVER0=a347bus DRIVER1=a347scsi INSTALLDIR="%programfiles%\Alcohol Soft\" /norestart

Потому то и не ставиться у тебя он.

Вот мой пример. Поправь его под себя:

Код:
prog[pn]=['Alcohol 120% 1.9.5.3105'] desc[pn]=['Эмулятор Лазерных Дисков <i>Установка Ключами</i>'] ordr[pn]=[4] cmd1[pn]=['msiexec /qn /quiet /i %cdrom%\\Software\\Programs\\Alcohol\\setup.msi DRIVER0=a347bus DRIVER1=a347scsi INSTALLDIR="%programfiles%\\Alcohol Soft\\" /norestart'] cmd2[pn]=['%cdrom%\\Software\\Programs\\Alcohol\\crack.exe'] rdflt[pn]=['yes'] cat[pn]=['Programs'] picf[pn]=['alcohol.png'] picw[pn]=['270'] pich[pn]=['162'] pn++


содержание файла crack.exe (это sfx rar архив, распаковывающийся в каталог, куда уже поставился Алкоголь):

crack.exe
patch.exe
alcohol.reg

После распаковки запускается скрипт autoit такого содержания:

Код:
Run('patch.exe') WinWaitActive ('Patch','Alcohol 120') ControlClick ('Patch','Alcohol 120','Button1') WinWait ('Patch','Alcohol 120') Sleep(5000) ControlClick ('Patch','Alcohol 120','Button3') Exit


а файл alcohol.reg остался от старых версий, на всякий случай:

Код:
Windows Registry Editor Version 5.00 [HKEY_CURRENT_USER\Software\Alcohol Soft\Alcohol 120%\Info] "UserName"="Denchik" "Company"="Babylon 5" "SerialNo"="ALCBCBCBCBC3T99TVJKK2G7XYBCVWDDB2MPCDR78YCDB2CCB289RTK234CD7MG7D43TC3M392C34V89T8DFJKBBT8MPMPQ6T8BB2 33HCDXXCCBCBCB"

CTEPBA 09-11-2005 14:53

Проблема не в том что он не ставиться все, а вот что когда очередь доходит до него в WPI, то почемуто WPI закрывается а Alcohol продолжает установку и все приложения которые стояли после Alcohol не ставяться так, как уже выгруженно WPI.

Sanja Alone 09-11-2005 18:22

CTEPBA
Цитата:
У меня закрывается WPI, а установка Alcohol продолжается?
Ну это наверно из-за ProcessClose ("rundll32.exe"). Логично? А воткнул ты это закрытие процесса в мой скрипт скорее всего по причине появления окна "мастер нового оборудования"?... Вот только закрывая rundll32.exe, ты, одновременно с выскочившим окном, закрываешь и окно установки прог, запускаемых из RunOnceEx (этот метод используется в WPI) через тот же самый rundll32. Твоя проблема решаема, а как - было сказано немного выше.


DenchikK
Цитата:
Алкоголь ставиться примерно так:
Это если через msi, а я делал через exe.

CTEPBA 10-11-2005 13:00

Sanja Alone
Я уже сам догдался теперь использую
такой метод установки:
Код:
msiexec /qn /quiet /i setup.msi DRIVER0=a347bus DRIVER1=a347scsi INSTALLDIR="%programfiles%\Alcohol Soft\" /norestart

но окно все равно выскакивает, весит потом изчезает само, жалко это тормозит установку.

Sanja Alone 10-11-2005 17:21

Добавил скрипт для Agnitum Outpost 3.0 (в архиве 2 скрипта: для версии 2.7 и для 3.0)


CTEPBA
Цитата:
но окно все равно выскакивает
И этот твик не помог?
Код:
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DriverSearching] "DontSearchWindowsUpdate"=dword:00000001 "DontPromptForWindowsUpdate"=dword:00000001
Может мы оворим о разных окнах? Если это какое-то другое окно, то можешь закрыть его с пом. функции AdlibEnable("имя_функции") - пример ее использования можешь посмотреть в моем скрипте для Pragma

XXXler 11-11-2005 08:52

Блин, в сети случайно наткнулся на прогу Almeza Multiset, поставил - вроде делает примерно то-же+создает оболочку для CD (правда не блещущую интерфейсом :) )
Какие будут мнения?
(имхо, ручками в AutoIt конечно увереннее - знаешь что не промажешь, но на мой взгляд когда срочно и на скорую руку - прога то, что надо...)

CTEPBA 11-11-2005 14:36

Sanja Alone
Насчет реестра я не пробовал, а окна это про "новое оборудование"

samsobi 15-11-2005 03:56

В треде твиков задавали вопрос про установку режимов "НИКОГДА" для текущей схемы электропитания.
Когда мне тоже не помогли твики реестра по установке схемы питания "никогда", я сделал это через AutoIt, может корявое решение, но все работает прекрасно:

Код:
#cs ---------------------- Установка режимов "НИКОГДА" для текущей схемы электропитания ---------------------- #ce Run( @WindowsDir & '\system32\rundll32 shell32.dll,Control_RunDLL powercfg.cpl' ) WinWait( 'Свойства: Электропитание' ) WinActivate('Свойства: Электропитание') ControlCommand ( 'Свойства: Электропитание', 'Отключение дисп&лея:', 'ComboBox2', 'SelectString' ,'никогда') ControlCommand ( 'Свойства: Электропитание', 'Отключение диско&в:', 'ComboBox3', 'SelectString' ,'никогда') ControlCommand ( 'Свойства: Электропитание', '&Ждущий режим через:', 'ComboBox4', 'SelectString' ,'никогда') ControlClick ( 'Свойства: Электропитание', '', 'Button5')


kovdaev 16-11-2005 04:41

Поделитесь скриптом установки DRWEB 4.33
Заранее спасибо.

qeraser 16-11-2005 05:45

kovdaev
Посмотри здесь
HTML коды:
http://sanjaalone.h15.ru/au3.php

vserd 16-11-2005 06:15

Всем доброго здравия!!!
Возникла такая проблемка как с помощью Autoit 2.63 ввести в поле ввода маленькую букву "я"
Код:
Send,"я"

или другую строку с "я" не срабатывает, вместо я вставляет пустую строку.

a_s_malyshev 16-11-2005 06:46

Помогите. Существует проблема с набором русского текста в элементах управления.
Набираются буквы нормально только при русской расскладке клавиатуры.
Что мне нужно добавить в начало моего скрипта, чтобы расскладка автоматом переключалась на русскую?

Заранее спасибо

a_s_malyshev 16-11-2005 06:48

Это будет происходить массово на разных компьютерах с помощью групповых политик. И сочетания клавиш для переключение расскладки у всех разная и язык по умолчанию тоже разный. Вот такая проблема?

Jangle 16-11-2005 11:15

Доброго времени суток!

ВОт хотел бы попросить помощи в следующем вопросе: как с помощью AutoIt или в сочетании Autoit + Win Api (виндовских DLL- ок) послать скопировать файл на FTP?
Попробовал следующее (по - тупому):

Цитата:
$D = FtpSetProxy(2, "ftp:\\xxx.com:21", "zzzzzz", "ccccccc")
FileCopy ("C:\0.txt", $D)


но почему-то файл 0.txt копируется на рабочий стол с именем 1.txt

Спасибо всем

kovdaev 16-11-2005 12:33

Спасибо qeraser.
Это действительно то, что нужно.

Sanja Alone 16-11-2005 17:55

Добавил скрипт для ABBYY FineReader 8.0 Professional Edition (в архиве 2 скрипта: для версии 7.0 и для 8.0)


vserd
Цитата:
как с помощью Autoit 2.63 ввести в поле ввода маленькую букву "я"

1. Пора переходить на AutoIt 3.x (я тоже начинал с 2.64). Для конвертации имеющихся скриптов в новую версию можно исп-ть "v2 to v3 Converter" (AutoIt3\Extras\v2_to_v3_Converter\AutoItV2toV3.exe)
2. По сути. Вот два способа, навскидку:
Код:
;239 - ASCII-код символа "я" Send("{ASC 239}")

Код:
;можно исп-ть доп. переменную: $str = 'строка с "я" или чем угодно' Send($str)


a_s_malyshev
Цитата:
проблема с набором русского текста в элементах управления...
Ответ чуть-чуть выше :) Ес-но, при этом au3-файл должен быть не в DOS (CP866) кодировке.

a_s_malyshev 16-11-2005 23:59

Да нет проблема вот в чем, например:
Run("Notepad.exe")
WinWaitActive("Безымянный - блокнот")
Send("Привет")

Если при запуске блокнота стоит английская раскладка, то получаются ироглифы.
Если при запуске блокнота стоит русская раскладка, то получаются все нормально.
Вот мне и надо чтобы после открытия блокнота, какой-нибудь командой поменять расскладку клавиатуры на русскую.
И при этом файл должен не в DOS кодировке.

Sanja Alone 17-11-2005 18:53

Добавил скрипты
Compare It 3.8.1660
Rar Key 7.0.1180


a_s_malyshev
1. Можешь прописать в реестр вот такие параметры, например:
Код:
;Переключние на Английский по Ctrl+Shift+1 [HKEY_CURRENT_USER\Control Panel\Input Method\Hot Keys\00000100] "Virtual Key"=hex:31,00,00,00 "Key Modifiers"=hex:06,c0,00,00 "Target IME"=hex:09,04,09,04 ;Переключние на Русский по Ctrl+Shift+2 [HKEY_CURRENT_USER\Control Panel\Input Method\Hot Keys\00000101] "Virtual Key"=hex:32,00,00,00 "Key Modifiers"=hex:06,c0,00,00 "Target IME"=hex:19,04,19,04
Можешь вписывать скриптом эти параметры в реестр когда тебе будет нужно, а затем тем же скриптом удалять. Данные изменения применяются без перезагрузки системы, хотя Винда и пишет обратное при их ручной установке посредством языковой панели :)

Сочетание клавиш для последовательного переключения языков находится здесь HKEY_CURRENT_USER\Keyboard Layout\Toggle, например:
Код:
;левый Ctrl+Shift [HKEY_CURRENT_USER\Keyboard Layout\Toggle] "Hotkey"="2" "Language Hotkey"="2" "Layout Hotkey"="1" ;или ;левый Alt+Shift [HKEY_CURRENT_USER\Keyboard Layout\Toggle] "Hotkey"="1" "Language Hotkey"="1" "Layout Hotkey"="2"


selanec555
Цитата:
MultiSet автоматически устанавливет приложения, при этом ни надо писать ни каких скриптов!
...Нужно только заплатить 99$ за одну копию или найти крякнутую экзешку для старой версии 1.3 (текущая 1.5) и не иметь никакой возможности что-то подправить при неудовлетворительной работе какого-то "скрипта" программы...

a_s_malyshev 17-11-2005 23:56

Огромное спасибо!!!
Пробую.

С уважением, Александр

selanec555 18-11-2005 06:05

цена MultiSet
 
"
...Нужно только заплатить 99$ за одну копию или найти крякнутую экзешку для старой версии 1.3 (текущая 1.5) и не иметь никакой возможности что-то подправить при неудовлетворительной работе какого-то "скрипта" программы...
"

для русскоговорящих пользоватлей, насколькоя я понял регистрация 300руб.
смотрим тут:
http://www.almeza.com/press/rus/pay/pay.html

Sanja Alone 18-11-2005 16:29

selanec555
Цитата:
для русскоговорящих пользоватлей
Все может быть... Как говорится: "на вкус и цвет..." Меня подобная прога изначально не устаивает, т.к. не позволяет внести хоть какую-то логику в скрипт. Возьмем в кач-ве примера "случайно" появляющиеся окна - данную прогу такое событие введет в ступор. Прибавим к этому невозможность проверки существования какого-то файла/каталога и т.д, и т.п. Я ставлю крест на такой проге, АднАзначнА! Хотя и не исключаю возможности ее использования кем-то для установки "простых" приложений при полном отсутствии желания тратить время на написание гораздо более функциональных АвтоИт-скриптов.

selanec555 20-11-2005 11:25

Цитата:
Хотя и не исключаю возможности ее использования кем-то для установки "простых" приложений при полном отсутствии желания тратить время на написание гораздо более функциональных АвтоИт-скриптов.

Как мне кажется MultiSet - это решение для большинства простых пользователей, которым не надо думать как там написать скрипт для той или иной проги. = просто установил ее вместе с МultiSet и все, не паришься. А со скриптами АвтоИт надо еще и думать и после выхода очередной версии любимой проги надо скрипт переписывать, а если этих любимых прог 10, 20, 100, 500? Че все перелапачивать, нет уж нафиг, нафиг.
Ну в принципе скрипты конечно могут и пригодится но только в редких случаях, очень редких.
Не знаю как вам а я эту прогу уже использую!!!

fox_sly 20-11-2005 11:47

selanec555
- ну а причем тут AutoIt скрипты, создайте тему и там описывайте, все что захочется, а насчет простоты установки полностью согласен с Sanja Alone - так как довольно часто встречаются нестандартные ситуации при установке популярных программ

CTEPBA 20-11-2005 12:07

Sanja Alone
Цитата:
И этот твик не помог?



Код:
Код: [HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DriverSearching] "DontSearchWindowsUpdate"=dword:00000001 "DontPromptForWindowsUpdate"=dword:00000001


Нет не помог, при первом вхоже он не помог, но если ставить Alcohol автоматом уже в полностью загруженной системе все ставиться и ничего не выскакивает, даже не заню как от это избавиться.

Sanja Alone 20-11-2005 17:39

CTEPBA
Цитата:
но если ставить Alcohol автоматом уже в полностью загруженной системе все ставиться и ничего не выскакивает
Ну дак в этом и весь смысл данного твика - применить его на стадии установки Виндов. У меня, например, приведенный твик вносится в реестр из RegTweaks.reg через cmdlines.txt.

selanec555 21-11-2005 00:41

Цитата:
- так как довольно часто встречаются нестандартные ситуации при установке популярных программ

Неужно на АвтоИт можно описать ВСЕ нестандартные ситуации? Или как? Для каждого сетапника все описывать?
Я к тому что есть решение гораздо удобнее. А решать каждому.

CTEPBA 21-11-2005 12:22

Sanja Alone
У меня он тоже от туда вноситься, но ничего не пашет.

AlikPan 24-11-2005 05:08

Интересная ситуация, может кто сталкивался ?
Кусочек скрипта для регистрации в сети (домен 2000):
...
$AUserName=@UserName
MsgBox(4096, "Имя пользователя (Login)", $AUserName)
...

Работает в WIN2000, WIN XP. Под WIN 98 ни в какую.
после регистрации то же срабатывает везде.
Ограничения WIN98 или глюка ?

Sanja Alone 24-11-2005 17:24

AlikPan
Цитата:
Ограничения WIN98 или глюка ?
Первое. Под 9x-Окнами у АвтоИта вообще куча ограничений.

AlikPan 25-11-2005 00:07

Sanja Alone
Спасибо.
А через реестр брать Login - это нормально ?

DenchikK 25-11-2005 15:59

Проблема с последним окном в русификаторе для FastStone 2.28
http://www.4ru.info/FastStone.htm
Окно нафиг не определяется со всеми вытекающими...
Но вот что интересно - я забыл однажды снять из трея застопорившийся скрипт, и запустил его снова - окно видимо определилось, скрипт сработал.
Замучился уже, кучу вариантов перепробовал - не хочет работать!

Sanja Alone 25-11-2005 18:12

AlikPan
Цитата:
А через реестр брать Login - это нормально ?
А какая разница? :)

DenchikK
Цитата:
кучу вариантов перепробовал
Через идентификаторы пробовал? (если нет - см. пример здесь).

EgOrus 25-11-2005 22:54

DenchikK
а вариант с простым копированием FSViewer.ru в папку программы, не нравится?

DenchikK 26-11-2005 02:00

EgOrus
Так то оно так, но просто хочется понять, как заставить работать инсталяху. Спортивная злость, как говорится.

Sanja Alone
Видать что-то я не так делаю - не получается.

a_s_malyshev 29-11-2005 03:13

Подскажите. А можно ли как-нибудь получить список всех имен компьютеров с Dns- суффиксом (например: inf1.scool.ru) в анном домене с помощью AutoIt или же какой-нибудь другой программой например выгрузить в файл. Очень нужно

Sanja Alone 30-11-2005 19:14

Добавил скрипты
AutoGordianKnot 2.20
FastStone Image Viewer 2.2x (Image Viewer + русификатор + Screen Capture + Photo Resizer)


DenchikK
Цитата:
Проблема с последним окном в русификаторе для FastStone
Да вроде все нормально... :search:


a_s_malyshev
Цитата:
как-нибудь получить список всех имен компьютеров

Может вот это подойдет:
NET VIEW - эта команда выводит список доступных для совместного использования ресурсов данного компьютера.
Kогда используется без параметров, отображает список компьютеров текущего домена или сети.

a_s_malyshev 03-12-2005 00:45

Цитата:
Может вот это подойдет:
NET VIEW - эта команда выводит список доступных для совместного использования ресурсов данного компьютера

Команда хорошая, но мне нужно полные имена компьютеров.
Т.е. test.scool.r36.ru <- Что то вроде этого.
Они должны выдаваться из системы.
А не так чтобы я получил список с помощью команды net View а потом добавлял к элементам списка хвосты (scool.r36.ru).
Если какая-нибудь такая команда?

ghosty 05-12-2005 20:24

Здравствуйте. Спасибо, что вы есть :)
Прошу помочь написать простенький (по-видимому) скриптик.

Имеется выделенный текст. При нажатии определенного сочетания кнопок этот текст необходимо сохранить в виде отдельного *.txt файла с названием
- либо соответствующим первым трем словам первой строки текста;
- либо просто порядковым номером (только как в этом случае отследить, какой порядковый номер в папке явл-ся последним)
в определенную папку.

Очень надеюсь на вашу помощь.

selanec555 07-12-2005 16:13

Здравствуйте. Каким образом можно отловить AutoIt'ом перезагрузку ПК, у меня есть пара скриптов установки софта, дак вот так есть такие дистрибутивы котоые сами перезагрузают комп :( как это отловить/недопустить/корректно обработать? Спасибо.

Sanja Alone 10-12-2005 22:59

ghosty
Цитата:
Имеется выделенный текст. При нажатии определенного сочетания кнопок этот текст необходимо сохранить в виде отдельного *.txt файла

Ну, можно вот так, например:
Код:
;предотвращение возможности множественного запуска скрипта If WinExists(@ScriptName) Then Exit AutoItWinSetTitle(@ScriptName) ;устанавливаем хоткей (в данном сл. это Ctrl+Alt+Z; выбор за тобой) HotKeySet("^!z", "SaveToFile") ;определение каталога для сохранения файлов Global $DestinationDir = "c:\working folder" ;запуск основного бесконечного цикла While 1 Wend Func SaveToFile() ;заносим выделенный текст в буфер обмена Send ('^c') ;режим записи: 1 - дописывание данных; 2 - перезапись файла $mode = 1 ;имя файла (в данном сл. будет иметь вид ГодМесяцДень-ЧасыМинутыСекунды.txt, например 20051211-053438.txt) $Destination = $DestinationDir & '\' & @YEAR & @MON & @MDAY & '-' & @HOUR & @MIN & @SEC & '.txt' ;если каталог назначения не существует - создаем его If Not FileExists($DestinationDir) Then DirCreate($DestinationDir) ;берем данные из буфера обмена $Data = ClipGet() ;запись данных в файл (совмещена с проверкой и выводом сообщения в сл. неудачи) If WriteArrayToFile($Destination, $Data, $mode)<>1 Then MsgBox(16,'Error','Unable to write data to destination file',8) EndFunc ;функция записи массива в файл Func WriteArrayToFile($sFilePath, $Array, $writemode) Local $hOpenFile Local $hWriteFile $hOpenFile = FileOpen($sFilePath, $writemode) If $hOpenFile = -1 Then SetError(1) Return 0 EndIf $hWriteFile = FileWrite($hOpenFile, $Array) If $hWriteFile = -1 Then SetError(2) Return 0 EndIf FileClose($hOpenFile) Return 1 EndFunc

Цитата:
- либо соответствующим первым трем словам первой строки текста;
- либо просто порядковым номером
Можно и так, и так, но это сложнее и неудобнее.


selanec555
Цитата:
как это отловить/недопустить/корректно обработать?

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

Sanja Alone 13-12-2005 18:02

Добавил скрипты
Anti-Blaxx 1.18
DAEMON Tools 4.00HE

kovdaev 16-12-2005 09:22

Помогите написать скрипт нужно
вызвать "Свойства панели задач и меню пуск"
проверить стоят ли галочки в определенных местах если нет то установить галочки
затем закрыть окно.
Заранее спасибо.

Sanja Alone 16-12-2005 22:57

kovdaev
Цитата:
Помогите написать скрипт

Лови:
Код:
;заголовок окна Global $Title = 'Свойства' ;вызов окна 'Свойства панели задач и меню "Пуск"' Run ('RunDll32.exe shell32.dll,Options_RunDLL 1') ;дожидаемся появления окна и активизируем его WinWait ($Title) WinActivate ($Title) WinWaitActive ($Title) ;Далее идет непосредственно установка/снятие чекбоксов (измени/допиши то, что именно тебе нужно) ;Закрепить панель задач (поставить галку) If ControlCommand ($Title,'','Button1','IsChecked','')=0 Then ControlCommand ($Title,'','Button1','Check','') ;Автоматически скрывать панель задач (снять галку) If ControlCommand ($Title,'','Button2','IsChecked','')=1 Then ControlCommand ($Title,'','Button2','UnCheck','') ;...и т.д. ;Скрывать неиспользуемые значки (поставить галку) If ControlCommand ($Title,'','Button7','IsChecked','')=0 Then ControlCommand ($Title,'','Button7','Check','') ;Закрыть окно (нажать кнопку "OK") ControlClick ($Title,'','Button11')

bogomolv 16-12-2005 23:40

kovdaev
Двумя страницами ранее уже приходлось писать, что
за поведение Панели Пуск отвечает ключ
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\StuckRects2]
"Settings"=

Настрой Панель под себя, скопируй ключ в reg-файл, а затем воспроизведи...

Sanja Alone
А зачем в твоем последнем скрипте проверка If ControlCommand ($Title,'','Button1','IsChecked','')=0 Then?

Sanja Alone 17-12-2005 17:33

bogomolv
Цитата:
А зачем в твоем последнем скрипте проверка
Я, как и ты, настраиваю панель Пуск "реестровым" методом (причем еще на этапе установки Винды) и уже не помню, что там стоит "по умолчанию". Человек просил скрипт - я наваял, ну и влепил проверки для примера.

kovdaev 19-12-2005 07:33

Ответ на вопрос зачем это нужно,
в моем случае пользователи делают что хотят, но когда начинаются проблемы зовут меня при этом, мне удобно когда скажем панель задач не убиралась с экрана, пришел запустил скрипт и все галочки стаят там где надо и не стоят где ненадо, мне кажется это удобно.
Спасибо большое за помощь.

asdfghjk 21-12-2005 14:08

Кто-нибудь знает, как переключить раскладку клавиатуры в En, например? Пробовал API функцию - "LoadKeyboardLayoutA"
$result = DllCall("user32.dll", "long", "LoadKeyboardLayoutA", "str", "00000409", "long", 1)
не отрабатывает.

Имхо, прежде чем пользоваться SEND, не мешало бы переключить клавиатуру.

Sanja Alone 21-12-2005 18:45

asdfghjk
Цитата:
Кто-нибудь знает, как переключить раскладку клавиатуры в En, например?
Немного выше я описывал один метод - не подходит?

Цитата:
Имхо, прежде чем пользоваться SEND, не мешало бы переключить клавиатуру.
АвтоИту все равно какая в данный момент раскладка - функция Send тупо посылает указанные символы. Единственная загвоздка возникает при висящих в памяти автопереключателях раскладки (Punto Switcher, Keyboard Ninja и т.п.) - но это опять-таки не вина АвтоИт-а, а юзера, забывшего закрыть процесс подобного приложения перед применением ф-ции Send.

asdfghjk 22-12-2005 05:19

Спасибо за ответ. Вышеописанный метод я действительно не заметил. Однако,
Цитата:
функция Send тупо посылает указанные символы
Очевидно, у меня она наделена интеллектом.(В отличии от меня). Подобный код выдает русские сообщения в другой кодировке:
Код:
Run("notepad.exe") WinWaitActive("Безымянный - Блокнот") ;Run("regedit /s en.reg") Send("This is some text.", 1) Send("{Enter}") ;Run("regedit /s ru.reg") Send("Это текст на русском.") Send("Это текст на русском.", 1)

Если запустить из-под русской раскладки, наоборот, латиницу неправильно отображает. Скрипт сохраняю в ANSI-кодировке. У кого-то правильно работает?
Закомментированные reg-файлы (переключение клавиатуры, как ты рекомендовал) не отрабатывают ни в скрипте, ни при запуске руками (точнее, отрабатывают: реестр правят, но на раскладку это не влияет). WinXP RUS SP2. Никаких автопереключателей клавиатуры нет.

Sanja Alone 22-12-2005 18:15

asdfghjk
Цитата:
Скрипт сохраняю в ANSI-кодировке
Она же Win1251 (CP1251) - это правильно.

Цитата:
Run("regedit /s en.reg")

1. Любой импорт данных в реестр нужно делать при пом. ф-ции RunWait - т.е. нужно дождаться окончания операции импорта. Ф-ция Run просто запускает приложение/команду, указанную ей в кач-ве аргумента и (не дожидаясь завершения) скрипт идет дальше.
2. Ты не до конца понял описанный мной метод. Импортируя в реестр вышеуказанные ключи, ты просто включаешь возможность переключения на разные языки с пом. разных комбинаций клавиш. Но ведь для самого переключения нужно еще сделать Send('^+1') /Send('^+2')/, а не просто импортировать reg-файлик :)


Похоже я нашел причину твоих проблем - это Блокнот.
В Блокноте должен быть указан шрифт с кириллическим набором символов (а по ум. там Terminal - без такового). Вот нужная ветка реестра:
Код:
[HKEY_CURRENT_USER\Software\Microsoft\Notepad] ;набор символов (00000000 - западноевропейский, 000000cc - кириллический) "lfCharSet"=dword:000000cc ;шрифт (обязательно с кириллическим набором, иначе будут кракозяблы). ;Примеры шрифтов с кириллическим набором символов: Arial, Times New Roman, Tahoma, Lucida Console. "lfFaceName"="Tahoma"


P.S. Ты бы не извращался с импортом reg-файликов, а юзал ф-ции АвтоИта: RegWrite/RegDelete (лишние reg-файлы неудобны в подобных ситуациях). Если лень переводить reg в АвтоИт - можешь воспользоваться моим конвертером crta.

asdfghjk 23-12-2005 18:14

Sanja Alone
Да, протупил я насчет Send('^+1'). Сейчас работает, только вместо точки "ю" вставляет.
Собственно, меня сей вопрос интересует только из любви к искусству. Практической необходимости в нем нет.
Хотелось бы все-таки уточнить, у кого-нибудь она (функция Send) просто "тупо посылает указанные символы "? Безо всяких раскладок клавиатуры.
Свой Блокнот я проверил - вышеописаные ключи соответствуют.

Sanja Alone 24-12-2005 01:54

asdfghjk
Цитата:
у кого-нибудь она (функция Send) просто "тупо посылает указанные символы "?
У меня.
Для примера возьмем твой код:
Код:
Run("notepad.exe") WinWaitActive("Безымянный - Блокнот") Send("This is some text.") Send("{Enter}") Send("This is some text.", 1) Send("{Enter}") Send("Это текст на русском.") Send("{Enter}") Send("Это текст на русском.", 1)
Результат можешь посмотреть здесь


Я решил написать это в форуме, т.к. от подобной проблемы не застрахован никто. Дело в том, что на моей рабочей машине стоит WinXP SP1. Я проверил скрипт на VMWare с установленной WinXP SP2 - н-рые кириллические символы заменились кракозяблами. Логически поразмыслив о возможной причине подобного казуса, я пришел к выводу, что все дело в настройках кодовой страницы в самой Винде. Короче говоря, идем по многократно описанному в свете борьбы с кракозяблами пути, и смотрим, чтобы там было такое:
Код:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage] "1250"="c_1251.nls" "1251"="c_1251.nls" "1252"="c_1251.nls" "1253"="c_1251.nls" "1254"="c_1251.nls"
ВАЖНЫЙ момент! Буковки "c" должны быть в нижнем регистре ("c_1251.nls"). А у меня там были большие "C" ("C_1251.nls"). На SP1 это не влияло на ситуацию, а на SP2 стало причиной неправильного отображения н-рых (но не всех) кириллических символов в Блокноте - в других программах подобной зависимости на выявлено.

bogomolv 28-12-2005 16:53

Sanja Alone

Саша, по поводу [HKLM\SYSTEM\CurrentControlSet\Control\Nls\CodePage] могу лишь процитировать очень уважаемого специалиста, советы которого ни разу не оказались сомнительными: http://forum.ixbt.com/topic.cgi?id=22:29304:2488#2488.

Добавлено, спустя 1 мин.
Извиняюсь за прямую ссылку. Посмотри ее копи-пастом...

Sanja Alone 28-12-2005 22:40

bogomolv
Все это понятно, но какая есть альтернатива? К тому же, я не собираюсь смотреть немецкие/японские/китайские и т.п. сайты, а видеть меню того же Алкоголя мне приятнее на русском (а не каракулями или знаками вопроса) :)

Из описанных в приведеной тобой теме форума способов решения проблем "кракозяблов" значатся (насколько я понял):
  1. Cекция [RegionalSettings] файла winnt.sif. Тут у меня итак все выставлено правильно (ес-но, если оно реально применяется, а не игнорируется, как сказано здесь);
  2. Ветка HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes (а если посмотреть ту же статью, так это вообще составляющая часть первого способа);
  3. Ветка HKLM\SYSTEM\CurrentControlSet\Control\Nls\CodePage (тот самый, неправильный способ; часто применяется совместно с пунком 2).
Какой способ является подходящим по твоему мнению?

Vadikan 28-12-2005 23:45

Sanja Alone
Я у себя (XP EN) только 1251="c_1251.nls" выставляю, а шрифты даже не импортирую :) Ну и regopts.txt применяю, чтоб не дергаться. У меня, впрочем, очень мало русского софта, а при наличии двух языков я выберу английский. Остальные кодовые страницы были внесены в статью по причине "стандартности" решения и его многократном тиражировании на страницах форума. О побочных эффектах мне известно, как-то Павел Городянский упоминал на страницах форума (его сайт http://ourworld.compuserve.com/homepages/PaulGor/ ), но в реальности, люди которые хотят избежать проблем с отображением кириллицы, могут никогда и не столкнуться с некорректным отображением других языков :)

spol81 29-12-2005 03:20

Возможно ли сделать так, что бы весь процесс установки программы был невидим?

bogomolv 29-12-2005 06:46

Sanja Alone
Там описан еще один способ. Его и использую.
Код:
===== файл unattend.txt ======== [Shell] DefaultStartPanelOff=Yes CustomDefaultThemeFile="C:\WINDOWS\Resources\Themes\Windows Classic.theme"

Проблем нет.

Sanja Alone 29-12-2005 20:04

Vadikan
Цитата:
люди которые хотят избежать проблем с отображением кириллицы, могут никогда и не столкнуться с некорректным отображением других языков
Закончу твою фразу: ...потому, что не пользуются этими языками. Собс-но, весь сыр-бор по поводу правильности был затеян "из прЫнцыпа". Ладно, не буду продолжать, т.к. это уже явно не про АвтоИт :)


spol81
Цитата:
Возможно ли сделать так

Ответ на твой вопрос краток: Да. Но нужно бы конкретизировать задачу: какого именно приложения? Не у всех ведь есть ключи тихой установки (точнее, не все ими дают пользоваться). Для начала определи какой инсталлятор исп-ся в этом приложении, затем прочитай статью Типы инсталляторов. А уже потом обращайся к АвтоИту.


bogomolv
Цитата:
Там описан еще один способ

Угу, но я не посчитал его серьезным - нужно будет попробовать. Только потом придется привести все к более удобному виду ("Пуск" в 2 колонки):
Код:
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer] "ShellState"=hex:24,00,00,00,33,a0,01,00,00,00,00,00,00,00,00,00,00,00,00,00,\ 01,00,00,00,0d,00,00,00,00,00,00,00,03,00,00,00
На какой стадии применять этот твик, чтобы не превратить новоявленный правильный метод в новый вариант неправильного?

bogomolv 30-12-2005 01:25

Sanja Alone

В моем unattend.txt стоит вообще-то CustomDefaultThemeFile="C:\WINDOWS\Resources\Themes\Моя тема.theme".
Так что, скорее всего, "приводить что-либо к более удобному виду не приходится...

Zhiberya 02-01-2006 21:42

Здравствуйте!
У меня вопрос общего характера, пишу на autoit'е небольшой авторан, с возможностью выбора простой или тихой установки. Хочу вставить в него красивый прогресс бар.
Посмотрел в хелпе, есть 2 функции одна- GUICtrlCreateProgress(рисует сам прогресс бар), другая- GUICtrlSetData(задает значение в процентах прогрессбару). К чему привязать ход процесса в прогресс баре? К месту на жестком диске, не есть гуд, т.к. у меня ntfs и она сразу выделяет место под весь файл. К чему можно еще привязать прогресс бар??

Astarot 06-01-2006 05:28

Пытался сейчас установить Alcohol 120%, но при запуске установки появляется окошко с ошибкой там написано
RunWait ( @ScriptDir&'\'&$file & ' /qn REBOOT=Suppress' )
Error: Unable to execute the external program.

Потом пытался поставить Outpost, но там подобная ошибка в этом месте Run ( @ScriptDir&'\'&$file )

Что я делаю не правильно?

Astarot 06-01-2006 05:50

Всё сам разобрался ;) Просто не заметил что там название файла переменной присваивается.

a-v-g-u-r 06-01-2006 07:51

Возникла следующая проблема:
требуется установить программу в папку, которая находится на том же диске, что и Windows.

Вопрос:
Существует ли какая-нибудь переменная окружения, в которой бы хранилось имя диска, на котором Винда установлена (что-нибудь по аналогии с @ScriptDir или @WindowsDir)? Может есть способ выдрать эту букву из какой-то из этих переменных.

Если вопрос покажется дебильным извиняйте, AutoIt'ом пользуюсь второй день

DmitryOlenin 06-01-2006 08:03

bogomolv
Цитата:
===== файл unattend.txt ========
[Shell]
DefaultStartPanelOff=Yes
CustomDefaultThemeFile="C:\WINDOWS\Resources\Themes\Windows Classic.theme"


Вот только что попробовал такой способ (описанный еще ув. Vadikan).
Получилось... Но только при обычной установке. При установке с помощью WPI тема вроде как есть, но не применяется.
То есть в свойствах экрана стоит имя моего файла, но, при этом, тема стоит дефолтная(даже не дефолтная XP, а просто классическая, "необьемная").
Если выбрать ту же тему еще раз и нажать применить - все встает на свои места.

Что это и как побороть я пока не пойму. Может можно какой-то скрипт красивый сделать, чтобы вот так щелкать не приходилось?

specialist 06-01-2006 09:52

DmitryOlenin
нужно еще использовать модифицированный файл uxtheme.dll
воспользуйся поиском и никакие авто скрипты тут не нужны, все ставится само собой должно. у меня работает.

DmitryOlenin 06-01-2006 12:17

specialist
Я пользовался поиском. Естественно я использую модифицированный uxtheme.dll.
Хотя дело не в этом файле.
Во-первых, я написал, что при обычной установке(без WPI) тема прекрасно ставится.
Во-вторых, все изменение темы заключается в фоновой картинке(которая, кстати, другим путем уже прописана) и, главное, в измененных курсорах.

Sanja Alone 06-01-2006 18:22

a-v-g-u-r
Цитата:
в которой бы хранилось имя диска, на котором Винда установлена


Вот тебе два варианта:
  1. @HomeDrive - Drive letter of drive containing current user's home directory.
  2. EnvGet("SYSTEMDRIVE") - более надежный способ, т.к. "current user's home directory" может быть и не на диске с Виндой.

bogomolv 10-01-2006 10:39

DmitryOlenin
Цитата:
Получилось... Но только при обычной установке. При установке с помощью WPI тема вроде как есть, но не применяется.
А что такое - установке с помощью WPI?
Цитата:
Может можно какой-то скрипт красивый сделать...?
Так и делал раньше. Но что красивого в таком скрипте?

All
Что-то давно не было обновлений AutoIt!
Имевшаяся у меня версия v3.1.1 не позволила красиво реализовать одну функцию графического интерфейса. Полез за обновлениями. Новых официальных версий - нет. В "бетках" последней числится v3.1.1.100. Ее и взял.
Сразу нашел новый стиль $LVS_EX_CHECKBOXES для функции GUICtrlCreateListView , реализующий то, что меня интересовало. Но пост о другом - о том, что, скорее всего, ждет нас в новом релизе:
Новых функций мало. В основном фиксы, уточнения и новые возможности функций графического интерфейса и работы с внешними библиотеками и объектами.
Удивило, что при этом AutoIt3.exe "разросся" в объеме почти в полтора раза. И самое главное - авторы вновь (на моей памяти это происходит уже второй раз) изменили логику сравнений TRUE/FALSE. В итоге сразу перестали работать два моих скрипта. Придется проводить ревизию всей своей коллекции... :(
Нашелся и забавный глючок: если оператор #ce стоит в последней строке файла и не отбит "концом строки", это приводит последнюю бету в жуткое замешательство, и скрипт не стартует секунд 30-40, потом все работает, как надо.

DmitryOlenin 11-01-2006 15:20

bogomolv
Цитата:
А что такое - установке с помощью WPI?

Это установка, в которой используется WPI. То есть программы можно выбирать. Об этой программе можно почитать например на ээтом же сайте и форуме.
Цитата:
Так и делал раньше. Но что красивого в таком скрипте?

А он остался? Я бы с радостью воспользовался.

Sanja Alone 11-01-2006 18:05

Добавил скрипт
DaemonScript 1.6.0

bogomolv
Цитата:
А что такое - установке с помощью WPI?
WPI - прога для выбора устанавливаемых приложений (написана на JavaScript)
Вопросы по WPI
Выбор устанавливаемых приложений

Цитата:
изменили логику сравнений TRUE/FALSE
Конкретизируй.

bogomolv 11-01-2006 18:21

DmitryOlenin
Код:
Run('rundll32 shell32, Control_RunDLL desk.cpl,,') WinWaitActive ('Свойства: Экран','Темы') ControlCommand ('Свойства: Экран','Темы', 'ComboBox1', 'SelectString', 'Моя тема') ControlClick ('Свойства: Экран','Темы', 'Button5') WinClose ('Свойства: Экран','Темы')

Цитата:
Об этой программе можно почитать
Да, вспомнил. Что-то такое встречалось. Но зачем она тем, кто дружит с AutoIt?
Пропиши в CMDLINES.TXT заветную строчку и подложи к CMDLINES.TXT два файлика. И задавай установку дров и программ, каких хочешь, на какой хочешь стадии и с какой тебе нужно логикой ...
Код:
=========CMDLINES.TXT============== [Commands] "AutoIt3.exe .\cmdlines.au3" ==========CMDLINES.AU3============== FileCreateShortcut('@ScriptDir@\startup.au3','@StartupDir@\startup.lnk') ==========STARTUP.AU3============== FileDelete ('@StartupDir@\startup.lnk')

bogomolv 11-01-2006 18:26

Sanja Alone
Цитата:
Конкретизируй.

Я обломался на $srch=FileFindFirstFile().... If $srch=...
Таких изменений не одно. Скачай AutoIt3.chm и посмотри History.

Sanja Alone 12-01-2006 17:36

Добавил скрипты
Avenger 1.0.5.9
Unlocker 1.7.7

bogomolv
Цитата:
Но зачем она тем, кто дружит с AutoIt?
Приложения лучше устанавливать имея возможность выбора, и наиболее удобный, imho, для этого способ - проставление "галочек", что и реализовано в WPI. К тому же, в последней версии введена поддержка конфиглистов (упрощенно говоря - это разные default-конфигурации). Выбрал, например "Home" - проставились все свои любимые проги, а "Office" - только необходимые и т.д. А в моей ситуации, когда приложения находятся на отдельном DVD, вариант cmdlines.txt исключен по определению.

bogomolv 12-01-2006 18:25

Sanja Alone
Ключевое слово твоего поста - "любимые". В числе любимых прог, видно, оказалась и WPI. Против этого чувства бессисльны все доводы...
И только от нечего делать попридираюсь :)
1) $LVS_EX_CHECKBOXES для функции GUICtrlCreateListView в AutoIt как раз отвечает за галочки в списках;
2) какое такое определение исключает в приведенном мной варианте cmdlines.txt возможность его применения, когда приложения находятся на отдельном DVD?




Sanja Alone 13-01-2006 21:05

bogomolv
Цитата:
Против этого чувства бессисльны все доводы...
Ты не прав. Я не прочь попробовать (и пробовал) и другие проги аналогичного назначения, конечно, если они будут для меня столь же удобны в настройке (прямое редактирование конфига, а не кривенький gui) и использовании. А из описанных в статье Vadikan-а, меня вполне устаивает WPI.
В желании приукрасить свой мультибутовый DVD с Виндами, я даже намеревался перейти от консольного bcdw к gui-шному EasyBoot, но неудобсто его настройки (нет прямого редактирования конфиг-файла) и невозможность выбора разных шрифтов (хотя бы для пункта меню и его описания) мне не понравились (конечно, можно к фоновой картинке "пририсовать" описания другим шрифтом, но это лишняя морока).

Цитата:
1) $LVS_EX_CHECKBOXES
:beta: в 3.1.1 этого нет; когда будет в новой финальной версии - посмотрим...
Цитата:
2) какое такое определение исключает
отсутствие этого самого cmdlines.txt на диске с софтом :) Хотя, ес-но, можно сделать запуск и через стандартный autorun.inf (как у меня сейчас стартует WPI).

:biggrin: Ну нет у меня желания ваять свой Гуи (то, что это несложно ты и сам знаешь) на АвтоИт-е, имея подходящую (ПОКА !) прогу для интересующих меня задач. Другими словами, я не хочу "изобретать велосипед", даже не взирая на то, что он и не идеален...

Если у тебя есть время и желание переплюнуть javascript-овый WPI на АвтоИте - дерзай. Если прога выйдет лучше (возможности АвтоИт-а всецело этому способствуют) и ты представишь ее на суд общественности, а не сделаешь только для себя, то я буду первым, кто перейдет с WPI на твой вариант.

bogomolv 14-01-2006 03:04

Sanja Alone
Цитата:
и ты представишь ее на суд общественности, а не сделаешь только для себя, то я буду первым, кто перейдет с WPI на твой вариант

Нет, Саш, исходный посыл был совсем иным - не надо ни на что переходить, если есть AutoIt! Типа, нам не нужны чужие глюки, нам своих хватает. :)
Цитата:
$LVS_EX_CHECKBOXES - в 3.1.1 этого нет

В 3.1.1 есть $TVS_CHECKBOXES для GUICtrlCreateTreeView. Ей и пользовался. А GUICtrlCreateListView ближе по назначению к решавшейся задаче. Соответственно, код получается "красивше".

kovdaev 16-01-2006 06:12

Не судите строго помогите с скриптом
Вызываем "Свойства папки"
Вкладка "Вид"
Проверка вкладок стоит ли отметка в определенных позициях.

Заранее спасибо.

bogomolv 16-01-2006 19:39

kovdaev
Замени в скрипте, предложенном тебе Sanja Alone в http://forum.oszone.net/showpost.php?p=384015&postcount=260,
Run ('RunDll32.exe shell32.dll,Options_RunDLL 1') на Run ('RunDll32.exe shell32.dll,Options_RunDLL 0').
$Title у окошек сам догадаешься поменять или тоже "не судить тебя строго"? :)

kovdaev 17-01-2006 00:11

Спасибо.

Facet 17-01-2006 16:20

Вопрос к уважаемым специалистам от AutoIt:
"Тихая" установка Punto Switcher 2.9. (Специально взял себе попроще для начала)
-------------------------------------------------
If WinExists(@ScriptName) Then Exit

AutoItSetOption("TrayIconHide", 1)

BlockInput (1)

Run( "setup_ps29.exe")

WinWait("Установка")

If WinActive("Установка")=0 Then
WinActivate ( "Установка" )
EndIf

WinWaitActive("Установка")

ControlClick("Установка", "Готово", "Button3")

BlockInput (0)
-------------------------------------------------

ControlClick("Установка", "Готово", "Button3") - не работает. "Нажатие" батона не происходит.
Хотя посылка send("{ENTER}") вместо - "ControlClick" отрабатывает нормально, но не всегда же пользоваться
ENTERом. Мануал вроде полистал - выглядит типа всё нормально. В чём дело не пойму, может кто подскажет?
Меня тоже "Не судите строго".

Sanja Alone 17-01-2006 18:43

kovdaev
Цитата:
Вызываем "Свойства папки" Вкладка "Вид"
Как вызвать тебе уже сказал Сергей; переключение между вкладками - Send('^{TAB}')Но проверить состояние галок на закладке "Вид" не получится, т.к. они находятся внутри эл-та SysTreeView - нынешний АвтоИт не умеет проверять состояние/устанавливать пункты такого эл-та управления (ф-ция ControlCommand() не умеет с ним работать).

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


Facet
Цитата:
If WinExists(@ScriptName) Then Exit
Это строка в одиночку лишена смысла, т.к. окно АвтоИта по ум. имеет заголовок не @ScriptName, а "AutoIt <номер версии АвтоИта>" (afair). Нужно обязательно дописать и вторую строку AutoItWinSetTitle(@ScriptName) - изменение заголовка на имя стартовавшего скрипта. Логика здесь проста - если скрипт уже запущен и его невидимое окно "сидит" в памяти, то вторая строка, ес-но, была выполнена, а значит это окно имеет заголовок @ScriptName. След-но, при повторном запуске того же скрипта, условие в первой строке будет истиной и приведет к выходу из копии скрипта, давая возм-ть нормально отработать первому экземпляру.

Цитата:
В чём дело не пойму, может кто подскажет?
  1. эл-т управления ("Button3") может быть скрытым;
  2. имя эл-та управления может изменяться от запуска к запуску инталлятора (скажем, был "Button3", а в след раз стал "Button2");
  3. ф-ция ControlClick() тоже не во всех случаях помогает даже если первые два пункта и не имеют места быть.
Короче говоря, используй Send("{ENTER}") и не забивай себе зря мозги - тем более, что применив ф-цию WinWaitActive() до посыла Enter-а, ты можешь быть уверен в активности окна.

bogomolv 17-01-2006 19:46

Facet
Punto Switcher можно установить еще "тише":
1) скопировать каталог с установленной программой;
2) воспроизвести сохраненные (со всеми нужными настройками) ветки реестра:
HKEY_CURRENT_USER\Software\Punto Switcher\2.8
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Management\ARPCache\Punto Switcher 2.8
HKEY_LOCAL_MACHINE\SOFTWARE\Punto Switcher\2.8
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Punto Switcher 2.8

В твоей версии Punto Switcher в конце приведенных веток реестра, очевидно, будет значиться версия 2.9.
Автозапуск Punto Switcher прячется в
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run

kovdaev 18-01-2006 04:11

Спасибо за пояснения Sanja Alone .
Я как раз на этом и застрял при проверке стоит галочка или нет,
уже хотел просить совета.
Но все равно спасибо. Возможно в дальнейшем разработчик добавит данную функцию в свою программу.

bogomolv 18-01-2006 11:20

kovdaev
Выходит, я зря ехидничал?
Тогда в порядке извинения:
Код:
$hkey='HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced' If RegRead($hkey,"NoNetCrawling")='0' Then msgbox(0,'','Задан "Автоматический поиск сетевых папок и принтеров"') Else msgbox(0,'','"Автоматический поиск сетевых папок и принтеров" не задан') EndIf Exit #cs [HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;Автоматический поиск сетевых папок и принтеров "NoNetCrawling"=dword:00000001 ;НЕ Автоматический поиск сетевых папок и принтеров "NoNetCrawling"=dword:00000000 [HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;Восстанавливать прежние окна папок при входе в систему "PersistBrowsers"=dword:00000001 ;НЕ Восстанавливать прежние окна папок при входе в систему "PersistBrowsers"=dword:00000000 [HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\CabinetState] ;Выводить полный путь в панели адреса "FullPathAddress"=dword:00000001 ;НЕ Выводить полный путь в панели адреса "FullPathAddress"=dword:00000000 [HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\CabinetState] ;Выводить полный путь в строке заголовка "FullPath"=dword:00000001 ;НЕ Выводить полный путь в строке заголовка "FullPath"=dword:00000000 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa] ;Использовать простой общий доступ к Файлам (рекомендуется) "forceguest"=dword:00000001 ;НЕ Использовать простой общий доступ к Файлам (рекомендуется) "forceguest"=dword:00000000 [HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;Не кзшировать эскизы "DisableThumbnailCache"=dword:00000001 ;НЕ "Не кзшировать эскизы" "DisableThumbnailCache"=dword:00000000 [HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;Открывать каждую папку в отдельном окне "SeparateProcess"=dword:00000001 ;НЕ Открывать каждую папку в отдельном окне "SeparateProcess"=dword:00000000 [HKСU\Software\Microsoft\Windows\CurrentVersion\Explorer\HideMyComputerIcons] ;Отображать "Панель управления" в папке "Мой компьютер" "{21EC2020-3AEA-1069-A2DD-08002B30309D}"=dword:00000000 ;НЕ Отображать "Панель управления" в папке "Мой компьютер" "{21EC2020-3AEA-1069-A2DD-08002B30309D}"=dword:00000001 [HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;Отображать описание для папок и элементов рабочего стола "ShowInfoTip"=dword:00000001 ;НЕ Отображать описание для папок и элементов рабочего стола "ShowInfoTip"=dword:00000000 [HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;Отображать простой вид папок в списке папок "Проводника" "FriendlyTree"=dword:00000001 ;НЕ Отображать простой вид папок в списке папок "Проводника" "FriendlyTree"=dword:00000000 [HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;Отображать сведения о размере Файлов в подсказках папок "FolderContentsInfoTip"=dword:00000001 ;НЕ Отображать сведения о размере Файлов в подсказках папок "FolderContentsInfoTip"=dword:00000000 [HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;Отображать сжатые или зашифрованные Файлы NTF5 другим цветом "ShowCompColor"=dword:00000001 ;НЕ Отображать сжатые или зашифрованные Файлы NTF5 другим цветом "ShowCompColor"=dword:00000000 [HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;Отображать содержимое системных папок "WebViewBarricade"=dword:00000001 ;НЕ Отображать содержимое системных папок "WebViewBarricade"=dword:00000000 [HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;Помнить параметры отображения каждой папки "ClassicViewState"=dword:00000000 ;НЕ Помнить параметры отображения каждой папки "ClassicViewState"=dword:00000001 [HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;Скрывать защищенные системные Файлы (рекомендуется) "ShowSuperHidden"=dword:00000000 ;НЕ Скрывать защищенные системные Файлы (рекомендуется) "ShowSuperHidden"=dword:00000001 [HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;Скрывать расширения для зарегистрированных типов Файлов "HideFileExt"=dword:00000001 ;НЕ Скрывать расширения для зарегистрированных типов Файлов "HideFileExt"=dword:00000000 [HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;Не показывать скрытые Файлы и папки "Hidden"=dword:00000002 ;Показывать скрытые Файлы и папки "Hidden"=dword:00000001 [HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer] ;Показывать и обрабатывать пару как единый файл "NoFileFolderConnection"=dword:00000000 ;Показывать обе части и обрабатывать их отдельно "NoFileFolderConnection"=dword:00000001 ;Показывать обе части, но обрабатывать их как единый Файл "NoFileFolderConnection"=dword:00000002 #ce

Но, может, все-таки лучше задавать эти параметры напрямую через реестр?

kovdaev 18-01-2006 12:58

Сегодня вечером попробовал все работает.
Можно еще один вопрос по скрипту drweb?
Сам вопрос:
Если разрешение экрана самое низкое 800х640, стандартный драйвер windows, часть кнопок за пределами экрана и скрипт не работает, не приятно однако:
сам скрипт:

#cs
----------------------
Приложение: Dr.Web
На какой(их) версии(ях) тестировалось: 4.33

Автор скрипта: Sanja Alone (http://forum.oszone.net/member.php?userid=28800)
----------------------
#ce
;предотвращение возможности множественного запуска скрипта
If WinExists(@ScriptName) Then Exit
AutoItWinSetTitle(@ScriptName)
;скрыть в системной панели индикатор AutoIt
;AutoItSetOption("TrayIconHide",1)
;Отображать текущую строку сценария с помощью индикатора системной панели в режиме отладки.
AutoItSetOption("TrayIconDebug", 1)
If ProcessExists ( "ps.exe" )<>0 Then
ProcessClose ( "ps.exe" )
ProcessWaitClose ( "ps.exe" )
EndIf
;нельзя блокировать при находящемся в памяти Punto Switcher-е - не будет работать установка
;блокируем мышь и клаву
;If @OSType="WIN32_NT" Then BlockInput ( 1 )
#cs
----------------------
объявление переменных
----------------------

$Title - заголовок окна установки
$file - установочный файл
$programgroup - в какую программную группу положить ярлыки программы
$validkey - Легальный ключевой файл (положите его в любой подкаталог текущего, по ум это validkey)

Для регистрации программы нужно положить файл drweb32.key в каталог из к-рого запускается установка,
тогда файл-ключ будет скопирован в каталог DrWeb-а и программа будет зарегистрирована (если ключ подойдет).
Это в идеале, но т.к. тихая установка в версии 4.33 не работает, и при обычной установке с правильным key-файлой
запускается антивирусная проверка (к-рую нельзя отменить), то лучше положить в установочный каталог невалидный ключ, а
"правильный" скопировать в каталог установленного DRWeb-а уже после завершения инсталляции.

Файл setup.iss внутри этого архива - для версии 4.32b.
Я дополнительно вложил в архив еще и setup.iss для 4.33 - может у кого-то, как-то получится заставить заработать тихую установку и для этой версии.
----------------------
#ce
Global $Title='Установка Dr.Web', $file='drweb-433-win-ru.exe', $programgroup='Антивирусы\Dr.Web', $validkey=@ScriptDir & '\validkey\drweb32.key'
Run ( @ScriptDir&'\'&$file )
WinWaitActive ( 'Dr.Web - InstallShield Wizard' )
Send("{ENTER}")
WinWait ( $Title, 'Вас приветствует программа' )
WinActivate ( $Title, 'Вас приветствует программа' )
WinWaitActive ( $Title, 'Вас приветствует программа' )
Send("{ENTER}")
WinWaitActive ( 'Внимание!!!' )
;поставить галку "Да, на компьютере не установлено других антивирусных продуктов."
ControlClick ( 'Внимание!!!', '', 'Button4' )
Send("{ENTER}")
WinWaitActive ( $Title, 'Лицензионное соглашение' )
;выбрать "Я &принимаю условия лицензионного соглашения"
ControlClick ( $Title, 'Лицензионное соглашение', 'Button3' )
Send("{ENTER}")
WinWaitActive ( $Title, 'Выбор папки назначения' )
;по ум. C:\Program Files\DrWeb
$InstPath = ControlGetText ( $Title, 'Выбор папки назначения', 'Static4' )
Send("{ENTER}")
WinWaitActive ( $Title, 'Вид установки' )
;Обычная
Send("{ENTER}")
WinWaitActive ( $Title, 'Выбор папки' )
ControlSetText ( $Title, 'Выбор папки', 'Edit1', $programgroup )
Send("{ENTER}")
WinWaitActive ( $Title, 'Начало копирования файлов' )
Send("{ENTER}")
AutoItSetOption("MouseCoordMode",2)
WinWaitActive ( $Title, 'Настройки прокси сервера' )
MouseClick("left", 639, 472, 1, 0)
;это окно появляется только в сл. неподходящего key-файла
WinWaitActive ( 'Вопрос', 'Не обнаружено коммерческого или демонстрационного ключевого файла' )
ControlClick ( 'Вопрос', 'Не обнаружено коммерческого или демонстрационного ключевого файла', 'Button2' )
;и сразу идет переход к завершению установки
WinWaitActive ( $Title, 'Программа InstallShield Wizard завершена' )
;выбрать "Нет, перезагрузить компьютер позже."
ControlClick ( $Title, 'Программа InstallShield Wizard завершена', 'Button2' )
Send("{ENTER}")
Sleep ( 50 )
RunWait ( @Comspec & ' /C taskkill.exe /F /IM notepad.exe /IM spidernt.exe', '', @SW_HIDE )
;копирование рабочего ключевого файла в каталог антивируса (если файл существует)
If FileExists ( $validkey ) Then FileCopy ( $validkey, $InstPath & '\', 1 )
;копирование дополнений к базе вирусов в каталог DrWeb-а (если они есть)
If FileExists ( @ScriptDir & '\drw?????.vdb' ) Then
FileCopy ( @ScriptDir & '\drw?????.vdb', $InstPath & '\drw?????.vdb', 1 )
FileCopy ( @ScriptDir & '\drw?????.txt', $InstPath & '\drw?????.txt', 1 )
EndIf
;удаление ярлыка с рабочего стола
FileDelete ( @DesktopCommonDir & '\Сканер Dr.Web.lnk' )
ProcessWaitClose ( $file )
;BlockInput ( 0 )

Может автор поправит,
Это я к чему, может еще кому пригодиться.

Заранее спасибо.

Facet 18-01-2006 19:21

bogomolv

Цитата:
Punto Switcher можно установить еще "тише":

Спасибо, но дело не в том, чтобы просто получить "тихий" инсталлятор" Punto Switcher.
Я его попросту перепаковал InnoSetupом вместе со всеми ключами реестра и файлами, а установщик InnoSetup отлично поддерживает "тихие" ключи при инсталляции.
В порядке "освоения" AutoIt хотелось понять из-за чего не работает вроде бы нормальный скрипт.

А за ключи благодарствую - я оказывается
"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Management\ARPCache\Punto Switcher 2.8"
не включил в установщик, сейчас перекомпилирую.

Спасибо, также Sanja Alone. То-то мне показалось, что батоны меняют номера. Значит такое действительно может быть.
И за поправку "If WinExists(@ScriptName) Then Exit".

Sanja Alone 18-01-2006 19:37

kovdaev
Цитата:
Если разрешение экрана самое низкое 800х640
Точнее 800x600. Вот это да, а разве ниже где-то еще бывает :) У меня на VMWare при всех тестах стоит 800x600.

Цитата:
часть кнопок за пределами экрана и скрипт не работает, не приятно однако:
Не работала вот эта ф-ция - MouseClick("left", 639, 472, 1, 0). Я дописал проверку с последующим сдвигом окна - теперь все ОК даже при архаичном 640x480. А если сильно захочется потестить при 320x240 (320x200), то еще больше сдвинь окно (не -200, а -300-400) - но это уже клиника...

Цитата:
сам скрипт:
Приводить здесь листинг не требовалось - это напрасное засорение форума. У меня ведь он и так есть :)

Цитата:
Может автор поправит
Уже.

ANGRO 19-01-2006 12:00

Предлогаю вот такое решение вопроса переключения языка клавиатуры.Основанное на функциях WinAPI.
Работать должно начиная с Win98.
Код:
Opt("WinTitleMatchMode", 4) Run("notepad.exe") Sleep(500) $hWnd = WinGetHandle("classname=Notepad") _SetKeyboardLayout("00000409", $hWnd) Func _SetKeyboardLayout($sLayoutID, $hWnd) Local $WM_INPUTLANGCHANGEREQUEST = 0x50 Local $ret = DllCall("user32.dll", "long", "LoadKeyboardLayout", "str", $sLayoutID, "int", 0) DllCall("user32.dll", "ptr", "SendMessage", "hwnd", $hWnd, _ "int", $WM_INPUTLANGCHANGEREQUEST, _ "int", 1, _ "int", $ret[0]) EndFunc Exit


Дополнительные языки.

Код:
"00000407" Немецкий (стандартный) "00000409" Английский (США) "0000040C" Французский (стандартный) "0000040D" Финский "00000410" Итальянский "00000415" Польский "00000419" Русский "00000422" Украинский "00000423" Белорусский "00000425" Эстонский "00000426" Латвийский "00000427" Литовский

Sanja Alone 23-01-2006 17:10

Внес существенные изменения в свой конвертер crta (ConvRegToAu3)

2006-01-31
  • Добавлен индикатор выполнения (активируется ключом /b или параметром ProgressBar в ini-файле).
2006-01-30
  • Введена возможность исправления ошибок в строковых параметрах содержащих "возврат каретки" внутри (regedit при экспорте таких параметров в reg-файл ошибается) - отменяется ключом /f или параметром FixSZErr в ini-файле.
2006-01-29
  • Ужесточены условия проверок типов - мне они представляются однозначными. Допускается любое к-во символов равно '=' в названиях и в значениях любых параметров.
  • Обрамляются кавычками ветки/параметры в сл. использования команды REG ADD для пустых параметров типа "REG_MULTI_SZ" - сразу недосмотрел. При сложных для конвертации комбинациях символов в названиях таких параметров в рез. файл пишется соотв-щее предупреждение. А в сл. неприменения REG ADD, для данных параметров всегда пишется предупреждение о неправильности рез-та подобной конвертации. (ищите строки, начинающиеся с ;--- WARNING).
  • При невозможности конвертации любого параметра (из поддерживаемых конвертером типов) в результирующий файл пишется соотв-щее сообщение с информацией о номере строки исходного файла явившейся источником проблемы (ищите строки, начинающиеся с ;--- ERROR).
  • Появилась возможность установки приоритета процесса конвертера (ключи /p0 /p1 /p2 /p3 /p4 /p5; параметр Priority в ini-файле).
2006-01-27
  • Значительно (почти в 10 раз!) повышена скорость работы - тестовый файл вместо 4,5 мин. конвертируется около 30 сек.
  • Полностью устранены проблемы с одинарными кавычками в названиях веток, в названиях всех параметров, а также внутри "REG_MULTI_SZ" параметров (') - любое к-во таких символов теперь будет правильно преобразовано в последовательность Chr(39).
  • Введена возможность конфигурирования посредством ini-файла (см. комментарии в файле crta.ini). Ключи командной строки, как и положено, имеют больший приоритет, чем параметры ini-файла.
  • Добавлена возможность импорта в реестр пустых параметров типа "REG_MULTI_SZ" [hex(7):00,00 и hex(7):00] c пом. команды REG ADD. Cам AutoIt не умеет этого делать - все подобные строки превращаются в аналог hex(7):00,00,00. Отменить функцию можно ключом /r - тогда в результирующий файл будет записано предупреждение об ошибке.
  • Игнорирование параметров типа "REG_NONE" [hex(0)].
2006-01-23
  • Исправлена работа с многострочными параметрами типа "REG_MULTI_SZ" (теперь добавляются переносы строк @LF и параметры корректно импортируются в реестр - раньше же все превращалось в одну длинную строку).
  • Дополнено распознавание параметров "REG_BINARY" (hex и hex(3)). Это была не моя ошибка, просто regedit всегда экспортирует параметры типа "REG_BINARY" как hex, а довольно часто используемый мной RegShot (в редакции ParaGlider-а) - как hex(3). Оба варианта правильны.
  • Игнорирование параметров типов "REG_DWORD_BIG_ENDIAN" [hex(5)], "REG_LINK" [hex(6)].
  • Теперь в результирующий файл пишутся строки RegWrite('ветка') только если в reg-файле есть соотв-щая пустая (без параметров и подветок внутри) ветка. Это сделано для оптимизации результирующего autoit-скрипта, путем сокращения лишних действий в оном.
  • Переписан разбор командной строки - ключи теперь независимы, также их можно писать слитно (например: crta in.reg /c/h/d). Добавлен новый ключ /h - копировать в буфер обмена только результат последней конвертации (текущее содержимое результирующего файла пропускается; используйте совместно с ключем /c).
страница загрузки
история изменений

elakt 26-01-2006 00:09

Добрый день ! У меня такая задача:

Есть несколько программ для загрузки прайс-листов разных поставщиков товара. Необходимо последовательно: запустить каждую из них, получить прайс-лист, закрыть программу, запустить следующую. Как я понял, с помощью AutoIt это сделать вполне реально.

Теперь ВОПРОС: можно ли выполнить перечисленные действия так, что бы программы для загрузки прайс-листов запускались НЕВИДИМЫМИ, при условии, что все программы ведут диалог с пользователем (задаются вопросы с вариантами выбора типа "Обновить / Отмена" ???

Если можно, то начну разбираться с AutoIt.
Напишите, пожалуйста, в общих чертах как это сделать, или посоветуйте - где об этом можно почитать.

Спасибо.

lemon76 26-01-2006 06:52

Добрый день!
Нужна помощь профи. Есть программа, управление которой я хочу автоматизировать при помощи AutoIt. Суть проблемы в том, чтобы узнать какого цвета пиксел в данной точке экрана, черный или белый? Есть ли в AutoIt методы "считывания" цвета пиксела в заданной точке?
Заранее спасибо!

Sanja Alone 26-01-2006 21:43

elakt
Цитата:
можно ли выполнить перечисленные действия
Да. Что-то похожее здесь уже спрашивали - вот, что я предложил.
Цитата:
запускались НЕВИДИМЫМИ
См. флаг @SW_HIDE ф-ций Run() и RunWait().
Цитата:
где об этом можно почитать
В файле %ProgramFiles%\AutoIt3\AutoIt.chm.


lemon76
Цитата:
Есть ли в AutoIt методы "считывания" цвета пиксела в заданной точке?
PixelGetColor ( x , y )

elakt 27-01-2006 01:12

Спасибо за ответ! Теперь появились новые вопросы.

1. Запускаем блокнот в невидимом окне:
Run("notepad.exe", "", @SW_HIDE)

2. Далее мне нужно дождаться, когда это окно появится. Среди стандартных команд не нашёл ту, которая дожидалась бы появления НЕВИДИМОГО окна, поэтому использовал команду задержки Sleep, что бы дождаться загрузки блокнота. ВОПРОС: можно ли решить эту задачу иначе?

3. После того, как блокнот загрузился, посылаю ему строку текста:
ControlSend("Безымянный - Блокнот", "", "Edit1", "Send text to notepad")

4. Затем посылаю команду, которая в меню блокнота выбирает пункт "Выход":
WinMenuSelectItem("Безымянный - Блокнот", "", "&Файл", "В&ыход")

5. После этого на экране появляется окно с вопросом "Сохранить изменения? Да/Нет/Отмена" - не смотря на то, что основное окно блокнота невидимо! Ответить на этот вопрос проблем не составляет, но... ВОПРОС: как избежать появления окна с вопросом на экране? То есть что бы оно, как и основное окно, было невидимым? Можно дождаться его появления и "спрятать" командой WinSetState, но в этом случае окно всё равно мелькнет на экране. Как быть?

elakt 27-01-2006 05:35

Еще вопросы:

1. Нужно дозвониться до провайдера, выполнить некоторые действия, разорвать соединение. Это нужно сделать в НЕВИДИМОМ режиме, то есть без отображения окон. Как это можно сделать?

2. Как проверить, есть ли соединение с интернетом?

3. Как проверить, активно ли соединение с заданым именем?

Sanja Alone 28-01-2006 21:08

elakt
Цитата:
как избежать появления окна с вопросом на экране?
WinKill(""). Но мне неясна цель подобных действий. Если тебе нужно просто выдать сообщение, то есть другие вар-ты - банальный MsgBox(). А если ты хочешь незаметно записать что-то в файл, то для этого вообще не нужен Блокнот.

Цитата:
Еще вопросы:

В плане работы с сетью AutoIt пока откровенно беден. Посмотри раздел справки Network Functions
  1. Поискать инфу по ключам звонилки (если они есть).
  2. Макросы @InetGetActive - Is 1 if a InetGet download is currently active, otherwise is 0. @InetGetBytesRead During a InetGet download this is the number of bytes currently read. It is -1 when there is an error downloading. Доступность конкретного хоста - Ping ( address or hostname [, timeout] ).
  3. С таким условием никак.

elakt 30-01-2006 01:25

Sanja Alone
Цитата:
Но мне неясна цель подобных действий.

Есть некая программа для получения прайс-листа и отправки заказа поставщику. Ключи для автоматического получения/отправки эта программа не поддерживает, все операции нужно выполнять нажатием соответствующих кнопок, подтверждать выбор, отвечать на вопросы программы.

Цель - автоматизировать этот процесс. Желательно так, что бы все действия были "невидимы" для пользователя и выполнялись в фоне. Блокнот использовался только для примера.

Если я правильно понял, то можно "спрятать" главное окно программы, но нельзя избежать отображение диалогов программы с пользователем?

__Koval__ 30-01-2006 05:37

как с помощью AutoIt сменить раскладку клавиатуры.
а то столкнулся с такой проблемой:
у меня язык по умолчанию английский стоит, а винда русская,
так вот при написании скрипта управления блокнотом не работают горячии клавиши
т.е. сочетания ALT+,CTRL+ и т.д. с русскими символами пока включена английская раскладка.
Send("{ALT down}")
Send("{ALT up}")
Send("{ф down}")
Send("{ф up}")
вот не работает если не сменить раскладку.

как мне быть?

godoo 30-01-2006 07:53

2All
Помогите разобраться как сделать пренос стороки при использовании функции SplashTextOn:
SplashTextOn("", "Длинный текст", 600, 400, -1, -1, 1, "Comic Sans MS", "14", "500")
Надо принудительно расставить переносы, т.к. автоматически получается некрасиво.


boss911 30-01-2006 08:28

__Koval__

А ты не пробывал править через реестр, расскладку клавиатуры, или я твою проблему не правильно понял!?

__Koval__ 30-01-2006 09:00

boss911Конечно не правильно :)
Не работают комбинации спецклавишь с русскими символами пока раскладка английская.

__Koval__ 30-01-2006 10:23

да и вот еще что не понимаю почему не работает эта команда:
Run("WinRAR.exe", "D:\0NoInstall\WinRar\", @SW_MAXIMIZE)

Sanja Alone 30-01-2006 20:34

elakt
Цитата:
Есть некая программа для получения
Меня не это озадачило. Зачем тебе писать текст в Блокноте при пом. АвтоИта, если можно просто вывести сообщение?
Цитата:
но нельзя избежать отображение диалогов программы с пользователем?
Да, если так была написана та программа.


__Koval__
Цитата:
как с помощью AutoIt сменить раскладку клавиатуры.
Можно так (через реестр) или так (сам я этот метод не проверял).
Цитата:
не работает эта команда:

Второй параметр - это рабочий каталог, а не путь. А в первом параметре указывается полный путь, а не имя экзэшника. Правильно писать так:
Код:
Run("D:\0NoInstall\WinRar\WinRAR.exe", "", @SW_MAXIMIZE) или так: FileChangeDir ( "D:\0NoInstall\WinRar\" ) Run("WinRAR.exe", "", @SW_MAXIMIZE)



godoo
Цитата:
Помогите разобраться как сделать пренос стороки
Также, как и всегда: "Длинный текст" записать в виде 'строка 1' &@LF&'строка 2' &@LF&'строка n'.

Matroskin13 31-01-2006 01:24

Помогите разобраться с установкой PowerDVD.

Написал скрипт:

Код:
run("SETUP.EXE") WinWaitActive ("PowerDVD Setup", "Welcome to the InstallShield Wizard for PowerDVD") ControlClick ("PowerDVD Setup", "&Next >", "Button1",) WinWaitActive ("PowerDVD Setup", "End User License Agreement") ControlClick ("PowerDVD Setup", "&Yes", "Button2",) WinWaitActive ("PowerDVD Setup", "Installing Following Programs") ControlClick ("PowerDVD Setup", "&Next >", "Button1",) WinWaitActive ("PowerDVD Setup", "Installing Following Programs") ControlClick ("PowerDVD Setup", "&Next >", "Button1",) WinWaitActive ("PowerDVD Setup", "Please enter your information") Send("User") Send("{TAB}") Send("Company") Send("{TAB}") Send("MV588995988G2285") ControlClick ("PowerDVD Setup", "&Next >", "Button2",) WinWaitActive ("PowerDVD Setup", "Choose Destination Location") ControlClick ("PowerDVD Setup", "&Next >", "Button1",) WinWaitActive ("PowerDVD Setup", "Select Program Folder") ControlClick ("PowerDVD Setup", "&Next >", "Button2",) WinWaitActive ("PowerDVD Setup", "Please select your default PowerDVD skin") ControlClick ("PowerDVD Setup", "&Next >", "Button2",) WinWaitActive("PowerDVD Setup", "CLPV and CLEV") ControlClick ("PowerDVD Setup", "&Next >", "Button1",) WinWaitActive("PowerDVD Setup", "Yes, I want to register now") Send("{Space}") Send("{TAB}") Send("{Space}") Send("{TAB}") Send("{Space}")


Не понимаю - иногда срабатывает, иногда останавливается на страничке ввода персональных данных и ключа диска.
Помогите!

__Koval__ 31-01-2006 06:13

Sanja Alone
Цитата:
или так (сам я этот метод не проверял).

За то я проверил, все отлично работает. Огромное спасибо.



А можно ли как нибудь по ярлыкам кликать, не используя метод координат?

godoo 31-01-2006 06:44

__Koval__
Попробуй ALT и стрелки. Например у меня так отлично работает:
Send ( '{ALT}' & '{RIGHT}' & '{RIGHT}' & '{RIGHT}' & '{RIGHT}' & '{UP}' & '{ENTER}' & '^+{TAB}' ) - до нужной закладки в меню, а потом ControlClick-ами

Sanja Alone
Огромное спасибо всё получилось!

__Koval__ 31-01-2006 08:32

godoo
так ведь не всегда известно точное положение ярлыка вот в чем фишка.

elakt 01-02-2006 02:10

Sanja Alone
Цитата:
Меня не это озадачило. Зачем тебе писать текст в Блокноте при пом. АвтоИта, если можно просто вывести сообщение?

Блокнот был призван ПРОИЛЛЮСТРИРОВАТЬ проблему, которая возникла в другой программе и не более того :-)

Sanja Alone
Цитата:
Да, если так была написана та программа.

Ценное замечание. Делаю вывод, что не все программы ведут себя подобным образом.

Спасибо Sanja Alone!

Aspirine 01-02-2006 08:42

Пдскажите, можно ли написать такой скрипт, чтобы во время установки программ блокировал клаву, и мог разблокировать только по паролю, или горячим клавишам. А то поставишь сразу нескольким юзверям ставить софт, а они все лезут что-то менять, трогать т.д.

Sanja Alone 01-02-2006 15:01

Matroskin13
Цитата:
иногда срабатывает, иногда останавливается

Очевидно, что Send("{TAB}") иногда просто не успевает перейти к след. эл-ту управления. Решений два:
  1. Увеличить задержку Opt("SendKeyDelay", x) - значение x по ум. равно 5 мс. Поставь, например 20;
  2. Вместо Send()-ов исп-ть ControlSetText ( "title", "text", controlID, "new text" ).


__Koval__
Цитата:
А можно ли как нибудь по ярлыкам кликать
Хоть в этом и нет особого смысла (т.к. ярлык - это ссылка с картинкой), но можно так:
Код:
;каталог с ярлыком $dir=@DesktopDir&'\' ;имя ярлыка $lnk='VMware Workstation' Run(@ComSpec & ' /c start ' & FileGetShortName($dir&$lnk&'.lnk'))
А чем тебе не подходит обычный запуск проги с указанием пути Run('путь\прога.exe')?


Aspirine
Цитата:
Пдскажите, можно ли написать такой скрипт, чтобы во время установки программ блокировал клаву
BlockInput(1)
Цитата:
и мог разблокировать только по паролю, или горячим клавишам
И как ты себе это представляешь при заблокированном вводе :) Снятие блокировки - BlockInput(0)

Aspirine 02-02-2006 06:38

Sanja Alone
Цитата:
И как ты себе это представляешь при заблокированном вводеСнятие блокировки - BlockInput(0)

Виноват, ступил. А мышка блокирутся при BlockInput(1)?
Может можно сдеалть, что бы снималась блокировка после определённого, последовательного нажатия епо кнопкм мыши.



bogomolv 02-02-2006 12:10

Молодежь! :)
Вы не перепутали эту ветку с горячей линией службы поддержки? Вынь-да-положь им решение!
Я о "А мышка блокирутся при BlockInput(1)?" и пр.
А слабо проверить? Это займет меньше времени, чем написание поста!

All
Страсть, как хочется похвалиться! :)
Часто нужный параметр прячется в реестре по "адресу", содержащему ID железки или пользователя, ключ безопасности и пр. Для таких случаев в AutoIt есть оператор RegEnumKey(). Однако при этом нужно выстраивать циклы, делать проверки и т.д.
Нашел красивое решение подбной задачи, когда мне нужно на стадии CMDLINES узнать будущее разрешение экрана устанавливаемой Windows.
Код:
If RunWait('@ComSpec@ /C reg query "HKLM\SYSTEM\CurrentControlSet\Control\DeviceClasses" /s | find "DefaultSettings.XResolution" | find "500"','',0)=0 Then $screen=1280 ElseIf RunWait('@ComSpec@ /C reg query "HKLM\SYSTEM\CurrentControlSet\Control\DeviceClasses" /s | find "DefaultSettings.XResolution" | find "400"','',0)=0 Then $screen=1024 Else $screen=800 EndIf

Cherepan 02-02-2006 17:11

Прастите чайника :sorry: (тем более, что не в тему - ну не нашел я тему :-) )

Нада вставить путь из переменной "$path") в поле Edit
Делаю примерно так:
Код:
ControlFocus ( "title", "text", "Edit") ControlSend ( "title", "text", "Edit", $path)


В результате в поле вставляется какая-то лабуда типа "C:\Ё ЁigЁiЁ FiЁEs\ЁiЁi ЁiFTWAE\ЁEEFAЁ Ё ЁiFEЁiЁEAL" :blink:

VelDmi 02-02-2006 22:56

Cherepan
Такая лабуда обычно получается, если включена не та раскладка клавиатуры. Например в винде стоит русский, а писать пытаешься по английски.

Cherepan 03-02-2006 09:07

VelDmi
Ага... Нада попробовать. Пасиба.
Сразу выскакивает другой ворос - как определить, какими кнопками переключает юзер раскладку?
Или как сменить раскладку средствами AutoIt?

Sanja Alone 03-02-2006 18:30

Cherepan
Цитата:
Сразу выскакивает другой ворос - как определить, какими кнопками переключает юзер раскладку?
Или как сменить раскладку средствами AutoIt?
Посмотри это и это сообщения.

Cherepan 04-02-2006 04:04

Sanja Alone
Пасибки, работает.
VelDmi
После переключения раскладки еще интересней:
C^\~ ~ig~i~ Fi~Es\~i~i ~iFTWAE\~EEFA~ ~ ~iFE~i~EAL

Send() не хочет нормально работать с латиницей в любой раскладке. С кириллицей проблем нет.

Scratch56 04-02-2006 06:30

Cherepan А случаем не в Виртуальном писюке Send() делаешь? У меня такое в Виртуальном, а в обычном - нормально.

Cherepan 04-02-2006 06:44

Scratch56
Не, в винде XP SP2 RUS

Cherepan 04-02-2006 08:58

Еще одна интересная особенность - этот глюк не во всех окнах. В некторых все прокатывает на ура.

Dirk Diggler 10-02-2006 11:47

Можно ли с помощью AutoIt выбрать каталог? Хочу нацарапать оболочку, которая мне будет конфиги для nnBackup писать, дык выбрать каталог для бэкапа пока только вручную получается... Нельзя ли как-нть вывалить стандартный диалог по выбору файлов-папок, и получить из него результат действий пользователей?

Dirk Diggler 10-02-2006 13:16

А также вопрос про - как перебрать все элементы контрола типа List, для проверки, совпадает ли новый его элемент с уже существующими?

Sanja Alone 11-02-2006 03:22

Dirk Diggler
Цитата:

вывалить стандартный диалог по выбору файлов-папок
FileOpenDialog ( "title", "init dir", "filter" [, options [, "default name"]] )
Цитата:

как перебрать все элементы контрола типа List
См. в сторону ControlCommand ( "title", "text", controlID, "command", "option" ), ControlListView ( "title", "text", controlID, "command" [, option1 [, option2]] )

amel27 12-02-2006 13:04

Это не вопрос, но грабли... Вот два способа вызова одного скрипта - откомпилированного в EXE и нет:
Код:

script.au3 "%ALLUSERSPROFILE%\Desktop"
Код:

script.exe "%ALLUSERSPROFILE%\Desktop"
Первый восстанавливает переменную окружения ALLUSERSPROFILE нормально, а вот второй нет...

Вывод: используем откомпилированные скрипты (принимающие параметры) только из CMD-файлов!

forumuser 13-02-2006 14:27

Переключение раскладки клавиатуры.
 
Может кому-то понадобиться, потому что я не сразу додумался как это сделать :)
Понадобилось мне как-то переключить раскладку во время установки программы. Первое что пришло в голову - Send("+^"). И обломался я сильно, и полез в инет за ответом!:search: Найти у далось только два поста в архиве, которые мне не помогли. :sorry: Но стоило тщательнее порыться в Хелпе, как ответ тут же нашелся - Send("{LSHIFT}+{LCTRL}"). Удачи:)

Dirk Diggler 13-02-2006 20:27

Как определить наличие хоста? Встроенный пинг не работает. Проверил тремя разными способами, вот последний:
Код:

MsgBox(0,&quot;&quot;,ping(&quot;192.168.0.1&quot;))
  ping(&quot;192.168.0.1&quot;)
  MsgBox(0,&quot;&quot;,@error)

говорит, что хост доступен(23 мс, @error=0) , несмотря на то, что моя подсетка 192.168.100.0/24, а вот что виндовый пинг говорит
Код:

Ответ от 217.106.xxx.xxx: Заданная сеть недоступна.
 
  Статистика Ping для 192.168.0.1:
      Пакетов: отправлено = 1, получено = 1, потеряно = 0 (0% потерь),
  Приблизительное время приема-передачи в мс:
      Минимальное = 0мсек, Максимальное = 0 мсек, Среднее = 0 мсек

Может, его смущает выделенное? Но такой случай в докуменатции описан, @error д.б. равен 2, так что за отмазку не канает

Аутоитовский пинг даже на ping(&quot;192.168.0.0&quot;) говорит 23, т.е. ответ через 23 мс.

Dirk Diggler 13-02-2006 20:30

да и в приведенном в документации примере стоит заменить DNS-имя на IP, как сразу оно перестает работать как надо
Код:

$var = Ping("10.0.0.1",2500)
If $var Then ; also possible:  If @error = 0 Then ...
    Msgbox(0,"Status","Online, roundtrip was:" & $var)
Else
    Msgbox(0,"Status","An error occured with number: " & @error)
EndIf


Sanja Alone 14-02-2006 04:05

forumuser
  • Для обсуждения общих вопросов по AutoIt специально создана эта тема, новых создавать не нужно (Правила Форума).
  • Вот здесь описаны еще 2 способа переключения раскладки:
    AutoIt скрипты - введение и FAQ (с возм-тью переключения на конкретный язык, а не по кругу).

amel27 14-02-2006 12:50

Dirk Diggler

Пробовал вроде активные хосты определяет, по крайней мере по IP...

192.168.0.0 (моя подсеть) дает ошибку 3
на любые другие сети или несуществующие IP дает ошибку 1

Dirk Diggler 14-02-2006 14:20

проблема однозначно существует, в случае ответа от роутера по ICMP Autoit думает, что получил ответ от искомого хоста. Нашел аналогичную тему на родном для AutoIt форуме, насколько мой английский позволяет, понял, что баг был исправлен в одной из текущих бет, я скачал январскую(или уже февральскую) beta 106, пока не пробовал. Вы не бету пользуете случаем?

amel27 15-02-2006 16:32

Нет, не бета, у меня наоборот DNS не отзывается. Фича новая, значит без глюков не обойтись. Если бы не ваш пост не сунулся бы в справку и не обнаружил что версия уже устарела... :)

Dirk Diggler 17-02-2006 12:02

А как отследить, что было активизировано окно "Запуск программы"(это которое Пуск -> Выполнить)? Оно собственного заголовка не имеет.

amel27 17-02-2006 16:53

А разве "Запуск программы" не заголовок? Вроде работает:
Код:

WinWait("Запуск программы")
MsgBox(0,"Внимание!","Окно активировано!")


Dirk Diggler 17-02-2006 22:44

Да, но теперь другая проблема... Я пишу задачу для nnCron, которая при активизации этого окна будет переключать в нем раскладку. Использовал пример из FAQ.
Суть проста - при логоне в цикле пускается нижеследующий скрипт, который сперва ждет активизации окна, переключает раскладку, а потом ждет деактивизации, и завершает работу. Тут же запускается по новой, ждёт и т.п. Как можно убедиться, переключение раскладки - не работает! Я жму Win-R, вижу окно и... печатаю в нем по-русски. А как указано в секции параметры, должен бы по-английски... а в трее балун кажет, что уже WinWaitNotActive выполняется, значит _SetKeyboardLayout уже отработал... Тестировал скрипт на одиночном его запуске, добавил строку, которой проверяю правильность полученного хэндла... все вроде правильно....

Код:

Const $DEU = "00000407" ;Немецкий (стандартный)
  Const $ENU = "00000409" ;Английский (США)
  Const $FRA = "0000040C" ;Французский (стандартный)
  Const $FIN = "0000040D" ;Финский
  Const $ITA = "00000410" ;Итальянский
  Const $PLK = "00000415" ;Польский
  Const $RUS = "00000419" ;Русский
  Const $UKR = "00000422" ;Украинский
  Const $BLR = "00000423" ;Белорусский
  Const $EST = "00000425" ;Эстонский
  Const $LTH = "00000426" ;Латвийский
  Const $LVI = "00000427" ;Литовский
  Const $CHS = "00000804" ; Chinese (People's Republic of China)
  Const $CHT = "00000404" ; Chinese (Taiwan)
 
 
  ;--------=========================ПАРАМЕТРЫ========================-------------
 
  ;
  $WinTitle = "Запуск программы"
  $layout =  $ENU
 
 
 
  ;--------=========================КОД========================-------------
 
 
 
  Opt("TrayIconDebug", 1)
  Opt("WinTitleMatchMode", 2)
  WinWaitActive($WinTitle)
  Opt("WinTitleMatchMode",4)
  $hWnd = WinGetHandle("last")
 
  ; раскомментируйте следущую строку, чтобы убедиться, что handle получается правильный!
  ; WinClose($hWnd)
 
  ;переключение раскладки в окне, определяемом указателем $hWnd
 
  ; вот эта функция не работает
  _SetKeyboardLayout($layout, $hWnd)
 
  Opt("WinTitleMatchMode", 2)
  WinWaitNotActive($WinTitle)
 
  Exit
  ; --------=========================ПОДВАЛ========================-------------
 
 
  Func _SetKeyboardLayout($sLayoutID, $hWnd)
  Local $WM_INPUTLANGCHANGEREQUEST = 0x50
  Local $ret = DllCall("user32.dll", "long", "LoadKeyboardLayout", "str", $sLayoutID, "int", 0)
  DllCall("user32.dll", "ptr", "SendMessage", "hwnd", $hWnd, "int", $WM_INPUTLANGCHANGEREQUEST, "int", 1, "int", $ret[0])
  EndFunc


Может, это не работает потому, что у меня помимо русской и английской стоит также и китайская раскладка?

Dirk Diggler 19-02-2006 01:38

спасибо за внимание, конечно, в общем, поборол проблему. теперь я, переключаясь в окно cmd.exe или нажимая Win+R, могу не беспокоиться за раскладку, она у меня всегда английская.... если кому-то надо, выложу скрипты...

Sanja Alone 19-02-2006 03:55

Dirk Diggler
Цитата:

если кому-то надо, выложу скрипты...
Это действительно FAQ - сам видишь... Можешь и свой вариант добавить - многим это может пригодиться.

Dirk Diggler 19-02-2006 14:41

в случае с окном "Запуск программы..." из FAQ не подошло.

Dirk Diggler 19-02-2006 20:36

Как сделать так, чтобы элементы TreeView можно было перетаскивать из одной ветки в другую?

Sanja Alone 20-02-2006 04:05

Dirk Diggler
Цитата:

в случае с окном "Запуск программы..." из FAQ не подошло.
Как ты сам понимаешь, все ситуации нельзя предвидеть. Я у себя на компе вообще не использую ни одного из приведенных в FAQ методов - у меня ф-ции Send и ControlSetText нормально отрабатывают при посылке как англ. так и рус. символов без всякого переключения раскладки. Уж не знаю с чем связана такая беспроблемность, но это факт... Теперь по сути - если есть желание помочь народу, то приведи свой листинг в этой теме; если метод окажется работоспособным, то он также будет включен в FAQ.

Цитата:

Как сделать так, чтобы элементы TreeView
AutoIt не умеет работать с такими эл-тами.

Dirk Diggler 20-02-2006 11:28

Цитата:

Send и ControlSetText нормально отрабатывают при посылке
Я писал эти скриптики не для Send и ControlSetText, а для исключения сиуации, когда я хочу запустить regedit, а он запускаю купувше

Цитата:

AutoIt не умеет работать с такими эл-тами.
Ну у него есть же контрол TreeView, вполне стандартный виндовый. Он порождает вполне виндовые события... Может, можно как-то написать обработчик?
В целом задача стоит так: есть древовидная структура - корень, от него ветки, достаточно одного уровня, т.е. ветка в ветке уже не обязательно, в этих ветках - некие элементы. Надо лишь одну вещь сделать - чтобы эти элементы можно было легко перекидывать из одной ветки в другую. может, использовать что-то отличное от TreeView?

Sanja Alone 21-02-2006 03:26

Dirk Diggler
Цитата:

хочу запустить regedit, а он запускаю купувше
А как у тебя такое вообще получается?
Я пробовал так:
Код:

Run('regedit.exe')
И так:
Код:

Send('#r')
WinWaitActive('Запуск программы')
Send('regedit.exe')
;или (как вариант)
ControlSetText('last','','Edit1','regedit.exe')
Send('{ENTER}')

...и всегда запускается именно regedit, а не купувше. Причем, это не зависит от текущего состояния раскладки. Что нужно сделать, чтобы получить упомянутую тобой ошибку?

Цитата:

Ну у него есть же контрол TreeView
Если ты создаешь свой gui с пом. AutoIt, то им можно управлять. А "чужими" TreeView - шиш. Если знаешь WinAPI - попробуй через DllCall (тут я тебе не советчик).

Dirk Diggler 21-02-2006 11:23

Цитата:

Что нужно сделать, чтобы получить упомянутую тобой ошибку?
Вводить имя файла вручную 8-)))) слово "он" во фразе “хочу запустить regedit, а он запускаю купувше“ - просто опечатка.

Dirk Diggler 21-02-2006 11:44

Цитата:

Если ты создаешь свой gui с пом. AutoIt, то им можно управлять
А в чем отличие? Мне как-то казалосьь, что они общие для всех... я не в курсе подробностей реализации этого дела... Но все равно, как минимум, там предусмотрен стиль $TVS_DISABLEDRAGDROP...

У меня вопрос - как получить раскладку текущего окна???

Sanja Alone 22-02-2006 07:00

Dirk Diggler
Цитата:

А в чем отличие?
Этот вопрос нужно адресовать разработчикам АвтоИт, а не мне.

Цитата:

я не в курсе подробностей реализации этого дела...
Вот-вот, и я тоже :)

Цитата:

там предусмотрен стиль $TVS_DISABLEDRAGDROP...
А использовать этот стиль можно только в GUICtrlCreateTreeView, т.е. при создании эл-та TreeView в созданном ранее с пом. АвтоИт-а gui.

Цитата:

как получить раскладку текущего окна???
WinAPI - GetKeyboardLayout.
А вот и еще один вариант ответа на вопрос "Как программно переключить раскладку клавиатуры?". Нужный кусочек с этой страницы:
Код:

Упрощенный пример смены текущего языка на русский:
ActivateKeyboardLayout(LoadKeyboardLayout(IntToHex(MAKELANGID(LANG_RUSSIAN, SUBLANG_DEFAULT), 8).c_str(), 0), 0);

на английский:
ActivateKeyboardLayout(LoadKeyboardLayout(IntToHex(MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), 8).c_str(), 0), 0);

Для переключения между имеющимися языками:
ActivateKeyboardLayout(LoadKeyboardLayout(IntToHex(MAKELANGID(HKL_NEXT,SUBLANG_DEFAULT), 8).c_str(), 0), 0); — следующая раскладка

ActivateKeyboardLayout(LoadKeyboardLayout(IntToHex(MAKELANGID(HKL_PREV,SUBLANG_DEFAULT), 8).c_str(), 0), 0); — предыдущая.

Ес-но, придется преобразовать эти простые строчки в АвтоИт-ные DllCall-ы, при этом нигде не перепутав типы переменных и т.п. Если есть желание - дерзай.

Dirk Diggler 23-02-2006 13:43

Как работают функции типа TCPRecv? Они ждут получения данных или просто проверяют сокет и завершают работу? Их надо зацикливать или нет?

VelDmi 26-02-2006 10:58

Как закрыть окно експлорера? Например после инсталляции antivir открывается папка C:\Documents and Settings\All Users\Главное меню\Программы\AntiVir - Personal Edition. Конструкция
If WinWait ("Главное меню\Программы\AntiVir - Personal Edition","", 10) Then WinClose ("Главное меню\Программы\AntiVir - Personal Edition")
не помогает. Где я туплю???

amel27 26-02-2006 11:32

VelDmi

WinWait()
WinClose()

"If" зачем?

Sanja Alone 26-02-2006 18:18

VelDmi
Цитата:

Как закрыть окно експлорера?
FAQ читай (раздел "Отлов "случайных" окон" -> пункт 4. Окно браузера).

VelDmi 27-02-2006 17:13

Всем спасибо. Нашел ошибку. Почитал справку.

NikLok 28-02-2006 16:34

Использую для установки скрипты автоита. Уже набралось пордка 15 и грозит добавиться еще! Каждый весит по 120 кило. Что можно предпринять для экономии места:
- паковать чем нибудь экзешники скриптов
- не создавать экзешники а ставить первым делом сам автоит и выполнять непосредственно тексты скриптов.

Скажите как культурно или как лучше?

amel27 28-02-2006 16:59

NikLok
Цитата:

Скажите как культурно или как лучше?
AutoIT не нуждается в "установке" - достаточно одного autoit3.exe. Компиляция необходима в редких специальных случаях... Да и править AU3-файлы ИМХО удобней.

rhtu 01-03-2006 13:42

вопрос по закрытию, предупреждения в Explore
 
Пожалуйста, представьте себе такой этап работы.
На локальной машине с OC Windows'98 установлен сервер, например, Apach.
Пользователь запустил броузер IE (4-я версия), выполнил некоторые дей-
ствия и переходит к работе в VB-форме, которая станет активной, а
окно IE перестанет быть нужным и его можно будет закрыть! Перед выводом
VB-формы на экран осуществляется по методу ieView.Navigate запуск файла
"_close.htm" (технол. VBScript), расположенного или где-то на диске C:,
или в директории /cgi-bin/ сервера Apach (выбор места размещения файла
"demo.htm" сейчас четко не определяю, об этом я попрошу позже, сформу-
лировав задачу до конца!). Предназначенный только, чтобы закрыть окно
броузера (т.е. сам IE), файл "_close.htm" имеет вид:
Код:

<html><head></head><body>
<form name="Form1">
</form>
<script for="Form1" language="VBScript">
Window.Close
</script>
</body></html>

Проблема стала заключаться в том, что на экране появилось меню с двумя
клавишами -- "Да" и "Нет" и необходимостью выбора "Да" без каких-либо
действий со стороны пользователя.
Мои мытарства по решению этой проблемы привели к знакомству с пакетом
AutoIt 3.1, программы которого я установил на компьютере. Далее я запи-
сал код (см. ниже) для "_close.au3" и откомпилировал его, воспользовав-
шись pop_up меню от правой клавиши мышки. Полученный "_close.exe" я
разместил в /cgi-bin/ сервера и запустил этот файл.
Код:

WinWaitActive("Microsoft Internet Explorer", "Просматриваемая веб-страница пытается закрыть это окно. Закрыть окно?")
Send("{ENTER}")

В функции ожидания приведены тексты, которые я списал с появляющегося
меню. Как можно догадаться, результат моих попыток обескураживающий!
Все галочки в свойствах броузера, разрешающих использование ActiveX
не помогли. Я упростил для себя задачу, записав в броузере страницу,
с которой следует начать обзор, файл "_close.htm". Так что, загрузив
страницу, броузер должен был сам себя закрыть без сервера... и тут я
окончательно запутался. Обращение к Форуму на OSzone_net.htm показало,
что на нем рассматриваются преимущественно "мягкие" способы установки
программных пакетов с винчестера. Моя же задача несколько иная и форму-
лируется традиционно по-русски: что делать? Прошу подсказки по разме-
щению "_close.exe" и закрытию этого ненужного мне меню!! Спасибо.

NikLok 02-03-2006 11:39

Вот наверное дурацкий вопрос. Как средствами автоита работать с треем. То есть выбрать нужную программу в нем? При различных разрешениях экрана!

VelDmi 03-03-2006 09:01

rhtu
Раз пока никто не ответил напишу я.

>> Полученный "_close.exe" я разместил в /cgi-bin/ сервера и запустил этот файл.
Надеюсь вы запустили его до того, как запустили скрипт на закрытие окна?

>> В функции ожидания приведены тексты, которые я списал с появляющегося меню.
Часто списывая тексты с окон допускаются ошибки. Лучше всего копировать текст из встроенной программы Au3Info.

>> Предназначенный только, чтобы закрыть окно броузера (т.е. сам IE), файл "_close.htm"
Предлагаю вам закрывать окно AutoIt-ом, а не скриптом, например: WinClose ("Microsoft Internet Explorer - моя страница"). Тогда меню появляться не будет.

nsergeip 03-03-2006 15:19

Возникла следующая проблема. Я делаю дистрибутив винды с автоустановкрй необходимых приложений при первом запуске оси. Есть такая софтина - FinePrint (или pdf printer), которая печатает документ в pdf файл. Написал сценарий instPDF_Printer.au3 для autoit. При попытке запуска следующим методом из командной строки C:\install\AutoIt3.exe C:\install\FinePrint\instPDF_Printer.au3 вываливается сообщение 'Для установки и настройки компонентов системы воспользуйтесь панелью управления'.
И в трее появляется значек autoit. После повторного выполнения команды все работает. Как можно избавиться от этой проблемы?

nsergeip 03-03-2006 15:41

Все разобрался AutoIt3.exe нужно кидать в одну папку вместе с исполняемым скриптом, в моем случае команда получилась такая: C:\install\FinePrint\AutoIt3.exe instPDF_Printer.au3/ Сам спросил - сам ответил. Мож кому и пригодиться!!!

samsobi 03-03-2006 18:15

nsergeip
А почему нельзя скомпилить .au3 в ехе? И пользуй C:\install\instPDF_Printer.exe!

VelDmi 04-03-2006 09:20

nsergeip

>> При попытке запуска следующим методом из командной строки C:\install\AutoIt3.exe C:\install\FinePrint\instPDF_Printer.au3
Должно работать, вероятно внутри скрипта что-то не так. Используй @ScriptDir для запуска приложений.

nsergeip 06-03-2006 13:10

Столкнулся еще с одной проблемой: устанавливаю pdfFactory Pro 2.5! Инсталлятор кривучий такой или руки у меня такие, незнаю. В конце инсталляции вываливается информационное окно с кнопкой 'OK'. Его ничем не могу отловить, не WinWait, не WinActive, не WinWaitActive не помогает!!! Если кто с такой прогой сталкивался или мож знает как всетаки 'нажать' эту кнопку подскажите плиз...

nsergeip 06-03-2006 13:13

VelDmi дело не в том что неработает то что в нутри скрипта, autoit не запускается таким образом, обычно он в трее висит при запуске, а так его там вообще нет...

amel27 06-03-2006 13:34

Цитата:

Столкнулся еще с одной проблемой: устанавливаю pdfFactory Pro 2.5! Инсталлятор кривучий такой или руки у меня такие, незнаю. В конце инсталляции вываливается информационное окно с кнопкой 'OK'. Его ничем не могу отловить, не WinWait, не WinActive, не WinWaitActive не помогает!!! Если кто с такой прогой сталкивался или мож знает как всетаки 'нажать' эту кнопку подскажите плиз...
Код:

Send("{SPACE}")

nsergeip 06-03-2006 14:46

amel27 я делал Send("{ENTER}")! не работает, как будто операция раньше появления окна проходит, или вообще не выполняется, что-то не пойму!?

Shaul 06-03-2006 23:59

Написал скрипт для запуска подряд других скриптов (на данный момент для автоматизации установки программ). Но автоиту не нравится выделенная строка:
Код:

#include <GUIConstants.au3>
 
$mainwindow = GUICreate("Installer", 400, 300)
$label1 = GUICtrlCreateLabel("Select programs to install", 10, 10, 200)
$list1 = GUICtrlCreateTreeView(10, 30, 380, 240, BitOr($TVS_CHECKBOXES, $TVS_DISABLEDRAGDROP))
$cmdinstall = GUICtrlCreateButton("Install", 10, 270, 110)
$cmdcancel = GUICtrlCreateButton("Cancel", 120, 270, 110)
 
GUISetState(@SW_SHOW, $mainwindow)
 
$installlist = IniReadSection("installer.ini", "Programs")
If @error Then
    MsgBox(4096, "", "Error with INI")
Else
    Dim $items[$installlist[0][0]]
    For $c = 1 To $installlist[0][0]
        $item = GUICtrlCreateTreeViewItem($installlist[$c][0], $list1)
        $items[$c] = $item
    Next
EndIf
 
Do
    $msg = GUIGetMsg()
    Select
        Case $msg = $cmdinstall
            For $i = 1 To $installlist[0][0]
                If GUICtrlRead($items[$i]) = $GUI_CHECKED Then
                    RunWait($installlist[$i][1])
                EndIf
            Next
        Case $msg = $cmdcancel
            GUIDelete()
            Exit
    EndSelect
Until $msg = $GUI_EVENT_CLOSE or $msg = $cmdcancel

Что я делаю не так и как это должно быть на самом деле?

Sanja Alone 07-03-2006 04:35

nsergeip
Цитата:

Если кто с такой прогой сталкивался или мож знает как всетаки 'нажать' эту кнопку подскажите плиз...
Не сталкивался, но, если ты здесь приведешь инфу о той кнопке, полученную с пом. AutoIt Window Info ("%ProgramFiles%\AutoIt3\AU3Info.exe"), то, скорее всего, решение найдется (для фиксации показаний в окне AutoIt Window Info нужно нажать Ctrl+Alt+F). А для начала можешь попробовать способ из FAQ (раздел "Вввод данных / работа с элементами управления", пункты 5, 6, 7).

amel27 07-03-2006 06:30

Shaul
Счет элементов массива начинается с 0, нужно так:
Код:

For $c = 0 To $installlist[0][0]-1
...
Next


amel27 07-03-2006 11:24

nsergeip
Цитата:

как будто операция раньше появления окна проходит
Код:

Sleep (1000)
Send("{SPACE}")

Извиняюсь, забыл паузу вставить. Время ожидания подбирается опытным путем. Если срабатывает с клавы, значит будет работать и из AutoIT. В самых тяжелых случаех приходилось даже прибегать к MouseClick().

Shaul 07-03-2006 12:55

amel27
Цитата:

[Shaul
Счет элементов массива начинается с 0, нужно так:

Код:
For $c = 0 To $installlist[0][0]-1
...
Next
В элементе [0][0] содержится количество элементов массива, поэтому я начинаю с $c = 1. Проблема в другом. Автоиту не нравится то, как я назначил количество элементов в массиве $items, который я использую, чтобы впоследствии обратиться к конкретному элементу списка $list1. Еще одна проблема в том, что нужно как-то перехватывать событие выбора чекбокса в графике и где-то отмечать, что этот элемент $items[$c] выбран ($GUI_CHECKED)

Paki 07-03-2006 13:09

Извините за тупость вопроса но очень нужно сделать такое. Имеется назначение клавиши например:

Код:

HotKeySet("{F1}", "go")
Можно ли сделать например какой нибудь ini файл или что нибудь такое, откуда будет тянуться значение клавиши в данном случае F1. Что бы просто можно было быстро поменять значение.

dark_n 07-03-2006 13:28

запуск программы
 
Приветствую.
Выполняю такой коротенький скрипт
Код:

Run( \\\\mycomp\\auditscaner\\ina32.exe)
Send("{Enter}")

почему-то запускается несколько экземпляров ina32.exe
Окно не имеет заголовка.
в чем может быть дело?
Заранее спасибо.

amel27 07-03-2006 14:33

Shaul
Цитата:

Автоиту не нравится то, как я назначил количество элементов в массиве $items, который я использую, чтобы впоследствии обратиться к конкретному элементу списка
Вот-вот, если кол-во элементов массива N, то корректные индексы массива будут от 0 до (N-1), а при обращении к эл-ту $items(N) вывалится ошибка, кстати очень правильная! :)
Цитата:

The number of elements to create for the array dimension, indexed 0 to n-1.

Snejok 07-03-2006 20:41

isDirectory?
 
Как с помощью AutoIt узнать что директория, а что файл? Я сделал так, но может можно проще
Код:

If FileChangeDir("C:\Windows") Then
 MsgBox (0, "Info", "This is Directory!", "")
Else
MsgBox (0, "Info", "This is File!", "")
EndIF


Sanja Alone 08-03-2006 04:43

Paki
Цитата:

Можно ли сделать например какой нибудь ini файл или что нибудь такое, откуда будет тянуться значение клавиши
Ес-но, можно - FAQ (раздел "Работа с ini-файлами"). Код буде выглядеть примерно так:
Код:

$ini=@ScriptDir & '\my.ini'
$HotKey=IniRead($ini,"Section","HotKey","{F1}") ;последний параметр - значение по ум. (если параметр HotKey отсутствует в файле или ini-файла вообще нет)
HotKeySet("'"&$HotKey&"'", "go")


amel27 08-03-2006 04:50

Snejok

Так же, как из командной строки - используя обратный слэш в конце имени, пример:
Код:

; Прием параметра из командной строки
If $CmdLine[0]=0 Then
  Exit
Else
  $file=$CmdLine[1]
EndIf

Код:

; Убираем оконечные слэши
While StringRight($file,1)="\"
  $file=StringLeft($file,StringLen($file)-1)
Wend

; Определяем тип
If FileExists ($file & "\") Then
  MsgBox(0,"","This is Directory!")
Else
  If FileExists ($file) Then
  MsgBox(0,"","This is File!")
  Else
  MsgBox(0,"","File or Directory Not Exist!")
  EndIf
EndIf


rhtu 09-03-2006 00:47

Уточнение получения объекта AutoIt3X при технологии VBScript.

Запись из AutoIt_ru.chm для AutoIt3X, которая приведена ниже, машина
в моем случае применения метода CreateObject() воспринимает как 429-ю
ошибку -- не может создать объект! Поэтому надо ли указывать путь к
autoit3.exe? Или запись, которая ниже, позволяет найти autoit3.exe где
угодно, даже на съемном диске (USB-диске)? Или моя первая строка для
"fso" обладает недостатком, который приводит к невозможности создания
объекта "oAutoIt" при записи из AutoIt_ru.chm? Также есть ли какая-л.
литература на рус. языке с примерами применения AutoIt3Х? Пожалуйста,
подскажите решение для CreateObject(" ???? ").
Код:

Dim fso, oAutoIt
Set fso = GetObject("c:\windows\wscript.exe", "WScript.Application")
Set oAutoIt = fso.CreateObject("AutoItX3.Control")
oAutoIt.WinClose "Microsoft Internet Explorer", ""


amel27 09-03-2006 02:29

rhtu
Цитата:

Set oAutoIt = WScript.CreateObject("AutoItX3.Control")
oAutoIt.WinClose "Untitled - Notepad", ""
Пример взят из справки

nsergeip 09-03-2006 08:36

Цитата:

Не сталкивался, но, если ты здесь приведешь инфу о той кнопке, полученную с пом. AutoIt Window Info ("%ProgramFiles%\AutoIt3\AU3Info.exe"), то, скорее всего, решение найдется (для фиксации показаний в окне AutoIt Window Info нужно нажать Ctrl+Alt+F). А для начала можешь попробовать способ из FAQ (раздел "Вввод данных / работа с элементами управления", пункты 5, 6, 7).
Код:

Вот информация полученная autoit

>>>>>>>>>>>> Window Details <<<<<<<<<<<<<
Title:        pdfFactory Pro
Class:        #32770
Size:        X: 420    Y: 206    W: 524    H: 133

>>>>>>>>>>> Mouse Details <<<<<<<<<<<
Screen:        X: 675        Y: 311
Cursor ID:        2

>>>>>>>>>>> Pixel Color Under Mouse <<<<<<<<<<<
RGB:        Hex: 0xECE9D8        Dec: 15526360

>>>>>>>>>>> Control Under Mouse <<<<<<<<<<<
Size:                X: 221    Y: 67    W: 75    H: 23
Control ID:        2
ClassNameNN:        Button1
Text:                ОК

>>>>>>>>>>> Status Bar Text <<<<<<<<<<<


>>>>>>>>>>> Visible Window Text <<<<<<<<<<<
ОК
pdfFactory Pro was successfully installed!

To use pdfFactory Pro, just print to the pdfFactory Pro printer from any Windows application.

>>>>>>>>>>> Hidden Window Text <<<<<<<<<<<

скрипт вот такой писал, не работает почему-то
Код:

WinWaitActive("pdfFactory Pro","OK")
Send("{TAB}")
Send("{ENTER}")


dark_n 09-03-2006 08:50

Активное окно
 
Имеется такой скрипт.
Цитата:

run("\\neiwton\auditscaner\ina32.exe")
sleep(200)
WinActivate("")
sleep(200)
send("{Enter}")
sleep(200)
WinWaitActive("Inventory Analyzer")
sleep(200)
send("{Enter}")
Когда я запускаю его ,все работает ,как надо.
1) Когда я закидываю его в автозапуск : ina32.exe при входе в систему появляется ,но на окне нет фокуса, соответственно я не могу послать в окно нажатие клавиши.Даже не представляю почему WinActivate("") не срабатывает(у окна нет заголовка т.е. title). !!??
2)как можно послать {Enter} определенной кнопке на окне?

Заранее спасибо.

nsergeip 09-03-2006 09:50

Вот скрипт
Код:

Run("Setup.exe")
WinWaitActive("pdfFactory Pro","Да")
Send("{ENTER}")
WinWaitActive("pdfFactory Pro License Agreement","accept the terms")
Send("{TAB}")
Send("{ENTER}")
WinWait("pdfFactory Pro")
if WinWaitActive("pdfFactory Pro","Да",2) Then
Send("{TAB}")
Send("{ENTER}")
WinWaitActive("pdfFactory Pro","ОК")
Send("{TAB}")
Send("{ENTER}")
Else
WinWaitActive("pdfFactory Pro","ОК")
Send("{TAB}")
Send("{ENTER}")
EndIf

Этим скриптом я устанавливаю pdfFactory/ Проблема в том что если на компе установлена уже эта программа то окно

Код:

Press CTRL-ALT-F to pause the display.

>>>>>>>>>>>> Window Details <<<<<<<<<<<<<
Title:        pdfFactory Pro
Class:        #32770
Size:        X: 429    Y: 341    W: 620    H: 126

>>>>>>>>>>> Mouse Details <<<<<<<<<<<
Screen:        X: 536        Y: 431
Cursor ID:        2

>>>>>>>>>>> Pixel Color Under Mouse <<<<<<<<<<<
RGB:        Hex: 0xECE9D8        Dec: 15526360

>>>>>>>>>>> Control Under Mouse <<<<<<<<<<<
Size:
Control ID:
ClassNameNN:
Text:

>>>>>>>>>>> Status Bar Text <<<<<<<<<<<


>>>>>>>>>>> Visible Window Text <<<<<<<<<<<
&Да
&Нет
Setup found settings from a previous installation of pdfFactory Pro.  Would you like to import those settings now?

>>>>>>>>>>> Hidden Window Text <<<<<<<<<<<

появляется, но если уже программа была у становлена то оно не появляется.
ВОПРОС: как написать этот скрипт правильно, так чтобы было предусмотрено то что программа уже имеется, и то что ее еще нет.

Sanja Alone 09-03-2006 10:15

All
На этом форуме принято приводить листинги внутри тэга code !
По теме - Прочтите FAQ !!!



nsergeip
Цитата:

не работает почемуто
Да потому, что у тебя (скорее всего) в каждом окне текст "ОК" есть :) Попробуй так (это очень перестраховочный способ):
Код:

WinWait("pdfFactory Pro","successfully installed")
WinActivate("pdfFactory Pro","successfully installed")
WinWaitActive("pdfFactory Pro","successfully installed")
Send("{TAB}")
Send("{ENTER}")

А на эту кнопку можно и сразу нажать: ControlClick("pdfFactory Pro","successfully installed","Button1")

Цитата:

Вот скрипт
фрагмент:
Код:

if WinWaitActive("pdfFactory Pro","Да",2) Then
Send("{TAB}")
Send("{ENTER}")
WinWaitActive("pdfFactory Pro","ОК")
Send("{TAB}")
Send("{ENTER}")
Else
WinWaitActive("pdfFactory Pro","ОК")
Send("{TAB}")
Send("{ENTER}")
EndIf

заменить на:
Код:

if WinWait("pdfFactory Pro","Да",2) Then
WinActivate("pdfFactory Pro","Да")
WinWaitActive("pdfFactory Pro","Да")
Send("{TAB}")
Send("{ENTER}")
EndIf
WinWaitActive("pdfFactory Pro","ОК")
Send("{TAB}")
Send("{ENTER}")

Этот способ (наряду с другими) описан в FAQ, а вопрос неоднократно разбирался в старой теме - начни с этого поста и прочитай ответы на него.


dark_n
Цитата:

WinActivate("")
  1. Пустые кавычки в кач-ве аргумента означают последнее активное окно, а при старте из автозапуска вполне возможно, что нужное тебе окно не является таковым. Нужно вписать хотя-бы что-то из этого окна (если нет заголовка, то можно написать WinActivate("","Текст")).
  2. ControlClick, ControlSend.

dark_n 10-03-2006 06:28

Код:

run("\\neiwton\auditscaner\ina32.exe")
sleep(2000)
WinActivate("", "Inventory Anlyzer")
sleep(200)
WinWaitNotActive("","Inventory Anlyzer")
send("{Enter}")
sleep(200)
WinActive("Inventory Analyzer")
sleep(200)
send("{Enter}")

почему-то при первом входе в систему(exe-шник скрипта выполняется при входе в систему)
Код:

WinActivate("", "Inventory Anlyzer")
не срабатывает,окно не активно
когда я делаю выход из системы а
затем вход- фокус появляется и все нормально.Почему так?.

kralex 11-03-2006 11:42

Мужики, поможите, не сочтите за невежество. Все перечитал на форумах, создал диск для установки винды XP с автоустановкой приложений. Вроде разобрался со всеми необходимыми нюансами. Винда втыкается, все путем, доходит до автоустановки приложений и выходит такая картина - все приложениия с использованием AutoIt не ставятся. Все скрипты пашут, проверял, все путем. Видимо я напартачил в пакетнике - RunOnceEx.cmd. У меня так прописано:
Код:

cmdow @ /HID
@echo off
 
SET CDROM=%~d0
 
SET KEY=HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx
SET i=100
 
REG ADD %KEY% /V TITLE /D "Installing Applications" /f
 
REG ADD %KEY%\%i% /VE /D "Preparing Installation..." /f
REG ADD %KEY%\%i% /V 1 /D "%CDROM%\prepare.cmd" /f
 
REG ADD %KEY%\%i% /VE /D "K-Lite codepack" /f
REG ADD %KEY%\%i% /V 1 /D "%CDROM%\Software\K-lite codepack\AutoIt3.exe klcodec.au3" /f
SET /A i+=1
 
REG ADD %KEY%\%i% /VE /D "Total Commander" /f
REG ADD %KEY%\%i% /V 1 /D "%CDROM%\Software\TOTALCOM\AutoIt3.exe total.au3" /f
SET /A i+=1
 
REG ADD %KEY%\%i% /VE /D "WinAmp 5_03 FULL" /f
REG ADD %KEY%\%i% /V 1 /D "%CDROM%\Software\WINAMP\AutoIt3.exe winamp503.au3" /f
SET /A i+=1
 
REG ADD %KEY%\%i% /VE /D "RUSSIFIKATOR WinAmp 5_03" /f
REG ADD %KEY%\%i% /V 1 /D "%CDROM%\Software\WINAMP\AutoIt3.exe ruswiamp.au3" /f
SET /A i+=1
 
REG ADD %KEY%\%i% /VE /D "Nero 6316" /f
REG ADD %KEY%\%i% /V 1 /D "%CDROM%\Software\Nero6316\nero6316.exe /silent /noreboot /no_ui /sn=1A23-0019-3030-1988-5100-7298 /write_sn
" /f
SET /A i+=1
 
REG ADD %KEY%\%i% /VE /D "RUSSIFIKATOR Nero 6316" /f
REG ADD %KEY%\%i% /V 1 /D "%CDROM%\Software\Nero6316\NBR6316rus.exe /silent /noreboot /no_ui" /f
SET /A i+=1
 
REG ADD %KEY%\%i% /VE /D "PowerDVD XP v4.0" /f
REG ADD %KEY%\%i% /V 1 /D "%CDROM%\Software\PowerDVD\Setup.exe /s /sms" /f
SET /A i+=1
 
REG ADD %KEY%\%i% /VE /D "Office2003" /f
REG ADD %KEY%\%i% /V 1 /D "%CDROM%\Software\Office2003\SETUP.EXE" /f
SET /A i+=1
 
REG ADD %KEY%\%i% /VE /D "Cleaning Up and Rebooting" /f
REG ADD %KEY%\%i% /V 1 /D "%CDROM%l\cleanup.cmd" /f
SET /A i+=1
 
EXIT

Возможно сначала надо проинсталлировать сам AutoIt ? Например:
Код:

REG ADD %KEY%\%i% /VE /D "autoit-v3-setup" /f
REG ADD %KEY%\%i% /V 1 /D "%CDROM%\Software\Autoit\autoit-v3-setup.exe /s" /f
SET /A i+=1


VelDmi 11-03-2006 12:25

Как написать скрипт, выполняющийся в системе с наивысшим приоритетом, при этом, не использующим (почти) системных ресурсов.
По горячей клавише снимает все процессы или делает log off. Дело в том, что некоторые игры настолько грузят систему, что она не реагирует даже на сеть. или игра глючит. Так вот необходимо по горячей клавише выходить из любой игры, если она зависла.
Код:

HotKeySet("{ESC}", "Terminate")

; Что написать здесь, чтобы повысить приоритет и при этом не жрало ресурсов?

Func Terminate()
        Exit 0
EndFunc


VelDmi 11-03-2006 12:27

kralex
Переконвертируй au3 в exe.

Sanja Alone 11-03-2006 14:26

dark_n
Цитата:

"Inventory Anlyzer"
А здесь точно нет опечатки? Я конечно не знаю, что это за Аналайзер такой, но может должно быть "Inventory Analyzer". А возможно и одного слова "Inventory" будет вполне достаточно...

Цитата:

WinWaitNotActive("","Inventory Anlyzer")
send("{Enter}")
Эта конструкция начисто лишена смысла, т.к. ф-ция Send "Sends simulated keystrokes to the active window". Другими словами, этот ENTER гарантированно будет послан не тому окну, что нужно.

Цитата:

WinActive("Inventory Analyzer")
WinActive - "Checks to see if a specified window exists and is currently active". Использовать данную ф-цию имеет смысл лишь в каких-то проверках, может здесь должна быть WinActivate?

Цитата:

не срабатывает,окно не активно
Как я сказал выше, для неактивного окна можно еще попробовать:
  1. ControlSend ( "title", "text", controlID, "string" [, flag] ) - "works in a similar way to Send but it can send key strokes directly to a window, rather than just to the active window".
  2. ControlClick ( "title", "text", controlID [, button] [, clicks]] ) или ControlClick + ControlFocus ( "title", "text", controlID ) (учитывая ремарку "The control might first need to be given focus with the ControlFocus command.").
P.S.
Цитата:

run("\\neiwton\auditscaner\ina32.exe")
Честно говоря, не думал, что подобная конструкция может нормально работать - вроде, были проблемы, к-рые решались так или так.



kralex
Нужно писать полный путь к au3-файлу:
Код:

REG ADD %KEY%\%i% /V 1 /D "%CDROM%\Путь_к_AutoIt3.exe\AutoIt3.exe %CDROM%\Software\TOTALCOM\total.au3" /f
И не стоит класть AutoIt3.exe в каталог к каждой проге (тогда уж лучше откомпилировать), достаточно положить AutoIt3.exe в какой-то один каталог и ссылаться на него. И еще один момент - если у тебя в au3-файлах присутствуют строки вида Run('setup.exe'), то, без приведения их к виду Run(@ScriptDir&'\setup.exe') способ установки с использованием одного AutoIt3.exe на диске не сработает, т.к. не сможет найти эти самые setup.exe.

А можешь и проинсталлить - тогда можно будет сразу au3-запускать (если ты принудительно не изменишь действие по ум. для au3-файлов), или откомпилируй (не забыв заменить au3 на exe в своем батнике, ну и пути, ес-но).
P.S. Для кого я писал про тэг code?



VelDmi
Цитата:

Что написать здесь, чтобы повысить приоритет и при этом не жрало ресурсов?
Код:

ProcessSetPriority(@ScriptName, приоритет)

где, приоритет:
0 - Idle/Low
1 - Below Normal (Not supported on Windows 95/98/ME)
2 - Normal
3 - Above Normal (Not supported on Windows 95/98/ME)
4 - High
5 - Realtime (Use with caution, may make the system unstable)

А можешь не париться со скриптом, а использовать прогу Process Killer - размер около 40Кб, запускается незаметно при старте системы (через HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\run или HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\run), вызывается по Ctrl+Shift+~. Любой процесс убивается одним нажатием на Del. Также присутствует ф-ция рестарта оболочки.

DimkaZar 12-03-2006 00:51

Подскажите, плиз.
Могу ли я написать скрипт, который при нажатии на оба Shift'а переключал бы раскладку ? У меня стоит ХР и там нету такой опции. А очень хочеться.
Если такое возможно, то напишите как. Или хотя бы скажите как мне поставить скрипт в режим ожидания нажатия двух Шифтов.

Sanja Alone 12-03-2006 04:09

DimkaZar
Цитата:

при нажатии на оба Shift'а
Нет. Процитирую ремарку к ф-ции HotKeySet:
Цитата:

The following hotkeys cannot be set:
Ctrl+Alt+Delete - It is reserved by Windows
F12 - It is also reserved by Windows, according to its API.
NumPad's Enter Key - Instead, use {Enter} which captures both Enter keys on the keyboard.
Win+B,D,E,F,L,M,R,U; and Win+Shift+M - These are built-in Windows shortcuts. Note: Win+B and Win+L might only be reserved on Windows XP and above.
Alt, Ctrl, Shift, Win - These are the modifier keys themselves!
Other - Any global hotkeys a user has defined using third-party software, any combos of two or more "base keys" such as '{F1}{F2}', and any keys of the form '{LALT}' or '{ALTDOWN}'.

Shaul 12-03-2006 16:27

Есть TreeView с $TVS_CHECKBOXES. Строки в список загружаются из файла. Мне нужно, чтобы скрипт выполнял некоторые действия над выбранными ("оптиченными") элементами (строками) списка. Я так и не смог толком понять, как из скрипта проверить, выделена ли строка в списке

DimkaZar 12-03-2006 16:39

Sanja Alone
А ты не подкажешь, может есть другие программы..или еще что...мне очень надо сделать что бы на два Шифта переключалась раскладка.

Sanja Alone 13-03-2006 02:59

DimkaZar
Цитата:

может есть другие программы
Они точно есть - многие старые ДОС-овские "кейрусы" переключали языки по двум шифтам и использовали L/R Shift для прямого переключения на конкретный язык. Попробуй задать свой вопрос в в соседнем подфоруме. Вот тебе две темы сходу: первая и вторая

dark_n 13-03-2006 06:55

Запуск программы под дос
 
А если на машине стоит MS-Dos,то как быть (запустить Inventory Analyzer)?Может надо с какими-нибудь ключами?

nsergeip 13-03-2006 10:44

Sanja Alone у тебя на сайте я нашел скрипт по установке remote administrator, а вот с регистрацией ты не постарался как я посмотрел, а ето помоему немаловажно в автоматическо установке.
Я столкнулся с проблемой по этой части, при запуске ....Radmin\radmin.exe вываливается окно у кот. нет названия, что с этим делать незнаю, мож накидаешь скрипт доконца?

kralex 13-03-2006 11:24


Цитата:

И не стоит класть AutoIt3.exe в каталог к каждой проге (тогда уж лучше откомпилировать), достаточно положить AutoIt3.exe в какой-то один каталог и ссылаться на него. И еще один момент - если у тебя в au3-файлах присутствуют строки вида Run('setup.exe'), то, без приведения их к виду Run(@ScriptDir&'\setup.exe') способ установки с использованием одного AutoIt3.exe на диске не сработает, т.к. не сможет найти эти самые setup.exe.
А можешь и проинсталлить - тогда можно будет сразу au3-запускать (если ты принудительно не изменишь действие по ум. для au3-файлов), или откомпилируй (не забыв заменить au3 на exe в своем батнике, ну и пути, ес-но).
P.S. Для кого я писал про тэг code?
Большое спасибо мужики, разобрался, все влетает теперь в "лысую машину" "как слива в ж....пу". DrWeb 4.33 так никто и не победил до конца? Коли спрашивать еще, так еще вопрос: можно ли через скрипт au3 поиздеваться над разрешением экрана (установить например 1024 х 768, 32 bit, 75 Гц) и активировать винду, т.е. как прописать reboot с заходом в режим защиты от сбоев и автоматом активировать некоторые действия, запустить все тот же скрипт.

Merg 13-03-2006 13:32

Почитал фак, форум про АутоИт3 в принципе ясен принцип...
Установил!
Решил посмотреть как работает, залез в examples и запустил calculator.au3...
Открывается калькулятор встроенный и баста.

По идее там должна произойти операция 2*4*8*16=
Подождать 2 секунды и закрыться.

А у меня ничего не происходит :(

В чем могет быть проблема????

PS: Стоит XP professional service pack 2

тоже самое и с примером notepad1.au3, открывается блокнот и все ...

kralex 13-03-2006 14:04

Цитата:

Почитал фак, форум про АутоИт3 в принципе ясен принцип...
Установил!
Решил посмотреть как работает, залез в examples и запустил calculator.au3...
Открывается калькулятор встроенный и баста.

По идее там должна произойти операция 2*4*8*16=
Подождать 2 секунды и закрыться.

А у меня ничего не происходит :(

В чем могет быть проблема????

PS: Стоит XP professional service pack 2

тоже самое и с примером notepad1.au3, открывается блокнот и все ...

Уважаемый Merg! Твоя проблема для калькулятора по-моему такая - у тебя винда русская? Там в демо скриптах все для English винды. Смотри внимательно в данном скрипте для калькулятора строка:

Код:

; Wait for the calulator become active - it is titled "Calculator" on English systems
Код:

WinWaitActive("Calculator")


Жирным выделена проблема, titled окна должен быть как у тебя, с русским названием окна - "Калькулятор". Например:

Код:

; Wait for the calulator become active - it is titled "Calculator"
Код:

on English systems
Код:

WinWaitActive("Калькулятор")


и ниже по скрипту также, тогда все заработает. Проверь.

Merg 13-03-2006 15:14

Цитата:

Уважаемый Merg! Твоя проблема для калькулятора по-моему такая - у тебя винда русская? Там в демо скриптах все для English винды. Смотри внимательно в данном скрипте для калькулятора строка:


Код:
; Wait for the calulator become active - it is titled "Calculator" on English systems
WinWaitActive("Calculator")

Жирным выделена проблема, titled окна должен быть как у тебя, с русским названием окна - "Калькулятор". Например:


Код:
; Wait for the calulator become active - it is titled "Calculator" on English systems
WinWaitActive("Калькулятор")

и ниже по скрипту также, тогда все заработает. Проверь.

Винда русская.

Большое спасибо! ПОМОГЛО! :)

Неискушенному зрителю достаточно трудно заметить разницу (воспринимается как должное)...

ЗЫ: Получается что надо писать скипты под рус и инг версии?! мде

kralex 13-03-2006 15:57

Цитата:

ЗЫ: Получается что надо писать скипты под рус и инг версии?! мде
Погоди, скрипт пишется не для винды (пусть она хоть китайская), а в нем учитываются названия активных окон, для которых он исполняется. Скрипты в основном применяются для автоустановки программ, а они есть как русские так и всякие. Главное чтобы скрипт "увидел" правильное название окна. Я сам все это познал 3 дня назад. Уже шпарю в этом AutoIt-е все программы (установки оных), которые нужны. Диск с виндой втыкается, а после автоматом сразу весь необходимый софт шпарит без участия юзера. Очень удобно, особенно когда в день по 10 компутеров грузишь.

NikLok 13-03-2006 18:59

Так получается, что скрипты вроде как отлаженные на винде, дают сбой на виртуальной машине!!! Вся беда в том, что при установке приложений нет строки статуса, а значит и диагностики. Как люди выкручиваются?
Далее если срубаем саму установку, то есть выходим из нея, то скрипт то продолжает работать!!! И пока его не срубишь процесс манагером, все стоит и ждет.
Я было пытался в WinWaitActivate ставить временные задержки, но там надо городить кучу if then для того что бы скрипт далше шол на выход. Может есть культурнее решение???

Tanis 13-03-2006 20:31

А меня наоборот, когда ставлю на реальной машине, не появляется индикатор установки и заключительное окно. В котором написано, что программа успешно установлена. При этом на соседней машине все нормально. Еще заметил, что эта неприятность происходит с программами устанавлеваемыми из msi пакетов. Не подскаже как это можно исправить?

XXXler 13-03-2006 21:43

Tanis
Цитата:

устанавлеваемыми из msi пакетов
не легче к msi делать транформации и запускать с ключами?
ИМХО, автоит нужен там где остальными путями пробится не удалось

Tanis 13-03-2006 23:05

Может быть. Но я уже написал скрипты для 45 программ и не хочу начинать все с начала. Да и просто надо же разобраться в чем дело.

Sanja Alone 14-03-2006 08:33

nsergeip
Цитата:

скрипт по установке remote administrator, а вот с регистрацией ты не постарался
Постарался... Прочти комментарий к переменной $dependonsn. Подобным образом, я "не постарался" и в скрипте для CDCheck 3.1.10.0 (переменная $encodedserial). Реестровый способ регистрации этих приложений проще и не требует их запуска.

Цитата:

вываливается окно у кот. нет названия, что с этим делать незнаю, мож накидаешь скрипт доконца?
Я на днях посмотрю, и, возможно, добавлю в скрипт и стандартный способ регистрации, хотя он и неудобен, imho.


kralex
Цитата:

DrWeb 4.33 так никто и не победил до конца?
В каком смысле? Ну не ставится он тихо, но нетихо :) - без проблем (скрипт для автоуст. Dr.Web 4.33).
Цитата:

поиздеваться над разрешением экрана
Это вполне возможно: через меню "Свойства: Экран" (RunDll32.exe shell32.dll,Control_RunDLL desk.cpl,,3) или через реестр (HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Hardware Profiles). Оба способа не шибко удобны, т.к. в первом нужно будет пересовывать ползунок (trackbar) для изменения разрешения, а второй потребует перезагрузки.

Цитата:

как прописать reboot с заходом в режим защиты от сбоев
Код:

bootcfg.exe /raw "/safeboot:minimal" /a /id 1
shutdown.exe -r -t 0 -f

В первой команде /id 1 - 1-й элемент списка загрузки файла boot.ini. Если на компе несколько ОС, то можно не туда дописать параметр. Поэтому, лучше воспользоваться ф-циями работы с ini-файлами самого АвтоИт-а - так точно не ошибешься.
Цитата:

и автоматом активировать некоторые действия
Ну, это уже от твоей фантазии зависит :) Только не забудь восстановить нормальный режим загрузки, удалив /safeboot:minimal из boot.ini, а то комп так и будет постоянно в safe-mode грузиться :)


Tanis
Цитата:

не появляется индикатор установки и заключительное окно.
Применительно к msi, это определяется ключами /q (детальнее см. msiexec /?):
Код:

/q[n|b|r|f]
Выбор уровня интерфейса пользователя
n - Без интерфейса
b - Основной интерфейс
r - Сокращенный интерфейс
f - Полный интерфейс (по умолчанию)

Цитата:

неприятность происходит с программами устанавлеваемыми из msi пакетов.
Ну и как тебе помочь, ты даже строки запуска не привел. А при таких исходных условиях, как любят говорить в fido, - "Телепаты в отпуске" :) Хотя, XXXler в данном сл. прав - для msi лучше использовать файлы трансформации mst. Только нужно найти нормальный редактор для удобного создания/редактирования таких файлов - Orca (можно взять на http://www.wasm.ru) плоховат в этом отношении.

nsergeip 14-03-2006 09:51

кто знает как при помощи реестра изменить текущий часовой пояс в windows. по умолчанию стоит москва, а мне надо екатеринбург? или мож есть какой другой способ?

Sanja Alone 15-03-2006 02:55

nsergeip
Доделал скрипт для Radmin 2.2 (добавил регистрацию стандартным методом + все действия теперь определяются переменными в секции Global).

kralex 15-03-2006 12:38

Цитата:

Ну, это уже от твоей фантазии зависит Только не забудь восстановить нормальный режим загрузки, удалив /safeboot:minimal из boot.ini, а то комп так и будет постоянно в safe-mode грузиться
Все сделал, спасибо за код
Код:

bootcfg.exe /raw "/safeboot:minimal" /a /id 1
.
С восстановлением нормального режима пришлось повозиться (плохо когда мало знаний). Так и не смог найти команду после действий в Safe mode, чтобы винда "ребуталась" в нормальном режиме. пришлось прописать AutoIt-ом скриптик замены файла boot.ini - safe mode на boot.ini -normal. Дополнительно слепить пришлось SFX архив с указанием абсолютного пути. Но все равно, огромное спасибо Sanja Alone, свою проблему я решил.

Vadikan 15-03-2006 12:58

nsergeip
Цитата:

кто знает как при помощи реестра изменить текущий часовой пояс в windows. по умолчанию стоит москва, а мне надо екатеринбург? или мож есть какой другой способ?
Твики реестра прикреплены в соседнем форуме
Код:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones

nsergeip 15-03-2006 15:15

Vadikan
Цитата:

Твики реестра прикреплены в соседнем форуме
там я уже читал, написано там немного не про то что я спрашивал, по ветке
Код:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones
можно поменять лишь название определенного часового пояса, а мне нужно изменить не название, а сам часовой пояс!!!

Sanja Alone 16-03-2006 04:33

kralex
Цитата:

Так и не смог найти команду после действий в Safe mode, чтобы винда "ребуталась" в нормальном режиме
И неудивительно - с пом. bootcfg.exe нельзя удалить параметр, внесенный в режиме /raw. Поэтому я и сказал, что лучше все сделать с пом. АвтоИт (используя ф-ции работы с ini-файлами).

Цитата:

Дополнительно слепить пришлось SFX архив с указанием абсолютного пути
А это еще зачем? Чем тебя не устраивает переменная %systemdrive% (из АвтоИт скрипта к ней можно достучаться с пом. EnvGet("systemdrive"))?

Tanis 16-03-2006 17:05

Sanja Alone
Пакеты MSI я cтавлю такой командой
Код:

Run ( 'msiexec /i "'&$file&'" /norestart')
Я поразбирался, все было связано с библиотекой msi.dll. Проблемы начинались с версией 3.1.4000.2457 пришлось заменить на 3.1.4000.2435. Сейчас вроде все нормально. Еще возник вопрос : Можно ли с помощью AutoIt выставить права на ветку реестра, если нет то как это можно сделать?

Sanja Alone 17-03-2006 05:21

Tanis
Цитата:

Run ( 'msiexec /i "'&$file&'" /norestart')
Одобряю, но с одной оговоркой:
Код:

$filename = '\filename.msi'
$file = @ScriptDir & $filename

Т.е., переменная $file должна содержать полный путь, а не только filename.msi (если использовать откомпилированный скрипт, то "И так сойдет..." :) /цитата с мультика о зайце-"мастере"/ ).
P.S. У меня тоже версия 3.1.4000.2435, но не думаю, что это имеет особое значение.

Цитата:

Можно ли с помощью AutoIt выставить права на ветку реестра
С пом. средств АвтоИт никак, а какой MS-утилкой это сделать я не знаю (мне известен только ручной способ - regedit -> "Разрешения"), увы :(

amel27 25-03-2006 12:48

Цитата:

Цитата:

Можно ли с помощью AutoIt выставить права на ветку реестра
С пом. средств АвтоИт никак, а какой MS-утилкой это сделать я не знаю (мне известен только ручной способ - regedit -> "Разрешения"), увы
1. В оснастке MMC "Шаблоны безопасности" создать шаблон с нужными правами к реестру и сохранить в INF файле.
2. Применить шаблон к системе можно следующей командой (пример):
Код:

secedit /configure /cfg rights.inf /db %TEMP%\rights.sdb
P.S. Следует иметь ввиду что права назначаются не по имени а по SID. Поэтому для тиражирования шаблонов по другим компам нужно использовать только учетные записи с предопределенными SID, например Users (S-1-5-32-545), Administrators (S-1-5-32-544) и т.д.

Sergio12305 28-03-2006 00:12

У меня вопрос по AutoIt. Как скомпилировать скрипт, который будет включать в себя *.exe , *.mp3 , *.jpg , и т.д. (все в одном exe-файле). Функция "Fileinstall" добавляет любые файлы к сценарию. А как запустить их внутри сценария ? Заранее спасибо.

Sanja Alone 28-03-2006 03:53

Sergio12305
Цитата:

Как скомпилировать скрипт, который будет включать в себя *.exe , *.mp3 , *.jpg , и т.д.
Обычным способом. Все файлы, указанные в параметрах source ф-ции FileInstall ( "source", "dest" [, flag] ) будут автоматически включены в откомпилированный скрипт.

Цитата:

А как запустить их внутри сценария ?
Никак. Считай эту ф-цию аналогом sfx-архива. Т.е., сначала включенные файлы "разархивируются" в указанные в параметрах dest места, а уже затем их можно запускать и т.п.

shita 30-03-2006 18:46

У меня вопрос как в автоите вызвать функцию WinApi SetSystemTime. Т.е. как ее вызвать с помощью DLLCall я знаю, а вот как правильно передать параметры чтобы поменять дату незнаю.

bogomolv 30-03-2006 23:23

shita
Ну молодежь и дает! Как вызвать функцию WinApi SetSystemTime ... с помощью DLLCall знают, а что такое DATE из CMD - нет!

Sanja Alone 31-03-2006 04:23

bogomolv
Привет, Сергей. Что-то давно тебя не видно было...

Цитата:

а что такое DATE из CMD - нет!
Ну, не суди так строго. Не все ведь свое знакомство с ПК начинали с DOS-а. Да и всего знать невозможно... Мне, например, нечего сказать по WinAPI :(

shita
Код:

$date = '30.12.2006'
RunWait(@comspec & ' /c date ' & $date,'',@SW_HIDE)


bogomolv 31-03-2006 08:16

Sanja Alone
Саня, и тебе привет.
Да я не строго! Я любя и немножко с завистью.

А вы здесь все переиначили! Я сначала не разобрался и недели три тупо заглядывал по старому адресу, удивляясь, а чего это никто не пишет...
Новая структура стала информативнее. Только общих тем все равно не будет хватать, и зря вы, модераторы, гонятете Osa-7. Не обращал внимание, как обсуждение особенностей установки программы часто перетекает в обсуждение самих установщиков и возможностей их применения?
Именно из таких обсуждений узнал об InstallRite и удобной связке InnoUnp+InnoSetup. C удовольствием опробовал их. С помощью InnoUnp+InnoSetup расковырял Download Master, а на основе InstallRite создал свой установщик DrWeb (ставится за две секунды!). На радостях накинулся на MS IntelliPoint. Но не тут-то было. InstallRite с ним справиться не может. Но даже с непобежденным IntelliPoint установка WinXP и всех программ занимает у меня теперь 15 мин 30 сек. Именно, так - с секундомером, и вылизываю теперь свои скрипты автоустановки.

shita 31-03-2006 19:50

Sanja Alone
Спасибо, а то надоело каждый раз дату менять чтобы PL/SQL Developer запустить, время trial закончилось.
bogomolv
Да вроде не молодежь, но с этим не стыкался. А DLLCall то, что в справке нашел.

Vadikan 02-04-2006 02:52

bogomolv
Цитата:

Я сначала не разобрался и недели три тупо заглядывал по старому адресу, удивляясь, а чего это никто не пишет...
Так вроде в первый пост прописали большими красными буквами :)
Цитата:

зря вы, модераторы, гонятете Osa-7
Уже никто не гоняет :)
Цитата:

Именно из таких обсуждений узнал об InstallRite
Гм, а как же материалы сайта? http://oszone.net/display.php?id=2767 :)


NORIO 02-04-2006 09:44

Привет.
Я хочу с помощью autoi it производить копирование выделенного текста(в edit полях) но не симулируя ввод с клавиатуры ctrl+c, а исползуя api windows. Хотелось бы узнать как это сделать.

NORIO 02-04-2006 09:56

Добавлю что это нужно сделать под win 98, нужно копировать plain text и rich text.

proxy 03-04-2006 09:14

Доброго Времени Суток.
Подскажите пожалуйста, как отследить нажатую - какая именно была нажата?

bogomolv 03-04-2006 14:27

Vadikan

Да я не ради спора. :)

NikLok 03-04-2006 16:21

Неожиданно выяснилось, что AutoIt вставляет символы в зависимости от текущей раскладки клавиатуры. В частности при вводе серийного номера в AcdSee 8 при русской раскладке, всталвяется левый номер! Вопрос как узнать текущую раскладку? Ну не анализировать же собственный воод?

amel27 03-04-2006 17:09

NikLok
Цитата:

Неожиданно выяснилось, что AutoIt вставляет символы в зависимости от текущей раскладки клавиатуры.
Поконкретней - "вставляет" какой командой?.. И, кстати, AutoIT посвящена отдельная ветка.

NikLok 04-04-2006 11:01

amel27
Цитата:

Поконкретней - "вставляет" какой командой?.. И, кстати, AutoIT посвящена отдельная ветка.
"Вставляет" командой -
Код:

        Send("DKXDVH-3348T-3NHQXB-GHCPRXQ")
Хотя в строке посылаются английские символы, увы попадает кракозябра. Получается, он настолько честно эмулирует, что посылает не те коды которые указаны в строке, а скан коды соотв. клавиш!?
Не смотрел как работает команда посылки в окно ввода (забыл как она называется - SendEdit может?). Неужели у нее те же грабли?

Выяснилось все это когда систему которая ставится с MUI, поставилась без него. Причем непонятно почему то раскладка клавы по умолчанию все ранво всегда русская!
Я уже всю страницу по локализации прочитал и воплотил а воз и ныне там.
Видать где то, что накрутил.
О существовании отдельной ветки знаю и читаю. Но мне кажется этот нюанс должен учитываться и в этой ветке.


amel27 04-04-2006 11:51

Цитата:

Не смотрел как работает команда посылки в окно ввода (забыл как она называется - SendEdit может?). Неужели у нее те же грабли?
ControlSetText()
Цитата:

О существовании отдельной ветки знаю и читаю. Но мне кажется этот нюанс должен учитываться и в этой ветке.
Все-таки это ветка ИМХО для готовых решений, а особенности конкретного ПО лучше обсуждать отдельно.

bogomolv 04-04-2006 19:52

NikLok

Используй
Код:

ClipPut('DKXDVH-3348T-3NHQXB-GHCPRXQ')
Send('+{Ins}')


Vadikan 07-04-2006 01:25

В шапку добавлена ссылка на справочник по rundll32 - мне показалось, что в AutoIt это пригодится.

NikLok 07-04-2006 18:49

Подскажите, как из автоит скрипта запустить другие автоит скрипты?

bogomolv 08-04-2006 04:13

NikLok
Сначала поблагодари за предыдущий ответ :)

proxy 08-04-2006 19:03

Доброго Времени Суток ещё раз.
1. Подскажите пожалуйста, как отследить нажатую клавишу? - какая именно была нажата?


bogomolv 09-04-2006 07:13

proxy
Поясни вопрос. Обычно AutoIt сам эмулирует нажатие нужных клавиш. А ты хочешь от него обратного?

proxy 09-04-2006 10:30

Я хочу узнать какую клавишу (к примеру ASCII код) нажал пользователь, для последующей записи в log.
.......проще говоря: Как в AutoIt реализовать перехват клавиш, без их замены как это делает HotKeySet.
К примеру я пишу текст в блокноте, а программа будет показывать все нажатые клавиши.

bogomolv 09-04-2006 12:00

proxy
На мой взгляд, ты хочешь от AutoIt то, для чего он не предназначен. "AutoIt", - все-таки, это: "a freeware BASIC-like scripting language designed for automating the Windows GUI".
Наверное, тебе больше подойдет брат AutoIt'а - AutoHotKey. Без труда найдешь его в сети.

proxy 10-04-2006 14:12

Большое Спасибо, по обилию функций в справке - AutoHotKey - это именно то, что я искал.

NikLok 10-04-2006 15:38

bogomolv Канычна сапасиба. Везде поменял на твой вариант и усе замечательно за...лось!


В раже даже написал скрипт для смены веремени выбора систеым в файле BOOT.INI
мОЖЕТ ЕГО еще как можно было изменить, но я сделал так!

Код:

$file = FileOpen("c:\boot.ini",0)
; Check if file opened for writing OK
If $file = -1 Then
    MsgBox(0, "Error", "Unable to open c:\boot.ini file.")
    Exit
EndIf

$newfile = FileOpen('c:\boot_new.ini',2)
; Check if file opened for writing OK
If $newfile = -1 Then
    MsgBox(0, "Error", "Unable to open c:\boot_new.ini file.")
    Exit
EndIf

; Read in lines of text until the EOF is reached
While 1
    $line = FileReadLine($file)
    If @error = -1 Then ExitLoop
    If StringInSTr( $line, "timeout=", 0) = 1 Then
            FileWriteLine($newfile, "timeout=7")
    Else
            FileWriteLine($newfile, $line)
    EndIf
;    MsgBox(0, "Line read:", $line)
Wend

FileClose($file)
FileClose($newfile)

FileSetAttrib ( "c:\boot.ini", "-R-S-H" )
FileCopy ( "c:\boot.ini" , "c:\boot_old.ini", 1 )
FileCopy ( "c:\boot_new.ini", "c:\boot.ini" , 1 )
FileDelete("c:\boot_new.ini")
FileSetAttrib ( "c:\boot.ini", "+R+S+H" )
Exit

Может кому надоть.

VelDmi 10-04-2006 18:31

Имеется следующий скрипт:

$netsh = @ScriptDir & '\netsh.cfg'
RunWait (@SystemDir & '\netsh.exe interface ip dump > ' & $netsh, @SystemDir, @SW_HIDE)

Так вот файл netsh.cfg создается в ДОС кодировке. И я не могу прочитать русские слова командами автоита.
$file = FileOpen($netsh, 0)
$line = FileReadLine($file)
Получаесся абракадабра. Что делать?

bogomolv 10-04-2006 20:28

NikLok
Пожалуйста! Приходите еще! :)
Код:

RunWait('AutoIt3 script.au3')

bogomolv 11-04-2006 08:52

VelDmi
Когда-то решал подобную проблему так:
Код:

$f = 'C:\1.txt'
$aa = FileRead($f, FileGetSize($f))
$a1 = " ЎўЈ¤Ґс¦§Ё©Є«¬*®ЇабвгдежзийклмнопЂЃ‚ѓ„…р†‡?‰Љ‹ЊЌЋЏђ‘’“”•–—?™љ›њќћџ"
;переменная $a1 взята из ECHO "абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ" > C:\1.txt
$a2 = "абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ"
For $i = 1 To StringLen($aa)
 $k = StringInStr($a1, StringMid($aa, $i, 1))
 If $k>0 Then $aa = StringReplace($aa, $i, StringMid($a2, $k, 1))
Next
msgbox(0,'',$aa)


VelDmi 11-04-2006 09:11

bogomolv
Спасибо, решил свою проблему так:
RunWait (@COMSPEC & ' /c chcp 1251 && netsh.exe interface ip dump > netsh.cfg', @SystemDir, @SW_HIDE)
Файл создается в нужной кодировке.

bogomolv 11-04-2006 12:48

VelDmi
И это правильно! Что-то подобное и я тогда искал, но не доискал...

Sanja Alone 12-04-2006 02:48

VelDmi
bogomolv
Вы, конечно, будете смеяться, но когда я вчера пробовал подобный вариант в кач-ве возможного способа решения обозначенной проблемы, то рез-т был неутешительным:
Код:

RunWait (@comspec & ' /c chcp 1251 && ping.exe 127.0.0.1 > ping.log','', @SW_HIDE)
Файл ping.log получается в OEM-кодировке.

При этом, в конструкции:
Код:

RunWait (@COMSPEC & ' /c chcp 1251 && netsh.exe interface ip dump > netsh.cfg', @SystemDir, @SW_HIDE)
команда chcp реально изменяет кодировку.

Это я к тому, что способ неуниверсальный :(

amel27 13-04-2006 16:11

2 вложений
bogomolv
Цитата:

Когда-то решал подобную проблему так
ИМХО AutoIT не лучший выбор для подобных задач - не поддерживает работу со стандартными потоками и тормозит на циклах. Для командных утилит хочется "нечто", обрабатывающее транзитный текстовый поток, в тырнете не нашел ничего подходящего, только для файлов... Сначала подумал про VBS - там есть поддержка StdIn и StdOut, но проще всего оказалось на Си. Вот что у меня получилось, пример:
Код:

type file1.txt | dos2win >file2.txt
ping 127.0.0.1 | dos2win >ping.log

Sanja Alone
Цитата:

Это я к тому, что способ неуниверсальный
Можно для надежности воткнуть chcp 866 вначале но и это не гарантия, есть утилиты выводящие только в Win-кодировке.

bogomolv 14-04-2006 08:31

amel27
Цитата:

ИМХО AutoIT не лучший выбор для подобных задач
Так и задача была AutoIt'овская... В скрипте AutoIt нужно было обработать сообщение. Потом выяснилось, что и обрабатывать там особо нечего, и я просто вставил проверку на наличие искомого выражения в неправильной кодировке...

bogomolv 17-04-2006 10:15

amel27
Спасибо за упоминание StdOut.
Обратив внимание на где-то виденное сочетание буковок, освоил новую для себя функцию AutiIt3 - StdoutRead().
Раньше для считывания результатов командной строки использовал перенаправление в >C:\1.txt или CLIPCOPY.EXE.
Теперь все читаю напрямую.
Пример, где отыскиваются и затем запускаются все скрипты, нужные на конкретной стадии автоустановки:
Код:

$dr = Run('%Comspec% /c dir "c:\drivers\*_2.au3" /s /b', '', 0, 6)
 $f  = ''
 While not @error
  $f = $f & StdoutRead($dr)
 Wend
$dr=StringSplit(StringReplace($f,@LF,''),@CR)
For $i=1 To $dr[0]-1
 RunWait('AutoIt3.exe "'&$dr[$i]&'"')
Next


amel27 17-04-2006 13:23

bogomolv
Блин, надо же! Сам давно искал подобное, но пропустил - бум знать. :)

saguna 20-04-2006 13:16

всем привет!
вопрос: я заметил что скомпиленные в ехе скрипты во время своей работы занимают до 50-80 а иногда и 100% загрузки процессора! замечали ли вы подобное и как с этим бороться.. для примера:

Код:

AdlibEnable("buff", 500)
        While 1
        WEnd       
 Exit

Func buff()
        $bak = ClipGet()
        MsgBox(0,"","буфер содержит: " & $bak)
        Exit
EndFunc

данный скрипт грузит мой пень4 - 3ггц до 50% уровня... возможно ли написать более корректно сам алгоритм постоянной работы функции?
выход из зацикливания, необходим только в примере, на деле мне надо чтобы скрипт выполнялся постоянно в фоновом режиме..

NikLok 20-04-2006 16:08

bogomolv
Как задействовать в автоите функцию StdoutRead. Ибо версия 3 выдает - незнаю таковой!

bogomolv 20-04-2006 17:02

NikLok
Скачать более позднюю... Судя по ChangeLog, эта функция появилась в первых же бетах после выпуска официальной версии 3.1.1.
Я сейчас пользуюсь версией 3.1.1.102.

NikLok 20-04-2006 17:34

bogomolv
Спасибо! Ща скачаю!

Artya 25-04-2006 20:20

а подскажите как в комбо загрузить текст из файла.
в файле каждая отдельная строка это какое то слово. например
слово1
слово2
слово3
и т.д.

З.Ы.
всем спасибо :) уже разобрался :))

Ptyuch 26-04-2006 17:15

Никак не пойму: функция Global действует в теле только одного скрипта? Пытаюсь задать переменную в первом скрипте, и, пока он работает, использовать ее значение во втором:

1 файл - 1.exe
global $a=20
run("2.exe")
/тело скрипта/

2 файл - 2.exe
/тело скрипта/
msgbox(0,"","a is " &$a, 2)

Если это не работает, как бы мне еще ввести "переключатели" (в первом файле часть скрипта отработала - во втором происходит переключение на следующий этап)?
Все это для того, чтобы progressbar располагался отдельно от других скриптов, но был с ними связан... Это же возможно? :)

bogomolv 26-04-2006 20:13

Ptyuch
Код:

1 файл - 1.exe
  global $a=20
  run("2.exe "&$a)
  /тело скрипта/

2 файл - 2.exe
  /тело скрипта/
  $a=$CmdLine[1]
  msgbox(0,"","a is " &$a, 2)


Ptyuch 29-04-2006 10:05

Было бы красиво! ;) Только первый файл не выполняется: ошибок в скрипте нет, только вот:
Unable to execute an external program
Не удается найти указанный файл:
run("2.exe"&$a)

Без аргумента $a скрипт запускается. Any idea?

bogomolv 29-04-2006 12:49

Ptyuch
Идей нет. Есть замечания.
Разве у меня написано run("2.exe"&$a)?

Ptyuch 29-04-2006 16:32

Огромное спасибо!
%#! Даже в голову не пришло поставить пробел перед ". Может, где можно почитать про такой синтаксис? Потому что я иду дальше по схеме:
1 файл - 1.exe
global $a=20
run("2.exe "&$a)
/тело скрипта.../
global $a=40
и т.д.

2 файл - 2.exe
$a=$CmdLine[1]
msgbox(0,"","a is " &$a, 2)
/тело скрипта.../
msgbox(0,"","a is now " &$a, 2)
В этом случае прописанные условия во втором файле опирались бы на состояние изменяющейся переменной из первого файла. Пока срабатывает только первый триггер, прописанный в global $a -> $cmdlines[1]. Может, как-нибудь через Adlib? Не знаю, правда, как ;)

Dirk Diggler 29-04-2006 17:18

У меня есть скрипт, регистрирующию nnBackup. Его регистрация проходит в консольном окне, поэтому я посылаю туда кириллицу с помощью команды Send("{ASC 123}"). Однако это работает только в NT-системах, в 9х там лезет какая-то кразяберность. Как послать кириллицу в консольное окно 9х?

Dirk Diggler 29-04-2006 17:41

По старенькому пройдемся:
Цитата:

Доделал скрипт для Radmin 2.2 (добавил регистрацию стандартным методом + все действия теперь определяются переменными в секции Global).
Народ, а зачем его вообще так ставить? Я простое копирование файлов/импортирование ветки реестра делаю, работает на ура.
Цитата:

Цитата:

Можно ли с помощью AutoIt выставить права на ветку реестра
С пом. средств АвтоИт никак, а какой MS-утилкой это сделать я не знаю (мне известен только ручной способ - regedit -> "Разрешения"), увы
SubInAcl. НАсчет установки разрешений умеет все.

bogomolv 29-04-2006 19:49

Ptyuch
Ты, по моему, вообще задачу решаешь немного не с того конца. :)
Если это всего лишь бегунок, то лучше всего использовать Adlib.
Пример бегунка, приблизительно отсчитывающего время установки:
Код:

...
ProgressOn  ('Установка Nero 7','','',-1,-1,18)
$pr=0
AdlibEnable  ('progress',300)
...
ProgressOff  ()
AdlibDisable ()
...
Func progress()
 $pr=$pr+1
 ProgressSet($pr)
EndFunc


Lexi 01-05-2006 18:53

Я пытаюсь перевести конвертер ASCI ->UTF-8 с C на autoit :). Но видимо что-то не правильно понимаю. На вход функции подаю C3, а на выходе получаю C3 83, что явно неправильно. Или правильно и ошибка в другом?
Код на C
Код:

int conv_x2utf(unsigned char* bufin, int len, unsigned char* bufout)
{ int i, j = 0;

  for (i = 0; i < len; i++)
  {
    if (bufin[i] >= 0x80)
    { bufout[j++] = (((bufin[i] >> 6) & 0x3f) | 0xc0);
      bufout[j++] = (bufin[i] & 0x3f) | 0x80;
    }
    else
      bufout[j++]  = bufin[i];
  }

  return j;
}

Autoit:
Код:

Func StringToUTF($String)
Dim $String
$VarUTFArr = StringSplit ( $String, "" )

For $i = 1 To $VarUTFArr[0]
$code = Asc ($VarUTFArr[$i])

If $code < 128 Then
$VarUTFArr[$i] = Chr ($code)
        Else
$VarSt1 = BitOR (BitAND ((BitShift ($code, 6)), 0x3f), 0xc0)
$VarSt2 = BitOR (BitAND ($code, 0x3f), 0x80)
$VarUTFArr[$i] = Chr ($VarSt1) & Chr ($VarSt2)
        EndIf
Next

Dim $sResult
For $iCntr = 1 To $VarUTFArr[0]
        $sResult = $sResult & $VarUTFArr[$iCntr]
        If ($iCntr < $VarUTFArr[0]) Then
                $sResult = $sResult
        EndIf
Next

Return $sResult
EndFunc

Нашёл исходник конвертера на FoxPro. И он работает!:)
Код:

Func StringToUTF($String)
Dim $String
$VarUTFArr = StringSplit ( $String, "" )

For $i = 1 To $VarUTFArr[0]
$code = Asc ($VarUTFArr[$i])

Select
    Case $code >= 192 AND $code <= 239
        $VarUTFArr[$i] = Chr (208) & Chr ($code-48)
    Case $code >= 240 AND $code <= 255
        $VarUTFArr[$i] = Chr (209) & Chr ($code-112)
    Case $code = 168
        $VarUTFArr[$i] = Chr (208) & Chr (129)   
    Case $code = 184
        $VarUTFArr[$i] = Chr (209) & Chr (145)   
    Case Else
        $VarUTFArr[$i] = Chr ($code)
EndSelect
       
Next

Dim $sResult
For $iCntr = 1 To $VarUTFArr[0]
        $sResult = $sResult & $VarUTFArr[$iCntr]
        If ($iCntr < $VarUTFArr[0]) Then
                $sResult = $sResult
        EndIf
Next

Return $sResult
EndFunc


NORIO 10-05-2006 08:51

А кто нибудь знает как взять текст из TreeView, ListView и Listbox входящих в состав интерфейса других програм
(а не GUI сгенерированного autoit скриптом)?

VelDmi 10-05-2006 15:02

Имеется программа Runpad Shell. У нее есть API.

API в основном используется клиентами программ контроля, хотя может быть полезным и для любых сторонних утилит.

Все функции реализованы ввиде COM-сервера.
Примеры использования для C, C++, Delphi находятся здесь

Общие замечания:
- доступ к функциям осуществляется через единый интерфейс IRunpadShell
- все функции возвращают S_OK в случае успеха и другие коды в противном случае
- функции не являются Unicode

Моя задача написать утилиту, которая бы использовала апи программы на автоит.
Примеры на C, C++, Delphi имеются, но я совершенно не понимаю в этих языках, а с автоит поладил.
Возможно ли написание такой программы на AutoIt?

Sanja Alone 11-05-2006 04:22

NORIO
Цитата:

А кто нибудь знает как взять текст...
С уверенностью утверждать не буду (мне это пока не особо нужно было, поэтому лог обновлений просмотрел мельком), но, вроде в текущих бетах АвтоИт-а такие возм-ти реализованы - попробуй скачать.

VedunO 12-05-2006 22:46

StringRegExp - не работает :(
 
1 вложений
Пытаюсь разобраться с регулярными выражениями в AutoIt, но не получается :(

Следующий код не работает:

Код:

Local $sPattern, $sTest, $vResult, $nFlag

$sPattern = InputBox("StringRegExp Sample", "What is the pattern to test?")
$sTest = InputBox("StringRegExp Sample", "What is the line to test?")
$vResult = StringRegExp ($sTest, $sPattern)
Select
Case @Error = 2
    ; Error.  The pattern was invalid.  $vResult = position in $sPattern where error occurred.
Case @Error = 0
  if @Extended  Then
      ; Success.  Pattern matched.  $vResult matches @Extended
  Else
      ; Failure.  Pattern not matched.  $vResult = ""
  EndIf
EndSelect
MsgBox(0, "", $vResult)

Не работает, выпадает окошко (во вложении)

Что я делаю не так ???

XXXler 15-05-2006 14:17

VedunO, функцию по-ходу убрали (во всяком случае в 3.1.1 ее уже нет)

Никто не в курсе - в будующих версиях планируется ли введение в функцию FindFirstFile() рекурсивного просмотра (с вложенными папками)?

Sanja Alone 16-05-2006 04:39

VedunO
Цитата:

Что я делаю не так
Судя по скриншоту - пытаешься исп-ть более раннюю версию AutoIt не знающую данную ф-цию. Или не загрузил обновление для SciTE, в к-ром будут прописаны новые ф-ции.

XXXler
Цитата:

функцию по-ходу убрали (во всяком случае в 3.1.1 ее уже нет)
Точнее сказать - добавили, а в 3.1.1 ее еще нет.

The public history for AutoIt v3
Full technical log including beta versions

XXXler 16-05-2006 12:13

Sanja Alone,
Цитата:

Точнее сказать - добавили, а в 3.1.1 ее еще нет.
странно, в русской справке к v3.1.0 она упоминается

Sanja Alone 17-05-2006 03:03

XXXler
Цитата:

странно, в русской справке к v3.1.0 она упоминается
Это весьма забавный момент: в англ. справке к версии 3.1.1 этой ф-ции нет, но ее знает SciTE (с дефинишенами для AutoIt версии 3.1.1). Т.е., по идее, в 3.1.1 ф-ция должна быть, но, при попытке запуска скрипта вылазит окошко с ошибкой (неизвестное имя ф-ции) - тут явно авторы AutoIt намудрили...

Apple58 20-05-2006 00:54

Подскажите, как запустить процесс с параметром снятого атрибута ONTOP.
Сам процесс - это окошко с атрибутом ONTOP.
Если ждать появления окна а потом с помощью WinSetState снять атрибут ONTOP, то оно успевает вылезти на самый верх, после чего убирается.

Да, заодно еще вопросик.
Сможет ли, запущенный процесс со снятым атрибутом ONTOP, запускать окошки с атрибутами ONTOP?
А эту проблемку можно обойти?

Dirk Diggler 21-05-2006 04:28

Я использую Send для посылки текстати типа "xUSSR"
Код:

Send("xUSSR")
Но это работает только когда раскладка английская. Как сделать так, чтобы и в русской и прочих раскладках посылалось именно то, что написано?

bogomolv 21-05-2006 07:15

Dirk Diggler
Цитата:

Я использую Send...
А я использую Поиск...
Поэтому знаю, что проблема легко решается с помощью clipboard. :)

Dirk Diggler 21-05-2006 14:22

Какой еще клипборд в консольных приложениях типа окна cmd.exe????

bogomolv 22-05-2006 09:56

Dirk Diggler
Такой: http://forum.oszone.net/post-424899-108.html. Это ответ на твой первый вопрос.
И такой: http://forum.oszone.net/post-428524-126.html. Это - на второй.

Dirk Diggler 22-05-2006 10:57

Ни первая, ни вторая ссылка не в тему. Не работает вставка клипборда в консольное окно. Dixi. Нужен другой способ.
Особенно я не понял, причем тут Stdout

bogomolv 22-05-2006 21:13

Dirk Diggler
Код:

WinWaitActive('Командная строка')
ClipPut('xUSSR')
MouseClick('right')
Send('а')

Я на все вопросы ответил? Спасибо за внимание.

Dirk Diggler 23-05-2006 13:39

Нет. Ибо в моей практике 20% консольных окон не выкидывают контекстного меню. Пришлось доработать, но не в этом суть.. А в том, что всё это как-то через задницу. Результат - скрипт для регистрации nnbackup

Код:

$Dir = @ProgramFilesDir & "\NNbackup"
$SF= "nnbackup xReg"       


Opt        ("WinTitleMatchMode",        2)        ;1=start, 2=subStr, 3=exact, 4=...]
Opt        ("MouseCoordMode",        0)
Opt ("TrayIconDebug",1)

#include <Date.au3>


$iWeekday = _DateToDayOfWeek (@YEAR, @MON, @MDAY)

Select
    Case $iWeekday = 1
            $Day="воскресенье"
    Case $iWeekday = 2
            $Day="понедельник"
    Case $iWeekday = 3
            $Day="вторник"
    Case $iWeekday = 4
            $Day="среда"
    Case $iWeekday = 5
            $Day="четверг"
    Case $iWeekday = 6
            $Day="пятница"
    Case $iWeekday = 7
            $Day="суббота"
EndSelect


$TEMP = @WorkingDir
FileChangeDir ($Dir)
Run($SF)
WinWaitActive("nnbackup.exe")
;Sleep ( 1000 )
ClipPut('xUSSR регистрация')
MouseMove(10,10,0)
MouseClick('right')
Send("{DOWN 7}{RIGHT}{DOWN 2}{ENTER 2}")
ClipPut($day )
Sleep (500 )
MouseClick('right')
Send("{DOWN 7}{RIGHT}{DOWN 2}{ENTER 2}")


bogomolv 23-05-2006 21:10

Dirk Diggler
Твоя задачка напомнила что-то подозрительно знакомое. Вспомнил - SlyControl...
Хоть давно им не пользуюсь, удалось разыскать у себя в архиве скрипт:
Код:

RunWait('regedit /s "' & $pDir & 'Sly.reg"')
If @MON=01 Then $mnc='югбоьт'
If @MON=02 Then $mnc='хлбюмеч'
If @MON=03 Then $mnc='ноуь'
If @MON=04 Then $mnc='ббулзт'
If @MON=05 Then $mnc='нок'
If @MON=06 Then $mnc='йрот'
If @MON=07 Then $mnc='йрит'
If @MON=08 Then $mnc='бмаээь'
If @MON=09 Then $mnc='рлоьупыт'
If @MON=10 Then $mnc='пдсснюч'
If @MON=11 Then $mnc='маьпьт'
If @MON=12 Then $mnc='елйонюч'
RegWrite('HKEY_CURRENT_USER\Software\SlyDiman\SlyControl2', 'xUSSR', 'REG_SZ', $mnc)


VedunO 24-05-2006 19:23

Не могу понять, как работает функция "InetGet", пишу:

Код:

FtpSetProxy(1)    ; прокси не используется
InetGet ("ftp://user:password@10.1.1.18/file.ext", "D:\file.ext", 1)

... и ничего

P.S. вбиваю этот же адрес в Internet Explorer (v6.0) и все работает отлично, пока пользуюсь внешним WGET-ом

Solitude 28-05-2006 03:27

Подкажите как в AutoIt скрипте дождаться появления некотрого файла, тоесть выполнение скрипта надо продолжить только тогда как появиться конкреткный файл ???

Monarhia 28-05-2006 04:45

1) Можно ли замениь значок который светитса в панели здач?
2) Какой командой возможно открыть порт?

godoo 29-05-2006 15:05

Monarhia, по первому вопросу: в Aut2Exe смотри в раздел Options -> Custom Icon.

Sanja Alone 29-05-2006 22:36

Solitude
Цитата:

выполнение скрипта надо продолжить только тогда как появится конкретный файл
Способ 1 (ожидание с прерыванием основной программы)
Код:

While 1
If FileExists ('disk:\path\filename.ext') Then
...
действия, производимые после появления файла
...

EndIf
;интервал проверок (в данном примере - 2 с)
Sleep (2000)
WEnd

Или
Код:

While FileExists ('disk:\path\filename.ext')=0
Sleep (2000)
WEnd
...
действия, производимые после появления файла
...

Или
Код:

Do
Sleep (2000)
Until FileExists ('disk:\path\filename.ext')=1
...
действия, производимые после появления файла
...

Способ 2 (ожидание на фоне основной программы)
Код:

AdlibEnable('fe',2000)
...
Func fe()
If FileExists ('disk:\path\filename.ext') Then
...
действия, производимые после появления файла
...

EndIf
EndFunc


Monarhia 05-06-2006 10:11

А нельзя компилировать с путём к файлу, а он компилируетса со скриптом, типо одним целым становятса?
Хотябы картинку можно вставить?

godoo 05-06-2006 12:01

Monarhia Иконки, которые отображаются в трее хранятся в AutoIt3.exe. Можно попробовать скорректировать редактором ресурсов - но это не выход. Иконка будет другая, но опять-же одна. Проще всего просто скрыть иконку в трее.

adima 08-06-2006 11:58

Не подскажет ли кто как организовать индикатор процесса установки (типа бегунка или любой другой) для данной команды

RunWait (@ScriptDir & '\wmp10.exe /q:A /c:"setup_wm.exe /Q /R:N /DisallowSystemRestore"')

desperate 15-06-2006 02:52

извините если пишу немного не сюда, просто у меня не одна ссылка на скачивание самой программы AutoIT3 не работает.... ктобы мог поделиться этой прогой и прислать мне ее на niro@lipetsk.ru заранее спасибо

Redisych 15-06-2006 17:02

Объясните, что за функции Visa Management? В первый раз с таким сталкиваюсь.
И ещё, есть ли возможность как-то работать с железом - COM портом, USB, и т.д.

bogomolv 18-06-2006 11:03

adima
А чем тебя не устраивают ранее предлагавшиеся варианты? Особенно много вариантов (с активным обсуждением!) было в прародительнице этой темы.

desperate
Только что проверил ссылки: http://www.autoitscript.com/autoit3/downloads.php, http://www.autoitscript.com/autoit3/files/beta/autoit/
Работают!

Redisych
Про Visa Management ничего не знаю. Узнаешь сам - не забудь отписаться сюда и поделиться.
Про работу с железом. Не понял, что ты имеешь ввиду, но скорее всего тебе поможет использование в скриптах MS-овской утилитки devcon (http://support.microsoft.com/kb/311272/ru).

Redisych 20-06-2006 23:22

bogomolv
Хочется обработки сигналов, например, с COM порта, а ещё генерацию произвольных сигналов.

bogomolv 21-06-2006 08:54

Redisych
Могу лишь процитировать AutoIt Help:
Цитата:

AutoIt v3 is a freeware BASIC-like scripting language designed for automating the Windows GUI.

Redisych 21-06-2006 09:09

Надеюсь, что дойдёт и до остального, раз приличный конструктор GUI приделали. Я, если честно, когда начал осваивать язык, и не думал, что изначально он предназначался для "автокликанья". Хотелось бы услышать об опыте написания "классических" приложений и о перспективе такого подхода. Стоит ли, или лучше изучить языки, на которых пишет большинство?

Redisych 21-06-2006 09:32

Вот ведь, как чувствовал, что Visa близко к моим потребностям. Нашёл на их форуме такое:
Цитата:

Basically GPIB allows you to control instruments like Power Supplies, Signal Generators, Oscilloscopes, Signal Generators, etc. You need to install or connect a GPIB interface card (PCI, PCMCIA or USB) to your PC and install the corresponding GPIB driver.

VISA is a standard API that sits on top of the GPIB driver and it allows you to use the same programs to control your instruments regardless of the type of GPIB card that you have installed in your PC (most cards are made either by National Instruments or by Agilent/Hewlett-Packard).
Остаётся разобраться, что за GPIB interface card
bogomolv, кстати, мои соболезнования по поводу вентилятора. А мы соседи, я в городе химиков, энергетиков и строителей...

SyCraft 23-06-2006 19:47

а как в Auto IT сделать GUI, очень много прочел про то как описывается сам GUI но вот как назначить его элементам те или иные действия мне не ясно..

XXXler 23-06-2006 20:01

После прорисовки GUI гоняешь цикл:
Код:

While 1
        $msg = GuiGetMsg()
        ....
        ....
WEnd

В теле цикла проверяешь какой елемент послал сообщение:
Код:

Select
        Case $msg=$GUI_EVENT_CLOSE
                Exit
        Case $msg=$Имя_елемента_1
                ....
        Case $msg=$Имя_елемента_2
                ....
        ....
                EndSelect
        EndSelect

и соответственно обрабатываешь.
Взять значение с елемента можно с пом. GUICtrlRead(), установить - GUICtrlSetData(), GUICtrlSetState() и т.д. - все можно найти в справке

vasin 24-06-2006 00:55

1 вложений
Проблемка со скриптом для создания Dial-up подключения..
Суть проблемы в том что не всегда "ставиться" галка "использовать правила набора номера"..
Вот скрипт с пометками автора... Может кто-нибудь может что-то добавить/изменить..




SyCraft 24-06-2006 02:42

XXXler
Спасибо буду разбираться!!!

bogomolv 24-06-2006 07:44

vasin
Так проще:
Код:

;Настройка "Свойства" соединения
$pbk='@AppDataCommonDir@\Microsoft\Network\Connections\Pbk\rasphone.pbk'
$co=IniReadSectionNames($pbk)
For $i=1 to $co[0]
 IniWrite ($pbk, $co[$i], 'DataEncryption',                '8')
 IniWrite ($pbk, $co[$i], 'ShowMonitorIconInTaskBar',        '1')
 IniWrite ($pbk, $co[$i], 'ConnectBPS',                '460800')
 IniWrite ($pbk, $co[$i], 'Speaker',                        '0')
 IniWrite ($pbk, $co[$i], 'AreaCode',                $cod)
 IniWrite ($pbk, $co[$i], 'CountryCode',                $ccod)
 IniWrite ($pbk, $co[$i], 'CountryID',                $ccod)
 IniWrite ($pbk, $co[$i], 'UseDialingRules',                '1')
Next


SyCraft 24-06-2006 12:06

XXXler
Скажи а как скажем зделать что бы скажем было 2-е строки ввода пути
10 чек боксов, и кнопка старта. Идея копирование из источника в получатель тех групп файлов которые отмечены чек боксом, при нажатии на кнопку Старт но с возможностью отмены!
Такое возможно зделать?

XXXler 24-06-2006 14:22

SyCraft
Если я правильно понял про отмену (одна для всех перед копированием) то долно получится примерно так:
Код:

While 1
$msg = GuiGetMsg()
If $msg=$GUI_EVENT_CLOSE Or $msg=$Имя_кнопки_отмены Then
Exit (или ExitLoop)
ElseIf $msg=$Имя_кнопки_старт Then
GUISetState(@SW_HIDE)
TrayTip("Идет копирование файлов","Дождитесь окончания копирования файлов",1,1)
$FirstPath=GUICtrlRead($Имя_елемента_ввода_1)
$SecondPath=GUICtrlRead($Имя_елемента_ввода_2)

If GUICtrlRead($чек_бокс_1)=1 Then
....
EndIf

If GUICtrlRead($чек_бокс_2)=1 Then
....
EndIf

....

If GUICtrlRead($чек_бокс_n)=1 Then
....
EndIf

Exit (или ExitLoop)
EndIf
WEnd


SyCraft 25-06-2006 00:55

XXXler
Спасибо!!!

SyCraft 25-06-2006 17:12

Вот что получаеться, но при компиляции вываливаеться с ощибкой, подскажи пожалуйста что я напутал?
Код:

#include <GUIConstants.au3>

;Получаем переменные Opera AC
$AC_OPERA = RegRead ("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment", "AC_OPERA")
$AC_SOURCH = RegRead ("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment", "AC_SOURCH")

While 1
$msg = GuiGetMsg()
If $msg = $GUI_EVENT_CLOSE
        Or $msg = $Close Then
        ExitLoop

ElseIf $msg = $Start Then
        GUISetState(@SW_HIDE)
TrayTip("Идет копирование файлов","Дождитесь окончания копирования файлов",1,1)

$FirstPath=GUICtrlRead($Input)
$SecondPath=GUICtrlRead($Output)

$Form1 = GUICreate("AForm1", 659, 352, 214, 146)
$Pic1 = GUICtrlCreatePic("D:\Project\Soft\Opera$\Create\WizModernImage-IS.BMP", 8, 0, 153, 345)

GUICtrlCreateLabel("Источник", 176, 8, 52, 17)
$Input = GUICtrlCreateInput("AInput1", 176, 24, 425, 21, -1, $WS_EX_CLIENTEDGE)
GUICtrlCreateLabel("Получатель", 176, 56, 63, 17)
$Output = GUICtrlCreateInput("AInput2", 176, 72, 425, 21, -1, $WS_EX_CLIENTEDGE)

$Bookmaarks = GUICtrlCreateCheckbox("ACheckbox1", 184, 112, 97, 17)
$Notes = GUICtrlCreateCheckbox("ACheckbox2", 184, 136, 97, 17)
$cookies = GUICtrlCreateCheckbox("ACheckbox3", 184, 160, 97, 17)
$wand = GUICtrlCreateCheckbox("ACheckbox4", 184, 184, 97, 17)
$vlink4 = GUICtrlCreateCheckbox("ACheckbox5", 184, 208, 97, 17)
$global = GUICtrlCreateCheckbox("ACheckbox6", 184, 232, 97, 17)
$download = GUICtrlCreateCheckbox("ACheckbox7", 184, 256, 97, 17)
$cache = GUICtrlCreateCheckbox("ACheckbox8", 184, 280, 97, 17)

$Start = GUICtrlCreateButton("AButton1", 328, 312, 113, 25)
$Close = GUICtrlCreateButton("AButton2", 544, 312, 105, 25)

GUICtrlCreateLabel("Закладки", 288, 112, 315, 17)
GUICtrlCreateLabel("Заметки", 288, 136, 315, 17)
GUICtrlCreateLabel("Куки", 288, 160, 315, 17)
GUICtrlCreateLabel("Пароли жезла", 288, 184, 315, 17)
GUICtrlCreateLabel("Набранные адреса", 288, 208, 315, 17)
GUICtrlCreateLabel("История посещений", 288, 232, 315, 17)
GUICtrlCreateLabel("История закачек", 288, 256, 315, 17)
GUICtrlCreateLabel("Кеш", 288, 280, 313, 17)
GUISetState(@SW_SHOW)

If GUICtrlRead($Bookmaarks) = 1 Then
DirCreate("$SecondPath")
FileCopy("$FirstPath\profile\opera6.adr", "$SecondPath\profile\",1)
EndIf

If GUICtrlRead($Notes) = 1 Then
DirCreate("$SecondPath")
FileCopy("$FirstPath\profile\notes.adr", "$SecondPath\profile\",1)
EndIf

If GUICtrlRead($cookies) = 1 Then
DirCreate("$SecondPath")
FileCopy("$FirstPath\profile\cookies4.dat", "$SecondPath\profile\",1)
EndIf

If GUICtrlRead($wand) = 1 Then
DirCreate("$SecondPath")
FileCopy("$FirstPath\profile\wand.dat", "$SecondPath\profile\",1)
EndIf

If GUICtrlRead($global) = 1 Then
DirCreate("$SecondPath")
FileCopy("$FirstPath\profile\global.dat", "$SecondPath\profile\",1)
EndIf

If GUICtrlRead($download) = 1 Then
DirCreate("$SecondPath")
FileCopy("$FirstPath\profile\download.dat", "$SecondPath\profile\",1)
EndIf

If GUICtrlRead($cache) = 1 Then
DirCreate("$SecondPath")
DirCopy("$FirstPath\profile\cache4\", "$SecondPath\profile\cache4\",1)
EndIf

ExitLoop

EndIf
Wеnd


Creat0R 06-07-2006 19:42

Всем доброго времени суток!

У меня возникла следущая проблема:

Я создал скрипт, который вызывает окно где можно выбрать каталог, и затем скрипт вписывает результат выбора в файл.
Вот его состав:

Код:

$var = FileSelectFolder("Вибирите каталог...", "")

If @error Then
    Dim $iMsgBoxAnswer
$iMsgBoxAnswer = MsgBox(292,"?","Вы уверенны")
Select
  Case $iMsgBoxAnswer = 6;Yes

  Case $iMsgBoxAnswer = 7;No
EndSelect
Else
    $var = StringReplace($var, "|", @CRLF)
    MsgBox(4096,"","You chose " & $var)
    FileWrite ( "file.tmp", $var )
EndIf

Теперь вопрос:
Как я могу сделать так, что если в том окне, которое появится после нажатия на 'Отмена' (в первом окне), пользователь нажимает в нём 'Нет', то будет запущено первое окно снова. Т.е нужно как-то вернуться на метку, которая будет стоять перед выводом первого окна.

P.S:
Я знаю что существует команда Wend и она как-то связанна с командой While = - Но как ей пользоваться, т.е как её подставлять в скрипт, я беспонятия

Creat0R 06-07-2006 20:30

Есть ещё вопрос:
Можно ли каким-то образом, конвертировать скрипт Bath (файла *.bat), в скрипт AutoIT?

bogomolv 06-07-2006 22:33

SyCraft
Цитата:

Вот что получаеться, но при компиляции вываливаеться с ощибкой, подскажи пожалуйста что я напутал?
Насажал ошибок, причем не только в каждом слове этого сообщения, но и в скрипте :)
В частности, неправильно пишешь имена переменных внутри строки:
вместо "$FirstPath\profile\notes.adr",
нужно писать $FirstPath&"\profile\notes.adr"
или "$FirstPath$\profile\notes.adr" (в последнем случае нужно задать Opt("ExpandVarStrings",1)).

Creat0R
1) Нужная тебе конструкция While... Wend подробно и с примерами описана в AutoIt Help. Лучше, чем там, тебе никто не объяснит.
2) Конверторов скриптов Bath в скрипт AutoIT нет и не будет.

Creat0R 07-07-2006 01:09

bogomolv
Цитата:

1) Нужная тебе конструкция While... Wend подробно и с примерами описана в AutoIt Help.
Вот пример который описан в справке:

Код:

Пример

$i = 0
While $i <= 10
    MsgBox(0, "Значение $i равно:", $i)
    $i = $i + 1
WEnd

С этого примера, и с описании которые в справке, мне трудно понять, каким образом в моём скрипте, будет возвращено управление на метку в начало скрипта?! я пробовал так, но не работает, пишет ошибка в команде wend:

Код:

While $iMsgBoxAnswer = 7
$var = FileSelectFolder("Select a folder.", "")
If @error Then
Dim $iMsgBoxAnswer
$iMsgBoxAnswer = MsgBox(292,"Msg","you sure?")
Select
  Case $iMsgBoxAnswer = 6 ;Yes

  Case $iMsgBoxAnswer = 7 ;No

EndSelect
Wend
Else
        $var = StringReplace($var, "|", @CRLF)
       
        MsgBox(64,".....","Вы выбрали:  " & $var)
        FileWrite ( "c.tmp", $var )
EndIf

Тут, где команда While $iMsgBoxAnswer = 7, нужно чобыы туда происходил переход в том случае, если была нажата кнопка No
Цитата:

Лучше, чем там, тебе никто не объяснит.
А может всё-таки ты сможешь лучше объяснить? плиз? - очень очень нужно.

SyCraft 07-07-2006 01:50

Ну вроде все исправил.. но тепрь такая проблема.. после нежатии кнопки начала копирования, копирование не происходит, просто выскакивает информационное окно о начале процеса все..
Не подскажите где я вновь учудил?
Код:

#include <GUIConstants.au3>

;Получаем переменные Opera AC
$AC_OPERA = RegRead ("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment", "AC_OPERA")
$AC_SOURCH = RegRead ("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment", "AC_SOURCH")

$Form1 = GUICreate("AForm1", 659, 352, 214, 146)
$Pic1 = GUICtrlCreatePic("D:\Project\Soft\Opera$\Create\WizModernImage-IS.BMP", 8, 0, 153, 345)
$Bookmaarks = GUICtrlCreateCheckbox("Закладки", 184, 112, 97, 17)
$Notes = GUICtrlCreateCheckbox("Заметки", 184, 136, 97, 17)
$cookies = GUICtrlCreateCheckbox("Куки", 184, 160, 97, 17)
$wand = GUICtrlCreateCheckbox("Пароли жезла", 184, 184, 97, 17)
$vlink4 = GUICtrlCreateCheckbox("Набранные адреса", 184, 208, 97, 17)
$global = GUICtrlCreateCheckbox("История посещений", 184, 232, 97, 17)
$download = GUICtrlCreateCheckbox("История закачек", 184, 256, 97, 17)
$cache = GUICtrlCreateCheckbox("Кеш", 184, 280, 97, 17)
GUISetState(@SW_SHOW)

$Start = GUICtrlCreateButton("Go", 328, 312, 113, 25)
$Close = GUICtrlCreateButton("Exit", 544, 312, 105, 25)

GUICtrlCreateLabel("Источник", 176, 8, 52, 17)
$Input = GUICtrlCreateInput($AC_SOURCH, 176, 24, 425, 21, -1, $WS_EX_CLIENTEDGE)
GUICtrlCreateLabel("Получатель", 176, 56, 63, 17)
$Output = GUICtrlCreateInput($AC_OPERA, 176, 72, 425, 21, -1, $WS_EX_CLIENTEDGE)

$SecondPath=GUICtrlRead($Output)
$FirstPath=GUICtrlRead($Input)

While 1
$msg = GuiGetMsg()
If $msg = $GUI_EVENT_CLOSE  Or $msg = $Close Then
        Exit
ElseIf $msg = $Start Then
        MsgBox("Идет копирование файлов","Дождитесь окончания копирования файлов", "Дождитесь окончания копирования файлов",1)
EndIf

Opt("ExpandVarStrings",1)

If GUICtrlRead($Bookmaarks) = 1 Then
        FileCopy("$FirstPath$\profile\opera6.adr", "$SecondPath$\profile\*.*",1)
        EndIf

If GUICtrlRead($Notes) = 1        Then
        FileCopy("$FirstPath$\profile\notes.adr", "$SecondPath$\profile\*.*",1)
        EndIf

If GUICtrlRead($cookies) = 1 Then
        FileCopy("$FirstPath$\profile\cookies4.dat", "$SecondPath$\profile\*.*",1)
        EndIf

If GUICtrlRead($wand) = 1 Then
        FileCopy("$FirstPath$\profile\wand.dat", "$SecondPath$\profile\*.*",1)
        EndIf

If GUICtrlRead($global) = 1 Then
        FileCopy("$FirstPath$\profile\global.dat", "$SecondPath$\profile\*.*",1)
        EndIf

If GUICtrlRead($download) = 1 Then
        FileCopy("$FirstPath$\profile\download.dat", "$SecondPath$\profile\*.*",1)

If GUICtrlRead($cache) = 1 Then
        DirCopy("$FirstPath$\profile\cache4\", "$SecondPath$\profile\cache4",1)
        EndIf

EndIf
WEnd


bogomolv 07-07-2006 09:33

Creat0R
Ты не понимаешь суть базового понятия "цикл".
+
Несколько раз перечитал твое
Цитата:

Как я могу сделать так, что если в том окне, которое появится после нажатия на 'Отмена' (в первом окне), пользователь нажимает в нём 'Нет', то будет запущено первое окно снова. Т.е нужно как-то вернуться на метку, которая будет стоять перед выводом первого окна.
В твоем описании задачи все окна "первые"...

Поэтому могут лишь подправить твой скрипт:
Код:

While 1
$var = FileSelectFolder("Select a folder.", "")
If NOT @error Then
  $iMsgBoxAnswer = MsgBox(292,"Msg","you sure?")
  Select
    Case $iMsgBoxAnswer = 6 ;Yes
      $var = StringReplace($var, "|", @CRLF)
      MsgBox(64,".....","Вы выбрали:  " & $var)
      FileWrite ( "c.tmp", $var )
      Exit
    Case $iMsgBoxAnswer = 7 ;No
    Case Else
      Exit
  EndSelect
Else
  Exit
EndIf
Wend

SyCraft
Цитата:

Не подскажите где я вновь учудил?
Везде:
1. У оператора MsgBox другой синтаксис MsgBox(0,"", "",1)
2. Считывать значения редактируемых переменных нужно в цикле
Код:

While 1
$msg = GuiGetMsg()
$SecondPath = GUICtrlRead($Output)
$FirstPath = GUICtrlRead($Input)
...

3. Следи за условными переходами! У тебя $cache будет копироваться только, если копируется $download!
Сделай так:
Код:

While 1
...
If $msg = $GUI_EVENT_CLOSE  Or $msg = $Close Then
        Exit
ElseIf $msg = $Start Then
      MsgBox(0,"Идет копирование файлов","Дождитесь окончания копирования файлов",1)
      If GUICtrlRead($Bookmaarks) = 1 Then
              ...
              EndIf
      ...
EndIf
WEnd

4. Учись отлаживать свои скрипты сам! Мне очень помогает вставка в проверяемое место MsgBox(0,"", "",1).
Например, в твой скрипт я вставил вместо FileCopy("$FirstPath$\profile\opera6.adr", "$SecondPath$\profile\*.*",1)
проверку MsgBox(0,"","$FirstPath$\profile\opera6.adr TO $FirstPath$\profile\*.*").
Тут же все твои косяки вылезли наружу.
5. Много мелких недочетов. В частности, зачем циклишь объявление опции Opt("ExpandVarStrings",1)? Обычно это делается в начале скрипта.

SyCraft 07-07-2006 10:39

bogomolv
Спасибо, ты уж не взыщи просто я далек от программирования и только учусь!!!
Спасибо тебе!

Creat0R 07-07-2006 11:59

bogomolv
Огромное тебе спасибо! Всё так как и нужно было! :bye:
Я кажется понял суть работы команд Wend и While - Всё что находится между ними, будет выполняться до тех пор, пока значение одной из команд будет ровно 0 (или любое другое кроме 1 - если есть такого), но как я понял, это в случае если у команды While присутствует значение 1 (While = 1). А какие ещё есть возможности её использования?

У меня есть пару вопросов:

1) Как осуществлять поиск существующего пути\каталога, и затем произвести определённое действие?
Т.е, вот например команда $search = FileFindFirstFile("file.tmp"), произведёт поиск файла file.tmp.
А если сделать так:
Код:

$search = FileFindFirstFile("File.tmp")
If $search = -1 Then
MsgBox(0, "Error", "File was not found")
    Exit
EndIf

То в случае если файл не найден, будет выведенно сообщение.
Но мне вообще-то нужно, чтобы был поиск не файла, а каталога\пути (или даже будет лучше, если значения $var). Примерно так я себе это представляю:
Код:

$search = FileFindFirstFile("$var")
If $search = -1 Then
Тут нужно перейти в начало файла (думаю вместо этой строки поставить просто wend, а в строке выше, поменять -1 на 0, так?)

2) Как во время выполнения сценария, можно спрятать окно другого-запущенного приложения? (в данном случае - *.bat файл). Т.е чтобы сам скрипт, какой то командой, скрыл запущенное окно командной строки. Или хотябы сделать так, чтобы запущенное окно (Bath файла) самим скриптом AutoIt, было скрыто в момент его (батника) запуска!

Dirk Diggler 07-07-2006 12:52

в хелпе все написано. Ох, батенька, взяли бы какую-нть книжку по информатике для 9 класса.

Creat0R 07-07-2006 14:01

Dirk Diggler
Цитата:

в хелпе все написано.
Не всё, и не понятно! :no: (уж извените) - а книжка по информатике чем мне поможет? как правильно восспринимать информацию с хелпов? думаю тут ни это нужно... мне нужна практика (ведь как известно, одна лишь практика даёт желаемые результаты почти в любом деле - а в програмировании тем более)... читать и понимать написанное, я умею, вот если бы написанно было кем-то не очень ленивым (или занятым?) чувалеком, было бы легче понимать. Ясное дело, что тем кто уже знает толк в этом деле (да и в любом другом), легче рассуждать и утверждать, что в хелпе, и в факе, и ещё где, написанно всё понятно - хотя для такого, можно сказать - чайника в сфере программирования как я сам, то что там пишут, и так как это пишут, далеко не понятно! (по крайней мере не всё!).
Имхо, справку, которую переделали на русский, как будто с помощью словаря переделывали. Не то чтобы автор этой справки не знает английского, или программирования в AutoIt, я вовсе этого не утверждаю, просто считаю что можно было бы приложить немного больше усилии, ради такой весчи - как помощь по AutoIt'у!).

P.S:
Извеняюсь за офтоп! (если он таков есть).

Dirk Diggler 08-07-2006 01:27

книжка поможет освоить базовые понятия программирования.
2ALL Написал тут скрипт VBS-> AU3. Ничего особенного, просто закатывает VBS в AU3, а тот пишет его в темп и запускает. Какую длину потянет - не проверял. Да и всякие ситуации хэндлятся не особо. Но мне достаточно, я более доделывать не буду. Работает из командной строки
script.au3 vbsname.vbs Au3name.au3
при отсутсвии параметров или только второго запросит соот-но оба или один в виде виндового диалога. Запрос на перезапись не дает.
Код:

Global $filename
Global $vbs
Global $vbshandle
Global $au3handle
Global $au3filename
Global $Line
Global $error

   
$func = 'Func RunVBS( $vbs)  ' & @CRLF  _ 
& ' Local $batname= "temp"& @MIN & @SEC & ".bat"  ' & @CRLF  _
& ' Local $vbsname= "temp"& @MIN & @SEC & ".vbs"  ' & @CRLF  _
& ' FileDelete(@TempDir & "\" & $vbsname)  ' & @CRLF  _
& ' FileWrite(@TempDir & "\" & $vbsname  , $vbs)  ' & @CRLF  _
& ' FileWrite(@TempDir & "\" & $batname, $vbsname)  ' & @CRLF  _
& ' sleep(1000)  ' & @CRLF  _
& ' RunWait( @ComSpec &' & " ' /c" & ' "' & "'& @TempDir & '\' & $batname &" & "'" &  '"' &  "'" & ',@TempDir,@SW_HIDE)  '  & @CRLF  _ 
& ' FileDelete(@TempDir & "\" & $vbsname )  ' & @CRLF  _
& ' FileDelete(@TempDir & "\" & $batname) ' & @CRLF  _
& ' EndFunc'


If $cmdline[0] =0 Then
        $filename = FileOpenDialog("Choose vbs", @HomeDrive,"VBScript (*.vbs)", 1)
        if @error = 1 Then
            MsgBox(0,"Error","Wrong filename or file error")
            Exit
        EndIf
       
    Else
        $filename = $cmdline[1]
EndIf

$vbshandle =FileOpen($filename,0)
If $vbshandle = -1 Then
    MsgBox(0,"Error","vbs file read error")
    Exit
EndIf
   
if $cmdline[0]>1 Then
    $au3filename = $cmdline[2]       
Else
    $au3filename = FileSaveDialog("Enter au3 filename", @HomeDrive,"AutoIt3 (*.au3)",0, "vbs.au3")
    if @error = 1 Then
            MsgBox(0,"Error","Wrong filename or file error")
            Exit
    EndIf
EndIf

$au3handle =FileOpen($au3filename,2)
If $au3handle = -1 Then
    MsgBox(0,"Error","Au3 file write error")
    Exit
EndIf
$Line = " $vbsscript = '" & FileReadLine($vbshandle)
FileWrite($au3handle,  $Line)
SetError(0)
While $error <> -1
    $Line = FileReadLine($vbshandle) 
    $error = @error
    if ($error <> -1) And StringStripWS($Line,8) <> ""  Then 
        FileWrite($au3handle, "' & @CRLF  _ " & @CRLF)
       
    EndIf
    if StringStripWS($Line,8) <> "" Then
        $Line = "& '" & $Line   
    Else
        ContinueLoop
    EndIf
    FileWrite($au3handle,  $Line)   
WEnd   
    FileWrite($au3handle,"'")
    FileWrite($au3handle,@CRLF & @CRLF)
    FileWrite($au3handle,"RunVBS($vbsscript)")
    FileWrite($au3handle,@CRLF & @CRLF)
   
    FileWrite($au3handle,$func)
FileClose($vbshandle)
FileClose($au3handle)


bogomolv 08-07-2006 08:15

Creat0R
Цитата:

Думаю вместо этой строки поставить просто wend, а в строке выше, поменять -1 на 0, так?
Ну так ставь! Вместо пустых простыней и споров, лучше бы двадцать раз перепопробовал все свои варианты. Глядишь бы, и понял, что Wend без While не бывает, да и много чего другого полезного узнал.
Цитата:

Как во время выполнения сценария, можно спрятать окно другого-запущенного приложения?
Shows, hides, minimizes, maximizes, or restores a window - WinSetState ( "title", "text", flag )

"Всему лучшему в себе я обязан книгам". А.М.Горький

VelDmi 08-07-2006 13:39

Creat0R
Цитата:

Имхо, справку, которую переделали на русский, как будто с помощью словаря переделывали. Не то чтобы автор этой справки не знает английского, или программирования в AutoIt, я вовсе этого не утверждаю, просто считаю что можно было бы приложить немного больше усилии, ради такой весчи - как помощь по AutoIt'у!
Не удержался, так как считаю что сдесь ты не прав. Я не задаю сдесь кучу вопросов потому, что русификация справки ВЕЛИКОЛЕПНА! Может быть не идеал, но по сравнению с другими русификациями что я видел сделано очень хорошо. По крайней мере большинство вопросов решалось именно путем перечитывания справки.

PS А тебе действительно поможет учебник для начинающих, так как само понятие циклов, условных переходов и т.д. одинаково для всех языков и начинать нужно с изучения основ.

ANGRO 08-07-2006 15:29

Попробовал решить проблему с выводом из CMD как предлогал bogomolv в 120 посте. Во первых если копировать код из инета то он не работает т.к. изменяется строка в $a1 надо брать именно по ECHO, но у меня и она не заработала пока не взял эту строку из GUI самого скрипта. Более того есть большое подозрение что на Win с MUI эта строка будет другой и вообще памятуя о проблемах с кодировками сделал запрос при запуске скрипта. Теперь $a1 будет генерироваться при запуске скрипта под каждой виндой заново.
Код:

#include <Constants.au3>
#NoTrayIcon
$f = "C:\test.txt"
$aa = FileRead($f, FileGetSize($f))
$a2 = "абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ"
    $cmdRun = Run(@ComSpec & " /c ECHO " & $a2, @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
                $a1 = StdoutRead($cmdRun, -1)
For $i = 1 To StringLen($aa)
 $k = StringInStr($a1, StringMid($aa, $i, 1))
 If $k>0 Then $aa = StringReplace($aa, $i, StringMid($a2, $k, 1))
Next
msgbox(0,'',$aa)

P.S. Метод предложенный VelDmi в 121 посте не сработал при выводе в GUI скрипта.
Хотя здесь и писалось хочу напомнить что StdoutRead работает только в последних беттах.
P.P.S. bogomolv, VelDmi смотрел форум на сайте разработчиков, не нашёл таких решений как у Вас, хотя конечно все посты не читал но поиск поюзал основательно. Было бы неплохо закинуть код туда.

ANGRO 08-07-2006 16:05

Creat0R хелп не ругай коли чайник. Я сам полный самовар в программировании, как здесь советовали пробую сотни вариантов кода и методом научного тыка пытаюсь разобраться. ИМХО читать не люблю особенно учебники. А объяснять основы программирования справка не обязанна. Если мозги текут отпишись в PM гуру, здесь люди отзывчивые помогут. А вообще для того чтобы писать листинги на чистом листе уходят годы обучения. Так что если не готов закажи нужную весч у знающих людей. Кстати справочку человек переводил бесплатно и нужно сказать спасибо за человекачасы и применённые знания.

Извените не удержался.

Creat0R 08-07-2006 18:39

bogomolv
Цитата:

"Всему лучшему в себе я обязан книгам". А.М.Горький
А есть книги по AutoIt'у? (Хорошо, т.е понятно написанны).

Creat0R 08-07-2006 19:32

ANGRO
Цитата:

хелп не ругай коли чайник.
Я и не ругал хелп. Конечно же огромное спасибо автору справки, просто я лично не узнал в ней то что мне нужно (также как и из справки которая сделана на английском) - Кстати, я если и возмущён по поводу этой справки, так это только по поводу того, что она не сильно информативна (та что на английском).


P.S:
А у автора этой справки, прошу искринние извинения, у меня небыло намеринии оскорблять, или ругать работу кого либо! -Просто как сказал ANGRO, я есть Чайник в сфере программирования (или самовар ;) )

ANGRO 08-07-2006 21:39

Решил собрать на основе кода из 196 поста что нить полезное так сказать для проверки в драйв тесте.
Почему-то получился пинг :biggrin: .
Код:

#include <GUIConstants.au3>
#include <Constants.au3>
#NoTrayIcon
Opt("GUICloseOnESC", 0)
GUICreate("Пинг", 372, 304)
;GuiSetIcon("11.ico", 0)
$Edit1 = GUICtrlCreateEdit("", 2, 2, 370, 251, $ES_READONLY + $WS_VSCROLL, $WS_EX_CLIENTEDGE)
GUICtrlSetFont ($Edit1,10, 550, 0, "Lucida Console")
GuiCtrlSetBkColor($Edit1,0xf5f5f5)
GuiCtrlSetCursor($Edit1,2)
GuiCtrlCreateLabel("Домен или IP", 42, 257, 112, 20)
GuiCtrlCreateLabel("Кол-во запросов", 141, 257, 90, 20)
$Quant = GUICtrlCreateInput("5", 140, 279, 90, 20)
$Host = GUICtrlCreateInput("www.ru", 26, 279, 112, 20)
$Button_1 = GUICtrlCreateButton("Пинг", 240, 257, 105, 43)
;------------------------------------------------
$a2 = "абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ"
$cmdRun = Run(@ComSpec & " /c ECHO " & $a2, @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
        $a1 = StdoutRead($cmdRun, -1)
;------------------------------------------------
GUISetState(@SW_SHOW)
; GUI BUTTON PROCESSING
Do
        $msgP = GUIGetMsg()
Select       
        Case $msgP = $Button_1
            $ip = GUICtrlRead($Host)
            $Quantity = GUICtrlRead($Quant)
                $PingI = Run(@ComSpec & " /c ping.exe -n "  & $Quantity & " " & $ip, @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
                While 1
                        $aa = StdoutRead($PingI, -1)
                        If @error = -1 Then ExitLoop
                        ;-------------------------------------
                                For $i = 1 To StringLen($aa)
                $k = StringInStr($a1, StringMid($aa, $i, 1))
                If $k>0 Then $aa = StringReplace($aa, $i, StringMid($a2, $k, 1))
                Next
                        ;-------------------------------------
                        GUICtrlSetData($Edit1, StringStripWS($aa, 1) & @crlf, 1)
                Wend
EndSelect
Until $msgP = $GUI_EVENT_CLOSE

Еслиб кто ещё прикрутил сюда кнопку стоп, а то я не додумался как выслать Control-C и главное куда.

Creat0R 10-07-2006 04:34

Кто-то может мне помочь со следующей задачей:

Нужно запустить прогрессБар, и чтобы он автоматом закрылся, в тот момент как завершит свою работу определённый запущенный процесс в системе (а точнее запущеный скрипт *.bat файла) - и если возможно, то чтобы в окне прогресс бара, была видна бегущая надпись, с текстом который я выберу. (если нет, то хотябы поместить этот текст обычно, как в MsgBox).
Возможно таке осуществить?

Есть ещё вопрос:

При запуске диалога для выбора файла, возвращается значение в переменную $var (что-то в этом роде):
Код:

$var = FileOpenDialog("Выбирите архив...", "", "Zip (*.zip)")
Но когда я пытаюсь записать результат в файл:
Код:

FileWrite("c.tmp", $var)
То файл (c.tmp) сохраняется в том каталоге, где и был выбран архив.
Следовательно вопрос: Как мне осуществить сохранение файла (c.tmp), в текущем каталоге? т.е в том каталоге где и находится сам скрипт. Но чтобы ненужно было указывать полный путь, так как запускаться скрипт будет постоянно с разных мест.

XXXler 10-07-2006 13:04

Цитата:

Как мне осуществить сохранение файла (c.tmp), в текущем каталоге? т.е в том каталоге где и находится сам скрипт. Но чтобы ненужно было указывать полный путь, так как запускаться скрипт будет постоянно с разных мест.
Смотри в списке макро папок (в данном случае @ScriptDir)
Код:

$var = FileOpenDialog("Выбирите архив...", "", "Zip (*.zip)")
FileWrite(@ScriptDir&"\c.tmp", $var)


DenchikK 12-07-2006 04:47

Подскажите пожалуйста, как можно совместить работу такого (примерного)
скрипта. На основе поставленной в ней задачи, хочу научится некоторым
нужным впоследствии, рабочим скриптам. Так что не удевляйтесь
возможной несуразности его (скрипта) логики.

По частям он работает, но как совместить его работу, моего ума, хелпов
и статей форума явно не достаточно...

Идея вот в чём:

1. Выбираю первую или вторую колонку, и/или ставлю вручную нужные
галочки.
2. Жму на "Кнопка Выбора".
3. Если надо, повторяю п.1 и/или п.2 для выбора другой колонки.
4. Жму "Выполнить" - выполняются соответствующие чекбоксам операции.

5. Нажатия на кнопку "Выход" должно приводить к выходу из скрипта на
любом этапе.

6. Не знаю, как придумать, чтоб при повторном нажатии на "Кнопка
Выбора" происходил бы select / deselect чекбокса.


Вроде бы смог понятно обяснить...

Вот скрипт:
Код:


#include <GUIConstants.au3>

Opt("GUICoordMode", 1)

GUICreate("Учусь Работать С Чекбоксами", 400, 300)

$checkCN1 = GUICtrlCreateCheckbox ("CHECKBOX 1", 10, 10, 120, 20)
$checkCN2 = GUICtrlCreateCheckbox ("CHECKBOX 2", 10, 30, 120, 20)
$checkCN3 = GUICtrlCreateCheckbox ("CHECKBOX 3", 10, 50, 120, 20)
$checkCN4 = GUICtrlCreateCheckbox ("CHECKBOX 4", 130, 10, 230, 20)
$checkCN5 = GUICtrlCreateCheckbox ("CHECKBOX 5", 130, 30, 230, 20)
$checkCN6 = GUICtrlCreateCheckbox ("CHECKBOX 6", 130, 50, 230, 20)

$Start = GUICtrlCreateButton("Выполнить", 10, 100, 120, 20)
$Close = GUICtrlCreateButton("Выход", 10, 120, 120, 20)

$button_1 = GUICtrlCreateButton ("Кнопка Выбора ", 10, 150, 120, 20)
$group_1 = GUICtrlCreateGroup ("Группа", 5, 175, 120, 95)
GUIStartGroup()
$radio_1 = GUICtrlCreateRadio ("Первая Колонка", 10, 190, 120, 20)
$radio_2 = GUICtrlCreateRadio ("Вторая Колонка", 10, 205, 120, 20)

$radioval1 = 0    ; We will assume 0 = first radio button selected, 2 = last button
$radioval2 = 2

GUISetState ()

While 1
  $msg = GUIGetMsg()
  Select
      Case $msg = $GUI_EVENT_CLOSE
        Exit
      Case $msg = $GUI_EVENT_MINIMIZE
        MsgBox(0,"", "Dialog minimized",2)
      Case $msg = $GUI_EVENT_MAXIMIZE
        MsgBox(0,"", "Dialog restored",2)
 
      Case $msg = $button_1

        if  $radioval1 = 0 then
                ControlCommand ( 'Учусь Работать С Чекбоксами', '', 'Button1', 'Check', '' )
                ControlCommand ( 'Учусь Работать С Чекбоксами', '', 'Button2', 'Check', '' )
                ControlCommand ( 'Учусь Работать С Чекбоксами', '', 'Button3', 'Check', '' )
        EndIf

        if  $radioval1 = 1 then
                ControlCommand ( 'Учусь Работать С Чекбоксами', '', 'Button4', 'Check', '' )
                ControlCommand ( 'Учусь Работать С Чекбоксами', '', 'Button5', 'Check', '' )
                ControlCommand ( 'Учусь Работать С Чекбоксами', '', 'Button6', 'Check', '' )
        EndIf
     
; Назначение этих двух строчек я не понимаю...
      Case $msg >= $radio_1 AND $msg <= $radio_2
        $radioval1 = $msg - $radio_1

  EndSelect
WEnd

;************************************************************************
#cs
----------------------


While 1
$msg = GUIGetMsg()
If $msg = $GUI_EVENT_CLOSE  Or $msg = $Close Then
        Exit

ElseIf $msg = $Start Then

      If GUICtrlRead($checkCN1) = 1 Then
                    MsgBox(0,"Установка","Чекбокс 1",1)
        EndIf

        If GUICtrlRead($checkCN2) = 1 Then
                    MsgBox(0,"Установка","Чекбокс 2",1)
        EndIf

        If GUICtrlRead($checkCN3) = 1 Then
                    MsgBox(0,"Установка","Чекбокс 3",1)
        EndIf

        If GUICtrlRead($checkCN4) = 1 Then
                    MsgBox(0,"Установка","Чекбокс 4",1)
        EndIf

        If GUICtrlRead($checkCN5) = 1 Then
                    MsgBox(0,"Установка","Чекбокс 5",1)
        EndIf

        If GUICtrlRead($checkCN6) = 1 Then
                    MsgBox(0,"Установка","Чекбокс 6",1)
        EndIf

EndIf
WEnd

----------------------
#ce


bogomolv 12-07-2006 10:35

DenchikK
Цитата:

Вроде бы смог понятно обяснить...
Наоборот :)

Цитата:

По частям он работает, но как совместить его работу, моего ума, хелпов
и статей форума явно не достаточно.
По каким частям? Что нужно совмещать?

Цитата:

5. Нажатия на кнопку "Выход" должно приводить к выходу из скрипта на
любом этапе.
Этапе чего? У тебя нет никаких этапов. Если тебя интересует прекращение (отмена) выполняемого действия, то такая возможность зависит от самого выполняемого действия.

Цитата:

6. Не знаю, как придумать, чтоб при повторном нажатии на "Кнопка
Выбора" происходил бы select / deselect чекбокса.
Это придумали за тебя и назвали оператором GUICtrlSetState
Код:

      Case $msg = $button_1
        If GUICtrlRead($checkCN1)=$GUI_CHECKED Then
          GUICtrlSetState($checkCN1,$GUI_UNCHECKED)
        Else
          GUICtrlSetState($checkCN1,$GUI_CHECKED)
        EndIF

Цитата:

; Назначение этих двух строчек я не понимаю...
Ну, так не ставь их!

DenchikK 12-07-2006 13:55

bogomolv
Попробуйте, пожалуйста, запустить мой скрипт - всё наглядно увидите. ;-)

Цитата:

;Назначение этих двух строчек я не понимаю...
Ну, так не ставь их!
Ну так не работает без них! :-)

Ладно - попробую ещё понятнее объяснить:
Как видно по моему скрипту - есть одна часть, которая выполняется, и вторая - закоментированная. Это я думаю видно и понятно. Первая (незакоментированная) часть в зависимости от того, какая из RadioButton выбрана, выделяет три левых или правых чекбокса - то же вроде должно быть понятно. Вторая, закоментированная, часть показывает, что с выделенными чекбоксами делать. И если запустить скрипт в том виде, как у меня он дан, можно увидеть - что первая часть (отметка чекбоксов) работает. Если закоментитровать первую часть, и раскоментировать вторую - видим что и вторая часть так же выполняет свою функцию, что на неё возложена.

Теперь немного понятнее стало какие части и что нужно совмещать?

Может и не так, как у меня записано, принцип того, что должно получится, ясен?

Добавлено:
Всё, вопрос снимается - разобрался, как это всё работает (вроде-как).
Видать жара и недосып дают о себе знать ;-) Вот что в итоге вышло:
Код:

#include <GUIConstants.au3>

GUICreate("Учусь Работать С Чекбоксами", 400, 300)

$checkCN1 = GUICtrlCreateCheckbox ("CHECKBOX 1", 10, 10, 120, 20)
$checkCN2 = GUICtrlCreateCheckbox ("CHECKBOX 2", 10, 30, 120, 20)
$checkCN3 = GUICtrlCreateCheckbox ("CHECKBOX 3", 10, 50, 120, 20)
$checkCN4 = GUICtrlCreateCheckbox ("CHECKBOX 4", 130, 10, 230, 20)
$checkCN5 = GUICtrlCreateCheckbox ("CHECKBOX 5", 130, 30, 230, 20)
$checkCN6 = GUICtrlCreateCheckbox ("CHECKBOX 6", 130, 50, 230, 20)

$Start = GUICtrlCreateButton("Выполнить", 10, 100, 120, 20)
$Close = GUICtrlCreateButton("Выход", 10, 120, 120, 20)

$button_1 = GUICtrlCreateButton ("Кнопка Выбора ", 10, 150, 120, 20)
$group_1 = GUICtrlCreateGroup ("Группа", 5, 175, 120, 95)
GUIStartGroup()
$radio_1 = GUICtrlCreateRadio ("Первая Колонка", 10, 190, 120, 20)
$radio_2 = GUICtrlCreateRadio ("Вторая Колонка", 10, 205, 120, 20)

$radioval1 = 0    ; We will assume 0 = first radio button selected, 2 = last button
$radioval2 = 2

GUISetState ()

While 1
  $msg = GUIGetMsg()

  Select
 
      Case $msg = $GUI_EVENT_CLOSE  Or $msg = $Close
        Exit
      Case $msg = $GUI_EVENT_MINIMIZE
        MsgBox(0,"", "Dialog minimized",2)
      Case $msg = $GUI_EVENT_MAXIMIZE
        MsgBox(0,"", "Dialog restored",2)


  Case $msg = $button_1
   
    if  $radioval1 = 0 then

        If GUICtrlRead($checkCN1)=$GUI_CHECKED Then
          GUICtrlSetState($checkCN1,$GUI_UNCHECKED)
        Else
          GUICtrlSetState($checkCN1,$GUI_CHECKED)
        EndIF

        If GUICtrlRead($checkCN2)=$GUI_CHECKED Then
          GUICtrlSetState($checkCN2,$GUI_UNCHECKED)
        Else
          GUICtrlSetState($checkCN2,$GUI_CHECKED)
        EndIF

        If GUICtrlRead($checkCN3)=$GUI_CHECKED Then
          GUICtrlSetState($checkCN3,$GUI_UNCHECKED)
        Else
          GUICtrlSetState($checkCN3,$GUI_CHECKED)
        EndIF
   
    EndIf


if  $radioval1 = 1 then

        If GUICtrlRead($checkCN4)=$GUI_CHECKED Then
          GUICtrlSetState($checkCN4,$GUI_UNCHECKED)
        Else
          GUICtrlSetState($checkCN4,$GUI_CHECKED)
        EndIF

        If GUICtrlRead($checkCN5)=$GUI_CHECKED Then
          GUICtrlSetState($checkCN5,$GUI_UNCHECKED)
        Else
          GUICtrlSetState($checkCN5,$GUI_CHECKED)
        EndIF

        If GUICtrlRead($checkCN6)=$GUI_CHECKED Then
          GUICtrlSetState($checkCN6,$GUI_UNCHECKED)
        Else
          GUICtrlSetState($checkCN6,$GUI_CHECKED)
        EndIF
   
    EndIf


     
; Назначение этих двух строчек я не понимаю...
      Case $msg >= $radio_1 AND $msg <= $radio_2
        $radioval1 = $msg - $radio_1

Case $msg = $Start

      If GUICtrlRead($checkCN1) = 1 Then
                    MsgBox(0,"Установка","Чекбокс 1",1)
        EndIf

        If GUICtrlRead($checkCN2) = 1 Then
                    MsgBox(0,"Установка","Чекбокс 2",1)
        EndIf

        If GUICtrlRead($checkCN3) = 1 Then
                    MsgBox(0,"Установка","Чекбокс 3",1)
        EndIf

        If GUICtrlRead($checkCN4) = 1 Then
                    MsgBox(0,"Установка","Чекбокс 4",1)
        EndIf

        If GUICtrlRead($checkCN5) = 1 Then
                    MsgBox(0,"Установка","Чекбокс 5",1)
        EndIf

        If GUICtrlRead($checkCN6) = 1 Then
                    MsgBox(0,"Установка","Чекбокс 6",1)
        EndIf

  EndSelect
WEnd


Creat0R 13-07-2006 13:07

XXXler
Цитата:

Смотри в списке макро папок (в данном случае @ScriptDir)
Огромное Спасибо!

Есть такой вопрос:

Как по команде IniWrite, записывать строчки в файл конфигурации, но не в самый конец раздела, а, например, во вторую строчку заданного раздела?

И ещё, при команде IniRead, возвращается
Цитата:

Значение указанного ключа или <стандартное значение>, если указанный ключ отсутствует. (справка)
А как можно проверить совпадает ли указанная строка (или ключь в разделе) с существующей строкой в файле конфигурации? (*.ini) - и если совпадает, то нужно выполнить определённые действия (например, показать сообщение по MsgBox).

XXXler 13-07-2006 13:35

Цитата:

Как по команде IniWrite, записывать строчки в файл конфигурации, но не в самый конец раздела, а, например, во вторую строчку заданного раздела?
С помошью только IniWrite - никак
Цитата:

А как можно проверить совпадает ли указанная строка (или ключь в разделе) с существующей строкой в файле конфигурации? (*.ini) - и если совпадает, то нужно выполнить определённые действия (например, показать сообщение по MsgBox).
строки здесь причем? Если используем Ini файл, так и работаем с Секция\Параметр\Значение, со строками как таковыми работа невозможна.

Если надо сравнить одно значение:
Код:

If IniRead($File,"Section","Parameter","Default Value")="Текст для сравнения" Then MsgBox(0,"","Значение совпадает")

DenchikK 13-07-2006 13:46

Creat0R
Цитата:

А как можно проверить совпадает ли указанная строка (или ключь в разделе) с существующей строкой в файле
конфигурации? (*.ini) - и если совпадает, то нужно выполнить определённые действия (например, показать сообщение по
MsgBox).
Так пойдёт?

Код:

$var = IniRead("boot.ini", "boot loader", "timeout", "")
        if $var = 5 then
                MsgBox(0,"Информация", "Запись существует",2)
        else
                MsgBox(0,"Информация", "Запись не существует",2)
        endif
Exit


Creat0R 13-07-2006 14:11

XXXler
Цитата:

С помошью только IniWrite - никак
Мне в принципе не важно с помощью чего, главное как такое сделать?

А на счёт строк, так дело в том, что мне нужно проверить именно ключь, а не значение. Т.е пусть даже восспользоваться другой командой, и обращаться к файлу как к обычному (например, как к файлу *.txt), но чтобы сравнить указанный текст со строкой в файле.

DenchikK
Цитата:

Так пойдёт?
Таким образом у меня в любом случае выводится сообщение “Запись не существует”, и ключь в файле не проверяется... или я просто что-то не так делаю?

Цитата:

if $var = 5 then
Разве IniRead возвращает значение 5, судя по справке, оно возвращает либо значение указанного ключа, либо значение которое приютствует у ключа в указанном разделе.

XXXler 13-07-2006 14:55

Может найдешь что тебе именно нужно:
Код:

;~ Условия поиска
$Sect="Имя_секции"
$Param="Имя_параметра"
$Val="Значение_параметра"
$File="Имя_файла"

If Not FileExists($File) Then Exit 1
       
;~ Поиск по имени секции
$SecList=IniReadSectionNames($File)
For $i=1 To $SecList[0]
        If $SecList[$i]=$Sect Then        MsgBox(0,"","Секция "&$Sect&" существует")
Next

;~ Поиск по имени параметра в любой секции
$SecList=IniReadSectionNames($File)
For $i=1 To $SecList[0]
        $ParList=IniReadSection($File,$SecList[$i])
        For $y=1 To $ParList[0][0]
                If $ParList[$y][0]=$Param Then MsgBox(0,"","Параметр "&$Param&" существует в секции "&$SecList[$i])
        Next
Next

;~ Поиск по значению параметра в любой секции
$SecList=IniReadSectionNames($File)
For $i=1 To $SecList[0]
        $ParList=IniReadSection($File,$SecList[$i])
        For $y=1 To $ParList[0][0]
                If $ParList[$y][1]=$Val Then MsgBox(0,"","Значение "&$Val&" существует в  параметре "&$ParList[$y][0]&", секции "&$SecList[$i])
        Next
Next

;~ Поиск по имени секции и параметра
If IniRead($File,$Sect,$Param,"А вот и нет такого параметра")<>"А вот и нет такого параметра" Then MsgBox(0,"","Параметр "&$Param&" существует в секции "&$Sect)

;~ Поиск по имени секции, параметра и значения
If IniRead($File,$Sect,$Param,"А вот и нет такого параметра")=$Val Then MsgBox(0,"","Значение "&$Val&" существует в параметре "&$Param&", секции "&$Sect)


Creat0R 15-07-2006 20:39

XXXler
Огромное спасибо! помогло!


Появился у меня интерес к такому вопросу - Можно ли каким то образом, воспринимать переданный ключь (рефферер) из другой программы, и чтобы скрипт распознавал, и если это определённый ключь, то что-то должно происходить. Т.е, например, скрипт был вызван из контекстного меню определённой программы, и при этом вызове, был указан ключ (Пример: Item, "Script" = Execute program, "Script.exe", "%A") - И теперь, скрипт должен распознать этот ключь, и если был передан именно этот ключь, то скрипт продолжит заданные действия в цепочке, а если ключь не совпадает, т.е если не был передан именно этот ключ, или вообще не был передн ключь, то должен происходить выход из цепочки (Do....Until...)


P.S:
Как делать цепочку\выход с неё, продолжение действии и т.д, я уже знаю, и мне нужно только узнать, как распозновать тот самый ключь (рефферер).

И ещё вот что хотел узнать, кто-то знает, где мможно посмотреть на разные структуры скриптов, например, для чекбоксов, для передачи результата из выбранного файла\каталога через FileOpenDialog, в затемнённое поле GUI интерфейса, и тому подобное (что-то вроде преведённого XXXler'ом в посте на один выше чем мой).

XXXler 16-07-2006 00:53

Цитата:

как распозновать тот самый ключь (рефферер).
команданая строка обрабатывется с пом. переменной $CmdLine, которая возвращает массив значений, где $CmdLine[0] количество параметров, $CmdLine[1], $CmdLine[2], $CmdLine[3] - параметры (в командной строке м\у параметрами разделитель - пробел, если параметр с пробелом внутри, его надо заключить в кавычки).
Обработка коммандной строки выглядит примерно так:
Код:

For $i=1 To $CmdLine[0]
Select
Case CmdLine[$i]="Параметр_1"
....

Case CmdLine[$i]="Параметр_2"
....

......
Case CmdLine[$i]="Параметр_n"
....

EndSelect
Next


Creat0R 16-07-2006 17:28

XXXler
Ещё раз огромное Сенкс за наводку!
Вот как мне впринципе нужно было:

Код:

Select
Case $CmdLine[1] = 1
MsgBox(0, "", "ok 1")
Case $CmdLine[1] = 2
MsgBox(0, "", "ok 2")
Case $CmdLine[1] = 3
MsgBox(0, "", "ok 3")
EndSelect

Тут, Меседжь боксы естественно для примера, мне требуются совсем инные действия :).

Если запустить из внешней программы, этот скрипт с ключём, например 1, то будет сообщение: "ок 1", если с ключём 2, то естественно сообщение будет "ок 2" и т.д.
--------------------------

У меня остался один открытый вопрос, и буду очень благодарен если сможешь помочь (очень нужно):

*Вопрос который я уже задавал:
Цитата:

Как по команде IniWrite, записывать строчки в файл конфигурации, но не в самый конец раздела, а, например, во вторую строчку заданного раздела?
Но мне НЕ важно по какой команде (просто я думал что раз уж файл ини, значит нужно именно этой командой).

Dirk Diggler 16-07-2006 23:34

Никак. Только написать свою функцию.

Creat0R 17-07-2006 01:00

Dirk Diggler
Цитата:

Только написать свою функцию.
А как это сделать?

VelDmi 17-07-2006 20:46

Уважаемый bogomolv!
Большое спасибо за скрипт по настройке dial-up подключений. Когда я давным давно видел его на форуме не думал что он пригодится.
Поясните пожалуйста некоторые моменты, которые у меня не получаются.
Итак, подключение создается, но:
Не стоит галочка "использовать правила набора номера" - как ее поставить?
Код страны или региона почему-то США, как сделать Россию?

Dirk Diggler 17-07-2006 21:54

Creat0R. Для начала прочитать всё-таки книжку по информатике и хелп к AutoIt3

bogomolv 18-07-2006 02:08

VelDmi
Не "выкай". Настаиваю именно на этой форме общения. Тем более, что двухлетнее знакомство дает право обращаться "на ты" даже за пределами интернета.

Цитата:

Не стоит галочка "использовать правила набора номера" - как ее поставить?
Код:

;Настройка "Свойства" соединения
$pbk='@AppDataCommonDir@\Microsoft\Network\Connections\Pbk\rasphone.pbk'
$co=IniReadSectionNames($pbk)
For $i=1 to $co[0]
 IniWrite ($pbk, $co[$i], 'DataEncryption',                '8')
 IniWrite ($pbk, $co[$i], 'ShowMonitorIconInTaskBar',        '1')
 IniWrite ($pbk, $co[$i], 'ConnectBPS',                '460800')
 IniWrite ($pbk, $co[$i], 'Speaker',                        '0')
 IniWrite ($pbk, $co[$i], 'AreaCode',                $cod)
 IniWrite ($pbk, $co[$i], 'CountryCode',                $ccod)
 IniWrite ($pbk, $co[$i], 'CountryID',                $ccod)
 IniWrite ($pbk, $co[$i], 'UseDialingRules',                '1')
 $phone2= IniRead($ini, $con[$i],'Phone_Number2','')
 If $phone2<>'' Then
  IniWrite ($pbk, $co[$i], 'Comment','@CRLF@PhoneNumber=$phone2$@CRLF@AreaCode=$cod$@CRLF@CountryCode=$ccod$@CRLF@CountryID=$ccod$@CRLF@UseDialingRules=0@CRLF@Comment=')
 EndIF
 ;это выделено для Creat0R в качестве примера того, как записать в ini-файл параметры в нужной последовательности

Next

Цитата:

Код страны или региона почему-то США, как сделать Россию?
Уточни, что имеешь ввиду.
Если код страны как параметр драйвера модема, так этот скрипт драйверы не настраивает.
Если же Area_Code и Country_Code, то это коды выхода на межгород и международную связь. У меня там, наверное, были жестко забиты код саратовские - 8452 и 7. В приведенном выше кусочке скрипта Area_Code и Country_Code определяются переменными $cod и $ccod.
(Кстати, а на какой мой скрипт настройки интернет ты ссылаешься? Давай ПМ, вышлю свеженький.)
Цитата:

Большое спасибо за скрипт по настройке dial-up подключений. Когда я давным давно видел его на форуме не думал что он пригодится.
А как же ты настривал соединения? Хотя, даже не удивляюсь. И в знакомом тебе обсуждении на хоботе, и здесь возможности автоматической настройки соединений почему-то мало кого интересуют.

Creat0R
Глянь в скрипт. Там есть пример того, как можно записать в ini-файл параметры в нужной последовательности.

Creat0R 18-07-2006 03:15

bogomolv
Цитата:

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

Вот так (см. код ниже), мне удалось во второй раздел ini файла, поместить ключ со значением, но уже не в конец раздела, а в его начало:

Код:

$co=IniReadSectionNames("Test.ini")
For $i=2 to $co[0]

IniWrite ("Test.ini", $co[$i], "Test" , "OK")
Next

Мне нужно как то узнать, каким образом я могу монипулировать помещением ключа в нужную строку (именно заданного раздела).
Буду очень благодарен если сможешь помочь!
И спасибо за внимание (за пример, и за попытку помочь).

Dirk Diggler
Цитата:

Для начала прочитать всё-таки книжку по информатике и хелп к AutoIt3
Справку почти всю прочёл, но у меня голова начинает пухнуть, когда перечитываю снова и снова один и тот же пример\объяснение и т.д....
А на счёт книжки по информатике - как это связанно с AutoIt? или эта книжка предназначена для него?, тогда дай пожалуйста полное название этой книжки, или по возможности, линк по которому я смог бы её скачать...

VelDmi 18-07-2006 15:35

bogomolv
Привет! Использовал этот скрипт:
Код:

$f = FileOpen(@TempDir & '\ispcnfg.ins', 2)
FileWriteLine($f, '[Entry]')
FileWriteLine($f, 'Entry_Name=otts')
FileWriteLine($f, '')
FileWriteLine($f, '[Phone]')
FileWriteLine($f, 'Dial_As_Is=yes')
FileWriteLine($f, 'Phone_Number=8w770')
FileWriteLine($f, 'Area_Code=')
FileWriteLine($f, 'Country_Code=7')
FileWriteLine($f, 'Country_ID=7')
FileWriteLine($f, '')
FileWriteLine($f, '[Device]')
FileWriteLine($f, 'Type=modem')
FileWriteLine($f, '')
FileWriteLine($f, '[User]')
FileWriteLine($f, 'Name=otts')
FileWriteLine($f, 'Password=otts')
FileWriteLine($f, 'Display_Password=no')
FileWriteLine($f, '')
FileWriteLine($f, '[ConnectionSettings]')
;FileWriteLine($f, 'ApplyInsToConnection='&$con[$i])
FileWriteLine($f, '')
FileClose($f)

Run(@ComSpec&' /C Start %temp%\ispcnfg.ins','',0)
WinWaitActive('Мастер подключения к Интернету')
Send('{ENTER}')
WinWaitActive('Мастер подключения к Интернету','Завершена подготовка')
Send('{ENTER}')

$pbk=@AppDataCommonDir & '\Microsoft\Network\Connections\Pbk\rasphone.pbk'
IniWrite ($pbk, 'otts', 'UseDialingRules', '1')
IniWrite ($pbk, 'otts', 'CountryCode', '7')
IniWrite ($pbk, 'otts', 'CountryID', '7')
IniWrite ($pbk, 'otts', 'ConnectBPS', '115200')
IniWrite ($pbk, 'otts', 'AreaCode', '')
IniWrite ($pbk, 'otts', 'RedialSeconds', '3')
IniWrite ($pbk, 'otts', 'RedialAttempts', '100')

В итоге подключение настраивается, и даже галочка ставится, но при нажатии свойства->правила выскакивает окно изменение местонахождения, там где указывают код города и регион.

Цитата:

Уточни, что имеешь ввиду.
Если код страны как параметр драйвера модема, так этот скрипт драйверы не настраивает.
Если же Area_Code и Country_Code, то это коды выхода на межгород и международную связь.
При использовании файла *.ins в котором даже прописаны все параметры все равно получается США с кодом города 805. Может и правда от дров модема зависит. Поэтому после правлю rasphone.pbk по твоему совету. Вроде галки поставились где надо, но местоположение все равно спрашивает.

Цитата:

Кстати, а на какой мой скрипт настройки интернет ты ссылаешься? Давай ПМ, вышлю свеженький.
Намылил тебе по этому поводу.

Цитата:

А как же ты настривал соединения? Хотя, даже не удивляюсь. И в знакомом тебе обсуждении на хоботе, и здесь возможности автоматической настройки соединений почему-то мало кого интересуют.
А вот так вот вручную и настраивал. Пока не принесли подряд 3 компьютера. Только тогда понял насколько рутинная эта операция.

XXXler 18-07-2006 15:44

Creat0R,
Цитата:

Как по команде IniWrite, записывать строчки в файл конфигурации, но не в самый конец раздела, а, например, во вторую строчку заданного раздела?
пложение самого раздела в файле тоже критично?

Creat0R 18-07-2006 18:02

XXXler
Цитата:

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

P.S:
Под словом Раздел - я подразумиваю начало пунктам под которым есть ключи и значение у них, вот пример:
[Раздел1]
Ключь = Значение

[Раздел2]
Ключь = Значение

И т.д..

XXXler 18-07-2006 20:09

Вызов функции:
IniWriteVP(Файл,Секция,Параметр,Значение,[опционально:позиция параметра в секции])
Например:
IniWriteVP($File,"Section","Parametr","Этот параметр будет вторым",2)
IniWriteVP($File,"Section","Parametr","Этот параметр будет записан также, как и с пом. IniWrite")

Код:

Func IniWriteVP($File,$Sect,$Param,$Val,$Pos=0)
        Local $ValArr,$i
        If $Pos<>0 Then IniDelete($File,$Sect,$Param)
        $ValArr=IniReadSection($File,$Sect)
        If @error Or $Pos=0 Or $ValArr[0][0]<$Pos Then
                IniWrite($File,$Sect,$Param,$Val)
                SetError(@error)
        Else
                For $i=1 To $ValArr[0][0]
                        IniDelete($File,$Sect,$ValArr[$i][0])
                Next
                For $i=1 To $ValArr[0][0]
                        If $Pos=$i Then        IniWrite($File,$Sect,$Param,$Val)
                        IniWrite($File,$Sect,$ValArr[$i][0],$ValArr[$i][1])
                Next
        EndIf
EndFunc


Creat0R 19-07-2006 01:11

XXXler
У меня что-то не получается :( . Я если честно, так и не понял, что куда прописывать - Я пытался сделать так:

Код:

$Sect="Test1"
$Param="Параметр"
$Val="Значение"
$File="Test.ini"

        Func IniWriteVP($File,$Sect,$Param,$Val,$Pos=0)
  IniWriteVP($File,$Sect,$Param,$Val, 2)

EndFunc

Но я понимаю что тут явно чего то нехватает, и этот вариант не срабатывает.

Если не трудно, напиши пожалуйста скрипт так, чтобы он в файл Test.ini, в секцию "Test3", и в третью строчку этой секции, записывал параметр "Проба" со значением "1". Т.е вот так должна быть прописана строка:

Код:

[Test3]
Тут неважно что, но что-то записано.
Тут тоже неважная запись.

Проба = 1
Тут тоже неважная запись, но не обязательно последняя


Creat0R 19-07-2006 02:48

bogomolv
Цитата:

"Я читал в справке раздел по использованию функций. Приведенный там пример меня не вдохновил, и я решил усовершенствовать синтаксис команд в AutoIt3, засунув обращение к функции внутрь самой функции. Но я понимаю, что тут явно чего-то не хватает! Как бы мне еще поиздеваться над AutoIt'ом, а заодно и над сокнижниками?"
А зачем-же так издеваться надо мной, я всего навсего, прошу о помощи в том, чего ещё не понимаю, но это не значит что я полный тупицца, который не хочет слушать то, что ему твердят... вот только твердили бы ясно, а не вырожениями типа „Как бы мне еще поиздеваться над AutoIt'ом“ - Я же не знаю как эти функции работают, и что куда можно пихать, а что нельзя.
Ты хочеш сказать, что в справке ясно описанно как сделать мою задумку, или что мою задумку не реально сделать в AotoIt? Тогда как-же в нём делают очень сложные задачи? а такую простую, как запись в определённую строку определённой секции ини файла, не возможно?! не поверю. Просто другое дело, нехватает опыта, или знании сделать такую задачу (или желания), а так или иначе, прямым, или обходным путём, реализовать мою задумку возможно... и надеюсь найдутся добрые, опытные, и желающие помочь новичку в этом деле (в программировании) люди (В их число, думаю входишь и ты, но почему-то предпочитаешь видеть во мне не новичка в программировании, а чайника в целом - что вовсе неверно!).

P.S:
Извеняюсь за офтоп, но мне хочется чтобы меня понимали, это необходимо для моего прибывание на форуме!

Creat0R 19-07-2006 16:32

bogomolv
Цитата:

Ты не хочешь:
1) читать справку;
2) слушать советы прочитать справку;
3) договариваться, что ты все-таки почитаешь справку.
Я справку почитал, и теперь попытаюсь объяснить (метафорой), как я понимаю то что я с неё (и не только) вычитал...

Во многих кодах, мне ясны только основные вырожения, типа IniWrite, IniRead, For..Next, Do...Untill, переменные $var, $Func, $Sect, $param, $val, $File и т.д и т.п... Но во многих случаях (да почти во всех), увидив их в примерах справки, или тут на форуме, мне не удаётся соеденить их логический смысл воедино. Это подобно тому, как я знаю с десяток слов на французском в отдельности (их звучание и дословный перевод), но если мне начнут говорить на этом языке, даже услышав знакомые слова, я не пойму о чём речь, потому что нету опыта в разгаворе и понимании языка. А взяв русско-французский словарь (аналогия на справку в AotoIt), и прочитав его залпом, будет таже ситуация, и разговор на этом языке я не пойму, пока не стану говорить на нём (разве что если тот самый словарь, будет написан с подробными разъяснениями и мини-уроками по практике речепонимания и произношения).

А пример выше, огромное конечно спасибо за попытку, но он, как я понял, проверяет существует ли заданное значение в заданной секции, и если да, то создаёт заданный параметр с заданным значением в этой секции на одну строчку ниже, распознанного значения... а если значение не найдено, то заданный параметр со значением записывается в первую строчку заданного параметра...

Но мне, вообще-то, ненужно чтобы там была какая-то либо или чего-то либо проверка, нужно чтобы был скрипт, в определённую команду которого (типа $Pos=3), я смог бы внести номер строки заданной секции, и после запуска данного скрипта, в эту строку прописался бы заданный параметр со значеним.

Цитата:

На основе этого примера очень легко нарисовать свою конструкцию:
Я согласен, что может быть тебе просто, но вот мне, вовсе не просто, не то чтобы написать такую конструкцию, но и понять мне её вовсе не просто.

Цитата:

Ты так и не прочитал пример использования функций из справки:
Так я и немогу, у меня в справке приведённого тобой примера вовсе нет... может у меня другая справка? если не трудно, дай пожалуйста ссылку, на ту справку которую юзаешь...

Creat0R 20-07-2006 15:43

bogomolv
Цитата:

Скопируй написанный для тебя код в конец своего скрипта (после Exit) и обратись к функции командой IniWriteVP($File,"Section","Parametr","Этот параметр будет вторым",2).
Я делал точно так, но параметр со значением прописывается именно в первую строчку секции.

Цитата:

Кстати, а зачем тебе это? Обычно, программам, работающим с INI-файлами, по барабану, какая последовательность у нужных им параметров.
В моём случае, как раз-то не побарабану. Дело в том, что эти параметры, это пункты меню в программе (Файл | Правка | Вид и т.д), которые нужно убирать\показывать при необходимости. Но для этого, нужно именно прописывать строчки в то место, где они и должный быть (я знаю заранее где), чтобы небыло путанницы в последовательности их появления в программе.

А на счёт справки, Спасибо, так намного проще понимать что тебе советуют! :)

XXXler 20-07-2006 15:54

Creat0R, пустые строки в секции имеют место?

Creat0R 20-07-2006 16:04

XXXler
Цитата:

пустые строки в секции имеют место?
Их там нету (за исключением последней, и то, я могу её стереть, она там не обязательна).

XXXler 20-07-2006 16:18

Creat0R, все отловил ситуацию:
при таком заполнении:

Код:

Func IniWriteVP($File,$Sect,$Param,$Val,$Pos=0)
        Local $ValArr,$i
        If $Pos<>0 Then IniDelete($File,$Sect,$Param)
        $ValArr=IniReadSection($File,$Sect)
        If @error Or $Pos=0 Or $ValArr[0][0]<$Pos Then
                IniWrite($File,$Sect,$Param,$Val)
                SetError(@error)
        Else
                For $i=1 To $ValArr[0][0]
                        IniDelete($File,$Sect,$ValArr[$i][0])
                Next
                For $i=1 To $ValArr[0][0]
                        If $Pos=$i Then        IniWrite($File,$Sect,$Param,$Val)
                        IniWrite($File,$Sect,$ValArr[$i][0],$ValArr[$i][1])
                Next
        EndIf
EndFunc

For $i=1 To 3
        For $y=1 to 10
                IniWriteVP(@ScriptDir&"\Test.ini","Test"&$i,"Par"&$y,"Фигня")
        Next
Next


IniWriteVP(@ScriptDir&"\Test.ini","Test1","Par100","пятое значение",5)
IniWriteVP(@ScriptDir&"\Test.ini","Test3","Par3","третье значение",3)
IniWriteVP(@ScriptDir&"\Test.ini","Test3","Par1","седьмое значение",7)

при присвоении Par1 седьмой позиции Par3 становится вторым, т.к. Par1 переходит в 7 строку:

Код:

[Test1]
Par1=Фигня
Par2=Фигня
Par3=Фигня
Par4=Фигня
Par100=пятое значение
Par5=Фигня
Par6=Фигня
Par7=Фигня
Par8=Фигня
Par9=Фигня
Par10=Фигня
[Test2]
Par1=Фигня
Par2=Фигня
Par3=Фигня
Par4=Фигня
Par5=Фигня
Par6=Фигня
Par7=Фигня
Par8=Фигня
Par9=Фигня
Par10=Фигня
[Test3]
Par2=Фигня
Par3=третье значение
Par4=Фигня
Par5=Фигня
Par6=Фигня
Par7=Фигня
Par1=седьмое значение
Par8=Фигня
Par9=Фигня
Par10=Фигня

тут наверное прийдется, предварительно загнать все изменения ini-файла в массив, а потом его перезаписать с нуля - тогда позиции будут жесткими, иначе все будет плавать.

попожжа наваяю, может быть

Creat0R 20-07-2006 17:10

XXXler
Огромное спасибо за такое внимание!

А может быть есть такая команда, которая после вставки параметра в первую строку, будет как бы двигать его (параметр) по одной строке вниз?

А вообще, как я потихоньку начинаю убиждаться, моя задумка очень сложная для выполнения (не только на AutoIt) тем способом который я объяснил. Тогда у меня есть немного другая альтернатива, но цель впринципе та же:

Вместо прописывания параметров в определённую строку секции, можно было бы проверять если заданный параметр прописан так как он определён (в скрипте), и если так и прописан, то пусть к этому параметру дописывается символ ; (чтобы параметр был как бы закоментирован), а если у этого параметра уже прописан такой символ, то пусть он убирается, и параметр таким образом становится активным - Этот вриант, как мне кажется, наиболее подходящий, и думаю даже более прост для выполнения скриптом AutoIt.

XXXler 20-07-2006 19:44

Creat0R, чего-то я недопонимаю: если тебе нужно добавить\убрать, например, 5 и 6 по счету элемент меню, зачем изменять позиции остальных елементов?

добавить:
IniWriteVP($IniFile,"Menu_1","Item_5","пятый элемент",5)
IniWriteVP($IniFile,"Menu_1","Item_6","шестой элемент",6)


убрать:
IniDelete($IniFile,"Menu_1","Item_5")
IniDelete($IniFile,"Menu_1","Item_6")

Creat0R 20-07-2006 20:23

XXXler
Дело в том, что там 7 пунктов меню, и если я, допустим уберу третьий пункт, то тот который был четвёртым, автоматом станет третьийм, и уже потом скрипт ошибётся. А также, может быть такая ситуация (если почти все меню будут убранны), когда останутся два-три пункта меню, и их ненужно трогать, а также ненужно создавать тех которых нету (и которые должный быть, если их включикли - по вызову этого же скрипта, но с другим ключём), поэтому я немогу узнать, какие есть, а каких нету, и нужно просто не убирать их, а закоментировать (как я писал в последнем посте про альтернативу), или раскоментировать, если они закоментированный (символом ; ).

Creat0R 20-07-2006 20:38

bogomolv
Цитата:

Давай проверим.
Создай Блокнотом файл C:\Test.ini из трех строк
Сделал всё в точности так, и вообще никакая строчка не прописалась.

Creat0R 20-07-2006 23:48

1 вложений
bogomolv
Цитата:

Запости скрипт, который ты написал для проверки.
В атаче скрипт Test.au3 и файл Test.ini.

ANGRO 21-07-2006 03:15

Цитата:

А есть книги по AutoIt'у? (Хорошо, т.е понятно написанны)
Возьми хорошо написанную книгу по WinAPI, почитай недельку перед сном, будеш AutoIt набирать с выключенным монитором. :laugh:

Creat0R 21-07-2006 05:05

ANGRO
Цитата:

Имелось в виду что ты Creat0R вставиш функцию целиком из поста выше
Так можно было так и написать, а не вводить такого как я, по твоим словам, чайника, в догадки.

Цитата:

для тебя человек целую функцию написал а ты даже разобраться не хочеш.
Спасибо ему что написал эту функцию, но я не то что не хочу - я не могу, не знаю как, не хватает опыта, знании и т.д и т.п.

Цитата:

Возьми за правило сначало разобраться в листинге хотя бы процентов на 50, а потом стремиться к результату в виде билда иначе соберёш 100% не работающий код.
Что такое листинг, и что такое билд?

Цитата:

Матрицу наверное смотрел от туда "Знать путь и пройти его это не одно и тоже"
А при чём тут это, и при чём тут матрица, то что я писал, не имеет никакого отношения к приведённой тобой цитате. Я же не про путь писал, я писал про понимание сочетании команд, при том что часть из них я знаю как отдельное значение, а сочетание их вместе, нет.

Цитата:

если нужен конечный результат закажи его и не разводи флуд.
А что значит заказать? я же и так рассказал что мне конкретно требуется, и флуд, если я и развожу, то только потому, что меня провоцируют на него.

Цитата:

Интересно в какой программе пункты меню храняться в ini фаилах ??
Неужели програмёр (даже с малой буквы ;) ), такого не знает?
Это в браузере Opera!

Цитата:

Возьми хорошо написанную книгу по WinAPI, почитай недельку перед сном, будеш AutoIt набирать с выключенным монитором.
Это было серъёзно, или в шутку? потому что если в шутку, то могу ответить лишь так (тоже в шутку):
Возле ссылки Полезное сообщение, нужно было-бы приделать и ссылку такую - Бесполезное сообщение :laugh:

P.S:
А вообще, спасибо за советы, думаю кога-то, в далёком будущем, они мне и пригодятся, и думаю если бы я и планировал серъёзно начинать программировать, то уж точно не начинал бы с AotoIt (При всём уважении к этому проэкту, и поверь, оно есть).

bogomolv 21-07-2006 07:39

Creat0R
Да-а-а, глянул твой скрип... Слов нет - одни буквы...
Надеюсь, ты сам все понял.

Я всю бурную и бесполезную переписку с тобой поудалял. Прошу это сделать и тебя.
Те проблемы, которые ты решаешь, - результат твоей фантастической безграмотности и не имеют никакого отношения к программированию и к AutoIt.

Creat0R 21-07-2006 12:59

bogomolv
Цитата:

результат твоей фантастической безграмотности
Если не понимание в прграммировании, называется безграмотностью, то грамотных людей в нашем мире, очень и очень мало!

Большое спасибо за помощь! :beer: (это я серъёзно, без всякого сорказма).

ANGRO 22-07-2006 01:54

Я тут людей спрашивал как получить данные сетевых соединений, вот как-то так
Код:

        Dim $strComputer = "."
        Dim $ret

        $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
                If Not @error = 0 Then
                        MsgBox(48, "Ошибка", "Не удалось соединиться со службой WMI")
                  EndIf
        $colNicConfigs = $objWMIService.ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True")
               
        For $objNicConfig In $colNicConfigs
                For $strIPAddress In $objNicConfig.IPAddress
               
                $objNic = $objWMIService.Get("Win32_NetworkAdapter.DeviceID=" & $objNicConfig.Index)
                        $ret &= "-- " & "Имя:  " &  $objNic.NetConnectionID & @CRLF & _
                                      "IP адрес:  " & $strIPAddress & @CRLF & _
                                      "Номер адаптера:  " & $objNicConfig.Index & @CRLF
                Next
        Next
                If $ret <> '' Then Msgbox(0,"Output", $ret )


ANGRO 22-07-2006 02:52

Цитата:

думаю если бы я и планировал серъёзно начинать программировать, то уж точно не начинал бы с AotoIt
Думаю это бан с высылкой своп фаила на мыло. По крайней мере с моей стороны.

adima 24-07-2006 11:11

Есть ли у кого пример или готовый скрипт поиска файла по всем дискам и всем директориям и поддиректориям

bogomolv 25-07-2006 02:24

adima
Пример поиска файла здесь уже приводился. В твоем случае нужно лишь зациклить поиск по дискам:
Код:

Opt('ExpandEnvStrings', 1); default = 0
Opt('ExpandVarStrings', 1); default = 0
Opt('RunErrorsFatal', 0); default = 1
Opt('TrayIconDebug', 1); default = 0

$drives = DriveGetDrive("all")
If @error Then Exit

For $i=1 to $drives[0]
  $dr=dir($drives[$i]&'\*_1.au3')
  For $k=1 To $dr[0]-1
    MsgBox(0,'',$dr[$k])
  Next
  $dr=0
Next
Exit

Exit

Func dir($d)
 $dr = Run('%Comspec% /c dir "$d$" /s /b','',0,6)
 $f  = ''
 While not @error
  $f = $f & StdoutRead($dr)
 Wend
 Return (StringSplit(StringReplace($f,@LF,''),@CR))
EndFunc


kovdaev 25-07-2006 14:19

Где можно взять готовый скрипт или может у кого есть на программу R-STUDIO v.3 EN

xstranger 28-07-2006 06:19

Скажите, как с помощью AutoIt можно получить раздел реестра содержащий какой либо параметр=значение.
Надо чтобы результатом был раздел реестра содержащий данный параметр равный данному значению.

Или может кто подскажет как получить название устройства (установленого, например видео карты)из реестра. По адресу
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ имееется информация о всех установленых драйверах системы, но конечный раздел для каждого устройства разный, в зависимости от того как его назвали при разработке драйвера, единственное как можно определить например видеокарту - это что параметр Group = video

bogomolv 28-07-2006 09:55

xstranger
ПННХНЧ (Пишу, Но Ни Хрена Не Читаю)?

На основе этого примера можно считать и проверить на соблюдение любого условия любую информацию из любого раздела реестра:
Код:

;Считывание на стадии CMDLINES.TXT будущего разрешение экрана
$screen=1024
If RunWait('@ComSpec@ /C reg query "HKLM\SYSTEM\CurrentControlSet\Control\DeviceClasses" /s | find "DefaultSettings.XResolution" | find "500"','',0)=0 Then $screen=1280

Для работы железками есть специализированная утилита DEVCON: http://support.microsoft.com/kb/311272/ru.
Данный пример позволяет проверить наличие железки по ее HWID:
Код:

$hwid='PCI\VEN_10DE' ;nforce4
If RunWait('@ComSpec@ /C devcon.exe hwids "$hwid$" | find "$hwid$"','',0) Then Exit


xstranger 28-07-2006 12:24

нет.... это немного не то. Или то но я не могу понять как этого добиться.

Просто есть идея - скрипт запускающийся в detachedProgram и постоянно проверяющий либо реестр (если возможно оттуда получить значение) либо консольное приложение - которое возвращает установленый драйвер видео/звука/ит.д..
этот скрипт выводит на экран в процессе установки - установленые драйвера - видео, звук, модем и количество неопознанных устройств.

Можно конечно открыть devmgr по shift+а10, но какаяже тогда автоматизация..., а идея мне кажется хорошая.

может есть у когонибудь какие нибудь практические предложения!?... давайте вместе подумаем

xstranger 28-07-2006 12:56

вот уже кое что нашел:
в разделе HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Video - перечисляются все видео драйверы установленые на компьютере включая vgasave, но только один вложеный раздел содержит параметр Device Description и его значение равно названию видео карты.
с помощью утилиты из состава reskit 2k srv - regfind можно получить значение параметра Device Description

kpuk 28-07-2006 23:13

прошу сильно не пинать, а подробненько разжувать:
Есть прога. К ней есть API-функции.
Как их передать программе через autoit??
Просьба попожробенее и на примере.
Вот, для примера имею:
- доступ к функциям осуществляется через единый интерфейс IRunpadShell
----------------------------------------------
HRESULT TurnShell(BOOL bNewState);
Включает или отключает шелл (TRUE/FALSE соответственно)
----------------------------------------------

Как мне к примеру через автоит закрыть прогу через эту функцию???

bogomolv 29-07-2006 03:10

xstranger

Цитата:

может есть у когонибудь какие нибудь практические предложения!?... давайте вместе подумаем
Над чем подумать-то? Над тем, как вывести на экран за 9 мин. до конца установки "Диспетчер устройств"? Можно и devcon'ом вывести на экран все характеристики всех имеющихся в системе устройств (в том числе и какие драйвера установлены). У меня таких устройств devcon насчитал 118. Оно тебе надо?
Может все же поделишься, зачем тебе все это нужно?

Цитата:

в разделе HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Video - перечисляются все видео драйверы установленые на компьютере включая vgasave, но только один вложеный раздел содержит параметр Device Description и его значение равно названию видео карты
В разделе HKLM\SYSTEM\CurrentControlSet\Control\DeviceClasses тоже перечисляются различные устройства. И только один из подразделов содержит заветную информацию о том, какое разрешение подхватили драйвера... Поэтому и предложил простой способ выуживать информацию из реестра, не перебирая все подразделы и не зная точного иентификатора видеокарты.
Задай в параметре find название своей видеокарты и укажи в reg query свою ветку реестра, и мой скрипт ответит тебе, есть ли такая видеокарта.

kpuk

Цитата:

Как мне к примеру через автоит закрыть прогу через эту функцию???
А почему это нужно делать через эту функцию? Почему нельзя закрыть стандартной autoit'овской функцией WinClose?

kpuk 29-07-2006 13:31

Это только одна из функций для примера, вот другой пример, который можно тока через API сделать:
-------------------------------------------------------------------------------
HRESULT DoSingleAction(RSHELLACTION dwAction);

Выполняет определенное действие:
RSA_SHOWPANEL - показывает плавающую панель с закладками
RSA_MINIMIZEALLWINDOWS - минимизирует все активные окна
RSA_KILLALLTASKS - снимает все разрешенные задачи (аналог команды шелла/сервера)
RSA_RESTOREVMODE - восстанавливает видеорежим (после выхода из проблемных игр)
RSA_UPDATEDESKTOP - обновляет рабочий стол шелла
RSA_CLOSECHILDWINDOWS - закрывает все дочерние окна шелла
RSA_SWITCHTOUSERMODE - переключает шелл в режим пользователя
RSA_TURNMONITORON - включает монитор
RSA_TURNMONITOROFF - отключает монитор
RSA_ENDVIPSESSION - завершает личную (VIP) сессию клиента (только с версии 4.52)

Функция является асинхронной.
-----------------------------------------------------------------------------------
Как мне через апи завершить личную VIP сессию клиента? через API !!!!

bogomolv 29-07-2006 23:46

kpuk
А какое отношение имеет ко всему этому Autoit? Разбирайся с API!

kpuk 30-07-2006 14:11

Ну какбы на нём писать просто - это раз!
И в нём вроди как есть функция dllcall которая позволяет работать с апи!
ВОт по этому и спрашиваю

VelDmi 30-07-2006 15:47

kpuk
На Autoit сделать то, что ты хочешь невозможно. Так же как и на WBS. Это проблема реализации API в програме RunpadShell.

ANGRO 01-08-2006 23:30

Набросал включение отключение сетевой карточки, мож кому пригодится.
Код:

$sConnectionName = "Home Office Connection"
$shellApp = ObjCreate("shell.application")
$oNetConnections = $shellApp.Namespace(0x00000031)
For $folderitem in $oNetConnections.items
    For $verb in $folderitem.verbs
        if $folderitem.name = $sConnectionName Then
          $verb.DoIt
          Sleep(1000)
          ExitLoop 2
        EndIf
    Next
Next
If $folderitem.name <> $sConnectionName Then msgbox(48, "Ошибка", "Имя соединения указанно не правильно")
Exit

Посмотрите позжалуйста Namespace(0x00000031) по этому адресу находятся "Сетевые подключения" по крайней мере у меня, судя по всему и во всех ХР подобных операционках.

bogomolv 02-08-2006 07:03

ANGRO
??????
Код:

devcon disable *net*

ANGRO 02-08-2006 11:19

Цитата:

devcon disable *net*
Понятно, у меня его на W2K3SP1 нет я думаю что в WinXP его тоже не найдут. А если приложению необходимо работать скажем на 500 разных компьютерах не являющихся собственностью одной конторы, да даже если и являющихся, что закидывать на каждый комп кучу DLL, EXE, OCX и т.д. А ведь есть компы где запрещено инсталлирование каких либо компонентов без проверки.
Да да знаю скажиш можно включить в сборку и не кто не узнает, а ещё лучше прямо в реестор писать и всё.
Я стараюсь придерживаться другой концепции, пользоваться только стандартным API настолько глубоко насколько знания позволяют и ничего не писать напрямую в реестор, пусть Win сам с этим разбирается.
Для узкой направленности автокликанья в своей винде и сборках для друзей и помощи на работе самый короткий путь типа "взял скачал, на винт забросил, команду передал" подходит, а когда билд уходит на сторону хочется гарантировать определённые вещи.
В любом случаи ИМХО мне интересней учится взаимодействию с операционкой используя её возможности.
P.S. сколько твой devcon весит, а сколько мой код ?

bogomolv 02-08-2006 12:28

ANGRO
Может, все же зайдешь по ссылке, которую я тебе давал? Это снимет кучу заданных вопросов.
А на счет "интереснее" - тут спору нет. :)

ANGRO 03-08-2006 01:32

bogomolv
Спасибо воспользуюсь твоим предложением.
Namespace(49) разобрался писать нужно так Namespace(0x00000031)

Creat0R 03-08-2006 04:17

Кто нибудь может пожалуйста помочь разобраться с такой пропблемой:

Чтобы прописывать строчки в начало секции *.ini файла, я воспользовался функцией Func IniWriteVP...
Так вот, когда я попытался воспользоваться этой функцией в (цикле?) Select...Case...EndSelect, то выдалась ошибка о том что нету совпадения между Select и Case и между EndSelect (что-то в этом роде), и вообще практический все команды в таком цикле не исполняются (т.е если в этом цикле используется упомянутая функция). Вот пример, который по идее, должен записывать в заданную секцию, параметр со значением, в первую строку этой секции:


Код:

Select
       
        Case $CmdLine[0] = 0

$File = "Test.ini"
$Sect = "Test Section"
$Param = "Parametr Test"
$Val = "Value Test"


        IniWriteVP($File,$Sect, $Param, $Val, 1)
                Func IniWriteVP($File,$Sect, $Param, $Val, $Pos=0)
                        IniWrite($File,$Sect,$Param,$Val)
        EndFunc

EndSelect

Но как я уже упомянул, этого не происходит, и выдаётся ошибка.
Может кто нибудь подскажет в чём дело, как это осуществить?

XXXler 03-08-2006 17:23

Цитата:

IniWriteVP($File,$Sect, $Param, $Val, 1) Func IniWriteVP($File,$Sect, $Param, $Val, $Pos=0) IniWrite($File,$Sect,$Param,$Val) EndFunc
ну теперь я буду матерится :read: , сколько можно топтатся на этих граблях?

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

Код:

;~ Описываем функцию:
Func MyFunc($par1,$par2)
;~ Выводим сообщение с переданными параметрами
        MsgBox(0,$par1,$par2)
;~ Возвращаем результат Result
        Return "Result" 
EndFunc

;~ Тело программы
;~ .....................
$var=MyFunc("Заголовок","Сообщение")
MsgBox(0,"","Функция MyFunc возвранила значение "&$var)
;~ .....................

Значит смотрется это все будет так:

Код:

;~ Описываем функцию
Func IniWriteVP($File,$Sect,$Param,$Val,$Pos=0)
        Local $ValArr,$i
        If $Pos<>0 Then IniDelete($File,$Sect,$Param)
        $ValArr=IniReadSection($File,$Sect)
        If @error Or $Pos=0 Or $ValArr[0][0]<$Pos Then
                IniWrite($File,$Sect,$Param,$Val)
                SetError(@error)
        Else
                For $i=1 To $ValArr[0][0]
                        IniDelete($File,$Sect,$ValArr[$i][0])
                Next
                For $i=1 To $ValArr[0][0]
                        If $Pos=$i Then        IniWrite($File,$Sect,$Param,$Val)
                        IniWrite($File,$Sect,$ValArr[$i][0],$ValArr[$i][1])
                Next
        EndIf
EndFunc

;~ А теперь ее используем
Select
        Case $CmdLine[0] = 0
                IniWriteVP(@ScriptDir&"\Test.ini","Test Section","Parametr Test","Value Test",1)
;~ .......

EndSelect


Creat0R 03-08-2006 20:14

XXXler
Цитата:

ну теперь я буду матерится
Не надо :sorry:

Цитата:

Значит смотрется это все будет так:
Приогромнейшее человеческое спасибо - За разъяснения и за примеры!

это то что и нужно было!

ANGRO 05-08-2006 11:54

XXXler ты человек смотрю добрый разъесни тогда такую весч.

$var=MyFunc("Заголовок","Сообщение") ну с этим всё понятно, а вот здесь

Case $CmdLine[0] = 0
IniWriteVP(@ScriptDir&"\Test.ini","Test Section","Parametr Test","Value Test",1)


разве не нужно делать через Call(Func).

ANGRO 05-08-2006 12:24

Может кто подскажет как создать WAN PPPoE соединение (обычно это соединение создающееся для работы через модем) и прописать туда логин пароль. Спасибо

XXXler 05-08-2006 13:29

Цитата:

Цитата ANGRO
разве не нужно делать через Call(Func).

все встроенные и пользовательские функции можно и нужно вызывать напрямую, Call() же можно использовать для вызовов нескольких функций с подстановкой ее имени (посмотри пример в справке, там же кстати описано ограничение Call() - с ее пом. нельзя передавать функции никаких параметров), кроме того если функция вызванная из Call() отсуствует, компилятор не вылетит с ошибкой.

DenchikK 07-08-2006 05:14

C хитрым кейгеном столкнулся - идентификации не происходит. Почитал
help - но так и не понял, можно ли из этого положения выйти. Как видно
по картинке AutoIt определяет лишь:
видимый тект:
Digerati и ключ (например HEUBGOKIMFLQRJNSP) в полях Edit1 и Edit2
4 кнопки: Static4, Static3, Static2, Static1


Dirk Diggler 07-08-2006 15:08

я не понял, какой такой идентификации не происходит. Но попробуй еще WinSpy от nnCron, они здорово дополняют друг друга

DenchikK 07-08-2006 16:39

Цитата:

я не понял, какой такой идентификации не происходит
Грубо говоря, такой функции, как WinWaitActive (и иже с ней), не за что зацепится. В окне в принципе нет ничего в разделах:

>>>>>>>>>>>> Window Details <<<<<<<<<<<<<
Title:

>>>>>>>>>>> Control Under Mouse <<<<<<<<<<<
Text:

Dirk Diggler 07-08-2006 23:33

Как с пом. Autoit получить SID пользователя или группы? Я сделал функцию обработки файлового вывода от psgetsid.exe, но она слишком медленно работает.

Sanja Alone 08-08-2006 03:26

DenchikK
Цитата:

идентификации не происходит
Ну, это не проблема :) В подобной ситуации нужно исп-ть 4-й режим определения окон Opt("WinTitleMatchMode",4).
Можно подождать этого окна вот так:
Код:

WinWaitActive('')
или так:
Код:

Do
Sleep ( 200 )
$handle = WinGetHandle ( "classname=#32770" )
Until $handle <> ""
WinActivate ( $handle )
WinWaitActive ( $handle )

P.S. Все это есть в справке по AutoIt. Кстати, именно по этой причине я не включил сией инфы в FAQ.
Процитирую AutoIt.chm:
Цитата:

Mode 4
Advanced mode.

In this mode special sequences are used in the title parameter so that window classnames and handles can be used. The text parameter remains the same.

The special sequences must contain no whitespace. They are:
"classname=CLASSNAME"
"regexp=REGEXP"
"active"
"last" or ""


"classname=" matches a window based on its classname. For example to identify a window that has the classname "MYCLASS1" then you would use "classname=MYCLASS1" for the title parameter.

"regexp=" matches a window matching REGEXP pattern.
"active" matches the currently active window (same as "" in the default WinTitleMatchMode).
"last" uses the last successful window match so you don't have to keep specifying the title and text again and again. e.g.

AutoItSetOption("WinTitleMatchMode", 4)
WinWaitActive("Untitled - Notepad")
WinClose("last") ; Closes the previously matched notepad window


Note: If "classname=", "regexp=", "active", "last" or "" are not used as the title then the window matching takes place as in Mode 1 making this a good mode for general use.

Sanja Alone 08-08-2006 05:23

Dirk Diggler
Цитата:

Как с пом. Autoit получить SID пользователя или группы? Я сделал функцию обработки файлового вывода от psgetsid.exe
Столкнулся с подобной проблемой при написании скрипта для сохранения/восстановления настроек Outlook Express (нужен был SID текущего пользователя).
Решил похожим методом (т.е. слегка раком :) ), только без посторонних утилит и без обработки потоков с пом. соотв. ф-ций в последних бетах АвтоИт-а (RegRead здесь не катит по причине запрета на чтение требуемой ветки):
Код:

Func findsid()
        Local $file, $sid
        RunWait(@ComSpec & ' /c for /F "tokens=5 delims=\" %j in ('&Chr(39)&'reg query "HKEY_CURRENT_USER\Software\Microsoft\Protected Storage System Provider"'&Chr(39)&') do (echo %j> %temp%\sid.tmp)','',@SW_HIDE)

        $file = FileOpen(@TempDir&'\sid.tmp',0)
        If $file = -1 Then
                SetError(1)
                Return(0)
        EndIf
        $sid=FileReadLine($file,1)
        FileClose($file)

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

        Return $sid
EndFunc

А вообще, SID-ы пользователей записаны в ветке HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList; SID-ы групп - HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\GroupMembership и HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Group Policy\GroupMembership. Только не понятно, как их сопоставить с названиями групп (за исключением стандартных групп, вроде S-1-1-0 /Все/, S-1-5-544 /Администраторы/, S-1-5-545 /Пользователи/ и т.п.). В справочнике Джерри Хонейкатта по реестру WinXP, к сожалению, подробной инфы по рассматриваемой теме нет. Т.о., использованная тобой утилка Марка Руссиновича является вполне приемлемым ответом на твой же вопрос, если нет желания копать глубже или переписывать эту же утилку на АвтоИт с пом. DllCall-ов, вооружившись знанием WinAPI.
Цитата:

но она слишком медленно работает
И как это можно исправить, если ты не приводишь код?

Creat0R 08-08-2006 07:48

Подскажите пожалуйста, можно ли сделать сравнение даты создания (изминения) файла в сети, с другой датой (указанной в скрипте), и если дата создания (изминения) файла, ровняется указанной в скрипте, то пусть появляется меседжбокс, в противном случае, что-то должно делаться. Т.е, допустим в сети, лежит файл, который в последний раз был изменён 25-ого Января, 2006 г. А в скрипте, указать ту же дату для сравнения - 25-го января 2006 г. И если в момент запуска скрипта, файл не был изменён, и дата его изменения ровна указанной в скрипте, то пусть выскакивает меседжбокс, а если файл был изменён (т.е если уже его дата изминения не ровняется указанной), то что-то должно делаться (неважно что :) ).
Если такое возможно, подскажите плиз как это оуществить.

Заранее благодарю за внимание!

Dirk Diggler 08-08-2006 14:42

Цитата:

И как это можно исправить, если ты не приводишь код?
А никак. Надо придумать другой способ. Код вот:

Код:

Func GetSid($_Username)  ;возвращает сид юзера. имя должно быть полным, все довески(домен, комп) должны быть уже переданы в функкцию
        FileDelete(@TempDir & '\getsid.tmp')
        Run(@ComSpec & ' /c "' & @ScriptDir & '\psgetsid.exe" ' & $_Username & '> ' & @TempDir & '\getsid.tmp', '', @SW_HIDE)
        Sleep(50)
        Local $f= FileOpen(@TempDir & '\getsid.tmp',0)
        Local $a= FileReadLine($f,2)
        FileClose($f)
        If StringStripWS ( $a, 8) <> "" Then Return StringStripWS($a, 8)
        Return $_Username
EndFunc

Дело в том, что эта функция используется в цикле до 2-3 тыс. раз. И обработка файлового вывода вообще не вариант, цикл будет выполняться годами. Есть вариант вот такой:
Код:

Func GetSid($UserName, $Domain)

    Dim $UserSID, $oWshNetwork, $oUserAccount
    $objWMIService = objGet( "winmgmts:{impersonationLevel=impersonate}!//"  & @ComputerName & "/root/cimv2")
    $oUserAccounts = $objWMIService.ExecQuery("Select SID from Win32_UserAccount WHERE Name = '" & $UserName & "' AND Domain = '" & $Domain & "'")
    For $oUserAccount In $oUserAccounts
        Return $oUserAccount.SID
    next
EndFunc

Но у него свои недостатки - в функцию надо передавать отдельно имя пользователя и домен. В то время как первая функция умеет конвертировать имена в любом формате, например user@domain.local

AdrenalinE 10-08-2006 13:40

Код:

HotKeySet("{PAUSE}", "Pause")
Global $Paused

While 1
    $Click = _FindMonster()
    MouseClick('left', $click[0], $click[1], 1, 0)
    Attack()
WEnd



Func _FindMonster()
    Dim $iCoord
    While 1
        $iCoord = PixelSearch(250, 225, 374, 274, 0xFF00FF, 25, 1)
        If @error <> 1 Then ExitLoop
        $iCoord = PixelSearch(375, 225, 474, 274, 0xFF00FF, 25, 1)
        If @error <> 1 Then ExitLoop
        $iCoord = PixelSearch(415, 275, 474, 359, 0xFF00FF, 25, 1)
        If @error <> 1 Then ExitLoop
        $iCoord = PixelSearch(375, 360, 474, 399, 0xFF00FF, 25, 1)
        If @error <> 1 Then ExitLoop
        $iCoord = PixelSearch(250, 225, 374, 399, 0xFF00FF, 25, 1)
        If @error <> 1 Then ExitLoop
        $iCoord = PixelSearch(250, 175, 474, 224, 0xFF00FF, 25, 1)
        If @error <> 1 Then ExitLoop
        $iCoord = PixelSearch(475, 175, 574, 399, 0xFF00FF, 25, 1)
        If @error <> 1 Then ExitLoop
        $iCoord = PixelSearch(0, 400, 424, 474, 0xFF00FF, 25, 1)
        If @error <> 1 Then ExitLoop
        $iCoord = PixelSearch(0, 175, 259, 399, 0xFF00FF, 25, 1)
        If @error <> 1 Then ExitLoop
        $iCoord = PixelSearch(0, 100, 664, 174, 0xFF00FF, 25, 1)
        If @error <> 1 Then ExitLoop
        ; The sleep is there to prevent the PixelSearches
        ; from lagging the script a lot if a monster is not found
        ; in the first loop
        Sleep(250)
    WEnd
    $iCoord[0] = $iCoord[0] + 4
    $iCoord[1] = $iCoord[1] + 4
    Return $iCoord
EndFunc  ;==>_FindMonster

Func Attack()
    While 1
        If WinActive("SRO_Client") And PixelGetColor(77, 47) = 3947324 Then;IF ACTIVE AND INGAME
            ; USE SKILL 1 (mine is sword attack, strike and smash) UNLESS MONSTER IS CLOSE TO DYING
            if (PixelGetColor(605, 23) = 14077580 And PixelGetColor(442, 45) = 16762566) Then
                Send("2")
                Sleep(1000)
            EndIf
            ; USE SKILL 7 (mine is combo sword attack (5hits)) UNLESS MONSTER IS ALMOST DOWN
            if (PixelGetColor(605, 23) = 14077580 And PixelGetColor(475, 45) = 16743291) Then
                Send("1")
                Sleep(1000)
            EndIf
            ; USE IMBUE SKILL (mine is skill 2) UNLESS MONSTER IS ALMOST DOWN
            if (PixelGetColor(605, 23) = 14077580 And PixelGetColor(475, 45) = 16743291) Then
                Send("3")
                Sleep(1000)
            EndIf
            ; USE SKILL 5 (mine is sword attack, stab and smash)UNLESS MONSTER IS CLOSE TO DYING
            if (PixelGetColor(605, 23) = 14077580 And PixelGetColor(442, 45) = 16762566) Then
                Send("4")
                Sleep(1000)
            EndIf
            ;THIS WILL TRY AND PICK UP ANYTHING EVEN IF YOU WALK PASSED SOME GOLD
            Send("g"); CHECK WICH KEY TO USE IN SILKROAD OPTIONS !!
            Sleep(1000); DEFAULT GRABKEY IN SILKROAD IS "G"
        EndIf
    WEnd
EndFunc  ;==>attack

Func Pause()
    $Paused = Not $Paused
    While $Paused
        Sleep(100)
    WEnd
EndFunc  ;==>Pause

нужно подправить скриптик, после нахождения монстра-клика-атаки - почему-то не происходит возврат на поиск монстра =\
подскажите что не так?

Sanja Alone 11-08-2006 03:38

AdrenalinE
Цитата:

почему-то не происходит возврат на поиск монстра
Причина в отсутствии условия завершения ф-ции Attack(). Там должен быть не бесконечный цикл, а условный:
Код:

Func Attack()
While <монстр жив>
;чистим монстру репу
WEnd
EndFunc


sunb0rn 11-08-2006 19:47

Цитата:

Код:

Func GetSid($_Username)  ;возвращает сид юзера. имя должно быть полным, все довески(домен, комп) должны быть уже переданы в функкцию
        FileDelete(@TempDir & '\getsid.tmp')
        Run(@ComSpec & ' /c "' & @ScriptDir & '\psgetsid.exe" ' & $_Username & '> ' & @TempDir & '\getsid.tmp', '', @SW_HIDE)
        Sleep(50)
        Local $f= FileOpen(@TempDir & '\getsid.tmp',0)
        Local $a= FileReadLine($f,2)
        FileClose($f)
        If StringStripWS ( $a, 8) <> "" Then Return StringStripWS($a, 8)
        Return $_Username
EndFunc


А если попробовать вместо Run() и Sleep(50) --> RunWait () ставить, а то точно по как минимум 100 секунд функция исполняется!!! И скорость выполнения не будет зависить от времени, а менятся.

Creat0R 14-08-2006 01:19

Есть такой вопрос - как заставить скрипт удалить самого себя? Я пробовал сделать такое, прописав создание файла (батника), который удляет скрипт, а затем и самого себя, но мне нужно запускать скрипт не из текущего каталога, а из другого, поэтому при запуске батника, он (батник) работает как бы из того каталога, с которого был запущен скрипт, поэтому и не удаляет сам скрипт (хотя на странность, удаляет сам себя).

Creat0R 14-08-2006 02:05

Всё, разобрался :) ...

Я пробовал через макрос @ScriptName, но таким образом удаляется сам скрипт, а если он закомпилирован в екзешник, то он не удаляется... вот я и решил эту задачю другим способом, и опять таки в помощь пришёл батник:

Код:

FileWrite(@ScriptDir&"\temp.bat", "Del /q """ & @ScriptDir & "\" & @ScriptName & """" & @CRLF & "Del /q """ & @ScriptDir & "\temp.bat""")
Run("temp.bat", @ScriptDir, @SW_HIDE)


P.S:
А на счёт моего предыдущего вопроса в посте #272 никто не знает? хотябы подскажите, возможно такое реализовать на AutoIt, или нет?

amel27 14-08-2006 08:31

Есть вопрос - можно ли по хэндлу восстановить имя файла?.. В противном случае функции FileFind* почти бесполезны

EDIT: все, разобрался - повелся на имена функций, несмотря на схожее название эти две функции делают совершенно разные вещи - одна возвращает хэндл, а другая имя

Creat0R 15-08-2006 07:43

Кто-то может подсказать - как можно осуществить поиск определённого слова, в файле (например, в test.tmp), и именно в простом файле содержащем текст, а не в ini (т.к решение для ини уже тут пдооставили ранее).

Заранее спасибо!

Sanja Alone 15-08-2006 10:40

Creat0R
Цитата:

поиск определённого слова в файле
Код:

;в каком файле искать текст
$InputFile = 'test.tmp'
;какой текст искать
$TxtToFind = 'иСкоМый Текст'

;демонстрация работы ф-ции
$var = _FindTextInFile($InputFile,$TxtToFind)
MsgBox(0,'','Текст <'&$TxtToFind&'> найден в строке '&$var[0]&@LF&'Содержимое строки:'&@LF&@LF&$var[1])

;ф-ция возвращает массив из двух эл-тов (0 - номер строки файла, к-рая содержит искомый текст, 1 - сама строка)
Func _FindTextInFile($ifile,$text)
Local $i
Dim $ret[2]
$file = FileOpen($ifile,0)
$a = StringSplit( FileRead($file, FileGetSize($ifile)), @LF)
FileClose($file)
#cs
поиск кириллического текста без учета регистра символов возможен только в сл.
принудительного приведения искомой и текущей анализируемой строк к общему регистру
(ф-ции StringLower или StringUpper),
т.к. данный режим ф-ции StringInStr работает только с латиницей
#ce

If StringIsASCII($text) Then
        For $i = 1 To UBound($a,1)-1
                If StringInStr($a[$i],$text) Then
                        $ret[0]=$i
                        $ret[1]=$a[$i]
                        Return $ret
                EndIf
        Next
Else
        For $i = 1 To UBound($a,1)-1
                If StringInStr(StringLower($a[$i]),StringLower($text)) Then
                        $ret[0]=$i
                        $ret[1]=$a[$i]
                        Return $ret
                EndIf
        Next
EndIf
EndFunc


bogomolv 15-08-2006 14:35

Creat0R
И для обычного файла решение предоставляли заранее.
Это решение я взял из справки по Dos и прикрутил к AutoIt:
Код:

If RunWait('@ComSpec@ /C find "Pacific Rim" < trade.txt','',0)=0 Then
...
EndIf

Ксати, ini-файл ничем не отличается от обычного файла, и в нем можно искать текст таким же способом.

Sanja Alone, привет!
Ты быстрее набираешь тексты! А я - короче! :)

amel27 15-08-2006 19:54

bogomolv

Строго говоря, оба варианта находят не слова, а заданные последовательности символов. Например, при поиске слова "кот" мы найдем и "котлету", и "антрекот" и много еще чего... В AutoIt явно не хватает поддержки регулярных выражений, в качестве альтернативы можно использовать FINDSTR. Например, следующий скрипт ищет все вхождения слова BASIC:
Код:

If RunWait('@ComSpec@ /C findstr /I "\<baSic\>" lang.txt','',0)=0 Then
...
EndIf

Ложка дегтя - судя по всему FINDSTR распознает только слова из английских букв, остальные для него лишь набор символов.

XXXler 15-08-2006 20:33

Цитата:

Строго говоря, оба варианта находят не слова, а заданные последовательности символов. Например, при поиске слова "кот" мы найдем и "котлету", и "антрекот" и много еще чего...
что мешает искать в строке вхождение не "кот" а " кот ", т.е. с пробелами с обоих сторон?

Creat0R 15-08-2006 23:04

Sanja Alone, amel27, XXXler:
Во-первых, большое спасибо за помощь.
Пример который привёл Sanja Alone, выводит ошибку (в MsgBox), также пример от bogomolv, выводит ошибку о том, что не возможно найти файл (хотя он наместе)...

Но не в этом суть, я в результате использовал пример от Sanja Alone, но немного модифицировал его, т.к этот пример не искал кириллицу (для этого добавил перекодировку строк)... но есть другая проблема - если я пытаюсь указать строчку для поиска, не прямым способом, а через переменную ($Text), то поиск не осуществляется, и постоянно возвращается $Var = @error :

Код:

;Файл в котором будет произведён поиск
$InputFile = @ScriptDir& "\MyFile.txt"

;Текст для поиска
$Text = IniRead(@ScriptDir& "\Test.ini", "Section", "Parametr", "")

;Использование функции для перекодировки строчек в UTF
        $TxtToFindUTF = StringToUTF($Text)

$var = _FindTextInFile($InputFile,$TxtToFindUTF)

;Проверка на существование искомого текста, и если существует, то выводим сообщение об этом
If $var <> @error Then
MsgBox(64,"","Текст <" & $Text & "> Был найден в файле <" & $InputFile & ">, и находится в линии под номером <" & $var[0] & ">")

;Если не существует, то выводим сообщение об ошибке
Else

MsgBox(48,"","Текст <" & $Text & "> Не Был найден в файле <" & $InputFile & ">" & @CRLF & "Или файл <" & $InputFile & "> не найден")

        EndIf
Exit

;Начало функции для поиска текста
Func _FindTextInFile($ifile,$text)
Local $i
Dim $ret[2]
$file = FileOpen($ifile,0)
$a = StringSplit( FileRead($file, FileGetSize($ifile)), @LF)
FileClose($file)

If StringIsASCII($text) Then
        For $i = 1 To UBound($a,1)-1
                If StringInStr($a[$i],$text) Then
                        $ret[0]=$i
                        $ret[1]=$a[$i]
                        Return $ret
                EndIf
        Next
Else
        For $i = 1 To UBound($a,1)-1
                If StringInStr(StringLower($a[$i]),StringLower($text)) Then
                        $ret[0]=$i
                        $ret[1]=$a[$i]
                        Return $ret
                EndIf
        Next
EndIf
EndFunc ;--> Конец функции для поиска текста (_FindTextInFile)

;Начало функции для перекодировки строк в UTF
Func StringToUTF($String)
        Dim $sResult = ""
        $VarUTFArr = StringSplit($String, "")
       
        For $i = 1 To $VarUTFArr[0]
                $code = Asc($VarUTFArr[$i])
               
                Select
                        Case $code >= 192 And $code <= 239
                                $VarUTFArr[$i] = Chr(208) & Chr($code - 48)
                        Case $code >= 240 And $code <= 255
                                $VarUTFArr[$i] = Chr(209) & Chr($code - 112)
                        Case $code = 168
                                $VarUTFArr[$i] = Chr(208) & Chr(129)
                        Case $code = 184
                                $VarUTFArr[$i] = Chr(209) & Chr(145)
                        Case Else
                                $VarUTFArr[$i] = Chr($code)
                EndSelect
               
                $sResult = $sResult & $VarUTFArr[$i]
        Next
       
        Return $sResult
EndFunc  ;==> Конец функции для перекодировки строк в UTF (StringToUTF)


Если в файле Test.ini, в секции [Section], у параметра Parametr, будет значение предназначенное для того самого поиска (т.е само искомое слово), то запустив этот скрипт, в любом случае $Var будет ровнятся @error, т.е текст указанный в ини файле, искаться не будет, а именно так мне нужно осуществить поиск.

И ещё раз спасибо, буду благодарен если сможете и в этом помочь.

bogomolv 15-08-2006 23:17

Creat0R
Цитата:

выводит ошибку о том, что не возможно найти файл (хотя он наместе)...
На каком месте? Именно это и укажи.
Например:
Код:

If RunWait('@ComSpec@ /C find "Pacific Rim" < C:\DOS\trade.txt','',0)=0 Then
...
EndIf

И не забудь прописать в начале скрипта
Код:

Opt('ExpandVarStrings', 1); default = 0

Creat0R 16-08-2006 01:16

bogomolv

Вот так выглядит у меня состав скрипта:

Код:

Opt("ExpandVarStrings", 1)
If RunWait('@ComSpec@ /C find "word" < C:\Test.txt','',0)=0 Then

MsgBox(64,"","Текст Был найден")

EndIf

На диске С:\, у меня лежит файл Test.txt, а в этом файле, среди прочего текста, есть строка содержащая слово Word - и после запуска этого скрипта, ничего не происходит, а если бы слово было найдено, то вывелось бы сообщение: "Текст Был найден".

Вот как можно заставить такой вариант сработать, но это тоже только для латиницы:

Код:

If RunWait(@ComSpec & " /C find /i /c ""Word"" ""C:\Test.txt"" | find /c "": 0"" > f.tmp","",0)<>0 Then
FileDelete("f.tmp")
MsgBox(64,"","Текст Был найден")

        EndIf

Можно конечно и легче написать этот код, но не в этом суть.

ANGRO 16-08-2006 01:30

Дополнил код по сетевым интерфейсам.
Не могу понять почему не получается обновить информацию по состоянию интерфейса после включения / выключения.
Мож кто подскажит.
Код:

#include <GUIConstants.au3>
#include <GuiCombo.au3>
#NoTrayIcon
Dim $i=1
Dim $NetArr[$i+1][6]
$objShare = ObjCreate("HNetCfg.HNetShare.1")
$shellApp = ObjCreate("Shell.Application")
; GUI ------------------------------------------------------
$Form1 = GUICreate("Сетевые подключения", 350, 198)
GuiSetIcon("netshell.dll", 100)
$Combo1 = GUICtrlCreateCombo("Подключения", 16, 16, 320, 21)
$Button1 = GUICtrlCreateButton("Вкл / Выкл", 100, 145, 150, 35)
$Label1 = GUICtrlCreateLabel("Выберите подключение", 16, 48, 320, 81, $BS_PUSHLIKE)
Data($NetArr, $objShare)
For $n = 1 To $NetArr[0][0]
        GUICtrlSetData($Combo1,$NetArr[$n][1])
Next       
GUISetState(@SW_SHOW)
While 1
        $msg = GuiGetMsg()
  Select
        Case $msg = $GUI_EVENT_CLOSE
                ExitLoop
        Case $msg = $Combo1
                $n = _GUICtrlComboGetCurSel($Combo1)
                If $n > 0 Then
        Output($n)
            Else
                  GUICtrlSetData($Label1, "Выберите подключение")
            EndIf
        Case $msg = $Button1
        $oNetConnections = $shellApp.Namespace(0x00000031)
        For $folderitem in $oNetConnections.items
                  For $verb in $folderitem.verbs
            if $folderitem.name = $NetArr[$n][1] Then
              $verb.DoIt
              Sleep(1000)
              ExitLoop 2
            EndIf
          Next
        Next
        If $folderitem.name <> $NetArr[$n][1] Then msgbox(48, "Ошибка", "Имя соединения указанно не правильно")
                GUICtrlSetData($Label1,"Ждите")
        Output($n)
  EndSelect
WEnd
Exit
; Func -------------------------------------------------------
Func Data(ByRef $NetArr, $objShare)
  If $objShare = 0 Then
          MsgBox(48, "Внимание", "Сетевых подключений не найдено", 5)
          Exit
  EndIf
  $objEveryColl = $objShare.EnumEveryConnection
  If $objEveryColl <> 0 Then
        For $objNetConn In $objEveryColl
          $objShareCfg = $objShare.INetSharingConfigurationForINetConnection($objNetConn)
          If $objShareCfg <> 0 Then
                $objNCProps = $objShare.NetConnectionProps($objNetConn)
                If $objNCProps <> 0 Then
                        ReDim $NetArr[$i+1][6]
                        Select
                                Case  $objNCProps.Status = 0
                    $Status = "The connection is disconnected."
                                Case  $objNCProps.Status = 1
                    $Status = "The connection is in the process of connecting."
                                Case  $objNCProps.Status = 2
                    $Status = "The connection is in a connected state."
                                Case  $objNCProps.Status = 3
                    $Status = "The connection is in the process of disconnecting."
                                Case  $objNCProps.Status = 4
                    $Status = "The hardware for the connection, for example network interface card (NIC), is not present."
                                Case  $objNCProps.Status = 5
                    $Status = "The hardware for the connection is present, but is not enabled."
                                Case  $objNCProps.Status = 6
                    $Status = "A malfunction has occurred in the hardware for the connection."
                                Case  $objNCProps.Status = 7
                    $Status = "The media, for example the network cable, is disconnected."
                                Case  $objNCProps.Status = 8
                    $Status = "The connection is waiting for authentication to occur."
                                Case  $objNCProps.Status = 9
                    $Status = "Authentication has succeeded on this connection."
                                Case  $objNCProps.Status = 10
                    $Status = "Authentication has failed on this connection."
                                Case  $objNCProps.Status = 11
                    $Status = "The address is invalid."
                                Case  $objNCProps.Status = 12
                    $Status = "Security credentials are required."
                        EndSelect
                        Select
                                Case $objNCProps.MediaType = 0
                    $MediaType = "No media is present."
                                Case $objNCProps.MediaType = 1
                    $MediaType = "Direct serial connection through a serial port."
                                Case $objNCProps.MediaType = 2
                    $MediaType = "Connection is through an integrated services digital network (ISDN) line."
                                Case $objNCProps.MediaType = 3
                    $MediaType = "Connection is to a local area network (LAN)."
                                Case $objNCProps.MediaType = 4
                    $MediaType = "Dial-up connection over a conventional phone line."
                                Case $objNCProps.MediaType = 5
                    $MediaType = "Virtual private network (VPN) connection."
                                Case $objNCProps.MediaType = 6
                    $MediaType = "Point-to-Point protocol (PPP) over Ethernet."
                                Case $objNCProps.MediaType = 7
                    $MediaType = "Bridged connection."
                                Case $objNCProps.MediaType = 8
                    $MediaType = "Shared connection to a LAN."
                                Case $objNCProps.MediaType = 9
                    $MediaType = "Shared connection to a remote or wide area network (WAN)."
                        EndSelect
                        $NetArr[$i][1] = $objNCProps.Name
                        $NetArr[$i][2] = $objNCProps.Guid
                        $NetArr[$i][3] = $objNCProps.DeviceName
                        $NetArr[$i][4] = $Status
                        $NetArr[$i][5] = $MediaType
                        $NetArr[0][0] = $i  ; Общее кол-во
                        $i = $i + 1
                  EndIf
          EndIf
        Next
  EndIf
Return $NetArr
EndFunc
Func Output($n)
        GUICtrlSetData($Label1, _
              "- Name: "      & $NetArr[$n][1] & @CRLF & _
              "- Device Name: " & $NetArr[$n][3] & @CRLF & _
              "- Status: "    & $NetArr[$n][4] & @CRLF & _
              "- Media Type: "  & $NetArr[$n][5] & @CRLF)
              ;"- Guid: "      & $NetArr[$n][2]
EndFunc


bogomolv 16-08-2006 02:05

Creat0R

У тебя потрясающее умение делать ошибки там, где их сделать невозможно!
В своих примерах ты в первом случае искал слово "word", а во втором - слово "Word". Естественно, что результаты были разными.

Проблема русского языка и DOS поднималась здесь не раз.
Один из вариантов:
Код:

If RunWait('@ComSpec@ /C  chcp 1251 | find "Ворд" < C:\Test.txt','',0)=0 Then MsgBox(64,"","Текст Был найден")

Creat0R 16-08-2006 02:44

bogomolv
Цитата:

У тебя потрясающее умение делать ошибки там, где их сделать невозможно!
Я знаю :)

Цитата:

В своих примерах ты в первом случае искал слово "word", а во втором - слово "Word". Естественно, что результаты были разными.
Если быть точным, то я искал совсем другое слово, а Word привёл в пример, и тот факт что первая буква большая, не играет роли, это тольку тут я написал так.

Цитата:

Один из вариантов:
И он не работает, слово есть, а он не выводит ничего, и поверь, я перебробовал множество вариантов (с большими буквами, с мелкими, писал даже слово в самое начало файла с пробелом после него, но ничего не сработало). Я даже без аутоита пробовал сделать (через батник), но командной строкой заставить делать поиск по рускому тексту, думаю не всегда возможно (кодировка файла, кодировка текста и т.д).

amel27 16-08-2006 03:29

XXXler
Цитата:

что мешает искать в строке вхождение не "кот" а " кот ", т.е. с пробелами с обоих сторон?
Тогда придется еще учесть все знаки препинания, а также расположение слова в начале и конце строки

Creat0R 16-08-2006 04:48

С поиском я разобрался, Всем спасибо, пример от Sanja Alone оказался верным, просто нужно учитывать, что поиск включая табы (когда нажимаем Tab), не даёт результатов, и слова для поиска, не должны содержать такие пробелы (Tab)...

Теперь у меня немного другой вопрос - как можно записать текст, в определённую строку файла, но не именно в указанную строку (номер строки), а в заданную строку плюс 4 строки? т.е к примеру, нужно в файл Test.txt, в 12-тую строку+4 (т.е получается как бы в 16-тую, но число строки мне заранее не известно, оно будет браться из возвращённого значения - $Var[0]), записать например такой текст - Hello world! -Возможно такое осуществить?

Кстати, хотел узнать, в чём разница между FileWrite и FileWriteLine? вроде они одинаково работают, я пологал, что FileWriteLine, как раз-то и поможет мне в прописовании текста в определённую строку файла, а оказалось, эта функция вовсе этого не умеет :( .

lakis 16-08-2006 08:15

Есть у кого нибудь скрипт на MsOffice 2003 rus?

bogomolv 16-08-2006 09:33

Creat0R
Цитата:

И он не работает
Не могут они не работать! Опять демонстрируешь свои потрясающие умения? :)

ANGRO 17-08-2006 00:47

lakis
Цитата:

Есть у кого нибудь скрипт на MsOffice 2003 rus?
А здесь смотреть не пробовал.

Dirk Diggler 17-08-2006 10:56

Цитата:

Не могут они не работать!
Вы по привычке там переменную окружения заключаете не в %%, а в @@. И уже не в первый раз. CreatOR, как и положено тупизню, не пытался разобраться в механизме действия скрипта, потому и не понял, почему скрипт не работает

Dark Engel 17-08-2006 14:27

Господа. Никто не подскажет как запустить файл.hta
Я делал так

Код:

run ("mshta.exe /имя файла.hta")
mshta.exe в прцессах появляется но ничего не открывает. Плиз хелп.

DmitryOlenin 17-08-2006 15:09

Dark Engel
Смоти соседнюю тему ;) Просто start /wait wpi.hta и все...

Sanja Alone 17-08-2006 21:36

Dark Engel
Цитата:

Никто не подскажет как запустить файл.hta
Нужно указать ПОЛНЫЙ путь к файлу:
Код:

run ("mshta путь\имя файла.hta")
Если файл находится рядом со скриптом, строка запуска будет выглядеть так:
Код:

run ("mshta " & @ScriptDir & "\имя файла.hta")

DenchikK 18-08-2006 04:51

AutoIt 3.2
Новая версия программы, предназначенной для автоматизации часто выполняемых действий в ОС Windows. Утилита позволяет повторять нажатия клавиш клавиатуры, перемещение и клики мышкой, манипуляции с окнами приложений, работу с буфером обмена и другие действия пользователя. Например, с помощью этой программы можно производить установку однотипных приложений. Для выполнения автоматических действий AutoIt создает текстовый сценарий, который использует функции и операторы VBScript и BASIC, а также некоторых других языков программирования. После создания программой специального управляющего скрипта, его можно скомпилировать в исполняемый файл, который будет работать в любой операционной системе семейства Windows. В новой версии изменен синтаксис написания скрипта, добавлены новые способы взаимодействия с ОС, улучшена совместимость с различными языковыми версиями Windows.
ОС: Windows 95/98/Me/NT/2000/XP/2003 | Англ. интерфейс | Бесплатно.
Скачать | download AutoIt 3.2 >> (2891 кб)
http://www.autoitscript.com/files/au...t-v3-setup.exe

ANGRO 18-08-2006 16:17

А вот очередной семпл cделанный на последней стабильной версии.
Код:

Const $RASPBDFLAG_PositionDlg      = 0x00000001 ;+ xDlg и yDlg
Const $RASPBDFLAG_ForceCloseOnDial = 0x00000002
Const $RASPBDFLAG_NoUser          = 0x00000010
Const $RASPBDFLAG_UpdateDefaults  = 0x80000000
;RASPBDLG
$a  = DllStructCreate("dword;int;dword;int;int;uint;ptr;dword;uint;uint")
; наполнение структуры
DllStructSetData($a,1,DllStructGetSize($a));dwSize
DllStructSetData($a,2,0);hwndOwner
DllStructSetData($a,3,$RASPBDFLAG_UpdateDefaults);dwFlags
DllStructSetData($a,4,100);xDlg
DllStructSetData($a,5,100);yDlg
DllStructSetData($a,6,0);dwCallbackId
DllStructSetData($a,7,0);pCallback
DllStructSetData($a,8,0);dwError
DllStructSetData($a,9,0);reserved
DllStructSetData($a,10,0);reserved2
; Вызов DLL
$Dll1 = DllCall("Rasdlg.dll", "int", "RasPhonebookDlg", "str", 0, "str", 0, "ptr", DllStructGetPtr($a))

MsgBox(48, "Error", "Error: " & @error & " | " & "Error RASPBDLG: " & DllStructGetData($a,8))


bogomolv 18-08-2006 20:17

ALL
Ну и как вам v3.2.0.1?
Пока самое сильное впечатление - это растолстевший втрое exe-шник.
Большинство новых функций уже имелись в бетах. Значит, весь "привес" - это COM object support?
По поводу последней новации. Знающие и неленивые, выкладывайте, плз, свои наработки с использованием COM object support. Особенно интересны сравнения: "Вот так приходилось делать раньше, а вот так - теперь!"
Кстати, что за инфа об изменении синтаксиса? Об этом говорится в анонсе, приведенном DenchikK. При изучении справки и changelog ничего подобного не заметил.

Dirk Diggler 19-08-2006 01:04

А что такое COM object support и COM вообще? Дайте пару ссылок

ANGRO 19-08-2006 01:23

Как вариант 288 пост

Creat0R 19-08-2006 13:17

Dirk Diggler
Цитата:

CreatOR, как и положено тупизню, не пытался разобраться в механизме действия скрипта, потому и не понял, почему скрипт не работает
А вот это зря. Зачем так оскорблять? во-первых, я всё пытался, и ставить там нужно не %%, а просто вместо второй @ символ & или как указал bogomolov, ставить в начало скрипта Opt("ExpandVarStrings",1)...
И вообще, оно не работает по другим причинам, именно по тем, что файл который предназначен для поиска в нём, сам по себе в кодировке UTF, а как известно, командная строка плохо работает с этой кодировкой (при поиске кириллицы)...


bogomolv
Цитата:

Не могут они не работать!
Могут (может), и не работает! Проверьте кто-нить если не трудно - Файл пусть будет в кодировке Utf-8, а поиск должен производится по русскому слову...

---------------
У меня есть другой трабл, буду благодарен если кто-то сможет помочь:

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

Код:

;Берём ссылку из буффера обмена

$Clip = ClipGet()

;Пытаемся закачать файл по ссылке из буффера обмена
$InetGet = InetGet($Clip, "c:\file.zip", 1, 1)

;Показываем процесс закачки
While @InetGetActive

  TrayTip("Закачиваю", "Байты = " & @InetGetBytesRead, 10, 1)
Sleep(250)

Wend

;Пытаемся проверить, закачался ли файл, но безуспешно :)
If Not FileExists("c:\file.zip") Then MsgBox(0, "error", "The Download is fail")

;Пытаемся другим способом, но он действует только если в буффере обмена не была ссылка, т.е если в буффера было что-то такое http://ссылка.zip, то ничего не происходит, а если типа такого - ссылка, то выдаёт ошибку
If $InetGet = 0 Then MsgBox(0, "error", "The Download is fail")

Неужели нету корректной проверки на то, закачался ли файл, или ещё лучше, правильная ли ссылка, т.е существует ли файл по ссылке?

XXXler 19-08-2006 13:58

Цитата:

;Пытаемся проверить, закачался ли файл, но безуспешно :) If Not FileExists("c:\file.zip") Then MsgBox(0, "error", "The Download is fail")
у меня, как ни странно но работает (если не забвать после удачной скачки удалить файл)

Цитата:

;Пытаемся другим способом, но он действует только если в буффере обмена не была ссылка, т.е если в буффера было что-то такое http://ссылка.zip, то ничего не происходит, а если типа такого - ссылка, то выдаёт ошибку If $InetGet = 0 Then MsgBox(0, "error", "The Download is fail")
есть предположение, что если отсылать закачку в фон, тогда результата у функции не будет...

можно например сначала попытатся получить размер:
Код:

If InetGetSize($Clip)=0 Then
 MsgBox(0, "error", "The Download is fail")
 Exit ; или Return для использования в функции
EndIf


Creat0R 19-08-2006 18:01

XXXler
Цитата:

есть предположение, что если отсылать закачку в фон, тогда результата у функции не будет...
Я пробвал ставить в дефолтное значение (вeзде ""), но таже история...

Цитата:

можно например сначала попытатся получить размер:
Не знаю почему, но в любом случае (если ссылка к примеру такая http://ссылка.rar), возвращается какое-то значение, а если ссылка не содержит расширения (.rar, .zip и т.д), то возвращается значение ноль и @error ровняется 1 - Но таким образом, не проверяется ссылка, т.к мне нужно именно проверка файла (.zip и .rar)...

Я пробовал так (без участия буффера обмена, думал в нём дело):

Код:

$Clip = "http://ссылка.zip"

    $InetGet = InetGet($Clip, "c:\file.zip", 1, 1)
 MsgBox(0, "error", $GetS)

    $GetS = InetGetSize($Clip)
 MsgBox(0, "error", $GetS)

В первом MsgBox, значение вывелось 1, во втором - 826

Когда я поменял немного ссылку (убрав расширение .zip):

Код:

$Clip = "http://ссылка"

    $InetGet = InetGet($Clip, "c:\file.zip", 1, 1)
 MsgBox(0, "error", $GetS)

    $GetS = InetGetSize($Clip)
 MsgBox(0, "error", $GetS)

То в обоих MsgBox'ах, вывелось значение 0... но если даже ссылка верна, то в первом меседже, также будет значение 1... т.е нет нормального способа, проверить существования файла по ссылке (или уровень ошибочности закачки файла).

Я даже пробовал через командную строку проверить файл, через функцию _RunDos (закачался ли, или нет), но даже и так файл как бы существовал... а когда делал проверку отдельно (в батнике), то всё ок, никакого файла не существовало.

Может всё же есть какой-то, пусть даже хитрый, но работающий способ?

Dirk Diggler 20-08-2006 17:00

Цитата:

Как вариант 288 пост
Это Вы мне? А что там написано про COM? я не понял. :(

ANGRO 20-08-2006 22:46

Очередной семпл, в дополнение к 301.
Пишу сюда чтоб сразу не утонул т.к. проявился интересный нюанс.
Размер структуры нужно выравнивать по 4 байтам. Уж не знаю везде или нет в приведённом примере точно.
Код:

Const $RASEDFLAG_PositionDlg      = 0x00000001
Const $RASEDFLAG_NewEntry          = 0x00000002
Const $RASEDFLAG_CloneEntry        = 0x00000004
Const $RASEDFLAG_NoRename          = 0x00000008
Const $RASEDFLAG_NewPhoneEntry    = 0x00000010
Const $RASEDFLAG_NewTunnelEntry    = 0x00000020
Const $RASEDFLAG_NewDirectEntry    = 0x00000040
Const $RASEDFLAG_NewBroadbandEntry = 0x00000080
Const $RASEDFLAG_InternetEntry    = 0x00000100
Const $RASEDFLAG_NAT              = 0x00000200
Const $Name                        = "TEST1"; или 0
$a  = DllStructCreate("dword;int;dword;int;int;char[257];dword;uint;uint")
; наполнение структуры
DllStructSetData($a,1,292);dwSize
DllStructSetData($a,2,0);hwndOwner
DllStructSetData($a,3,$RASEDFLAG_NewEntry);dwFlags
DllStructSetData($a,4,0);xDlg
DllStructSetData($a,5,0);yDlg
DllStructSetData($a,6,0);szEntry
DllStructSetData($a,7,0);dwError
DllStructSetData($a,8,0);reserved
DllStructSetData($a,9,0);reserved2
; Вызов Dialog DLL
$Dll_X = DllCall("Rasdlg.dll", "int", "RasEntryDlg", "str", 0, "str", $Name, "ptr", DllStructGetPtr($a))
MsgBox(48,"Error 2","Error: "&@error&" | "&"Size: "&DllStructGetSize($a))


sattva 21-08-2006 16:14

Какой будет правильный синтаксис в скрипте AutoIT для добавления программы в Firewall Windows XP
Мой вариант не правильный: RunWait ( 'netsh firewall add allowedprogram' '@ProgramFilesDir & '\' & 'InterVideo\DVD7\WinDVD.exe WinDVD ENABLE' )

SciTE выдает ошибку (C:\Install\WinDVD 7.0.27.191\autoit-windvd7.au3(67,69) : ERROR: syntax error
RunWait ( 'netsh firewall add allowedprogram' '@ProgramFilesDir & ')

XXXler 21-08-2006 18:05

Цитата:

RunWait ( 'netsh firewall add allowedprogram' '@ProgramFilesDir & '\' & 'InterVideo\DVD7\WinDVD.exe WinDVD ENABLE' )
Код:

RunWait('netsh firewall add allowedprogram ""'&@ProgramFilesDir&'\InterVideo\DVD7\WinDVD.exe"" WinDVD ENABLE')

sattva 21-08-2006 18:22

XXXler

Спасиба!

ANGRO 21-08-2006 21:08

А вот кстати как это будет на COM.
Особо не разбирался в возможностях просто транслировал пример из MSDN.
Не уверен что будет работать до WinXP_SP2, но стоит проверить.
Код:

;Firewall Adding an Application
;Set constants
Const $NET_FW_PROFILE_DOMAIN = 0
Const $NET_FW_PROFILE_STANDARD = 1
;Scope
Const $NET_FW_SCOPE_ALL = 0
;IP Version – ANY is the only allowable setting for now
Const $NET_FW_IP_VERSION_ANY = 2

;Create the firewall manager object.
$ObjfwMgr = ObjCreate("HNetCfg.FwMgr")
;Get the current profile for the local firewall policy.
$Profile = $ObjfwMgr.LocalPolicy.CurrentProfile

$App = ObjCreate("HNetCfg.FwAuthorizedApplication")
$App.ProcessImageFileName = @ProgramFilesDir&"\PowerDVD\PowerDVD.exe" ;Путь
$App.Name = "PowerDVD" ;Имя как будет значиться в списке исключений
;Use either Scope or RemoteAddresses, but not both !!!!!! (Если не понятно лучше не трогать)
$App.Scope = $NET_FW_SCOPE_ALL
;$App.RemoteAddresses = "*"
$App.IpVersion = $NET_FW_IP_VERSION_ANY
$App.Enabled = TRUE ; TRUE - Галочка стоит, FALSE - Галочка снята
$Profile.AuthorizedApplications.Add($App)


sattva 22-08-2006 01:21

Рабочий вариант:
Код:

Select
                Case @OSVersion='WIN_XP' and @OSServicePack='Service Pack 2'
                        RunWait('netsh firewall add allowedprogram program="'&@ProgramFilesDir&'\InterVideo\DVD7\WinDVD.exe" name=WinDVD7 profile=ALL mode=ENABLE ','',@SW_HIDE )
                Case @OSVersion='WIN_2003' and @OSServicePack='Service Pack 1'
                        RunWait('netsh firewall add allowedprogram program="'&@ProgramFilesDir&'\InterVideo\DVD7\WinDVD.exe" name=WinDVD7 profile=ALL mode=ENABLE ','',@SW_HIDE  )
EndSelect


bodro 22-08-2006 12:01

Нужен скрипт который бы сканировал текущий каталог и выводил в результате все подпапки, вот что у меня вышло
Код:

;--------------------------------------Start Dir----------------------------------------
$searchdir = (@ScriptDir & "\")
$search = FileFindFirstFile($searchdir & "*") 
$dirtot = 0
$i1 = 0

While 1
If $search = -1 Then ExitLoop
        $file = FileFindNextFile($search)
        If @error Then ExitLoop


$fs1 = StringReplace($file, ".", "-")
if @extended = 0 Then
$i1 = $i1 + 1
Assign ( "dirA" & $i1 , $searchdir & $file , 2)
$dirtot = $dirtot + 1
Assign ( "dirtot" & $dirtot , $searchdir & $file , 2)
EndIf
WEnd
FileClose($search)
;---------------------------------------------------------------------------------------



$is = $i1
$i1 = 0
For $i = 1 TO $is


$var = Eval( "dirA" & $i)
$searchdir = ( $var & "\")

   
$search = FileFindFirstFile($searchdir & "*")
 
While 1
If $search = -1 Then ExitLoop
        $file = FileFindNextFile($search)
        If @error Then ExitLoop


$fs1 = StringReplace($file, ".", "-")
if @extended = 0 Then
$i1 = $i1 + 1
Assign ( "dirB" & $i1 , $searchdir & $file , 2)
$dirtot = $dirtot + 1
Assign ( "dirtot" & $dirtot , $searchdir & $file , 2)
EndIf
WEnd
FileClose($search)


Next

;---------------------------------------------------------------------------------------


$is = $i1
$i1 = 0
For $i = 1 TO $is


$var = Eval( "dirB" & $i)
$searchdir = ( $var & "\")

   
$search = FileFindFirstFile($searchdir & "*")
 
While 1
If $search = -1 Then ExitLoop
        $file = FileFindNextFile($search)
        If @error Then ExitLoop


$fs1 = StringReplace($file, ".", "-")
if @extended = 0 Then
$i1 = $i1 + 1
Assign ( "dirC" & $i1 , $searchdir & $file , 2)
$dirtot = $dirtot + 1
Assign ( "dirtot" & $dirtot , $searchdir & $file , 2)
EndIf
WEnd
FileClose($search)


Next

;---------------------------------------------------------------------------------------

$is = $i1
$i1 = 0
For $i = 1 TO $is


$var = Eval( "dirC" & $i)
$searchdir = ( $var & "\")

   
$search = FileFindFirstFile($searchdir & "*")
 
While 1
If $search = -1 Then ExitLoop
        $file = FileFindNextFile($search)
        If @error Then ExitLoop


$fs1 = StringReplace($file, ".", "-")
if @extended = 0 Then
$i1 = $i1 + 1
Assign ( "dirD" & $i1 , $searchdir & $file , 2)
$dirtot = $dirtot + 1
Assign ( "dirtot" & $dirtot , $searchdir & $file , 2)
EndIf
WEnd
FileClose($search)


Next






$swar = ("")
$i1 = 0
For $i = 1 TO $dirtot

$var = Eval( "dirtot" & $i)
$swar = ($swar & $var & "; ")
Next
FileWrite("test.txt", $swar)

Как его можно оптимизировать чтобы он сканировал все папки независимо от уровня вложений?

amel27 22-08-2006 13:57

bodro
интересно чем не устраивает DIR?
Код:

DIR /AD /S /B >test.txt
хотя можно и AutoIT-ом, что-нибудь типа:
Код:

$root="C:"
DirList ($root,"test.txt")

Func DirList ($root,$file)
        $search = FileFindFirstFile($root & "\*.*")
        While 1
                $dir = FileFindNextFile($search)
                If @error Then ExitLoop
                $dir =$root & "\" & $dir
                If FileExists($dir & "\") Then
                        FileWriteLine($file,$dir)
                        DirList ($dir,$file)
                EndIf
        WEnd
        FileClose($search)
        Return 0
EndFunc


Dirk Diggler 22-08-2006 14:09

конечно, синтаксическая ошибка. внимательнее надо быть, у Вас апостроф вместо & .

XXXler 22-08-2006 14:12

Код:

;~ Функция вывода структуры каталогов
Func ParceDir($Path)
        Local $Pathes[2],$i,$Folders,$Str
        $Pathes[0]=1
        $Pathes[1]=$Path
        While $i<$Pathes[0]
                $i=$i+1
                $Folders=FileFindFirstFile($Pathes[$i]&"\*")
                If $Folders=-1 Then ContinueLoop
                While 1
                        $Str=FileFindNextFile($Folders)
                        If @error Then ExitLoop
                        If $Str="." Or $Str=".." Then ContinueLoop
                        $Str=$Pathes[$i]&"\"&$Str
                        If StringInStr(FileGetAttrib($Str),"D")<>0 Then
                                $Pathes[0]=$Pathes[0]+1
                                ReDim $Pathes[$Pathes[0]+1]
                                $Pathes[$Pathes[0]]=$Str
                        EndIf
                WEnd
                FileClose($Folders)
        Wend
        Return $Pathes
EndFunc

Вызывается с полным путем к каталогу, возвращает одномерный массив, где [0] - количество каталогов, [x] - полный путь к каталогу
Есть минус - каталоги в массиве идут по вложенности (сначала верхний уровень, потом вложенные папки), да и быстродействие хромает...

bodro 22-08-2006 20:15

спасибо DIR /AD /S /B >test.txt меня полностью удовлетворил :)

Creat0R 24-08-2006 01:15

Такой вопрос - Как можно корректно, закрыть определённую программу (не убивать её процесс, а именно нормально закрыть). Эту программу не получается уловить через WinWaitActive, она находится в трее, а как из трея вызывать окно, я не знаю.

И ещё, я запускаю Winamp из трея (повторным запуском), но не получается также уловить его окно, вроде знаю заголовок, но ничего не происходит, скрипт продолжает свои действия не активируя окно винампа (а действия связанный именно с ним). Может есть другой способ уловить окно? т.е не по заголовку, а по другим показателям, ведь заголовок может меняться (при разных языковых версиях).

Ivan1986 24-08-2006 01:32

А ProcessClose разве его не корректно завершеает?
Кстати не нашел там ProcessKill

По поводу винампа попробуй
Код:

AutoItSetOption("WinTitleMatchMode", 4)
WinClose("classname=Winamp v1.x", "")


Creat0R 24-08-2006 02:14

Ivan1986
Цитата:

А ProcessClose разве его не корректно завершеает?
Нет, эта опция "Убивает процесс".

Цитата:

По поводу винампа попробуй
Большое спасибо, немного помогло, но мне нужно чтобы появился винам, и затем открылось диалоговое окно для выбора файлов...
Я выкрутился временно так:

Код:

;Проверяю, если винам не запущен, то...
If Not ProcessExists("winamp.exe") Then

;Счинываю размещение винампа с реестра...
$PathToWinamp = RegRead("HKEY_CURRENT_USER\Software\Winamp", "")       

;Запускаю винамп...
        Run($PathToWinamp & "\winamp.exe", "")

EndIf

AutoItSetOption("WinTitleMatchMode", 4)
  WinActivate("classname=WINAMP", "")
  Sleep(1500)

;Открываю окно для выьбора файлов
Send ("l", 1)

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

LORDMA 28-08-2006 12:20

1 вложений
Уважаемые знатоки помогите как в элементе "ClassNameNN: SysTreeView321" поставить чекбокс в нужном мне месте . Перерыл справку но ничего не нашел , наверняка есть как это сделать но ничего не могу найти??

Creat0R 28-08-2006 15:52

Интересно, как можно задать в скрипте, чтобы определял два параметра командной строки? Т.е, например, я запускаю закомпилированный скрипт таким образом - start script.exe %l %c - Где %l это параметр, который интерпритируется как ссылка (запуск происходит их браузера opera), а %c это параметр, который передаёт содержимое буффера обмена. Так вот, после такого запуска, нужно чтобы для первого параметра происходило одно дейсТвие (пусть даже выводитя MsgBox со значением), а для второго параметра другое действие.

Или хотябы сделать так, чтобы можно было распозновать параметр не по его конечному значению (если %l то значение будет ссылкой по которой было нажато действие для вызова скрипта), а именно по его изначальному виду. Если скрипт допустим запущен так - start script.exe %l - то нужно чтобы в скрипте было распознование того, что его (скрипт) "вызвали" именно с таким ключом (т.к в скрипте есть ещё другие функции, вызываемые другими ключами)... я пробовал таким образом:

Код:

If $CmdLine[1] = "%l" Then
; Что-то делаем...
EndIf

Но Ничего не делается, в этом месте как будто не распознаётся реферрер...
Я пробовал и так:

Код:

If $CmdLine[1] = 0 Then
; Что-то делаем...
EndIf

Что-то делается :) , но тогда если в скрипте присутствует If $CmdLine[0] = 0 Then... То и в этом условии что-то делается (т.е как будто скрипт был запущен без параметров).

Sanja Alone 29-08-2006 05:09

Creat0R
Вот простенький разборщик ком. строки:
Код:

If $CmdLine[0]<>0 Then
        For $k=1 To $CmdLine[0] Step 1
                ;проверка наличия конкретного ключа
                If $CmdLine[$k]="/a" Then
                ; Что-то делаем...
                EndIf
                ;проверка наличия одного из ключей
                Select
                        Case $CmdLine[$k]="/b"
                ; Что-то делаем...
                        Case $CmdLine[$k]="/c"
                ; Что-то делаем...
                        Case $CmdLine[$k]="/d"
                ; Что-то делаем...
                EndSelect
        Next
Else
        MsgBox(16,'Ошибка',"Командная строка пуста...",7)
        Exit
EndIf

P.S. Гораздо удобнее вместо "Что-то делаем..." присваивать определенное значение какой-то переменной, а уже в самой программе производить действия в зависимости от значения этой переменной-флажка. К тому же, в данном сл., можно без проблем оформить анализ ком. строки в виде ф-ции.

KotoVAS 29-08-2006 20:01

Доброго времени суток!!!
1.Сначала у меня вопрос
Как запустить папку Панель управления? а ещё лучше сразу открыть "свойства системы" (Система)

2.Обнаружил косяк. Собрал exe-шник, у меня работает хорошо и закрывается, а вот у друзей работает, но не закрывается - просто сворачивается в трей - что делать ??

3.И ещё как оказалось - у них не отображаются сообщения

MsgBox(0, "Сменщик имени рабочей группы", "Вы уже в группе PLEXUS")

Вааще странно. У меня всегда отображались :(

boss911 29-08-2006 20:18

KotoVAS
Цитата:

Как запустить ... а ещё лучше сразу открыть "свойства системы" (Система)
Код:

%WINDIR%\system32\sysdm.cpl

boss911 29-08-2006 23:38

KotoVAS
Цитата:

А можно код открытия полностью ???
Если вопрос ко мне, то я AutoIt неюзаю, а вообще, чтоб запустить команду в скрипте, то это наверно элементарно, ты же юзаеш и незнаеш как запустить команду!! :)

KotoVAS 29-08-2006 23:43

Да все, как запустить я нашел - А мож знаешь надежный спосб переключения между закладками в "Свойства системы". Мышью пользвать и CTRL+TAB - не очень надежно )

Sanja Alone 30-08-2006 02:45

KotoVAS
Цитата:

надежный способ переключения между закладками в "Свойства системы"
Я еще в старой теме по AutoIt приводил ссылку на "Справочник по командам rundll32". Vadikan посчитал нужным внести эту информацию в "шапку" данной темы и был абсолютно прав. Там есть строки запуска любых диалоговых окошек...

Вот полный список закладок окна "Свойства системы":
System Properties: Advanced
System Properties: Advanced Tab
System Properties: Automatic Updates (2003)
System Properties: Automatic Updates (XP)
System Properties: Computer Name
System Properties: Device Manager
System Properties: General
System Properties: Hardware
System Properties: Hardware Profiles
System Properties: Network Identification
System Properties: Performance
System Properties: Remote (XP)
System Properties: Remote (2003)
System Properties: System Restore
System Properties: User Profiles

P.S. Сейчас подправлю шапку, чтобы всем было понятно зачем нужен этот справочник.

Creat0R 30-08-2006 12:04

Sanja Alone

Цитата:

Вот простенький разборщик ком. строки:
Болшое спасибо! это мне поможет запускать программу с несколькими ключами. Но вот как запускать с ключом, который заранее не известен? Т.е если запуск происходит с ключом %l, то скрипт его не распознаёт, т.к в результате этот ключь преобразовывается в ссылку (самим браузером). А нужно распознать что скрипт был запущен именно с таким ключом, и в данном случае должны происходить определённые операции.

XXXler 30-08-2006 15:39

Цитата:

Болшое спасибо! это мне поможет запускать программу с несколькими ключами. Но вот как запускать с ключом, который заранее не известен?
тогда надо либо определится с количеством и\или порядком ключей\параметров либо делать подключи и опциональные параметры
я уже давал пример здесь, если его видоизменить то можно передавать определенные значения с подключами:
Код:

For $i=1 To $CmdLine[0]
Select
Case StringLeft(CmdLine[$i],5)="/url="
$url=StringTrimLeft(CmdLine[$i],5)

Case StringLeft(CmdLine[$i],6)="/save="
$savename=StringTrimLeft(CmdLine[$i],6)

....

EndSelect
Next

тогда можно вызывать с параметрами /url=http://ya.ru/logo.gif и\или /save=c:\temp, только следует не забывать что параметры с пробелами следует заключать в кавычки

prokazzza 30-08-2006 16:07

Sanja Alone

помогите мне сделать сделать маленький скрипт на RAR SFX архив, нажать извлечь, потом вставить пароль с текстового дока, подождать пока распакуется, подождать пока запуститься установка проги, а потом нажать - No то есть не перезагружать комп.

заранее большое спасибо!

boss911 30-08-2006 18:22

prokazzza
Цитата:

маленький скрипт на RAR SFX архив, нажать извлечь
Зачем? Ключ /s , что не подходит!!

prokazzza 30-08-2006 18:42

boss911

Цитата:

Зачем? Ключ /s , что не подходит!!
Ключ то подходит а вот потом кто вставит пароль и нажмет на кнопки?

boss911 30-08-2006 19:02

prokazzza
Цитата:

а вот потом кто вставит пароль и нажмет на кнопки?
Так может можно решить подобное через твик и вообще, что это за приложение!?
Сори, оффтоп получаетса!!

Creat0R 30-08-2006 19:26

XXXler

Цитата:

можно передавать определенные значения с подключами
Приогромнейшее спасибо!

Цитата:

следует не забывать что параметры с пробелами следует заключать в кавычки
Если запускать программу с браузера опера, то там для этого предусмотренна возможность прописывания ключа с заглавной буквы, и тогда передаваемое значение (в данном случае адрес url + выделенный текст) будет автоматический помещаться в кавычки.

Вот как я приминил это дело:

Код:

Select

; Всё что ниже, буде делаться если скрипт был запущен с каким либо параметром

    Case $CmdLine[0] <> 0

For $i=1 To $CmdLine[0]
Select
Case StringLeft($CmdLine[$i],5)="/url="
$url=StringTrimLeft($CmdLine[$i],5)

Case StringLeft($CmdLine[$i],5)="/txt="
$Text=StringTrimLeft($CmdLine[$i],5)

EndSelect
Next

; Пишу в файл преобразованные параметры (ключи) используя заданные для них переменные

FileWrite(@ScriptDir & "\test.txt", "Скопированный текст: " & $Text & @CRLF & "Текст был скопирован с этой странички: " & $url)

EndSelect


А команда для запуска из браузера такая:

Код:

Execute program, "Test.exe", "/url=%u /txt=%T"
В результате получаю файл с выделенным текстом (в момент вызова функции), и с адресом того документа, на котором было произведенно выделение текста\вызов функции.

Кстати, ты упустил символы $ у некоторых переменных CmdLine ;)

Sanja Alone 31-08-2006 06:00

prokazzza
Цитата:

маленький скрипт на RAR SFX архив
Код:

;имя (или полный путь и имя) sfx-архива берем из ком. строки (если ничего нет - выходим)
If $CmdLine[0]=1 Then
        $sfx=$CmdLine[1]
Else
        MsgBox(16,'Ошибка',"Недопустимое содержимое командной строки",7)
        Exit
EndIf
       
;пароль (если нужно считать из файла, тогда см. в строну ф-ций FileRead, FileReadLine, IniRead в зависимости от формата файла)
$password='Мой pass'

AutoItSetOption("WinTitleMatchMode",4)
;запуск
$pid=Run('"'&$sfx&'" -s')
WinWait('classname=#32770','.exe')
$handle=WinGetHandle("")
;вставить пароль
ControlSetText($handle,'','Edit1',$password)
;нажать извлечь
ControlClick($handle,'','Button1')
;подождать пока распакуется
ProcessWaitClose($pid)

;дальнейшие действия зависят от того, что запускается из параметра комментария Setup sfx-архива
MsgBox(64,'Готово','Файлы извлечены из архива')


Sanja Alone 31-08-2006 06:11

Creat0R
Если порядок параметров строго определен, то можно не париться с доп. текстом.
Тогда "анализ" ком. строки будет выглядеть так:
Код:

If $CmdLine[0]<>0 Then
        $url=$CmdLine[1]
        If $CmdLine[0] = 2 Then
                $Text=$CmdLine[2]
        EndIf
Else
        MsgBox(16,'Ошибка',"Командная строка пуста...",7)
        Exit
EndIf

Команда запуска из браузера так:
Код:

Execute program, "Test.exe", "%u %T"

Creat0R 31-08-2006 18:11

Sanja Alone

Цитата:

можно не париться с доп. текстом.
Спасибо, действительно так проще.

Но у меня появилась немного другая проблема (на эту-же тему) - Дело в том, что если выделенный текст содержал кавычки (более чем две пары), то кавычки не попадают в файл. И ещё, если выделенный текст содержит кавычку, а затем пробел (в дальнейшем тексте, и именно в дальнейшем, не в предыдущем), то выдаётся сообщение с ошибкой выполнения сценария - Что мол переменная используется без того чтобы она была объявленна. А когда объявляю переменные, скрипт не выводит ошибок, но при таком случае (кавычка а затем пробел -> "текст ) вообще ничего не пишет в файл (кроме ссылки естественно). - Это лечится?


P.S:
Странно, но вот например, если выделить такой текст:

"Текст

То кавычка становится после слова (в файле):

Текст"

Sanja Alone 01-09-2006 04:57

Creat0R
Цитата:

кавычки не попадают в файл
При передаче AutoIt-скрипту текста в кавычках из ком. строки, обрезаются первая и вторая кавычки, а текст внутри них считаеся одним параметром, НО! если за второй кавычкой вплотную идет текст, то и он "приклеивается" к содержимому текущего параметра (возможно, это ошибка разработчиков AutoIt). Пробелы вне этих кавычек являются разделителями параметров ком. строки.

Например, если в ком. строке скрипта я напишу:
Код:

"Hello, Остап Ибрагимович. Вы являетесь работником фирмы "Рога и копыта"?"
, то получу при разборе строки 3 параметра:
Код:

1 - "Hello, Остап Ибрагимович. Вы являетесь работником фирмы Рога"
2 - "и"
3 - "копыта?"

Можешь это легко проверить при пом. такого тестового скриптика:
Код:

For $i=1 To $CmdLine[0]
Msgbox(0,"Параметр "&$i,'<'&$CmdLine[$i]&'>')
Next

Т.о., если ты хочешь не потерять какой-то части текста, то должен анализировать полное содержимое ком. строки - $CmdLineRaw. А в этом сл., удобнее будет использовать первый вариант передачи параметров скрипту - "/url=%u /txt=%T"

P.S. Можешь еще попробовать побороться с буфером обмена. Похожая на твою задача была в старой теме - я решал ее вот так

Creat0R 01-09-2006 10:55

Sanja Alone

Цитата:

Можешь еще попробовать побороться с буфером обмена
Как не странно, но к такому (подбному) решению я пришёл до затеи использовать параметры командной строки, для записи текста в файл - в скрипте я писал так:

Код:

$Text = ClipGet()

If $CmdLine[0] <> 0 Then

$Url = $CmdLine[1]

FileWrite(@ScriptDir & "\File.txt", "Скопированный текст: " & $Text & @CRLF & "Текст скопирован с документа: " & $Url)

EndIf

А команду в браузере писал так:

Код:

Copy & Execute program, "Script.exe", "%u"
Таким образом, до вызова самого скрипта, выделенный текст в документе, помещается в буффер обмена, и скрипт “берёт” из буффера полный текст в переменную, и вписывает в файл. Это решение в принципе не имеет проблем, но причина по которой я хотел узнать как передавать два значения (ключа) скрипту, являлась обходом помещения текста в буффер обмена, т.е чтобы не занимать лишни раз буффер обмена.

Ещё раз спасибо за помощь!
-------------------------------------

У меня тут появилась проблема с другой сферы...

Я сделал немного примитивный (пробный) гуи интерфейс (см. код ниже), и есть пару вопросов по этому поводу:

А) Как можно сделать, чтобы после зажатия галки у надписи “Опция”, окно (MsgBox) появлялось только после зажатия, а не каждый раз. Т.е в данный момент, если я зажму галку, то сообщение появляется, если отожму, то тоже появляется - как сделать чтобы появлялось только после зажатия?

Б) У меня в гуи (GUI), есть две кнопки (кроме прочих) - Одна для отмечивания всех галок ("Выбрать все"), а другая для их снятия ("Очистить все") - Вопрос: Как сделать чтобы была такая одна кнопка, а ещё лучше тоже чекбокс, после нажатия которого\ой, выделялись бы все чекбоксы, а если отжать эту\от кнопку\чекбокс, то чтобы также и отжимались все остальные чекбоксы?

Г) Это самая большая прблема, и она у меня имеет наивысшый приоритет для решения - Я поместил в гуи прогресс бар (progressbar), и хотел бы добиться такого результата, чтобы в то время, как происходит копирование определённых файлов, этот прогресс бар был задйствован. Т.е если я копирую например большой файл (фильм к примеру), то чтобы пока он копировался, ползунок бегал в прогрес баре. Мне в принципе не нужно чтобы происходил там какого то рода подсчёт размера файла (хотя думаю в этом и заключается достижение моей задачки), и на основе чего и делался прогресс, а чтобы просто было видно что копирование в прогрессе (и не важно в каком этапе оно находится :) ).

Я временно ограничелся запуском внешнего прогресс бара (через запуск этого же скрипта, с ком. строкой), который (прогрессбар) ходит туда сюда до тех пор, пока не будет существовать определёный файл, который создаётся самим скриптом в тот момент, как копирование окончено (т.е я поставил команду создания этого файла как метку, после команды копирования). Но хотелось бы чтобы этот прогресс бар был внутри гуи интерфейса.


Скрипт:

Код:

#include <GUIConstants.au3>

$Form1 = GUICreate("Test", 450, 370, 214, 126)

$Opt = GUICtrlCreateCheckbox("Опция", 230, 50, 300, 20)

$File = GUICtrlCreateCheckbox("Файл", 70, 50, 97, 17)
$Edit = GUICtrlCreateCheckbox("Правка", 70, 70, 97, 17)
$View = GUICtrlCreateCheckbox("Вид", 70, 95, 97, 17)
$Bookmarks = GUICtrlCreateCheckbox("Закладки", 70, 120, 97, 17)
$Session = GUICtrlCreateCheckbox("Сеансы", 70, 145, 97, 17)

$progressbar1 = GUICtrlCreateProgress (10,10,200,20)
GUICtrlSetColor(-1,32250)

$All1 = GUICtrlCreateButton("Выбрать все", 70, 330, 90, 23)
$All2 = GUICtrlCreateButton("Очистить все", 70, 300, 90, 23)

$Start = GUICtrlCreateButton("Выполнить", 260, 330, 93, 25)
$Close = GUICtrlCreateButton("Выход", 360, 330, 70, 25)

Dim $radioval1

$group_1 = GUICtrlCreateGroup ("Группа", 255, 190, 140, 110, 100)
GUIStartGroup()
$radio_1 = GUICtrlCreateRadio ("Вариант 1", 285, 220, 90, 20)
GUICtrlSetState ($radio_1,$GUI_CHECKED)
$radio_2 = GUICtrlCreateRadio ("Вариант 2", 285, 270, 90, 20)

GUISetState(@SW_SHOW)
GUISetState ()

        While 1

; Здесь по идее, хотелось бы чтобы прогресс бар начал крутится, а остановится пусть в конце скрипта (перед wend)

$msg = GuiGetMsg()
       
        If $msg = $Opt Then MsgBox(48, "Atantion", "This is a test")
       
If $msg = $All1 Then

        GUICtrlSetState ($File,$GUI_CHECKED)
        GUICtrlSetState ($Edit,$GUI_CHECKED)
        GUICtrlSetState ($View,$GUI_CHECKED)
        GUICtrlSetState ($Bookmarks,$GUI_CHECKED)
        GUICtrlSetState ($Session,$GUI_CHECKED)
       
EndIf

If $msg = $All2 Then

        GUICtrlSetState ($File,$GUI_UNCHECKED)
        GUICtrlSetState ($Edit,$GUI_UNCHECKED)
        GUICtrlSetState ($View,$GUI_UNCHECKED)
        GUICtrlSetState ($Bookmarks,$GUI_UNCHECKED)
        GUICtrlSetState ($Session,$GUI_UNCHECKED)

EndIf
       
If $msg = $GUI_EVENT_CLOSE  Or $msg = $Close Then Exit

Select
       
        Case $msg >= $radio_1 AND $msg <= $radio_2
        $radioval1 = $msg - $radio_1

        Case $msg = $Start

If $radioval1 = 0 Then

                If GUICtrlRead($Opt) = 1 Then

EndIf

                If GUICtrlRead($File) = 1 Then


EndIf
       
                If GUICtrlRead($Edit) = 1 Then

               
EndIf

                If GUICtrlRead($View) = 1 Then


EndIf

                If GUICtrlRead($Bookmarks) = 1 Then


EndIf

                If GUICtrlRead($Session) = 1 Then

                       
EndIf

If GUICtrlRead($File) <> 1 and GUICtrlRead($Edit) <> 1 and GUICtrlRead($View) <> 1 and GUICtrlRead($Bookmarks) <> 1 and GUICtrlRead($Session) <> 1 and GUICtrlRead($Opt) <> 1 Then

                MsgBox(48, "Error", "Выберите как минимум один чекбокс")
        ContinueLoop
EndIf

        MsgBox(64, "Finishing...", "Финито 1", 15)

        GUICtrlSetState ($Opt,$GUI_UNCHECKED)       
        GUICtrlSetState ($File,$GUI_UNCHECKED)
        GUICtrlSetState ($Edit,$GUI_UNCHECKED)
        GUICtrlSetState ($View,$GUI_UNCHECKED)
        GUICtrlSetState ($Bookmarks,$GUI_UNCHECKED)
        GUICtrlSetState ($Session,$GUI_UNCHECKED)
       
EndIf

If $radioval1 = 1 Then

                If GUICtrlRead($Opt) = 1 Then

EndIf

                If GUICtrlRead($File) = 1 Then

EndIf
       
                If GUICtrlRead($Edit) = 1 Then
                       
EndIf

                If GUICtrlRead($View) = 1 Then

EndIf

                If GUICtrlRead($Bookmarks) = 1 Then

EndIf

                If GUICtrlRead($Session) = 1 Then
       
EndIf


If GUICtrlRead($File) <> 1 and GUICtrlRead($Edit) <> 1 and GUICtrlRead($View) <> 1 and GUICtrlRead($Bookmarks) <> 1 and GUICtrlRead($Session) <> 1 and GUICtrlRead($Opt) <> 1 Then

                MsgBox(48, "Error", "Выберите как минимум один чекбокс")
        ContinueLoop
EndIf


        MsgBox(64, "Finishing...", "Финито 2", 15)

        GUICtrlSetState ($Opt,$GUI_UNCHECKED)
        GUICtrlSetState ($File,$GUI_UNCHECKED)
        GUICtrlSetState ($Edit,$GUI_UNCHECKED)
        GUICtrlSetState ($View,$GUI_UNCHECKED)
        GUICtrlSetState ($Bookmarks,$GUI_UNCHECKED)
        GUICtrlSetState ($Session,$GUI_UNCHECKED)

EndIf
        EndSelect
                WEnd


sattva 01-09-2006 22:34

Помогите разобраться почему не работает выбор строки из выпадающего меню для Adobe Creative Suite 2 Russian by cvs/SSG

Код:

ControlCommand('Adobe Creative Suite 2 Russian by cvs/SSG','Activation','obj_COMBOBOX1','SelectString','Photoshop CS2 9.0')
выбор строки "Photoshop CS2 9.0" не происходит

Sanja Alone 02-09-2006 05:07

Creat0R

А)
Код:

If $msg = $Opt Then
        If GUICtrlRead($Opt)=$GUI_CHECKED Then MsgBox(48, "Atantion", "This is a test")
EndIf

Б) См. пример выше и читай о ф-циях GUICtrlRead ( controlID ), GUICtrlGetState ( [controlID] )

А где ты В) потерял? :)

Г) Прогрессбар - это весьма муторная штука, когда нет естественных привязок. Твой вариант - это именно тот случай (такая же проблема была и у меня в OEsr). Я не стал париться, и сделал простой "светофор" :) Он не мешает работе основного приложения (в данном сл. - архиватора) и дает пользователю представление о происходящем (для верности, можно в процессе/конце операции еще проигрывать звуковой файл и/или выводить сообщения в трее - SoundPlay ( "filename" [, wait] ), TrayTip ( "title", "text", timeout [, option] ) ). Я этого делать не стал, а ты можешь попробовать...



sattva
Цитата:

не работает выбор строки из выпадающего меню
Для начала, дай фокус данному эл-ту управления:
Код:

ControlFocus('Adobe Creative Suite 2 Russian by cvs/SSG','Activation','obj_COMBOBOX1')
Если это не поможет, то замени свою строку выбора эл-та комбобокса такой:
Код:

ControlCommand('Adobe Creative Suite 2 Russian by cvs/SSG','Activation','obj_COMBOBOX1',"SetCurrentSelection", ControlCommand('Adobe Creative Suite 2 Russian by cvs/SSG','Activation','obj_COMBOBOX1',"FindString",'Photoshop CS2 9.0'))
Ну, и самый тежелый случай (если 2 первых не работают):
Код:

Send("{DOWN число}")
, где "число" - это требуемое к-во нажатий на кнопку для выбора нужной строки комбобокса.

prokazzza 02-09-2006 19:10

Sanja Alone

я не силен в скриптах пожалуста можно сделать вот скрипт

запуск c:/install/install.sfx.exe
нажать кнопку "извлечь"
вставить пароль из c:/install/password.txt
нажать кнопку "ок"
пождать пока распакуется RAR архив
подождать пока установится istall.exe
если выйдет надпись "сделать перезагрузку" нажать нет, если не выйдет надпись то ничего не делать.

sattva 02-09-2006 23:19

Sanja Alone

Спасибо, сработал только этот вариант
Код:

Global $file='Adobe Photoshop CS2.msi', $key='keygen.exe'

; Запуск кейгена
Run ( $key )
WinWaitActive ( 'Adobe Creative Suite 2 Russian by cvs/SSG' )
ControlFocus('Adobe Creative Suite 2 Russian by cvs/SSG','Activation','obj_COMBOBOX1')
Send ("{DOWN}")


Sanja Alone 03-09-2006 02:58

prokazzza
Цитата:

вставить пароль из c:/install/password.txt
Это неструктурированный текстовый файл или ini-файл? В какой кодировке? В какой строке находится пароль?

Цитата:

подождать пока установится istall.exe
Комментарий архива в студию!

Цитата:

если выйдет надпись "сделать перезагрузку" нажать нет, если не выйдет надпись то ничего не делать
А не проще ли будет указать ключ, отменяющий перезагрузку для данного приложения прямо в строке его запуска после извлечения из архива? (например: Setup=install.exe REBOOT=ReallySuppress /qn). Я надеюсь, что это загадочное приложение использует какой-то стандартный установщик (см. статью Типы инсталляторов).

amel27 03-09-2006 12:21

Возвращаясь к задаче поиска вхождений заданного слова в произвольный текст. Выше я дал маху утверждая, что AutoIT не поддерживает регулярные выражения... хотя с русским опять облом - если метасимволы \l \u \w еще работают, то (?i) ни в какую... :(

StringRegExp - Check if a string fits a given regular expression pattern.
StringRegExpReplace - Replace text in a string based on regular expressions.

вариант поиска слова с использованием регулярных выражений (на основе скрипта Sanja Alone):
Код:

#include <File.au3>

$fileInput = 'file.txt'
$wordToFind= 'исКать'

$find = _FindTextInFile ($fileInput,$wordToFind)
If $find Then
        MsgBox (0, 'Поиск слова в файле',  'Слово "' & $wordToFind & '" найдено в ' & $find & '-й строке.')
Else
        MsgBox (0, 'Поиск слова в файле',  'Слово "' & $wordToFind & '" в файле не обнаружено.')
EndIf

Func _FindTextInFile ($ifile, $word)
        Local $i, $a, $ret=0
        _FileReadToArray($ifile, $a)
        For $i=1 To Ubound ($a)-1
                If StringRegExp ($a [$i], _WordToReg ($word) ) Then
                        Return $i
                EndIf
        Next
        Return 0
EndFunc

; перевод произвольного слова в регулярное выражение
; требуется для поддержки русских слов, так как (?i)
; воспринимает только регистры английских букв;
; пример: "Кот" --> "\<[кК][оО][тТ]\>"


Func _WordToReg ($word)
        Local $i, $c, $w=""
        If StringIsASCII($word) Then
                Return '(?i)\<' & $word & '\>'
        Else
                For $i=1 To StringLen($word)
                        $c = StringMid ($word, $i, 1)
                        If StringLower($c) == StringUpper($c) Then
                                $w=$w & $c
                        Else
                                $w=$w & '[' & StringLower($c) & StringUpper($c) & ']'
                        EndIf
                Next
                Return '\<' & $w & '\>'
        EndIf
EndFunc


Creat0R 03-09-2006 20:50

Sanja Alone
Снова огромно спасибо за А) и Б)

Цитата:

А где ты В) потерял?
От волнения забыл про него ...

А на счёт Г), я всё же решил немного попариться, и нашёл, я бы сказал, обходное решение...

Вместо того, чтобы копировать файл командами AutoIt'а, я повесил копирование на ком. строку:

Код:

Run(@ComSpec & " /c copy /y ""c:\File.txt"" ""d:\File.txt""", "", @SW_HIDE)

; Затем заключил в вечную петлю прогресс бар, до тех пор, пока в системе висит процесс “cmd.exe”, т.е это значит, что до тех пор, пока будет делаться копирование...
While 1

        For $i = 5 To 100
          GUICtrlSetData ($progressbar1, $i)
          Sleep(1)
        Next
        If Not ProcessExists("cmd.exe") Then ExitLoop
Wend
        GUICtrlSetData ($progressbar1, 0)

Хотя и тут может быть проблема, ведь в этот момент, юзеру может приспичить включить ком. строку для своих целей...
Но и это можно обойти, создав той-же ком. строкой, файл во временной папке %temp%, и по завершению копирования удалять его, а проверку для завершения прогресс бара, делать так:

If Not ProcessExists("cmd.exe") or Not FileExists(@TempDir & "\mark.tmp") Then ExitLoop

Или может есть более надёжный способ, но тогда нужно узнать, возможно ли, и как, проверять когда был запущен процесс (cmd.exe), и если именно этот процесс не существует, тогда выходить с петли. Если кто-то подскажет возможно ли такое, и если да, то как осуществить, то буду очень признателен.
----------------------

У меня есть ещё один вопрос, и тоже в другом направлении -
Нужно взять в переменную, все последние символы идущие после определнного знака у значения другой переменной. Т.е, вот например значение переменной $Var ровняется c:\program files\my programm\test.zip - и нужно чтобы из этой переменной, вернулось такое значение - test.zip - в другую переменную, например в $Var1.
Но заранее, не известно, ни количество слэшей (\) в пути, ни количество символов после последнего слэша. Возможно такое осуществить?
Как я понимаю, тут как-то нужно задействовать одну из вариации команды String, но если честно, то я уже замучался в попытках подобрать подхолящюю для этой цели вариацию, и справка тоже не помогла :(

Я временно это решил опять-таки ком. строкой :) :
Код:

$Var = "c:\program files\my programm\test.zip"

; Беру нужное значение, и вывожу последние его символы после последнего слэша, в файл test.tmp
Run(@ComSpec & " /c for %a in (""" & $Var & "") do echo %~nxa> """ & @ScriptDir & "\test.tmp""")

; Помещаю новое значение (из файла) в переменную $Var1
$Var1 = FileReadLine(@ScriptDir & "\test.tmp", 1)

    MsgBox(0, "", The New Value is: " & $Var1)
FileDelete (@ScriptDir & "\test.tmp")

Но ту проблема в том, что нужно создавать файл, затем удалять его, а в моём случае, таких операции мне приходится делать не раз в моём скрипте, и каждый раз заного создовать файл, а затем удалять его, не лучший вариант... тем более, что скрипт может быть запущен из флешки, а всё время писать на флешку, это её вредит (хотя можно конечно писать файл во времеенный каталог - @TempDir, но всё же не удобно).

Sanja Alone 04-09-2006 03:17

Creat0R
Цитата:

значение переменной $Var ровняется c:\program files\my programm\test.zip - и нужно чтобы из этой переменной, вернулось такое значение - test.zip - в другую переменную, например в $Var1.
Это очень просто:
Код:

Func PathName($fullpath)
        Local $s=StringInStr($fullpath,'\',0,-1) ;первый слэш с конца
        Local $n=StringMid($fullpath,$s+1)
        Local $p=StringLeft($fullpath,$s-1)
        Dim $pn[2]
        $pn[0]=$p ;путь
        $pn[1]=$n ;имя
        Return $pn
EndFunc


amel27 04-09-2006 03:45

Creat0R
Цитата:

Нужно взять в переменную, все последние символы идущие после определнного знака у значения другой переменной. Т.е, вот например значение переменной $Var ровняется c:\program files\my programm\test.zip - и нужно чтобы из этой переменной, вернулось такое значение - test.zip - в другую переменную, например в $Var1.
Но заранее, не известно, ни количество слэшей (\) в пути, ни количество символов после последнего слэша. Возможно такое осуществить?
Вот вариант с применением регулярных выражений:
Код:

$var = 'c:\program files\my programm\test.zip'
$res = StringRegExpReplace ($var, '^.*\\', '')


Creat0R 04-09-2006 14:50

amel27, Sanja Alone:

Спасибо! то что нужно было!

Dirk Diggler 08-09-2006 11:43

Интереснейшая фигня наблюдается. Имеем скрипт, который пингует некий хост, и выходит с кодом либо 1, либо 0
Код:

If Ping($cmdline[1],2000) > 0 Then
        Exit(0)  ; if PING success, returns 0
Else
        Exit(1)
EndIf

Он вызывается из следующего батника:
Код:

@echo off
SET PING= ping.au3
SET HOST1=google.com
SET DG=192.168.100.12312

%ping% %HOST1%
echo ping %HOST1% returns %errorlevel%

if "%DG%"=="" (
rem
) ELSE (
%ping% %DG%
echo ping %DG% returns %errorlevel%
)

Так вот, здесь результат БУДЕТ ОДИНАКОВЫЙ для обоих пингов, и зависит только от того, пингуется ли %HOST1%!

Цитата:

ping google.com returns 0
ping 192.168.100.12312 returns 0
Цитата:

ping google.23rwefwe returns 1
ping 192.168.100.1 returns 1
А 192.168.100.1 - мой адсл-модем, и он пингуется всегда 8-)
Однако, удалим конструкцию с IF, и всё работает как надо:
Код:

@echo off
SET PING= ping.au3
SET HOST1=goowefwegle.com
SET DG=192.168.100.1

%ping% %HOST1%
echo ping %HOST1% returns %errorlevel%
%ping% %DG%
echo ping %DG% returns %errorlevel%

Цитата:

ping goowefwegle.com returns 1
ping 192.168.100.1 returns 0
Где грабли - в AutoIt или командном интерпретаторе винды?
Проверено на XP SP1, AutoIt 3.2.0.1

prokazzza 08-09-2006 14:14

Sanja Alone

вот ссылочка на архив посмотрите пожалуста

http://uploaded.to/?id=f31c2d

весит метр внутри реадми, файл с паролем и RAR SFX архив внутри архива простая прога Atnotes вирусов НЕТ.

Заранее спасибо!

Creat0R 09-09-2006 03:07

Такая проблема появилась:

Нужно взять значение пареметра в переменную, но брать нужно не из файла конфигурации (*.ini), а из обычного текстового файла.
Я решил эту задачу, но только если кодировка файла не является UTF-8, если она такой и является, то киррилица которая будет прописанна в значении, будет отображаться крякозябрами (если вывести переменную в MsgBox)... вот пример работающего скрипта, с файлом test.txt, который в кодировке ANSI:

Код:

$File = @ScriptDir & "\test.txt"

; Поиск нужных символов в файле test.txt
$Find = _FindTextInFile($File, "2000000")

; Очищаю строку с найденным текстом, от пробелов и кавычек (так надо ;) )
$Clean1 = StringRegExpReplace($Find[1], " ", "")
$Clean2 = StringRegExpReplace($Clean1, """", "")

; Беру все символы, которые находятся после искомого слова + 1 символ (=)
$MsgBox = StringTrimLeft($Clean2, 8)

; Вывожу результат в сообщении
MsgBox(0, "", $MsgBox)

; Функция для поиска в файле, предоставленная by Sanja Alone
Func _FindTextInFile($ifile,$text)
Local $i
Dim $ret[2]
$file = FileOpen($ifile,0)
$a = StringSplit( FileRead($file, FileGetSize($ifile)), @LF)
FileClose($file)

If StringIsASCII($text) Then
        For $i = 1 To UBound($a,1)-1
                If StringInStr($a[$i],$text) Then
                        $ret[0]=$i
                        $ret[1]=$a[$i]
                        Return $ret
                EndIf
        Next
Else
        For $i = 1 To UBound($a,1)-1
                If StringInStr(StringLower($a[$i]),StringLower($text)) Then
                        $ret[0]=$i
                        $ret[1]=$a[$i]
                        Return $ret
                EndIf
        Next
EndIf
EndFunc

Содержание файла test.txt такое:

Код:

2000000= "это тест"
И если этот файл будет в кодировке UTF-8, то в MsgBox выведутся каракули, как можно это исправить?

Sanja Alone 09-09-2006 07:24

prokazzza
Код:

If $CmdLine[0]=1 Then
        $sfx=$CmdLine[1]
Else
        MsgBox(16,'Ошибка',"Недопустимое содержимое командной строки",7)
        Exit
EndIf
;пароль (берется из 3-й строки)
$password=FileReadLine(@ScriptDir&'\пароль.ini',3)
$pid=Run('"'&$sfx&'" -s')
WinWait('Ввод пароля')
ControlSetText('Ввод пароля','','Edit1',$password)
ControlClick('Ввод пароля','','Button1')
ProcessWaitClose($pid)
ProcessWaitClose('INSTALL.exe')

Цитата:

иногда просит перезагрузиться
У меня не просил, след-но, этого окна я не видел.

P.S. Гораздо удобнее сделать тихую установку этого самого Atnotes непосредственно из его дистрибутива (с отменой перезагрузки, конечно, если она там требуется), а уже свои настройки для этого приложения восстановить из архива.

Код:

Global $file='atnsetup.exe', $InstPath=@ProgramFilesDir & '\ATnotes', $programgroup='ATnotes' , $rus=@ScriptDir & '\ATnotes.ini'
;установка в тихом режиме
RunWait(@ScriptDir & '\' & $file & ' /VERYSILENT /NORESTART /SP- /DIR="' & $InstPath & '" /GROUP="' & $programgroup & '"' )
;русификация
If FileExists($rus) Then Filecopy($rus,$InstPath & '\')
#cs
А вот здесь уже будет восстановление настроек
(файл ATnotes.dat и ветка реестра HKEY_CURRENT_USER\Software\Ascher\ATnotes, сохраненная в файл settings.reg)
Положи их в архив с таким комментарием:

Path=ATnotes
SavePath
Setup=cmd /c start /wait regedit /s settings.reg & del settings.reg
Silent=1

а приведенный выше скрипт (без последней строки) допиши в конец этого, и он обработает твой запароленный sfx-архив с настройками
№ce


amel27 10-09-2006 09:13

Dirk Diggler
Цитата:

Однако, удалим конструкцию с IF, и всё работает как надо:
дык сам и ответил - в батнике, нужно так:
Код:

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION

SET PING= ping.au3
SET HOST1=google.com
SET DG=192.168.100.12312

%ping% %HOST1%
echo ping %HOST1% returns %errorlevel%

if "%DG%"=="" (
rem
) ELSE (
%ping% %DG%
echo ping %DG% returns !errorlevel!
)

З.Ы. подробности смотри в "CMD /?"

prokazzza 10-09-2006 11:53

Sanja Alone

вот картинка перезагрузки (1 рисунок)
по умолчанию стоит сразу на YES

и просьба можешь доработать вот этот скрипт

Код:

Run("rundll32.exe netshell.dll,StartNCW")
WinWaitActive ('Мастер новых подключений','Мастер новых подключений')
Send('{Enter}')
Sleep ('500')
WinWaitActive ('Мастер новых подключений','Подключить к Интернету для просмотра веб-узлов и чтения  электронной почты.')
ControlClick ('Мастер новых подключений','Подключить к Интернету для просмотра веб-узлов и чтения  электронной почты.','Button1')
Sleep ('500')
Send('{Enter}')

WinWaitActive ('Мастер новых подключений','Каким образом подключиться к Интернету')
ControlClick ('Мастер новых подключений','Каким образом подключиться к Интернету','Button2')
Sleep ('500')
Send('{Enter}')
WinWaitActive ('Мастер новых подключений','Данное подключение использует модем и обычную телефонную линию или телефонную линию ISDN.')
ControlClick ('Мастер новых подключений','Данное подключение использует модем и обычную телефонную линию или телефонную линию ISDN.','Button1')
Sleep ('500')
Send('{Enter}')
WinWaitActive ('Мастер новых подключений','Им&я поставщика услуг')
ControlSetText ( 'Мастер новых подключений', '', 'Edit1', 'Peterstar' )
Sleep ('500')
Send('{Enter}')
WinWaitActive ('Мастер новых подключений','Номер &телефона:')
ControlSetText ( 'Мастер новых подключений', '', 'Edit1', '3203370,,,' )
Sleep ('500')
Send('{Enter}')
WinWaitActive ('Мастер новых подключений','&Имя пользователя:')
sleep (100)
ControlSetText ( 'Мастер новых подключений', '', 'Edit1', 'Login')
sleep (100)
ControlSetText ( 'Мастер новых подключений', '', 'Edit2', 'Password')
Send('{tab}')
sleep (100)
ControlSetText ( 'Мастер новых подключений', '', 'Edit3', 'Password')
Sleep ('500')
ControlCommand ( 'Мастер новых подключений', '', 'Button13', 'Check', '' )
ControlCommand ( 'Мастер новых подключений', '', 'Button2', 'Check', '' )
Sleep ('500')
Send('{Enter}')
WinWaitActive ('Мастер новых подключений','Завершение работы мастера новых подключений')
ControlCommand ( 'Мастер новых подключений', '', 'Button20', 'UnCheck', '' )
Send('{Enter}')
Exit

(2 рисунок) - добавить галочку "отобразить на рабочем столе" - нажимаем готово, после нажатия готово запуститься подключение, добавить галочку (3 рисунок) " сохранить имя пользователя и пароль" нажимаем свойства, переходим на вкладку параметры (4 рисунок), "число набора номера 100", "интервал между повторами номера - 1 секунда", "время до разьединения - никогда", и поставить галку - перезвонить после разрыва связи, все ок и закрыть подключение.

Sanja Alone 10-09-2006 15:39

prokazzza
Цитата:

вот картинка перезагрузки (1 рисунок)
Пик! пик! пииииик! :angry: Ты мне можешь объяснить какое отношение имеет "картинка перезагрузки" Office 2003 к скрипту установки Atnotes?

Цитата:

доработать вот этот скрипт
См. тему Соединение по dial-up автоматом и в старой теме по AutoIt bogomolv приводил вариант реализации подобного (ПОЛЬЗУЙСЯ ПОИСКОМ по форуму). Если тебе после всего прочитанного все-таки захочется доработать именно этот скрипт, то воспользовавшись AutoIt Window Info ты самостоятельно сможешь осуществить сие действо.

prokazzza 10-09-2006 17:36

Sanja Alone

Цитата:

какое отношение имеет "картинка перезагрузки" Office 2003 к скрипту установки Atnotes?
это просто пример. Он не просит на Atnotes перезагрузку пришлось сделать Office для примера, который точно попросил перезагрузку.

Цитата:

ты самостоятельно сможешь осуществить сие действо
еслиб я умел, я тя наверно не просил (без обид).

Sanja Alone 11-09-2006 04:53

prokazzza
Цитата:

это просто пример
Практически у любого приложения есть ключи/параметры файла ответов и т.п. прибамбасы для отмены перезагрузки. Тема по Офису на форуме - вот, статьи по Офису читай на сайте + все-таки прочти статью о типах инсталляторов (ссылку я тебе уже давал). Если все же возникнут непреодолимые с пом. ключей/параметров окна, то еще прочти маленькую заметку на тему "отлова случайных окон" в моем FAQ по AutoIt.

Цитата:

еслиб я умел
Если ты не представляешь что делать с AutoIt Window Info (%ProgramFiles%\AutoIt3\AU3Info.exe) в частности и/или с AutoIt-ом в целом, тогда скачай редактор SciTE. Помимо собственно редактора, ты также получишь ScriptWriter (%ProgramFiles%\AutoIt3\SciTE\ScriptWriter\scriptwriter.exe). Думаю, что помочь в написани скрипта он тебе сможет. Это, грубо говоря, прога записи твоих действий в готовый AutoIt-код. Правда, потом нужно будет вручную подправлять такой "самописный" скрипт, но это лучше, чем ничего.

Цитата:

я тя наверно не просил
Наглость - второе счастье. Я тебе искренне завидую, ибо не имею даже первого... Я не могу за всех все делать. Я могу лишь посильно помочь в чем-то. Я тебе дал всю необходимую инфу - изучай. Бери пример с Creat0R-а. Еще пару месяцев назад он не знал базовых принципов, а сейчас замахивается "на Вильяма нашего, Шекспира".

amel27 11-09-2006 10:25

Creat0R
Цитата:

и если этот файл будет в кодировке UTF-8, то в MsgBox выведутся каракули, как можно это исправить?
вариант реализации функции преобразования кодировок и пример использования:
Код:

$file = "test.txt"
$foo = FileOpen($file, 4) ; 4 - RAW-режим!

$text = _Utf8ToAnsi(FileRead($foo,FileGetSize($file)))
MsgBox(0,"Test",$text)
FileClose ($foo)

; Пример преобразования UTF-8 в ANSI
; другие варианты кодировок:
; 0  - ANSI
; 1  - OEM
; 2  - MAC
; 42 - Symbol
; 65000 - UTF-7
; 65001 - UTF-8


Func _Utf8ToAnsi($utf8String)
        Return _Uni2Any(_Any2Uni($utf8String, 65001),0)
EndFunc

; Преобразование символьной строки заданной кодировки в юникод

Func _Any2Uni($anyString, $codePage)
        Local $bufSize = StringLen($anyString) * 2
        Local $buf = DllStructCreate("byte[" & $bufSize & "]")
        Local $ret = DllCall("Kernel32.dll", "int", "MultiByteToWideChar", _
                "int", $codePage, _
                "int", 0, _
                "str", $anyString, _
                "int", StringLen($anyString), _
                "ptr", DllStructGetPtr($buf), _
                "int", $bufSize)
        Local $uniString = StringLeft(DllStructGetData($buf, 1), $ret[0] * 2)
        $buf = 0
        Return $uniString 
EndFunc

; Преобразование юникода в символьную строку заданной кодировки

Func _Uni2Any($uniString, $codePage)
        Local $uniStringLen = StringLen($uniString)
        Local $bufLen = $uniStringLen * 2
        Local $in = DllStructCreate("byte[" & $bufLen & "]")
        Local $out= DllStructCreate("char[" & $bufLen & "]")
        DllStructSetData($in, 1, $uniString)
        Local $ret = DllCall("kernel32.dll", "int", "WideCharToMultiByte", _
                "int", $codePage, _
                "int", 0, _
                "ptr", DllStructGetPtr($in), _
                "int", $uniStringLen / 2, _
                "ptr", DllStructGetPtr($out), _
                "int", $bufLen, _
                "int", 0, _
                "int", 0) 
        Local $anyString = DllStructGetData($out, 1)
        $out= 0
        $in = 0
        Return $anyString
EndFunc


Dirk Diggler 11-09-2006 15:34

Кстати, а что с поддержкой юникода(UTF-8) в autoit? Оч. хотелось бы сделать gui-оболочку для редактирования файлов с иероглифами. Возможно?

Creat0R 11-09-2006 16:46

amel27
Цитата:

вариант реализации функции преобразования кодировок и пример использования
Примного благодарен! спас меня от многих мучении и разного рода батниковых выкрутасов! :)

prokazzza 12-09-2006 10:34

Sanja Alone

Ты меня совсем не понял. Извини если я тя чем то задел. Мне не нужен Office (мне его и на работе хватает) я хотел показать тебе экран перезагрузки, я пользуюсь пользуюсь прогой Symantec Ghost AI Snapshot мне так более удобно сделал все настройки сохранил как с Atnotes и все Winamp, Nero устанавливаются за 2-3 секунды, со всеми ярлыками какие нужны, с настройками. Тока один недостаток просит перезагрузку понимаешь как это неудобно в режиме GuiRunOnce после каждой проги появляется экран перезагрузки - Nero перезагрузка, Promt перезагрузка ну и т.д. Постоянно приходится нажимать нет, нет.....
Цитата:

Практически у любого приложения есть ключи/параметры файла ответов и т.п
Облазил практически весь нет нигде даже в родной справке нет даже заиканий о ключиках для этой проги.
Насчет AutoIt, мне он не нужен в дальнейшем, вот как ты думаешь скока часов уйдет на то чтобы я овладел какимитами понятиями о действиях этой проги, для того чтобы поставить одну!!! единственную команду на отмену перезагрузки.

Sanja Alone 13-09-2006 09:20

prokazzza
Цитата:

я хотел показать тебе экран перезагрузки
Здесь нужны свойства этого экрана, а не он сам. Вот я тебе и твержу уже третий раз об AutoIt Window Info. Нужно при появлении экрана, тьфу ты... ОКНА перезагрузки запустить AutoIt Window Info, ткнуть мышью на окно, подвести указатель мыши к кнопочке "No" (но не нажимать на нее!), нажать CTRL + ALT + F (для фиксации сведений в AutoIt Window Info), снять скриншоты полного содержимого окна AutoIt Window Info, затем выложить снимки 2-3 таких окошек (от разных приложений), например, на imageshack, и только после этого можно будет предложить конкретные способы автоматического закрытия данных окон. Надеюсь, что теперь я все понятно описал...

Цитата:

пользуюсь прогой Symantec Ghost AI Snapshot
Я не знаю особенностей работы данного приложения. Насколько я понял, все отслеженные настройки и измененные файлы оно пихает в файл INSTALL.exe, запуск к-рого все это дело и восстанавливает. Возможно, в настройках самого Symantec Ghost AI Snapshot есть какой-то пункт отмены вывода окна перезагрузки, т.к. это окно не имеет ни малейшего отношения ни к Office 2003, ни к Atnotes.

Цитата:

единственную команду на отмену перезагрузки
Есть такая команда (shutdown -a), но в данном контексте она бесполезна :)

AxelM 17-09-2006 18:35

Здравствуйте.

Кто-нибудь знает, как в AutoIt реализована функция ProcessList?
Используется ли там DLLCall("psapi.dll"...) или DLLCall("kernel32.dll"...)

Заранее благодарен.

amel27 19-09-2006 05:21

AxelM
однако PSAPI.DLL, хотя конечно не DLLCall :)

Creat0R 19-09-2006 08:43

Есть два тревожующих вопроса:

1) Нужно запустить мелодию (точнее звук в 5 секунд), и чтобы она постоянно запускалась в цикле. Т.е пока скрипт запущен, чтобы один и тот-же файл играл по кругу (если закончилась мелодия, то чтобы началась по новой играть). Если нужно было бы только это, то можно обойтись так:

Код:

While 1
SoundPlay("File.wav", 1)
Wend

Но мне нужно запустить мелодию (в круговом режиме), и чтобы в это время скрипт делал что-то другое - Т.е чтобы была (или уже есть?) какая-то функция, которую можно было бы использовать примерно так:

Код:

Function("File.wav", 1) ; Ноль если нужно просто один раз проиграть, а единица (1) для повторного проигрывания.
.........
;тут будет что-то делаться во время того как играет мелодия

Возможно такое осуществить?


2) Мне нужно отнять от формата времени, определённое количество минут (до 60-ти), и нужно чтобы не просто отнимались числа от минут, а чтобы именно происходил подсчёт оставшегося времени (уитывая часы).
Допустим, есть данное время 22:07:01 - И отняв от этого времени, допустим 8 минут, нужно чтобы получился такой результат - 21:59:01...

Если речь идёт только о минутах (т.е без подсчёта часов), то я могу сделать это так:

Код:

$Time = "22:07:01"
$CleanSec = StringTrimRight($Time, 3)
$CleanHour = StringTrimLeft($CleanSec, 3)

If StringLeft($CleanHour, 1) = "0" Then
      $Minutes = StringLeft($CleanHour, 1)
    Else
 $Minutes = $CleanHour
EndIf

$Result = $Minutes - 8

If $Result < 0 Then
    $Minutes =  (60 - 8) + $Minutes

ElseIf StringLeft($CleanHour, 1) = "0" Then

$Minutes = "0" & $Minutes

EndIf

$TimeResult = StringLeft($Time, 3) & $Minutes & StringRight($Time, 3)

В результате, переменной $TimeResult присваивается значение равное времени, у которого отняли 8 минут (22:59:01), но в данном примере не учитывается изминения часов... я конечно же мог продолжить, и выявить всевозможные варианты и условия при которых достичь смену часов в соответствии смены минут, но это заняло бы слишком много времени, и наверное немало строк (при том как я бы их изложил), и тем более, что у меня возня с матиматикой, вызывает серъёзное головокружение :wacko: - Может кто-то плиз помочь разобраться с этим? - Задача вроде и не сложная, но я никак не приложу к этому ума.

amel27 19-09-2006 10:41

1, Можно через вызов внешнего (скомпилированного) скрипта:
Код:

Func Function ($file, $play)
        Local $pid=0
        If $play Then $pid = Run ("Au3Sound.Exe", @ScriptDir, @SW_HIDE)
        ...
        If $pid Then ProcessClose ($pid)
EndFunc

где Au3Sound.Exe:
Код:

While 1
SoundPlay("File.wav", 1)
Wend

2. Например так:
Код:

$Time = "22:07:01"
$Mins = 8

Dim $TMS0 = StringSplit ($Time,":")
Dim $TMS1 = $TMS0

$Mins = Mod (24*60 + $TMS0[1]*60 + $TMS0[2] - $Mins, 24*60)
$TMS1[2] = Mod ($Mins, 60)
$TMS1[1] = ($Mins - $TMS1[2])/60

$TimeResult = $TMS1[1] & ":" & $TMS1[2] & ":" & $TMS1[3]


Creat0R 20-09-2006 06:11

amel27

Цитата:

Можно через вызов внешнего (скомпилированного) скрипта:
Дело в том, что мне нужно именно в том же скрипте...

Пример который ты привёл, а точнее фраза которую я процетировал, навела меня на идею, которая решает эту проблему.
Вместо того, чтобы запускать ещё один скрипт, можно запустить этот-же скрипт, но с параметром ком. строки, а запуск мелодии в цикле, поставить под условие - т.е если скрипт запущен с ключём, то запустить цыкл с проигрыванием мелодии:

Код:

#NoTrayIcon
Dim $SoundText, $Flag = 64

Select
 
Case $CmdLine[0] = 0

$Ask = MsgBox(36, "question", "Play the sound?")

If $Ask = 6 Then
        Run(@AutoItExe & " """ & @ScriptFullPath & """ /ps")
$SoundText = ", exit the script and stop the sound?"
$Flag = 36
EndIf

$Else = MsgBox($Flag, "else", "I am somthing else" & $SoundText)
If $Else = 6 Then
        Send("^!s")
Exit
ElseIf $SoundText <> "" Then
        MsgBox(64, "close msg", "for stop the sound, hold down thees hotkeys:" & @CR & "CTRL+ALT+S")
EndIf

Case $CmdLine[1] = "/ps"
HotKeySet("^!s", "ExitScript")

While 1
SoundPlay (@WindowsDir & "\media\tada.wav", 1)
Wend

EndSelect

Func ExitScript()
Exit 0
EndFunc

Там где выделенный текст, это позволяет запустить не закомпелированный скрипт с ком. строкой, для того чтобы вызвать этот-же закомпелированный скрипт с ком. срокой, нужно поменять выделенный код на это - Run(@ScriptFullPath & " /ps")

Цитата:

Например так:
Большое спасибо! -Правда в некоторых случаях, у минут и у часов будет нехватать нуля (0) :blush2: . Например, если время будет такое: - 01:10:43, то отняв от него 8, результат мы получмим такой - 1:2:43. Поэтому я немного модифицыровал скрипт, и добавил определение для часов и минут на отсутствие нулей (см. выделенный текс в коде):

Код:

$Time = 01:10:43
$Mins = 8

Dim $TMS0 = StringSplit ($Time,":")
Dim $TMS1 = $TMS0

$Mins = Mod (24*60 + $TMS0[1]*60 + $TMS0[2] - $Mins, 24*60)
$TMS1[2] = Mod ($Mins, 60)
$TMS1[1] = ($Mins - $TMS1[2])/60

Switch $TMS1[1]
       
Case 0 to 9
        $TMS1[1] = "0" & $TMS1[1]
EndSwitch
       
Switch $TMS1[2]
       
Case 0 to 9
        $TMS1[2] = "0" & $TMS1[2]
EndSwitch


$TimeResult = $TMS1[1] & ":" & $TMS1[2] & ":" & $TMS1[3]

EndIf

-----------------------------------

Есть один глупый вопрос, но я его всё же задам (любопытство преодаливает :tongue: ) - Чем отличаются между собой: @CR, @LF, и @CRLF ?

amel27 20-09-2006 07:03

Creat0R
Цитата:

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

Цитата:

в некоторых случаях, у минут и у часов будет нехватать нуля
действительно не заметил, но тогда проще штатными средствами:
Код:

$Time = "01:10:43"
$Mins = 8

Dim $TMS0 = StringSplit ($Time,":")
Dim $TMS1 = $TMS0

$Mins = Mod (24*60 + $TMS0[1]*60 + $TMS0[2] - $Mins, 24*60)
$TMS1[2] = Mod ($Mins, 60)
$TMS1[1] = ($Mins - $TMS1[2])/60

$TimeResult = StringFormat("%.2d:%.2d:%.2d",$TMS1[1],$TMS1[2],$TMS1[3])

Цитата:

Чем отличаются между собой: @CR, @LF, и @CRLF ?
в справке же написано: @CR=Chr(13); @LF=Chr(10); @CRLF=@CR & @LF. Соответствуют управляющим (терминальным) кодам "возврата каретки" на начало строки (CR) и переходу на следующую строку (LF), в текстовых файлах по традиции используется @CRLF хотя тут явная избыточность и достаточно чего-нибудь одного.

Sanja Alone 20-09-2006 07:22

Creat0R
Цитата:

Чем отличаются между собой: @CR, @LF, и @CRLF
  • CR - "carriage return" ("возврат каретки")
  • LF - "line feed" ("перевод строки")
  • CRLF - соотв-но, оба действия вместе.
Вся эта кужня с переводами строк основывается на проведении параллели с печатной машинкой :)

Только последний (сдвоенный) символ является полноценным идентификатором перевода строки и воспринимается всеми ОС DOS (собс-но, он в DOS-е и появился) и Windows (в *NIX, afaik, переводы строк совсем другие), но, в msgbox-ах можно без проблем исп-ть и "половинчатые" (@LF, @CR) переводы строк.

Creat0R 20-09-2006 10:33

amel27
Sanja Alone
Спасибо вам, за столь исчерпывающие описания этих макросов :)

amel27
Цитата:

тогда проще штатными средствами:
И ещё раз спасибо - Ты оправдываешь поговорку: “Всё гениальное - просто!” :idea:

Creat0R 22-09-2006 05:30

Интересно, возможно ли осуществить проверку на подключённость к сети? Т.е проверять подключён ли компьютер к сети, или нет.


P.S:

Кстати, я как-то пару страниц назад, спрашивал на счёт проверки на битую ссылку... так вот, оказалось что можно элементарно проверить является ли заданная ссылка битой - нужно просто попытаться узнать размер файла по ссылке:

Код:

$Link = InetGetSize("http://test/test.zip")
  If $Link = 0 Then MsgBox(48, "Ошибка", "Ссылка по которой вы пытаетесь закачать файл, битая! (не рабочая)")

Но дело в том, что таким образом я немогу проверить подключён ли компьютер к инету, т.к в одном скрипте, мне нужно проверять на битость ссылки, и до проверки ссылки нужно надёжно проверить подключение к инету, и если подключение есть, то скрипт должен продолжить проверять ссылку, а если нет, то выдать сообщение об ошибке и завершить свою работу.

Sanja Alone 22-09-2006 07:56

Creat0R
Цитата:

возможно ли осуществить проверку на подключённость к сети?
С налету видится такой способ:
Код:

If Ping("www.google.com",3000) Then
        Msgbox(0,"Онлайн",'Есть контакт!')
Else
        #cs
        ---------------------------------
        Коды ошибок:
                1 = Host is offline
                2 = Host is unreachable
                3 = Bad destination
                4 = Other errors
        ---------------------------------
        #ce

        Msgbox(0,"Ошибка","Код ошибки: " & @error)
EndIf


EgOrus 22-09-2006 09:24

Sanja Alone
если человек сидит за проксёй это ничего не даст

amel27 22-09-2006 19:35

Цитата:

если человек сидит за проксёй это ничего не даст
Creat0R
вот несколько модифицированный пример из справки:
Код:

;Установка функции перехвата COM-ошибок
 $oMyError = ObjEvent("AutoIt.Error","MyErrFunc")

 If IsNotConnect() Then
    MsgBox (0,"Проверка связи","Интернет-соединение отсутствует!")
 Else
    MsgBox (0,"Проверка связи","Интернет-соединение установлено!")
 EndIf

;Функция проверки на отсутствие соединения
 Func IsNotConnect()
    Local $oHTTP=ObjCreate("winhttp.winhttprequest.5.1")
    $oHTTP.Open("GET","http://www.google.com")
    $oHTTP.Send()

    Return @error
 EndFunc

;Обработчик COM-ошибок
Func MyErrFunc()
    Select
        Case $oMyError.source = "WinHttp.WinHttpRequest"
            SetError($oMyError.number)
        Case Else
            Msgbox(0,"AutoIt COM Error !", _
                "err.source is: "      & @TAB & $oMyError.source        & @CRLF & _
                "err.description is: " & @TAB & $oMyError.description  & @CRLF & _
                "err.number is: "      & @TAB & hex($oMyError.number,8) & @CRLF & _
                "err.scriptline is: "  & @TAB & $oMyError.scriptline    & @CRLF )
            SetError($oMyError.number)
    EndSelect
Endfunc


Creat0R 22-09-2006 21:18

amel27
Цитата:

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

Есть только один маленьки вопрос про...

Цитата:

;Установка функции перехвата COM-ошибок
Как этим пользоваться? т.е как я понял, это возвращает значение ошибки в случае неподключенности? но если так, то когда я подставил в MsgBox переменную $oMyError, то отобразился странный квадрат, как будто кириллица в Utf-8. Т.е вот как я подставил:

Код:

MsgBox (0,"Проверка связи","Интернет-соединение отсутствует: " & $oMyError)
И вот что получилось:


amel27 23-09-2006 11:34

Creat0R
если код ошибки то $oMyError.number, другие параметры описаны в секции "Case Else" - на случай возникновения произвольных ошибок (кроме явно описанной для объекта WinHttp.WinHttpRequest)

Creat0R 27-09-2006 00:41

amel27
Мне нужно было именно описание ошибки ($oMyError.description), спасибо.

----------------------------------
Есть такой вопрос:
Как можно переименовать все файлы с одним расширением, в те же имена, но до самого расширения добавить символы _1 - а если уже существуют такие имена, то вместо _1 нужно подставить _2 и т.д.

Пробую так:

Код:

FileCopy("*.dat", "*_1.dat")
Но начинают появляться немеренное количество дублированных файлов, с именами которые содержат огромное количество символов _1
А добавление к коду определение на совпадение имён файлов (для замены _1 на последующие цыфры), я даже и не рискую делаь (если вообще смогу), т.к немогу решить первую проблему в задаче.
Возможно ли это решить?

diPhUZ8R 29-09-2006 17:08

Подскажите, как с помощью AutoIt, задать конкретному сетевому потключению общий доступ?

Creat0R 29-09-2006 22:07

По поводу моего предыдущего вопроса - Можно хотябы сделать так, чтобы символы _1 добовлялись вместе с другим расширением, и чтобы если уже есть такие файлы, за место _1 писать _2 и т.д?

Не могу понять почему, но вот этот пример не работает как ожидается (мной):

Код:

$Number = 1
;Вписываю все файлы с расширением *.inibak в отдельный временный файл, и ставлю самый новый файл в верх списка
RunWait(@ComSpec & " /c dir /o -d /b /d *.inibak > test.tmp", "", @SW_HIDE)
;Беру число (восьмой символ справа у первой строки) с имени файла (для проверки).
$NumN = StringLeft(StringRight(FileReadLine("test.txt", 1), 8), 1)
FileDelete("test.txt")

;Если в файле test.tmp есть восьмой символ справа у первой строки, то переменной $Num присваевается значение ровняющееся этому символу (числу), плюс 1.
If $NumN <> "" Then $Number = $NumN+1

;Копируются все файлы с расширением *.ini в те же имена, плюс добовляется число, и расширение inibak.
        FileCopy("*.ini", "*_" & $Number & ".inibak")

При повторном вызове, начинается старая проблема - файлы дублируются.
Почему это происходит, и как исправить?

-------------

Есть ещё один, более выжный вопрос...

Как можно послать команду в винамп (Winamp), например, на проигрывание файла - не запуск винампа с ком. строкой ровняющейся имени файла, а именно вызов команды в самом винампе?

Как я понимаю, нужно использовать ControlCommand, но как узнать какую команду посылать?
Я пробовал так:

Код:

ControlCommand("Player Window", "", "BaseWindow_RootWnd1", 4)
4, это для того, чтобы как-бы вызвать четвёртый пункт в "BaseWindow_RootWnd1" (в Au3Info это то поле, которое видно когда проводишь мышкой по пунктам “Играть”, “Пауза”, “Стоп” и т.д. - В “Восспроизведение”). Но это не срабатывает :( .
Я бы мог конечно просто посылать нажатие клавиш, но мне нужно чтобы это происходило при свёрнутом окне винампа, а для посылки сочетании клавиш, нужно сделать WinActivate, или чтобы окно само было активным.

Sanja Alone 30-09-2006 05:56

Creat0R
Цитата:

Как можно переименовать все файлы с одним расширением, в те же имена, но до самого расширения добавить символы _1 - а если уже существуют такие имена, то вместо _1 нужно подставить _2 и т.д.
Алгоритм такой:
  1. Считываем список файлов по требуемой маске в массив ( $s=_FileListToArray($Dir,"*.dat",1) ). Можешь посмотреть пример реалтизации в моем скрипте автоустановки/активации игр Reflexive.
  2. Пробегаем по массиву (цикл For), попутно анализируя имена файлов: разделяем по точке на имя ($name) и расширение ($ext). Во вложенном цикле по $i проверяем на существование файлы с окончанием имени "_"&$i в целевом каталоге - FileExists, или среди других эл-тов массива $s - при пом. ф-ции StrInStr (тут как тебе больше нравится; первый вариант для параноиков - а вдруг кто-то во время работы скрипта создаст файл с "хвостом" имени "_"&$i). Затем переименовываем текущий файл aka анализируемый эл-т массива в $name&"_"&$i+1&"."&$ext.
Все.


Цитата:

а для посылки сочетании клавиш, нужно сделать WinActivate
Ты о Global Hotkeys слышал? Очень удобная штука, особенно когда играешься в какую-нить игру в полноэкранном режиме и нужно уменьшить громкость или перейти к след. трэку в Winamp-е.
Вот тебе код:
Код:

;путь к Winamp
$WinampPath=RegRead ( 'HKEY_CURRENT_USER\Software\Winamp', '' )
If $WinampPath="" Then $WinampPath=@ProgramFilesDir & '\Winamp'
;включаем Global Hotkeys
IniWrite ( $WinampPath & '\winamp.ini', 'gen_hotkeys', 'enabled', '1' )
;запускаем Winamp
Run ( $WinampPath & '\Winamp.exe' )
;ждем загрузки процесса Winamp-а в память
ProcessWait ( 'Winamp.exe' )
;посылаем команду "Play"
Send ('^!{INS}')

Список хоткеев смотри в настройках Winamp-а (можно и свои сочетания прописать, причем, сразу в секцию [gen_hotkeys] файла winamp.ini).

Creat0R 30-09-2006 09:38

Sanja Alone
Цитата:

Алгоритм такой:
Приогромнейшее спасибо.
В теории я понимаю как это сделать, но на практике, хоть убейте не получается. Вроде всё просто, уже как говорится, “рецепт написан”, но немогу сложить два плюс два. Если не трудно, покажи плиз как должен выглядеть скрипт, по вызову которого, будет делаться то что я спрашивал:

Цитата:

Как можно переименовать все файлы с одним расширением, в те же имена, но до самого расширения добавить символы _1 - а если уже существуют такие имена, то вместо _1 нужно подставить _2 и т.д.
Цитата:

Вот тебе код:
И на этом спасибо. Если ты не против, можно немного усовершенствовать :) :

Код:

$WinampPath=RegRead ( 'HKEY_CURRENT_USER\Software\Winamp', '' )
If $WinampPath="" Then $WinampPath=@ProgramFilesDir & '\Winamp'

;Если Winamp небыл найден, то выводим соответствующее сообщение, и завершаем работу (скрипта)
If Not FileExists($WinampPath) Then
MsgBox(48, "error", "The Winamp ("& $WinampPath &") was not found")
Exit
EndIf

;Если Winamp не запущен, то запустим его
If Not ProcessExists("Winamp.exe") Then
Run($WinampPath & "\winamp.exe")
ProcessWait("Winamp.exe")
EndIf

;Если Global Hotkeys не установлен, то устанавливаем его через винамп
If IniRead($WinampPath,  'gen_hotkeys', 'enabled', '' )=0 Then
AutoItSetOption("WinTitleMatchMode", 4)
WinActivate("classname=BaseWindow_RootWnd", "")
WinWaitActive("classname=BaseWindow_RootWnd", "", 5)
Send("^p")
Send("{pgup}")
Send("{down 6}")
ControlCommand("classname=#32770", "", "Button2", "Check")
Send("{esc}")

  Send("!^{INS}")

;Если уже установлен, значит просто посылаем вызов команды проигрывания
Else
  Send("!^{INS}")
EndIf

Таким образом, ненужно прописывать в инишке - что позволит установить Global Hotkeys даже если винамп запущен.

garbals 30-09-2006 14:00

можно с помощью скрипта поменять имя рабочей группы и имя пользователя
мне нужно переделать ipset http://home.electronicinsanity.com/a...ipts/ipset.rar
тоесть добавить ввод рабочей группы и имя комтьютера

garbals 30-09-2006 14:12

и ещё можно ли с помощью AutoIt скрипта настроить VPN соединение

amel27 01-10-2006 11:48

Creat0R

вариант рабочей функции переименования (без контроля входных параматров!) - номера ранее переименованных файлов не трогаются, новые номера считаются от максимального существующего (поэтому возможны "дыры" в нумерации). По ходу производится приведение всех номеров к единому формату по количеству знаков в номере.
Код:

#include <File.au3>
#include <Array.au3>
#Include <String.au3>

_FilesFormatRename ("c:\Test", "_")

Func _FilesFormatRename ($sPath, $delim = "_")
        Local $i, $iMaxNum
        ;Считываем список файлов в массив
        Local $FileList = _FileListToArray($sPath, "*", 1)
        ;Создаем рабочий массив:
        Local $WorkList [$FileList[0]+1] [6]
                ;[][0] - имя файла без расширения
                ;[][1] - имя файла без расширения и номера
                ;[][2] - только расширение
                ;[][3] - старый номер
                ;[][4] - новый номер
                ;[][5] - индекс для сортировки
        ;Заполняем рабочий массив
        For $i=1 To $FileList[0]
                ;выделяем имя, расширение и номер
                $WorkList [$i][0] = StringRegExpReplace ($FileList[$i], "\.[^.]*$","")
                $WorkList [$i][1] = StringRegExpReplace ($WorkList [$i][0], $delim & '[0-9]*$',"")
                $WorkList [$i][2] = StringMid ($FileList[$i], StringLen ($WorkList [$i][0]) +2)
                $WorkList [$i][3] = StringMid ($WorkList [$i][0], StringLen ($WorkList [$i][1]) +2) +0
                ;формируем индекс для сортировки
                $WorkList [$i][5] = $WorkList[$i][1] & "." & $WorkList[$i][2] & "." & StringFormat ("%." & StringLen($FileList[0]) & "d", $WorkList[$i][3])
        Next
        ;Сортируем массив по убыванию старого номера
        _ArraySort ($WorkList, 1, 1, $FileList[0]+1, 6, 5)

        ;Основной цикл перенумерации
        For $i=1 To $FileList [0]
                ;проверка на совпадение имени
                If $WorkList[$i-1][1] & "." & $WorkList[$i-1][2] = $WorkList[$i][1] & "." & $WorkList[$i][2] Then
                        ;проверка на совпадение номера
                        If $WorkList [$i][3] = $WorkList [$i-1][3] Then
                                ;если номера совпадают, добавляем в конец списка
                                $iMaxNum = $iMaxNum +1
                                $WorkList [$i][4] = $iMaxNum
                        Else
                                ;если номера отличаются зачем менять?
                                $WorkList [$i][4] = $WorkList [$i][3]
                        EndIf
                Else
                        ;максимальный номер для нового имени
                        $iMaxNum=$WorkList [$i][3]
                        $WorkList [$i][4] = $iMaxNum
                EndIf
                ;формируем индекс для сортировки
                $WorkList [$i][5] = $WorkList[$i][1] & "." & $WorkList[$i][2] & "." & StringFormat ("%." & StringLen($FileList[0]) & "d", $WorkList[$i][4])
        Next
        ;Сортируем массив по убыванию нового номера
        _ArraySort ($WorkList, 1, 1, $FileList[0]+1, 6, 5)
        ;Подготовка к переименованию
        FileChangeDir ($sPath)
        FileSetAttrib("*", "-R")
        ;Собственно цикл переименования
        For $i=1 To $FileList [0]
                ;проверка на совпадение имени
                If ($WorkList[$i-1][1] & "." & $WorkList[$i-1][2]) <> ($WorkList[$i][1] & "." & $WorkList[$i][2]) Then        $iMaxNum = $WorkList [$i][4]
                FileMove ($WorkList [$i][0] & "." & $WorkList [$i][2], _
                        $WorkList [$i][1] & $delim & StringFormat ("%." & StringLen ($iMaxNum) & "d", $WorkList [$i][4]) & "." & $WorkList [$i][2])
        Next
EndFunc


amel27 01-10-2006 13:17

garbals
Цитата:

мне нужно переделать ipset
дык там все делается через NETSH, а AutoIT только графическая оболочка... поэтому подбери сначала (в другой ветке форума) требуемую CMD-утилитку, а потом _RunDOS или RunWait. :)

Creat0R 01-10-2006 14:27

amel27
Цитата:

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

Попробую перефразировать задачу:

В папке c:\test, есть 3 файла (кроме прочих) - myfile.dat, hisfile.dat, aourfile.dat - после запуска скрипта, нужно чтобы эти файлы (именно с таким расширением), переименовались в такие имена - myfile_1.dat, hisfile_1.dat, aourfile_1.dat.
Далее, при повторном запуске скрипта, если уже обнаружены такие файлы (myfile_1.dat, hisfile_1.dat, aourfile_1.dat), то именно их трогать ненужно, а нужно все остальные (с таким же расширением, и с таким же началом - до символа _), переименовать в такие файлы - myfile_2.dat, hisfile_2.dat, aourfile_2.dat, а те которые не совпадают в начале имени (до символа _), нужно переименовывать как и в первый раз (добовляя _1).
Точно такой способ, реализован в утилите 7-zip, там при расспаковке файлов (через командную строку), можно указать ключ, который позволит именно этим способом переименовывать существующие файлы.

amel27 01-10-2006 18:06

Creat0R
Цитата:

дело в том, что это не совсем то
ясен пень, я ведь делал для фоток :)
Цитата:

Этот пример переименовывает все файлы в указанном каталоге, а мне нужно чтобы переименовывались файлы с определённым расширением (чтобы в использовании функции возможно было указать рпасширение).
ну дык добавь в функцию еще один параметр "маски" и при загрузке в массив используй его вместо "*"
Цитата:

Также эта функция переименовывает всего один раз, при повторном запуске, если существуют такие-же файлы, но с последующей цифрой (на одну больше), то эти файлы не переименовываются в существующие, но на одну цифру выше...
звиняюсь, но нифига не понял... у меня переименовываются только те, которые НЕ содержат на конце знак разделителя с номером (aka _X), кстати именно поэтому в названии ф-ции присутствует слово "Format", т.е. происходит преобразование имени к определенному формату. Выравнивание по количеству знаков сделано для правильной сортировки, если не надо - можно убрать.
Цитата:

Точно такой способ, реализован в утилите 7-zip
такой, да не такой - в 7zip файл переименовывается ДО копирования в папку при условии наличия дубликата, т.к. в одной папке не могет быть двух одинаковых файлов, а у тебя все файлы изначально в одной папке и никаких конфликтов по сути нет - одна блаж (шутка). :)

FYI: скрипт подправил, теперь кол-во знаков в номере определяется автоматом

Creat0R 01-10-2006 22:19

amel27
Цитата:

переименовываются только те, которые НЕ содержат на конце знак разделителя с номером (aka _X)
Вот это-то мне и не нужно :no: . Нужно чтобы было определение на существование файла, и при совпадении, переименование должно происходить также, как это происходит с утилитой 7-zip.

Цитата:

у тебя все файлы изначально в одной папке и никаких конфликтов по сути нет
Вот именно что есть. Ведь я буду скриптом копировать с другого каталога, файлы с тем же расшрением что и в этом каталоге (в котором нужно произвести переименование), поэтому до самого копирования, мне нужно проверить на совпадение имён файлов, и если есть совпадение, то нужно переименовывать файлы как это делает 7-zip. Скорее всего, я не внятно объяснил цель всего этого, а пример с 7-zip привёл лишь для сравнения. В принципе, всё что нужно, так это сделать точно тот-же механизм переименовывания файлов как и у 7-zip.

amel27 02-10-2006 03:29

Creat0R
Цитата:

Ведь я буду скриптом копировать с другого каталога
Что и требовалось доказать: "не внятно" не то слово - это уже совсем другая задача:

- у ф-ции будет ДВА рабочих параметра (источник и приемник), а не один;
- сравнивать нужно ПОФАЙЛОВО и расширение тут непричем (конфликтуют ИМЕНА, а не расширения сами по себе)

Допустим, мы хотим проверить существование заданного файла в каталоге и вернуть его новое для этой папки (см. текст ф-ции), алгоритм будет следующий: перед записью в каталог файла (не из этого каталога!) возвращаем через функцию его новое имя и сохраняем уже под этим именем... если что в 7zip именно так.
Код:

MsgBox (0,"",_FileNewName ("myfile.dat", "c:\Test"))

Func _FileNewName ($sFile, $dDir, $delim = "_")
        $dDir = StringRegExpReplace ($dDir, "\\ *$", "")

        Local $sName= StringRegExpReplace ($sFile, "\.[^.]*$", "")
        Local $sExtn= StringMid ($sFile, StringLen ($sName) +1)
        Local $i=1, $dFile=$sFile
        While FileExists ($dDir & "\" & $dFile)
                $dFile = $sName & $delim & $i & $sExtn
                $i = $i +1
        WEnd
        Return $dFile
EndFunc


Creat0R 02-10-2006 19:39

amel27
Цитата:

сравнивать нужно ПОФАЙЛОВО и расширение тут непричем
Ну почему, мне нужно именно группу файлов одного расширения копировать, а проверять пофайлово я немогу, так как заранее не известно какие файлы будут копироваться. Известно лишь то, что в каталоге в который будут копироваться файлы, уже есть такие-же файлы (т.е с тем же расширением), и также 70% верятности того, что в этом каталоге будут совпадать имена файлов с теми что будут туда копироваться.

Функция что ты привёл в пример, отлично справляется с задачей, если бы нужно было переименовывать файлы которые копируются, в таком случае, можно указать и все файлы с определённым расширением. Но мне нужно проверять именно файлы в том каталоге, куда будут копироваться файлы с другого каталога...

Пример:

Имеем два каталога, первый - “c:\test\a” (с которого будут копироваться файлы), второй - “c:\test\b” (в который должный помещаться файлы, и в котором должно проверяться совпадение имён).

В каталоге “b”, перед копированием файлов с каталога “a”, нужно переименовать все файлы с расширением *.dat, но только те которые копируются. Т.е, если допустим, мы копируем два файла - filefirst.dat, filesecond.dat, то для них и нужно проверять совпадение в каталоге “c:\test\b”, если там такие файлы уже есть, то нужно переименовать их в те же имена + _1, но если уже есть и такие имена, то + _2 и т.д...
Чтобы в результате, не было потерь никаких файлов, чтобы те файлы которые копируются с “c:\test\a”, в том же виде поместились в “c:\test\b”, а существующие файлы в “c:\test\b”, чтобы всегда переименовались и сохранялись под разными последовательными именами (с приставкой на конце _1, _2 и т.д).

Balog 03-10-2006 13:05

Извините, может этот вопрос уже поднимался но поиском ответа не нашел.
Опыта в AutoIt у меня очень мало, и я споткнулся еще на примерах к программе.
У меня русскоязычная винда и хотелось бы писать на русском и английском языках скажем в блокноте и иметь доступ к меню (скажем через ALT).
Проблема в следующем: англоязычные комбинации клавиш не проходят по определению, русскоязычные типа ALT+Ф проходят только если стоит русский язык по умолчанию, но тогда неправильно выводится англоязычный текст. Переключение текущего языка проблемы не решает, а переключения языка по умолчанию я не нашел.
Объясните пожалуйста как решить подобную проблему.

amel27 03-10-2006 19:07

Creat0R
Цитата:

а проверять пофайлово я немогу
интересно почему?.. та же функция _FileListToArray прекрасно восстановит список файлов по маске
Цитата:

чтобы те файлы которые копируются с “c:\test\a”, в том же виде поместились в “c:\test\b”, а существующие файлы в “c:\test\b”, чтобы всегда переименовались и сохранялись под разными последовательными именами
собственно нет никакой разницы чье имя менять - нового файла или существующего, сравни варианты (второй твой):
Код:

$sDir = c:\Source\
$dDir = c:\Destin\

$sFiles = _FileListToArray ($sDir, "*.dat")

For $i=1 To $sFiles[0]
        $newName = _FileNewName ($sFiles[$i], $dDir)
        FileMove ($sDir & $sFiles[$i], $dDir & $newName)
Next

Код:

$sDir = c:\Source\
$dDir = c:\Destin\

$sFiles = _FileListToArray ($sDir, "*.dat")

For $i=1 To $sFiles[0]
        $newName = _FileNewName ($sFiles[$i], $dDir)
        If $sFiles[$i] <> $newName Then FileMove ($dDir & $sFiles[$i], $dDir & $newName)
        FileMove ($sDir & $sFiles[$i], $dDir & $sFiles[$i])
Next


Sanja Alone 04-10-2006 04:08

Balog
Цитата:

как решить подобную проблему
См. FAQ (WinAPI-метод должен помочь).

Creat0R 04-10-2006 05:51

amel27
Нижний пример почти достигает желаемого результата. Пишу почти, так как есть один нюанс...

При первом запуске скрипта, всё проходит отлично - файлы в папке назначения переименовываются в новые имена (с добавкой _1), а файлы с папки источника, копируются на место тех которые переименовались. Однако, после вторичного запуска скрипта, я ожидал чтобы те файлы (в папке назначения), имена которых совпадают с именами копируемых файлов (с папки источника), переименовались уже не в те же что и в первый раз (с добавкой _1), а в имена с добавкой последующей цифры тем что уже существуют (с добавкой _2 в этом случае). А файлы которые копируются, чтобы стали под их оригинальными именами в папку назначения. Таким образом, всегда будут сохраняться копии всех файлов, из всех попыток копирования файлов - но, рабочие файлы (те которые не должный переименовываться, т.е те которые копируются из папки источника), должный быть всегда под своими оригинальными именами, а те файлы (в папке назначения) которые были под этими же именами, должный всегда быть переименованы с добавкой _1, _2 и т.д, но чтобы были всегда последними в последовательности добавленных к ним цифрам.

Я пытался самостоятельно переделать немного алгоритм, но никак не получается :( - Я понимаю что там требуется внести какое-то мелкое изменение, но оно должно быть правильное, и я пока этого сделать немогу, нехватает опыта что-ли...

Creat0R 04-10-2006 06:12

amel27
Цитата:

Нижний пример почти достигает желаемого результата
Я сказал почти?! жутко извеняюсь!!! :sorry: - Всё что я описал выше, достигнуто тем примером который ты мне дал!!! СПАСИБО!

Мне всего лишь нужно было заместо перемещения, прописать копирование:

Код:

$sDir = "c:\source\"
$dDir = "c:\dest\"

$sFiles = _FileListToArray ($sDir, "*.dat")

For $i=1 To $sFiles[0]
        $newName = _FileNewName ($sFiles[$i], $dDir)
        If $sFiles[$i] <> $newName Then FileMove ($dDir & $sFiles[$i], $dDir & $newName)
        FileCopy ($sDir & $sFiles[$i], $dDir & $sFiles[$i])
Next


Balog 04-10-2006 10:26

Sanja Alone
WinAPI метод переключает раскладки а не изменяет язык по умолчанию. Переключать язык как я понял сугубо недостаточно. Нужно что бы менялся язык по умолчанию. Если язык по умолчанию русский то команда Send("!Ф") предположим, срабатывает, но тогда неправильно отображается английский текст. Да и надеяться что у пользователя язык по умолчанию будет русский (у меня у самого английский) не приходится.
Так что нужен способ изменения языка по умолчанию. Я понимаю, что для автоматизации инсталляций работа с меню неактуальна, но неужели никто не задавался таким вопросом?

amel27 04-10-2006 11:25

Creat0R
Цитата:

Мне всего лишь нужно было заместо перемещения, прописать копирование
вспомнил, но поздно... хотя самому разобраться пользы больше ;)

FYI: подредактировал ф-цию _FileNewName... старый вариант был короче, но для файлов без расширений всегда возвращал на конце точку - для операций с файлами это не важно, а вот для сравнений не есть гут

LORDMA 08-10-2006 11:34

1 вложений
Всем здрасти!
Если кому нетрудно помогите с такой проблемкой. Вот написал скрипт для автоматической установки драйверов
(просто автоматизировал "Мастер установки оборудования") для установки драйверов с CD. Так вот помогите зациклить процесс выполнения скрипта (сразу говорю я не программист, многое я не могу делать ) я попробовал сам сделать но не получилось.
Заранее благодарен!!!! :) :)




Все ребята разобрался сам.Всем спасибо!

LORDMA 09-10-2006 17:14

Мужики всем привет.
Если кому нетрудно объясните как правильно работать с функцией PixelSearch ( x , y )
Надо чтоб в клиентской части активного окна найден нужный цвета пиксель и если он найден происходит двойное нажание мыше в нужном месте окна. Делаю так

Цитата:

Run (запуск программы )

WinWaitActive('текст','',0)
Opt("PixelCoordMode", 2)
PixelSearch( 0, 53, 613, 391, 0x000000, 10 )
Sleep(5000)
$coord = PixelSearch( 0, 53, 613, 391, 0xFFFF00, 10 )
$coord1 = $coord

If $coord1 = $coord Then
;код, выполняемый если окно появилось
WinWaitActive('текст','',180)
Opt("MouseCoordMode",2)
MouseClick( "left", 67, 318, 2, 0 )
Else
;код, выполняемый если окно не появилось
EndIf
Сто процентов я здесь корявыми ручками напортачил. Пожалйста покажите как правильно?

xstranger 10-10-2006 09:25

Не подскажете - как убрать с помощью AutoIt часы на таскбаре

Sanja Alone 10-10-2006 15:23

xstranger
Цитата:

как убрать с помощью AutoIt часы на таскбаре
Убрать часы:
Код:

RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer","HideClock","REG_DWORD",0x00000001)
Снова включить:
Код:

RegDelete("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer","HideClock")

Creat0R 10-10-2006 19:25

LORDMA
Цитата:

Надо чтоб в клиентской части активного окна найден нужный цвета пиксель и если он найден происходит двойное нажание мыше в нужном месте окна.
Нажатие мышкой должно происходить в том месте где был найден пиксель?
Тогда попробуй так:

Код:

Opt("PixelCoordMode", 2)
Opt("MouseCoordMode",2)

Run (запуск программы )

;Ждём полного запуска процесса программы
ProcessWait(процесс программы\имя екзешника, 20)

;Выполнение дальнейшего скрипта, в случае если окно существует
If WinExists('текст','') Then

;На всякий случай, активируем окно
WinActivate('текст','')

;Ждём активности окна (три минуты - не слишкомм ли :) )
WinWaitActive('текст','',180)

;Ищем нужнй пиксель
$coord = PixelSearch( 0, 53, 613, 391, 0xFFFF00, 10 )

;Если пиксель найден, то жмём два раза левой кнопкой мышки в том месте где он найден
If Not @error Then MouseClick( "left", $coord[0], $coord[1], 2, 0)

EndIf

Если нужно нажать в другом месте, то вместо $coord[0] и $coord[1] нужно подставить свои соответствуюющие координаты (X и Y).

Lodoss 13-10-2006 20:27

Запуск exe файла из определённой директории
 
Есть потребность запускать некоторые exe файлы с параметрами определённой директории (как правило "лечилки" от жадности), например, строчка:

Код:

Run("с:\program files\everest\crack.exe")
не срабатывает.

Приходится обходиться батником в котором прописано:
Код:

C:
cd Program Files\Everest
crack.exe

Есть ли способ в autoit указать параметр запуска в определённой директории? Хелп читал, думаю такая возможность есть, но не могу понять как это сделать.

P. S. Я новичок, помидорами не кидать :)

Sanja Alone 14-10-2006 04:57

Lodoss
Код:

FileChangeDir ( @ProgramFilesDir & "\Everest" )
Run ( "crack.exe" )

Цитата:

есть ли способ в autoit указать параметр запуска в определённой директории?
Код:

Run ( @ProgramFilesDir & "\Everest\crack.exe", @ProgramFilesDir & "\Everest" )
Второй параметр и есть рабочий каталог, но часто от него мало толку. Приведенный выше способ надежнее.

LORDMA 14-10-2006 23:15

2 вложений
Вот кому интересно нацарапал пару скриптов для автоматизации установки

драйверов после установки операционки(звук ,видео,и т.д.).
Нужно иметь только диск с распакованными драйверами, а скомпилированный скрипт

запускать через autorun.inf
Один скрипт определяет неустановленное оборудование по желтому

пикселю, а второй просто клацает по списку устройств в верхней строчке пока

невыскочет "Центр справки"
Это мои первые скрипты, так что сильно несудите.

Creat0R
Большое спасибо,за помощь!

xstranger 18-10-2006 06:10

может кто подскажет код скрипта который делает следующее

Имеются общие задачи дня н количества файлов
например
Код:

modifype file 
makecab file
start file
del %windir%\system32\file

меняется только названия файлов. так вот, подскажите код скрипта чтобы в нем в начале были описаны действия, а ниже приводился список файлов

Sanja Alone 18-10-2006 06:59

xstranger
Цитата:

общие задачи дня н количества файлов
Код:

#include <File.au3>

;каталог, с файлами к-рого нужно выполнять н-рые действия
$Dir='C:\Test'
;маска для отбора файлов
$Mask='*.*'

;составление списка файлов
$s=_FileListToArray($Dir,$Mask,1)

;действия над файлами
For $i=1 To $s[0]
        ;в данном примере - вывод имени файла
        MsgBox (0,"Файл "&$i,$s[$i])
Next


xstranger 18-10-2006 07:23

Спасибо за ответ, но если можно немного по прозрачнее

опишу мою ситуацию. у меня системные файлы патчатся ресурсами в стиле висты на этапе RunOnceEx, так вот, я хотел бы поменять командный файл, на автоит скрипт. вот команды командного файла
Код:

...
 %WINDIR%\System32\fontext.dll TMP\fontext.dll
ZAP.exe %WINDIR%\System32\fontext.dll
RESHacker.exe -script "res\fontext\fontext.txt"
copy Out\fontext.dll %WINDIR%\System32\fontext.dll

copy "%ProgramFiles%\Internet Explorer\IEXPLORE.EXE" TMP\IEXPLORE.EXE
ZAP.exe "%ProgramFiles%\Internet Explorer\IEXPLORE.EXE"
RESHacker.exe -script "res\iexplore\iexplore.txt"
copy Out\iexplore.exe "%ProgramFiles%\Internet Explorer\IEXPLORE.EXE"
...

как мне тут лучше сделать? как я понимаю должен обрабатываться цикл в который будут передоваться поочередно описаные в скрипте имена файлов, но как это сделать я не знаю :(


и еще один вопрос. есть ли в автоит какое либо подобие xcopy? чтобы копировались только новые файлы, если есть, то скажите куда смотреть

заранее спасибо

Michail77 18-10-2006 14:08

Всем привет!
Может кто поможет.
Есть такая необходтмость устанавливать софт с диска на компы(ежедневно около 20-30 компов).Основной комплект прог для большинства компов одинаков,но достаточно часто возникает нужда поставить стандартный комплект прог с небольшими изменениями (вместо одних прог поставить другие,например вместо windvd power dvd).
Написал в AutoIt примитивный скрипт типа:

Код:

run ("Multemedia\Burn disk\Nero\Nero6608a.exe")
WinWaitActive("Nero Burning ROM Помощник установки", "Nero Burning ROM")
ControlCommand("Nero Burning ROM Помощник установки", "Nero Burning ROM", "Button2", "Check", "")
WinWaitActive("Nero Burning ROM Помощник установки", "Я принимаю все пункты")
ControlCommand("Nero Burning ROM Помощник установки", "", "Button8", "Check", "")
ControlCommand("Nero Burning ROM Помощник установки", "", "Button2", "Check", "")
ControlSetText("Nero Burning ROM Помощник установки", "", "Edit1", "User")
ControlSetText("Nero Burning ROM Помощник установки", "", "Static13", "C:\Program files\ahead")
ControlSetText("Nero Burning ROM Помощник установки", "", "Edit3", "XXXX-XXXX-XXXX-XXXX-XXXX-XXXX")
ControlCommand("Nero Burning ROM Помощник установки", "", "Button2", "Check", "")
WinWaitActive("Nero Burning ROM Помощник установки", "Завершить")
ControlCommand("Nero Burning ROM Помощник установки", "", "Button11", "unCheck", "")
ControlCommand("Nero Burning ROM Помощник установки", "", "Button12", "unCheck", "")
ControlCommand("Nero Burning ROM Помощник установки", "", "Button13", "unCheck", "")
ControlCommand("Nero Burning ROM Помощник установки", "", "Button3", "Check", "")

Как сделать так чтобы я мог ставить разные комплекты прог?Мне кажется что должно выпадать при авторане примитивное окно с кнопочками типа:установить комплект_1,установить комплект_2 и т.д. В связи с этиим возник вопрос:можно ли это окно сделать в AutoIt?Или есть какие-то другие способы решения данной проблемы?Может у кого есть уже готовый скрипт-поделитесь пожалуйста.
Заранее благодарен.

amel27 18-10-2006 14:09

xstranger
Цитата:

вот, я хотел бы поменять командный файл, на автоит скрипт
из приведенного куска не видно оснований для переезда на AutoIt - набор внешних команд проще вызвать из командного файла
Цитата:

есть ли в автоит какое либо подобие xcopy? чтобы копировались только новые файлы
такого точно нету, хотя несложно написать коротЕньку функцию, сравнивающую даты файлов перед заменой...

Creat0R 18-10-2006 16:37

Michail77

Цитата:

можно ли это окно сделать в AutoIt?
Можно, примерно так:

Код:

#NoTrayIcon
#Include <GuiConstants.au3>

$Title = "Выбор комплектов"

If WinExists($Title) Then Exit

GuiCreate($Title, 500, 250)

GUISetFont(13)
GUICtrlCreateLabel("Выбор комплектов", 170, 10)

GUISetFont(9)
$Complect1 = GUICtrlCreateCheckbox("Комплект 1", 60, 50)
$Complect2 = GUICtrlCreateCheckbox("Комплект 2", 60, 90)
$Complect3 = GUICtrlCreateCheckbox("Комплект 3", 60, 130)

$Next = GUICtrlCreateButton("Next>>", 440, 210, 50)
$Cancel = GUICtrlCreateButton("Cancel", 380, 210, 50)

GUISetState()

While 1
$Msg = GUIGetMsg()

Select       
       
        Case $Msg = $Gui_Event_Close or $Msg = $Cancel
                Exit

        Case $Msg = $Next
                  If GUICtrlRead($Complect1) <> 1 and GUICtrlRead($Complect2) <> 1 and GUICtrlRead($Complect3) <> 1 Then
                        GUISetState(@SW_DISABLE)
                            MsgBox(262144+48, "Attention", "Выберите как минимум одну птичку ;-)")
                        GUISetState(@SW_ENABLE)
                        WinActivate($Title, "")
                    ContinueLoop
                EndIf

                GUISetState(@SW_HIDE)
               
                If GUICtrlRead($Complect1) = $Gui_Checked Then
                        ;Тут должна выполняться установка комплекта № 1
                EndIf
               
                If GUICtrlRead($Complect2) = $Gui_Checked Then
                        ;Тут должна выполняться установка комплекта № 2
                EndIf
               
                If GUICtrlRead($Complect3) = $Gui_Checked Then
                        ;Тут должна выполняться установка комплекта № 3
                EndIf

EndSelect
Wend

У меня по поводу этого примера, есть один вопрос к знающим:

В примере я использовал метод диактивации гуи (Gui) перед выводом MsgBox (GUISetState(@SW_DISABLE)), и полсле нажатия на ОК, гуи активируется (GUISetState(@SW_ENABLE)). Но дело в том, что у меня, по не понятным причинам, после активации гуи, он как бы сворачивается. Почему это происходит, и как это предотвратить? - Я также в примере поставил активацию окна (WinActivate), но в момент активации окно на секунду мигает, хотелось бы достичь идеального способа диактивации и затем активации гуи интерфейса.

Sanja Alone 18-10-2006 17:07

Michail77
Цитата:

стандартный комплект прог с небольшими изменениями
Я уже на руборде ответил - WPI. Впрочем, не только...

Creat0R 23-10-2006 15:48

Есть два вопроса (взаимосвязаны между собой):

1) Как можно узнать общий размер всех файлов (в байтах или мб) с определённым расширением, но учитывать файлы в подкаталогах? - Есть функция _FileListToArray, но она не учитывает подкаталоги, может можно её как то улучшить? (там требуется #include <File.au3>).

2) Возможно ли вычислить самый новый файл (взять имя файла и путь к нему в масив), в определённом каталоге - файлы из подкаталогов тоже должны учитываться.

sattva 23-10-2006 22:39

Мне необходимо отобразить процесс копирования MS Office 2003 на жесткий диск, а затем отобразить сам процес установки через AutoIt.
Сделал это с помощью ProgressOn & ProgressSet...
Не устраивает: во первых процегресс-бар при копировании не изменяется, а во время установки приложений прогресс бар переваливает за 100 проценнтов и установка приложения при этом продолжается:

Код:

ProgressOn  ('Копирование MS Office 2003 на жесткий диск','Прогресс','Выполнено',-1,-1,18)
$pr=0
AdlibEnable  ('progresscopy',300)

If Not FileExists($diskC & '\Install\Office 2003 RUS SP2') Then DirCreate($diskC & '\Install\Office 2003 RUS SP2')
DirCopy(@ScriptDir & '\', $diskC & '\Install\Office 2003 RUS SP2', 1)
ProgressSet(2000 , "Done", "Complete")
sleep(500)
AdlibDisable ()

.....
ProgressOn  ('Установка MS Office 2003','Прогресс','Выполнено',-1,-1,18)
$pr=0
AdlibEnable  ('progress',300)
....
ProgressSet(1666 , "Done", "Complete")
sleep(500)
AdlibDisable ()
....
;----FUNCTION----------
Func progresscopy()
 $pr=$pr+1
  ProgressSet( $pr, $pr & " процент")
EndFunc

Func progress()
 $pr=$pr+1
  ProgressSet( $pr, $pr & " процент")
EndFunc


Sanja Alone 24-10-2006 08:17

Creat0R
Цитата:

но учитывать файлы в подкаталогах
Оч. просто это сделать при пом. cmd-файла:
Код:

@echo off
rem Каталог
set DIR=C:\Какой-то каталог\Какой-то подкаталог
rem Маска
set MASK=*.jpg
rem Выделенные слова должны быть в OEM-кодировке
for /F "usebackq tokens=3" %%j in (`dir "%DIR%\%MASK%" /s ^| find "байт" ^| find "файлов"`) do (set fsize=%%j)
echo Общий размер файлов %MASK% в каталоге "%DIR%" и его подкаталогах = %fsize% байт

Цитата:

вычислить самый новый файл
Здесь все муторней, т.к. соотв. ключ команды dir производит сортировку в пределах каждого подкаталога (/s), что неудобно, т.к. потребует последующего анализа. Т.е., придется бегать по всем подкаталогам и сравнивать дату/время наиболее новых файлов в каждом из них:
Код:

rem Каталог
set DIR=C:\Какой-то каталог\Какой-то подкаталог
for /F "usebackq tokens=*" %%j in (`dir "%DIR%" /a:-d /o:-d /t:w /b`) do (set filen=%%j&& goto metka)
:metka
rem Cамый новый (по времени последнего изменения) файл каталога %DIR%
echo Самым новым файлом в каталоге "%DIR%" является "%filen%"

Можно и в "чистом" AutoIt сделать тоже самое: в цикле гонять по всем подкаталогам (что является каталогом легко узнать анализируя вывод ф-ции FileGetAttrib - если в строке есть буква D, значит это каталог).


sattva
Цитата:

Мне необходимо отобразить процесс копирования MS Office 2003 на жесткий диск
Если именно копирования, то придется копировать при пом. утилиты xxcopy и прогрессбар привязывать к месту на диске (почему именно xxcopy обсуждали еще в старой теме - посты #108, #111, #112, #113, #114). А если речь о процессе установки, то лучше для setup.exe задать ключ /qb! - и прогресс установки будет виден, и отменить ее будет невозможно (без убийства процесса :) ).

amel27 24-10-2006 11:47

Creat0R

Если только средствами AutoIt, то вот что получилось
Код:

#include <File.au3>
#include <Array.au3>
;Поиск самого нового файла
Func _NewestFile ($sPath, $sMask='*')
        Local $i, $dlist[1]=[0], $blist=_MyFileListToArray ($sPath, $sMask)
        If $blist[0]=0 Then Return ""
        For $i=1 To $blist[0]
                _ArrayAdd ($dlist, FileGetTime ($blist[$i], 0, 1))
        Next
        Return $blist[_ArrayMaxIndex ($dlist, 0, 1)]
EndFunc
;Размер файлов с учетом подкаталогов
Func _MyDirGetSize ($sPath, $sMask='*')
        Local $i, $size=0, $blist=_MyFileListToArray ($sPath, $sMask)
        If $blist[0]=0 Then Return 0
        For $i=1 To $blist[0]
                $size = $size + FileGetSize ($blist[$i])
        Next
        Return $size
EndFunc
;Возвращает массив имен файлов с учетом подкаталогов
Func _MyFileListToArray ($sPath, $sMask='*')
        Local $i, $j, $blist, $rlist[1]=[0], $dlist = _DirListToArray ($sPath)
        _ArrayAdd ($dlist, $sPath)
        For $i=1 To $dlist [0] +1
                $blist = _FileListToArray ($dlist [$i], $sMask, 1)
                If Not @error Then
                        For $j=1 To $blist [0]
                                _ArrayAdd ($rlist, $dlist[$i] & "\" & $blist [$j])
                        Next
                EndIf
        Next
        $rlist [0] = UBound ($rlist) - 1
        Return $rlist
EndFunc
;Возвращает массив структуры подкаталогов
Func _DirListToArray ($sPath)
        Local $i, $j, $rlist[1]=[0], $blist, $alist=_FileListToArray ($sPath, '*', 2)
        If IsArray ($alist) Then
                For $i=1 To $alist [0]
                        _ArrayAdd ($rlist, $sPath & "\" & $alist [$i])
                        $blist = _DirListToArray ($sPath & "\" & $alist [$i])
                        If $blist[0]>0 Then
                                For $j=1 To $blist [0]
                                        _ArrayAdd ($rlist, $blist [$j])
                                Next
                        EndIf
                Next
        EndIf
        $rlist [0] = UBound ($rlist) - 1
        Return $rlist
EndFunc


Angelus 24-10-2006 13:56

Вопрос, где в этом скрипте ошибка???
Код:

Run ("d:\1\Winamp 5.24\Winamp 5.24.exe")
WinWait("Winamp Setup","License Agreement")
If Not WinActive("Winamp Setup","License Agreement")Then WinActivate("Winamp Setup","License Agreement")
WinWaitActive("Winamp Setup","License Agreement")
Send("{ENTER}")
WinWait("Winamp Setup","Choose Components")
If Not WinActive("Winamp Setup","Choose Components")Then WinActivate("Winamp Setup","Choose Components")
WinWaitActive("Winamp Setup","Choose Components")
Send("{ENTER}")
WinWait("Winamp Setup","Choose Install Options")
If Not WinActive("Winamp Setup","Choose Install Options")Then WinActivate("Winamp Setup","Choose Install Options")
WinWaitActive("Winamp Setup","Choose Install Options")
Send("{ENTER}")
WinWait("Winamp Setup","Choose Install Location")
If Not WinActive("Winamp Setup","Choose Install Location")Then WinActivate("Winamp Setup","Choose Install Location")
WinWaitActive("Winamp Setup","Choose Install Location")
Send("{ENTER}")
WinWait("Winamp Setup","Multi-user Settings")
If Not WinActive("Winamp Setup","Multi-user Settings")Then WinActivate("Winamp Setup","Multi-user Settings")
WinWaitActive("Winamp Setup","Multi-user Settings")
Send("{ENTER}")
WinWait("Winamp Setup","Internet Connection and Language Settings")
If Not WinActive("Winamp Setup","Internet Connection and Language Settings")Then WinActivate("Winamp Setup","Internet Connection and Language Settings")
WinWaitActive("Winamp Setup","Internet Connection and Language Settings")
Send("{DOWN}{DOWN}{TAB}{TAB}{TAB}{TAB}{ENTER}")
WinWait("Winamp Setup","Interface and Skin Selection")
If Not WinActive("Winamp Setup","Interface and Skin Selection")Then WinActivate("Winamp Setup","Interface and Skin Selection")
WinWaitActive("Winamp Setup","Interface and Skin Selection")
Send("{ENTER}")
If ProcessExists('winamp.exe') Then ProcessClose('winamp.exe')
If ProcessExists('winampa.exe') Then ProcessClose('winampa.exe')
If ProcessExists('EmusicClient.exe') Then ProcessClose('EmusicClient.exe')
Run ("d:\1\Winamp 5.24\winamp_5.24_rus.exe")
WinWait("Установка","Новости от")
If Not WinActive("Установка","Новости от")Then WinActivate("Установка","Новости от")
WinWaitActive("Установка","Новости от")
Send("{ENTER}")
WinWait("Установка","Выберите установки програмы")
If Not WinActive("Установка","Выберите установки програмы")Then WinActivate("Установка","Выберите установки програмы")
WinWaitActive("Установка","Выберите установки програмы")
Send("{ENTER}")
WinWait("Установка","Пожалуйста")
If Not WinActive("Установка","Пожалуйста")Then WinActivate("Установка","Пожалуйста")
WinWaitActive("Установка","Пожалуйста")
Send("{ENTER}")
If ProcessExists('winamp.exe') Then ProcessClose('winamp.exe')
If ProcessExists('winampa.exe') Then ProcessClose('winampa.exe')
If ProcessExists('EmusicClient.exe') Then ProcessClose('EmusicClient.exe')

Просто происходит не установка програмы, а бесконечный запуск скрипта......пути правильные....

Creat0R 25-10-2006 02:49

Sanja Alone
Цитата:

Оч. просто это сделать при пом. cmd-файла:
Спасибо, до сих пор, я именно при помощий ком. строки (которую “писал” Аутоит) и реализовал свою цель :) , правда более примитивней чем твой пример - Но хотел узнать как средствами одного лишь аутоита это сделать, т.к требуется увеличение скорости, и уменьшения загрузкий процессора и памяти.

Цитата:

Здесь все муторней
Ну почему, разве такой командой это не решить просто:
Код:

cd "путь\к папке"
dir /b /s /o:-d *.* > test.tmp

А затем, аутоитом проверять первую строку временного файла:

Код:

$NewFile = FileReadLIne("Test.tmp", 1)
amel27
Цитата:

вот что получилось
Получилось идеально!!! Огромное спасибо!


Angelus

Цитата:

где в этом скрипте ошибка?
В начало скрипта, поставь такую строчку:

Код:

Opt("TrayIconDebug", 1)
Если в скрипте есть строка скрывающая иконку скрипта в трее (#NoTrayIcon), то её нужно временно закоментировать (дописать в начале строки символ ; ).
И когда запустишь скрипт, то наведи мышку на иконку скрипта в трее, и посмотри на какой строке “зависает” скрипт.

Как я это вижу, скрипт зависает на одной из строк, содержащей WinWait или WinWaitActive - желательно ставить время, по истичению которого, скрипт больше не будет “ждать” появления окна или его активности...

Код:

WinWaitActive("Заголовок", "Текст", 120) ;Где 120, это секунды, по истичению которых, скрипт “продолжит” дальше, вне зависимости от того, появилось\активировалось ли окно или нет.

Sanja Alone 25-10-2006 04:56

Creat0R
Цитата:

Ну почему, разве такой командой это не решить просто:
Нет. Я же говорю, что эта команда производит сортировку в пределах каждого подкаталога, т.е., первой строкой будет самый новый файл рабочего каталога, а не всего дерева его подкаталогов. А это оч. сильно усложнит решение задачи при пом. cmd-файла.


Angelus
  1. А этот скрипт не подходит?
  2. Отлов ошибок в скриптах описан в FAQ.
  3. Код нужно заключать в тэг code. Прошу не игнорировать ПРАВИЛА ФОРУМА.

Lodoss 29-10-2006 20:11

Есть неплохая идея: написать оболочку (GUI) для авторизации запуска скрипта от имени админа.

начал писать и наткнулся на проблемку - незнаю как реализовать проверку строки RunAsSet на наличие прав администратора
вот код:

Код:

#include <GUIConstants.au3>
GUICreate("Авторизация", 198, 125)
;фон окна
GUISetBkColor (0x00E0FFFF)
;лейблы
GUICtrlCreateLabel("Имя администратора", 25, 5)
GUICtrlCreateLabel("Пароль администратора", 25, 50)
;запуск и отмена скрипта
$ok = GUICtrlCreateButton("Ok", 25, 98, 70,20)
$cancel = GuiCtrlCreateButton ("Cancel",105,98,70,20)
;ввод имени
$us = @UserName
$in1 =GUICtrlCreateCombo ($us, 25, 25, 150, 20)
GUICtrlSetData($in1, "admin|qwerty|Администратор|Винни-Пух")
GUICtrlSetTip(-1,"введите имя любой учётной записи" & @CRLF & "имеюшей права Администратора")
;ввод пароля
$in2 = GUICtrlCreateInput ("solo11",  25, 70, 150, 20, 0x20)
GUICtrlSetTip(-1,"введите пароль")

GUISetState(@SW_SHOW)

While 2
$msg = GUIGetMsg()
;считываем введённые данные
$out1 = GUICtrlRead($in1)
$out2 = GUICtrlRead($in2)

Global $user = $out1, $pass = $out2

Select
Case $msg = $ok
;инициализация запуска от имени админа
RunAsSet($user, "", $pass)

;проверка верны ли введённые записи на право обладания правами админа
;вот здесь незнаю как реализовать проверку. написал но думается неправильно
;---------------------------------------
if        IsAdmin() = -1 Then
MsgBox(16, "Ошибка", "Данная учётная запись не обладает правами Администратора")
EndIf
;---------------------------------------

;запуск программы
Run("setup.exe")
;закрытие окна
        Case $msg = $cancel
          ExitLoop
    Case $msg = $GUI_EVENT_CLOSE
                ExitLoop
        EndSelect
WEnd
;-------------------------------------

в дополнение хотелось бы сделать так чтобы при неправильном вводе имени или пароля GUI не закрывалось а предлагало заново ввести имя и пароль. Ещё , если пользователь обладает правами администратора GUI вобще не появлялось а начинало запуск скрипта с команды Run либо выводило окно без пароля.
Помогайте решать ! :) думаю вещь полезная и пригодиться многим.

Sanja Alone 30-10-2006 09:24

Lodoss
Цитата:

Помогайте решать
Это хотел?
Код:

#include <GUIConstants.au3>
Opt("RunErrorsFatal",0)
;что запускать
$what_to_run="setup.exe"

If IsAdmin() Then
        ;запуск программы
        Run($what_to_run)
Else
        ;если не админ, то "рисуем" GUI
        _GUI()
EndIf

Func _GUI()
GUICreate("Авторизация", 198, 125)
;фон окна
GUISetBkColor (0x00E0FFFF)
;лейблы
GUICtrlCreateLabel("Имя администратора", 25, 5)
GUICtrlCreateLabel("Пароль администратора", 25, 50)
;запуск и отмена скрипта
$ok = GUICtrlCreateButton("Ok", 25, 98, 70,20)
$cancel = GuiCtrlCreateButton ("Cancel",105,98,70,20)
;ввод имени
$us = @UserName
$in1 =GUICtrlCreateCombo ($us, 25, 25, 150, 20)
GUICtrlSetData($in1, "admin|qwerty|Администратор|Винни-Пух")
GUICtrlSetTip(-1,"введите имя любой учётной записи" & @CRLF & "имеюшей права Администратора")
;ввод пароля
$in2 = GUICtrlCreateInput ("solo11",  25, 70, 150, 20, 0x20)
GUICtrlSetTip(-1,"введите пароль")

GUISetState(@SW_SHOW)

While 1
$msg = GUIGetMsg()
;считываем введённые данные
$out1 = GUICtrlRead($in1)
$out2 = GUICtrlRead($in2)

Global $user = $out1, $pass = $out2

Select
        Case $msg = $ok
                ;инициализация запуска от имени админа
                RunAsSet($user, "", $pass)

                ;проверка верны ли введённые записи на право обладания правами админа
                ;---------------------------------------

                if IsAdmin() Then
                        ;запуск программы
                        Run($what_to_run)
                        If @error Then
                                MsgBox(16, "Ошибка", "Введен неправильный пароль или отсутствует файл "&$what_to_run&@LF&@LF&"Попробуйте еще раз.",5)
                        EndIf
                Else
                        MsgBox(16, "Ошибка", "Данная учётная запись не обладает правами Администратора",5)
                EndIf
                ;---------------------------------------

                ;закрытие окна
        Case $msg = $cancel
                ExitLoop
    Case $msg = $GUI_EVENT_CLOSE
                ExitLoop
EndSelect
WEnd
;-------------------------------------
EndFunc


Jilted 30-10-2006 12:45

Наваял тут скрипт для FastStone Image Viewer 2.8 с последующей русификацией.
Может, кому пригодится.
Код:

RunWait (@ScriptDir&'\'&'fs.exe /S') ; Тихая установка самой программы
Run (@ScriptDir&'\'&'Rus.exe') ; Установка русификатора
WinWait("Установка русификатора","Вас приветствует мастер")
WinActivate("Установка русификатора","Вас приветствует мастер")
WinWaitActive("Установка русификатора","Вас приветствует мастер")
Send("{ENTER}")
Send("{ENTER}")
WinWait("Установка русификатора","Внимательно ознакомьтесь")
WinActivate("Установка русификатора","Внимательно ознакомьтесь")
WinWaitActive("Установка русификатора","Внимательно ознакомьтесь")
Send("{UP}{UP}{ENTER}")
WinWait("Установка русификатора","Русификатор FastStone Image Viewer 2.8 будет установлен в следующую папку")
WinActivate("Установка русификатора","Русификатор FastStone Image Viewer 2.8 будет установлен в следующую папку")
WinWaitActive("Установка русификатора","Русификатор FastStone Image Viewer 2.8 будет установлен в следующую папку")
Send("{ENTER}")
WinWait("Установка русификатора","Русификатор FastStone Image Viewer 2.8 будет установлен в папку")
WinActivate("Установка русификатора","Русификатор FastStone Image Viewer 2.8 будет установлен в папку")
WinWaitActive("Установка русификатора","Русификатор FastStone Image Viewer 2.8 будет установлен в папку")
Send("{ENTER}")
WinWait("Установка русификатора","Русификатор FastStone Image Viewer 2.8 успешно установлен")
WinActivate("Установка русификатора","Русификатор FastStone Image Viewer 2.8 успешно установлен")
WinWaitActive("Установка русификатора","Русификатор FastStone Image Viewer 2.8 успешно установлен")
Send("{UP}{SPACE}{UP}{ENTER}")

Программа + Русификатор

Lodoss 31-10-2006 18:48

2Sanja Alone

Да это, но наполовину.
проверил:
Если пользователь админ - оболочка не запускается как и хотелось , если GUI запускается проверка учётки на привелегии админа
Код:

Case $msg = $ok
RunAsSet($user, "", $pass)
if IsAdmin() Then
Run($what_to_run)
If @error Then
MsgBox(16, "Ошибка", "Введен неправильный пароль или отсутствует файл "&$what_to_run&@LF&@LF&"Попробуйте еще раз.",5)
EndIf
Else
MsgBox(16, "Ошибка", "Данная учётная запись не обладает правами Администратора",5)
EndIf

несрабатывает !!!, т е выдаёт сообщение "Данная учётная запись не обладает правами Администратора" в любом случае, даже если я под пользователем с ограничеными правами правильно ввёл учётные данные администратора. :/

и ещё вопрос можно ли в комбо списке сделать отображение учёток обладающих этими правами администратора :). в макро переменных нашёл только @UserName а можно ли получить список всех учёток зарегестрированых на компе и обладающих администраторскими привелегиями?.

TERMINAL 01-11-2006 13:47

Как сделать закрытие окна (Alt+F4), например окно хелпа?!

Creat0R 01-11-2006 19:03

TERMINAL
Цитата:

Как сделать закрытие окна
Можно так:

Код:

WinClose("Заголовок окна", "Текст окна")
Или так:

Код:

WinActivate("Заголовок окна", "Текст окна")
WinWaitActive("Заголовок окна", "Текст окна", 10)
Send("!{F4}")


Creat0R 02-11-2006 09:08

Хотелось бы решить такую задачу...
Имеется файл, а в нём много разного текста, и нужно перечитать весь текст, и проверить, не содержатся ли в нём дубликаты определённой переменной.
Т.е, допустим файл содержит такой текст:

Код:

Первая строчка
Вторая строчка
Просто текст
Ещё текст...
Просто текст

И заранее известно, что именно нужно искать, и это помещенно в переменную - $Var = "Просто текст"...

Нужно в этом файле вычеслить, повторяется ли этот самый текст (тот который в переменной), если есть совпадения, то желательно вернуть номер строчки где есть совпадение, и строку содержащюю найденый дубликат (в Array[1].. [2] и т.п).

Возможно уже есть такая опция в AutoIt, но я что-то затрудняюсь найти в справке подобную функцию :(

TERMINAL 02-11-2006 11:40

Creat0R
Спасибо тебе-(Send("!{F4}")) конкретно помогло.

Вопрос ещё один. У меня в программе ACDSee 8 вводится ключ в поле регистрации,но на совремменых компах он успевает вводится, а на слабых компах скрипт успевает ввести только 4 первых символа (паузы почемуто непомогают). Как сделать чтобы скрипт дождался полного ввода серийника.

Код:

Global $serial='12345-67890-12345-67890'
Run ( @ScriptDir & '\' & 'Setup.exe' )
WinWait("ACDSee 8 - InstallShield Wizard","ACDSee 8 can run with previous")
WinActivate("ACDSee 8 - InstallShield Wizard","ACDSee 8 can run with previous")
ControlClick("ACDSee 8 - InstallShield Wizard","ACDSee 8 can run with previous","Button1")
WinWait("ACDSee 8 - InstallShield Wizard","I &accept the terms in the lic")
WinActivate("ACDSee 8 - InstallShield Wizard","I &accept the terms in the lic")
ControlClick("ACDSee 8 - InstallShield Wizard","I &accept the terms in the lic","Button3")
ControlClick("ACDSee 8 - InstallShield Wizard","I &accept the terms in the lic","Button5")
WinWait("ACDSee 8 - InstallShield Wizard","&Organization:")
WinActivate("ACDSee 8 - InstallShield Wizard","&Organization:")
ControlClick("ACDSee 8 - InstallShield Wizard","&Organization:","RichEdit20W3")
ControlSetText ( 'ACDSee 8 - InstallShield Wizard', 'Customer Information', 'Edit3', $serial)
;Send($serial)
Sleep(5000)
ControlClick("ACDSee 8 - InstallShield Wizard","&Organization:","Button8")
WinWait("ACDSee 8 - InstallShield Wizard","&Complete")
WinActivate("ACDSee 8 - InstallShield Wizard","&Complete")

И вот ещё-хотелось бы узнать, как сделать, например, окно под названием ММ, чтобы при установке программы, когда вылазит окно ММ закрыть его и повторить установку заново, а если не вылезет тогда продолжать установку?!

VelDmi 02-11-2006 15:55

Из скрипта запускается консольный nerocmd.exe. Можно ли как то получить данные, показываемые в консоли для отображения их в GUI автоита?

Creat0R 02-11-2006 18:25

TERMINAL
Цитата:

Как сделать чтобы скрипт дождался полного ввода серийника
Попробуй вместо ControlSetText прописать так:

Код:

ControlCommand("ACDSee 8 - InstallShield Wizard", "Customer Information", "Edit3", "EditPaste", $serial)
И ещё, заголовок окна, чувствителен к регистру, поставь в начало скрипта, такую строчку - Opt("WinTitleMatchMode", 4)

Цитата:

когда вылазит окно ММ закрыть его и повторить установку заново
Нужно всё поместить в цикл, и в конце проверять существование окна...

Код:

Opt("WinTitleMatchMode", 4)

While 1
Global $serial='12345-67890-12345-67890'
Run ( @ScriptDir & '\' & 'Setup.exe' )
WinWait("ACDSee 8 - InstallShield Wizard","ACDSee 8 can run with previous")
WinActivate("ACDSee 8 - InstallShield Wizard","ACDSee 8 can run with previous")
ControlClick("ACDSee 8 - InstallShield Wizard","ACDSee 8 can run with previous","Button1")
WinWait("ACDSee 8 - InstallShield Wizard","I &accept the terms in the lic")
WinActivate("ACDSee 8 - InstallShield Wizard","I &accept the terms in the lic")
ControlClick("ACDSee 8 - InstallShield Wizard","I &accept the terms in the lic","Button3")
ControlClick("ACDSee 8 - InstallShield Wizard","I &accept the terms in the lic","Button5")
WinWait("ACDSee 8 - InstallShield Wizard","&Organization:")
WinActivate("ACDSee 8 - InstallShield Wizard","&Organization:")
ControlClick("ACDSee 8 - InstallShield Wizard","&Organization:","RichEdit20W3")
ControlCommand("ACDSee 8 - InstallShield Wizard", "Customer Information", "Edit3", "EditPaste", $serial)
ControlClick("ACDSee 8 - InstallShield Wizard","&Organization:","Button8")
WinWait("ACDSee 8 - InstallShield Wizard","&Complete")
WinActivate("ACDSee 8 - InstallShield Wizard","&Complete")

WinWait("MM", "", 10) ; ждём 10 секунд окна с заголовком MM
If WinExists("MM", "") Then ContinueLoop
ExitLoop
Wend


VelDmi
Цитата:

Можно ли как то получить данные, показываемые в консоли
Попрубуй так:

Код:

$NerocmdTxt = WinGetText("Заголовок консоли", "")

TERMINAL 02-11-2006 19:10

Creat0R

<Нужно всё поместить в цикл, и в конце проверять существование окна...>

А примерчик простенький можна?

Creat0R 03-11-2006 03:07

TERMINAL
Цитата:

примерчик простенький можна?
Неужели не видно тот пример который я привёл в своём посте? :blink:

Цикл:

Код:

While 1
....
Wend

Это “заставит” скрипт “ходить” от While 1 до Wend, до тех пор, пока что то не заставит выйти из этого цикла...

Код:

While 1
ExitLoop ; Выход с цикла
Wend

И соответственно строим условие, при существовании которго, что то произойдёт (выход из цикла, или продолжение цикла)...

Код:

While 1
If WinExists("MM", "") Then ContinueLoop ;Если окно существует, то цикл начнётся заного, и скрипт моментально “продолжит” с начала цикла (While 1)
ExitLoop ;Выход из цикла (так как окно небыло найдено)
Wend


amel27 03-11-2006 06:50

Creat0R
Цитата:

Имеется файл, а в нём много разного текста, и нужно перечитать весь текст, и проверить, не содержатся ли в нём дубликаты определённой переменной.
Обычным циклом устроит? Функция выводит сообщения (Select) и возвращает двумерный массив со счетчиком (номер строки и текст) , можно на выбор оставить что-нибудь одно:
Код:

#include <File.au3>

$dups = _TextInFile ("c:\test.txt", "Просто текст")

Func _TextInFile ($file, $text)
        Local $i, $txtLines, $res [1][2] = [[0,0]]
        Local $str='Строки, содержащие "' & $text & '":' & @CRLF & @CRLF
        _FileReadToArray ($file, $txtLines)
        If Not IsArray ($txtLines) Then
                MsgBox (16, 'Ошибка', 'Файл пуст')
        EndIf
        For $i=1 To $txtLines [0]
                If StringInStr ($txtLines [$i], $text) Then
                        ReDim $res [$res [0][0]+2][2]
                        $res [0][0] = $res [0][0] +1
                        $res [$res [0][0]][0] = $i
                        $res [$res [0][0]][1] = $txtLines [$i]
                        $str = $str & $i & ':' & @TAB & $txtLines [$i] & @CRLF
                EndIf
        Next
        Select
                Case $res [0][0] =0
                        MsgBox (16, 'Ошибка', 'Вхождений не обнаружено!')
                Case $res [0][0] =1
                        MsgBox (64, 'Сообщение', 'Дублей нет')
                Case Else
                        MsgBox (48, 'Предупреждение', $str)
        EndSelect
        Return $res
EndFunc


amel27 03-11-2006 08:30

Lodoss
Цитата:

можно ли получить список всех учёток зарегестрированых на компе и обладающих администраторскими привелегиями?.
ну ты горазд задачки задавать... три дня колдовал на DllCall ;) ... самое забавное, что на форуме AutoIt не нашел ни одного рабочего варианта... Зато теперь можно смело замахнуться на всю линейку NetApi32 :)
Код:

;===============================================================================
; Использование:    _NetLocalGroupGetMembers ($s_Group, [$s_Computer, [, $i_ShowDomain [, $i_Filter]]])
; Параметры:        $s_Group - имя локальной группы;
;                    $s_Computer - DNS или NetBIOS имя компьютера, пустая строка или пропущенный
;                      параметр равнозначны локальному компьютеру;
;                    $i_ShowDomain - "1" включить имя домена, "0" не включать;
;                    $i_Filter - набор флагов, задающих фильтр отбираемых записей:
;                        1 - пользователи,
;                        2 - группы,
;                      16 - предопределенные (WellKnown) группы,
;                      32 - удаленные учетные записи,
;                      128 - неизвестный тип.
; Результат:        При успешном завершении возвращает 1-мерный массив учетных записей,
 ;                      1-й элемент массива (индекс 0) содержит количество записей.
;                    При неудаче 1-й элемент содержит "-1" и @error указывает код ошибки
;
;===============================================================================

Func _NetLocalGroupGetMembers ($sGroup, $sServer = "", $iShowDom = 1, $iFilter = 511)
    Local $res [1] = [0], $uPTR= DllStructCreate ("ptr")
    If $iShowDom Then
        $iShowDom=2
    Else
        $iShowDom=1
    EndIf
    Local $ret = DllCall ("netapi32.dll", "int", "NetLocalGroupGetMembers", _
        "wstr", $sServer, _
        "wstr", $sGroup, _
        "int", $iShowDom, _
        "ptr", DllStructGetPtr ($uPTR), _
        "int", -1, _
        "int_ptr", 0, _
        "int_ptr", 0, _
        "int_ptr", 0 )
    If $ret[0] Then
        SetError ($ret [0])
        $res[0] = -1
    Else
        If $ret[6]>0 Then
            Local $i, $string
            Local $uBUF = DllStructCreate ("ptr[" & $ret[6]*3 & "]", DllStructGetData ($uPTR,1) )
            For $i=3 To $ret[6]*3 Step 3
                If BitAnd (BitShift (1, 1 - DllStructGetData ($uBUF, 1, $i-1) ), $iFilter) Then
                    $ret = DllCall("kernel32.dll", "int", "WideCharToMultiByte", _
                        "int", 0, _
                        "int", 0, _
                        "ptr", DllStructGetData ($uBUF, 1, $i), _
                        "int", -1, _
                        "str", "", _
                        "int", 0, _
                        "int", 0, _
                        "int", 0 )
                    $string = DllStructCreate ("char[" & $ret[0] & "]")
                    $ret = DllCall("kernel32.dll", "int", "WideCharToMultiByte", _
                        "int", 0, _
                        "int", 0, _
                        "ptr", DllStructGetData ($uBUF, 1, $i), _
                        "int", $ret[0], _
                        "ptr", DllStructGetPtr ($string), _
                        "int", $ret[0], _
                        "int", 0, _
                        "int", 0 )
                    ReDim $res [$res[0]+2]
                    $res [0] = $res [0]+1
                    $res [$res[0]] = DllStructGetData ($string,1)
                EndIf
            Next
        EndIf
    EndIf
    DllCall ("netapi32.dll", "int" ,"NetApiBufferFree", _
        "ptr" , DllStructGetData ($uPTR,1) )
    Return $res
EndFunc


TERMINAL 03-11-2006 11:48

Я наверное плохо объяснил...
Суть проблемки с циклами вот в чём-программа имеет сетап и патч. При установки сетапа всё происходит ОК, а при установке патча (если нет видео драйверов) выдаётся ошибка и прекращается установка.Потом опять запускаешь патч до тех пор пока он не начинает сам ставится (это бывает от 1 до 2 раз). Вот я и хочу объяснить скрипту что если ничего не вылезет то можно продолжать установку (а не так как у тебя-ВЫХОД), а если вылезет окно ошибки, то нужно закрыть его и опять устанавливат этот патч пока он не установится.

Creat0R 04-11-2006 02:52

amel27
Цитата:

Функция выводит сообщения (Select) и возвращает двумерный массив со счетчиком (номер строки и текст)
Немного не так :( - Мне нужно чтобы вернулись в массив все номера строк, которые содержат дубляжи (именно дубляжи, без первой находки искомого слова), и желательно, чтобы в массиве эти номера строк, помещались через разделитель (допустим, через | ). В случае неудачи (или если вовсе не найденно вхождении), т.е если дубликатов нет, ненужно выводить сообщения, а просто в массив с нулём ($Array[0]) поместить содержание искомого слова (ну или вообще просто пустату "" - это нужно для проверки содержит ли массив номера строк, т.е дубляжи).

Просто дело в том, что задача у меня примерно такая:
-Проверить файл на дубликаты определённово слова (а точнее ссылки), если есть таковы, то просто удалить все дубликаты, оставив один-“оригинал” - Как удалять я знаю, имея номера строк, я могу восспользоваться функцией _FileWriteToLine...

Код:

#include <File.au3>

$Array = StringSplit("1|4|6|8", "|") ;Вместо цифр будет подставлен тот самый массив с номерами строк

For $i = 1 to $Array[0]
        _FileWriteToLine("File.txt", $Array[$i], "", 1)
Next

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

---------------------------------

TERMINAL

У тебя в примере, нет упоминания о патче, но попробую привести нужны пример на основе воображения :) :

Код:

Opt("WinTitleMatchMode", 4)

Global $serial='12345-67890-12345-67890'
Run ( @ScriptDir & '\' & 'Setup.exe' )
WinWait("ACDSee 8 - InstallShield Wizard","ACDSee 8 can run with previous")
WinActivate("ACDSee 8 - InstallShield Wizard","ACDSee 8 can run with previous")
ControlClick("ACDSee 8 - InstallShield Wizard","ACDSee 8 can run with previous","Button1")
WinWait("ACDSee 8 - InstallShield Wizard","I &accept the terms in the lic")
WinActivate("ACDSee 8 - InstallShield Wizard","I &accept the terms in the lic")
ControlClick("ACDSee 8 - InstallShield Wizard","I &accept the terms in the lic","Button3")
ControlClick("ACDSee 8 - InstallShield Wizard","I &accept the terms in the lic","Button5")
WinWait("ACDSee 8 - InstallShield Wizard","&Organization:")
WinActivate("ACDSee 8 - InstallShield Wizard","&Organization:")
ControlClick("ACDSee 8 - InstallShield Wizard","&Organization:","RichEdit20W3")
ControlCommand("ACDSee 8 - InstallShield Wizard", "Customer Information", "Edit3", "EditPaste", $serial)
ControlClick("ACDSee 8 - InstallShield Wizard","&Organization:","Button8")
WinWait("ACDSee 8 - InstallShield Wizard","&Complete")
WinActivate("ACDSee 8 - InstallShield Wizard","&Complete")

While 1
Run( @ScriptDir & '\' & 'Path.exe' )

WinWait("MM", "", 10) ; ждём 10 секунд окна с заголовком MM

;В случае появления окна с заголовком “MM”, Закрываем его, и запускаем патч снова
If WinExists("MM", "") Then
WinClose("MM", "")
ContinueLoop
EndIf
ExitLoop
Wend


XXXler 04-11-2006 04:08

Нижеприведенная функция убивает все возможные окна от запущенного ей процесса и если какие-либо окна появлялись - перезапускает прогу заново (убиваются окна также дочерних процессов, просто одноименные окна\процессы не затрагиваются)

Код:

;~ Пример запускает+закрывает setup.exe:
RunKillWin(@SystemDir&"\setup.exe")

;~ Использование:
;~ RunKillWin("Путь и имя файла"[, таймаут ожидания завершения выполнения exe(сек)][,количество попыток "тихого" выполнения])
;~ Возвращает количесто выполненых попыток

Func RunKillWin($Exe,$MaxTimeOutForProcess=300,$MaxCountToReRun=10)
Local $i,$PID,$Timer,$WinArr,$y,$z=0

For $i=1 To $MaxCountToReRun

        ;~ Корявая поверка необходимости перезапуска
        If $z=1 Then ExitLoop
        $z=1
       
        $PID=Run($Exe)
        ;~ Запуск таймера таймаута выполнения
        $Timer=TimerInit()
               
        While ProcessExists($PID)

                ;~ Сверка таймера
                If TimerDiff($Timer)>$MaxTimeOutForProcess*1000 Then
                        ProcessClose($PID)
                        If Not(ProcessWaitClose($PID,30)) Then Return -1
                        $z=0
                        ContinueLoop 2
                EndIf
               
                $WinArr=WinList()
                For $y=1 To $WinArr[0][0]
                        If Not(WinGetProcess($WinArr[$y][1])=$PID) Then ContinueLoop
                        ;~ Собственно действие над окном\доп. проверку его титла можно поменять здесь
                        WinKill($WinArr[$y][1])
                        $z=0
                Next
               
        WEnd
       
Next
Return $i-1
EndFunc


Sanja Alone 04-11-2006 04:55

TERMINAL
Цитата:

Как сделать чтобы скрипт дождался полного ввода серийника
Код:

$serial="серийник"
WinWait ("Заголовок", "Текст")
Do
        ControlSetText ( "Заголовок", "Текст", "Edit1", $serial )
Until ControlGetText ( "Заголовок", "Текст", "Edit1" )=$serial

Думаю, что идея ясна.

VelDmi 04-11-2006 14:10

Creat0R
Цитата:

Попрубуй так:
Код:
$NerocmdTxt = WinGetText("Заголовок консоли", "")
Не работает. Более того, AutoItInfo тоже не видит никакого текста в окне консоли. Еще есть идеи?

amel27 05-11-2006 10:42

Creat0R
Цитата:

$Array = StringSplit("1|4|6|8", "|")
ну ты умеешь озадачить... зачем делать сплит строки если предложенная функция возвращает уже готовый массив с номерами строк?
Цитата:

если дубликатов нет, ненужно выводить сообщения, а просто в массив с нулём ($Array[0])
именно такой массив ф-ция и возвращает, только не одномерный, а двумерный - ты же вроде заказывал не только номера строк ($Array[$i][0]), но и их содержимое ($Array[$i][1])? Счетчик $Array[0][0] содержит число возвращенных строк - если он равен 0, то вхождений соответственно нет. SELECT добавлен для наглядности, я же вроде сказал что его можно убрать.
Цитата:

Но и тут есть проблема, после удаления строки под первым номером присутствующем в массиве, все остальные теряют своё значения, и удаляются уже не те строки
эта проблема решается просто - нужно проходить массив в обратном направлении: от конца файла к его началу:
Код:

#include <File.au3>

$File = "c:\test.txt"
$Array = _TextInFile ($File, "Просто текст")
If $Array[0][0]>1 Then
        For $i = $Array[0][0] to 2 Step -1
                _FileWriteToLine($File, $Array[$i][0], "", 1)
        Next
EndIf

Func _TextInFile ($file, $text)
        Local $i, $txtLines, $res [1][2] = [[0,0]]
        _FileReadToArray ($file, $txtLines)
        If IsArray ($txtLines) Then
                For $i=1 To $txtLines [0]
                        If StringInStr ($txtLines [$i], $text) Then
                                ReDim $res [$res [0][0]+2][2]
                                $res [0][0] = $res [0][0] +1
                                $res [$res [0][0]][0] = $i
                                $res [$res [0][0]][1] = $txtLines [$i]
                        EndIf
                Next
        EndIf
        Return $res
EndFunc


Creat0R 06-11-2006 00:47

amel27
Приогромное спасибо! Я думал что функция для моей задумки, будет выглядеть намного длинее :)

В связи с тем, что эта функция относительно быстро срабатывает (я проверял на большом файле с текстом), у меня появился вопрос...

У меня есть функция (от Sanja Alone), которая делает поиск по файлу, и если текст найден, то возвращается в Array[0] номер строки где был найден текст, а в Array[1] возвращается состав этой строки. Так вот, та функция, визуально большая, и большие файлы обрабатывает довольно долго (доходит до 5-ти секунд). И ещё, возвращается только первое-найденное вхождение, а хотелось бы точно также как и с твоей функцией, чтобы в массив возвращались все номера строк, и все содержания этих строк.

В общем, вопрос в том, можно ли немного переделать эту функцию, чтобы вместо поиска дубляжей, искалось просто слово, и возвращались те же значения, что и в этой функции? (чтобы также можно было воспользоваться ими, ну, допустим для замены текста на что то другое - для этого у меня уже есть функция).

amel27 06-11-2006 05:20

Creat0R
Цитата:

та функция, визуально большая, и большие файлы обрабатывает довольно долго (доходит до 5-ти секунд).
Смотри текст скрипта - у Sanja Alone дополнительно реализована нечувствительность к регистру для русского текста (для английского это выполняется автоматически), возможно поэтому он и работает медленнее...

Цитата:

вопрос в том, можно ли немного переделать эту функцию, чтобы вместо поиска дубляжей, искалось просто слово, и возвращались те же значения, что и в этой функции?
м-да... подставь в функцию вместо "дубля" искомое "слово", и функция вернет "те же значения"... ;)
в чем разница-то?.. возвращаются всегда все значения, просто при замене использовались не все (смотри пределы):
Код:

For $i = $Array[0][0] to 2 Step -1
...
Next


Creat0R 06-11-2006 10:55

amel27
Ещё раз спасибо. В данном случае, нет необходимости в поиске текста содержащий кириллицу (разве что бывают ссылки с кириллицей :) ).

TERMINAL 06-11-2006 17:32

1. Creat0R спасибо за скрипт, но он всеравно не подходит. В твоём скрипте постоянно, бесконечно стартует Setup.exe

При установке программы (например-Setup.exe) может вывалиться окно с ошибкой ERROR (ошибка вылетает в том случае если неустановлены видео драйвера), а может и не вывалиться (если же установлены видео драйвера). Так вот, хотелось бы чтобы скрипт работал как с установленными дровами так и без них. Т.е. при старте Setup.exe может установка прекратиться и вылезет окно ERROR-так можно этот файл стартовать до 3х раз-потом уже ошибка не вылетает и прога начинает устанавливаться, а может ошибка и не вылезти.

=======================================================

2. ПОМОГИТЕ НАЙТИ ОШИБКУ !!!
Мне нужно убрать галочки при инсталяции (именно мышкой <ControlClick>)-написал такой скрипт, но он не убират галочки:

HTML код:

WinWait("InstallShield Wizard","InstallShield Wizard Complete")
WinActivate("InstallShield Wizard","InstallShield Wizard Complete")
ControlClick("InstallShield Wizard","InstallShield Wizard Complete","Static1")
ControlClick("InstallShield Wizard","InstallShield Wizard Complete","Static1")


Creat0R 06-11-2006 17:53

TERMINAL

Цитата:

постоянно, бесконечно стартует Setup.exe
Присмотрись в скрипт, там указанно окно при пресутствии которого, скрипт опять запустит Setup.exe

Цитата:

вылезет окно ERROR
Кажется это было окно "MM" ;) ...

Код:

If WinExists("ERROR", "") Then ;Если окно с заголовком ERROR существует, то....
WinClose("ERROR", "")  ;Закрываем это окно
ContinueLoop ;продолжаем (начинаем) скрипт сначала (запустив Setup.exe опять)
EndIf ;Конец условия (“Если окно с заголовком ERROR существует, то....”)
ExitLoop ;Выход из цикла (без запуска Setup.exe)

Цитата:

он не убират галочки
Он убирает, и, ставит сразу обратно :) - у тебя две одинаковые строки (два нажатия мышкой в одном и том же чекбоксе)...

Код:

ControlClick("InstallShield Wizard","InstallShield Wizard Complete","Static1")
ControlClick("InstallShield Wizard","InstallShield Wizard Complete","Static1")

Убери (или измени) один, и будет ставить галку (если все параметры верные).

Creat0R 06-11-2006 21:17

amel27
Есть ещё небольшой вопрос, также немного затрагивающий функцию поиска дубликатов...

Возможно ли сделать поиск по файлу на дубликаты, но заранее не знаяя вхождения? т.е нужно проверить все существующие строки в файле, и если хоть какая то из них имеет дубликат (именно по строке), то удалить все точно такие же строки, но оставив оригинал (для каждой такой найденной строки, произвести данную операцию - т.е удаление дубликатов найденных строк). Но, подвог (для меня) в том, что нужно удалить не именно те строки (их дубликаты), а те которые располагаются на три строчки выше.

Вот пример файла:

Код:

Первая строка
Ещё строка - > вот это и нужно чтобы удалилось (так как на три строки ниже, есть дубль той строки, которая на одну ниже этой (но её положение не фажно))
и ещё строка
просто текст
и ещё строка
и ещё больше текста
строка номер 7 - > и вот это нужно чтобы удалилось
строка 8
и текст строки номер 9
И ещё больше текста


P.S.
В данном случае, скорость обработки, не очень уж важно, да и визуализация тоже :) - Главное функционал!

amel27 07-11-2006 12:21

Creat0R
Цитата:

ещё небольшой вопрос
примерно так... Пара замечаний - во-первых, оператор "=" (для целых строк) в отличие от StringInStr (для вхождений) дружит с русским языком и это хорошо... во-вторых, строки с дополнительными пробелами в конце/начале строк будут рассматриваться как различные, если это не устраивает нужно применить функцию StringStripWS.
Код:

#include <File.au3>

$File = "c:\test.txt"

Dim $FileLines
_FileReadToArray ($file, $FileLines)
; Возвращаем массив из дублирующихся записей
$DupLines = _DupsInArray ($FileLines)
; Страховка от пустого массива если дублей нет
If $DupLines [0][0] >0 Then
        ; Рабочий массив для отметок удаляемых записей
        Local $DelFlags [$FileLines [0] +1]
        For $i=1 To $DupLines [0][0]
                ; расчитываем номер строки для удаления
                $delNum = $DupLines [$i][0] - 3
                ; отмечаем кандидата на удаление в массиве
                $DelFlags [$delNum] = 1
        Next
        ; Собственно цикл удаления
        For $i = $FileLines [0] To 1 Step -1
                If $DelFlags [$i] = 1 Then
                        _FileWriteToLine ($File, $i, "", 1)
                EndIf
        Next
EndIf

; Возвращает двумерный массив со счетчиком, содержащий только дубли
Func _DupsInArray (ByRef $array)
        Local $i, $i, $res [1][2] = [[0,0]]
        ; рабочий массив для отметки обработанных дублей
        Local $flags [$array [0] +1]
        For $i=1 To $array [0]
                For $j=$i+1 To $array [0]
                        If $flags [$j] <> 1 Then
                                If $array [$i] = $array [$j] Then
                                        ReDim $res [$res [0][0]+2][2]
                                        $res [0][0] = $res [0][0] +1
                                        $res [$res [0][0]][0] = $j
                                        $res [$res [0][0]][1] = $array [$j]
                                        $flags [$j] = 1
                                EndIf
                        EndIf
                Next
        Next
        Return $res
EndFunc


Creat0R 07-11-2006 13:01

amel27
Я извеняюсь, я не обращал внимания, но в том файле, для которго это будет делаться, есть дубли которые не должны быть тронуты. Т.е я даже заранее знаю начало строки - URL= но перед этим идёт таб (@Tab)... в общем, вот часть этого файла (это закладки от браузера Opera):

Код:

#URL
        ID=16
        NAME=ICQ2Go!
        URL=http://www.icq.com/icq2go/flicq.html
        ICONFILE=www.icq.com.ico
        IN PANEL=YES
        PANEL_POS=10

#URL
        ID=17
        NAME=Сетевые инструменты
        URL=file://C:/Program Files/Opera/help/tools/tools.htm
        ICONFILE=tools.ico
        IN PANEL=YES
        PANEL_POS=13

#URL
        ID=18
        NAME=Просмотр Кеша
        URL=file://C:/Program Files/Opera/help/Opera_Cache_Viewer76/viewer.htm
        ICONFILE=cash.ico
        IN PANEL=YES
        PANEL_POS=14

#URL
        ID=19
        NAME=ICQ2Go!
        URL=http://www.icq.com/icq2go/flicq.html
        ICONFILE=www.icq.com.ico
        IN PANEL=YES
        PANEL_POS=10

#URL
        ID=20
        NAME=Просмотр Кеша
        URL=file://C:/Program Files/Opera/help/Opera_Cache_Viewer76/viewer.htm
        ICONFILE=cash.ico
        IN PANEL=YES
        PANEL_POS=14

Так вот, тут видно, что есть много дублей, но не все нужно трогать, а именно те, которые имеют начало URL= (ссылка потом может быть любая). И нужно чтобы удалилась строчка, содержащая это - #URL (т.е она расположена на три строки выше чем совпавший дубль). Я пометил красным те строки, которые именно в этом куске, и должны будут быть удалены в конце обработки.

amel27 07-11-2006 14:02

Creat0R
просто добавь еще один IF:
Код:

...
For $i=1 To $DupLines [0][0]
        If StringLeft ($DupLines [$i][1], 5) = @TAB & "URL=" Then
                ; расчитываем номер строки для удаления
                $delNum = $DupLines [$i][0] - 3
                ; отмечаем кандидата на удаление в массиве
                $DelFlags [$delNum] = 1
        EndIf
Next
...

... судя по файлу это больше смахивает на работу с блоками текста, чем просто со строками

Creat0R 07-11-2006 17:39

amel27
Цитата:

просто добавь еще один IF:
Огромное THENX! - Как всё оказывается просто :)

Цитата:

судя по файлу это больше смахивает на работу с блоками текста, чем просто со строками
Ну да, просто содержимое этого файла, может доходить до 5-ти, а то и 10-ти ТЫСЯЧЬ! строк (иногда и больше) - и это всё закладки в браузере Opera (как избранное у IE), данная функция, позволит удалить в этом файле все дублирующиеся закладки. Просто если удалить у любого такого блока, строчку содержащюю #URL, то после запуска браузера, эта закладка не будет отображаться, и даже более этого, браузер сам всё “поправит” в файле, и “затрёт” оставшиеся строчки, которые для него, как бы являются “мусором”.

amel27 08-11-2006 03:04

Creat0R
Цитата:

если удалить у любого такого блока, строчку содержащюю #URL, то после запуска браузера, эта закладка не будет отображаться, и даже более этого, браузер сам всё “поправит” в файле, и “затрёт” оставшиеся строчки
все это замечательно... но представь, что в блоке поменялись местами две строчки (подправит ли это браузер, это ведь не ошибка?), или в новой версии добавили новый реквизит... работа скрипта будет нарушена. Поэтому более "правильным" представляется следующий алгоритм:
- читаем файл и сразу нумеруем записи по блокам (а не по строкам);
- один из реквизитов (URL) оформляем как ключевой для блока;
- формируем новый файл ссылок (поверх старого), но уже без дублей.

З.Ы. обычно чем "правильней" алгоритм, тем он медленней

Creat0R 08-11-2006 05:46

amel27
Цитата:

представь, что в блоке поменялись местами две строчки (подправит ли это браузер, это ведь не ошибка?)
Именно те строчки, которые в промежутке #URL и URL=ссылка, меняться местами не могут, и вообще, все строчки всегда присутствуют так, как это задуманно браузером, я пробовал убирать строки по разному, но браузер ставил так как ему нужно.

Цитата:

в новой версии добавили новый реквизит
Сомневаюсь я, что разработчики когда либо возьмутся за правку работы с закладками, в браузере и так много чего править нужно, и вещи куда серъёзней чем закладки :) (хотя предусмотреть такую функцию, как не позволения добовлять закладки повторно, они конечно должны были).

Цитата:

обычно чем "правильней" алгоритм, тем он медленней
Но мне скорость не очень важна, я конечно буду очень рад если будет более усовершенствованный скрипт :), но так как он выполняется сейчас, меня вполне устраивает. Ещё раз спасибо.

amel27 08-11-2006 13:28

Creat0R
Цитата:

я конечно буду очень рад если будет более усовершенствованный скрипт , но так как он выполняется сейчас, меня вполне устраивает.
другого не будет :) ...и тем не менее (на будущее) советую не заниматься сочинительством отвлеченных задачек, а сразу раскрывать все требования к скрипту. Кодирование общих задач может и полезно, но требует учета большего количества вариантов, что приводит к лишней трате времени и лишней длине кода... лучше постановку задачи сделать совместными усилиями. ;)

применительно к твоему скрипту код можно еще укоротить:
Код:

#include <File.au3>

$File = "c:\test.txt"

Dim $FileLines
_FileReadToArray ($file, $FileLines)
; Возвращаем массив из дублирующихся записей
$DupLines = _DupsInArray ($FileLines)
; Страховка от пустого массива если дублей нет
If $DupLines [0][0] >0 Then
        For $i=$DupLines [0][0] To 1 Step -1
                If StringLeft ($DupLines [$i][1],5) = @TAB & "URL=" Then _FileWriteToLine ($File, $DupLines [$i][0] - 3, "", 1)
        Next
EndIf

З.Ы. я ваще нудный... =)

Creat0R 08-11-2006 14:35

amel27
Цитата:

лучше постановку задачи сделать совместными усилиями.
Ок, буду далее только с открытыми картами появляться :) - просто по какой то причине, мне всё время кажется, что этими самыми “сочинениями”, мне удастса лучше объяснить цель моей задачи.

Цитата:

применительно к твоему скрипту код можно еще укоротить:
Спасибо, но как оказалось, ты в каком то смысле был прав :( ...

Дело вот в чём, браузер не всегда затирает нужные закладки, иногда, если были удалены заглавы (#URL) двух закладок (блоков) идущих подряд, то он удаляет иногда и ту закладку которая идёт выше этих двух. Может всё же как то можно чтобы уже сразу весь блок удалять? :blush2:

Цитата:

я ваще нудный
Желаю чтобы все пользователи этого форума были такими нудными, я бы тогда здесь по жизннно зависал :) - и вообще, нет ли такой возможности (может тоже скрипт написать?), чтобы за каждое твоё оставленное сообщение (пусть даже по всему форуму), автоматом оно обозначалось бы как “Полезное сообщение” - оно так и есть :)

amel27 09-11-2006 04:54

Creat0R
Цитата:

Дело вот в чём, браузер не всегда затирает нужные закладки, иногда, если были удалены заглавы (#URL) двух закладок (блоков) идущих подряд, то он удаляет иногда и ту закладку которая идёт выше этих двух. Может всё же как то можно чтобы уже сразу весь блок удалять?
Сказал же, другого не будет :) ... Лучше воспользоваться твоим утверждением о фиксированном формате блока и чуть переделать существующий:
1. перенес IF в код функции - это необязательно, но оптимизирует поиск дублей,
2. добавил удаление остальных строк блока (в обратном порядке!).
Код:

#include <File.au3>

$File = "c:\test.txt"

Dim $FileLines
_FileReadToArray ($file, $FileLines)
; Возвращаем массив из дублирующихся записей
$DupLines = _DupURLsInArray ($FileLines)
; Страховка от пустого массива если дублей нет
If $DupLines [0][0] >0 Then
        For $i=$DupLines [0][0] To 1 Step -1
                _FileWriteToLine ($File, $DupLines [$i][0] +3, "", 1)
                _FileWriteToLine ($File, $DupLines [$i][0] +2, "", 1)
                _FileWriteToLine ($File, $DupLines [$i][0] +1, "", 1)
                _FileWriteToLine ($File, $DupLines [$i][0]  , "", 1)
                _FileWriteToLine ($File, $DupLines [$i][0] -1, "", 1)
                _FileWriteToLine ($File, $DupLines [$i][0] -2, "", 1)

                _FileWriteToLine ($File, $DupLines [$i][0] -3, "", 1)
                _FileWriteToLine ($File, $DupLines [$i][0] -4, "", 1)
        Next
EndIf

; Возвращает двумерный массив со счетчиком, содержащий только дубли
Func _DupURLsInArray (ByRef $array)
        Local $i, $i, $res [1][2] = [[0,0]]
        ; рабочий массив для отметки обработанных дублей
        Local $flags [$array [0] +1]
        For $i=1 To $array [0]
                If StringLeft ($array [$i],5) = @TAB & "URL=" Then
                        For $j=$i+1 To $array [0]
                                If $flags [$j] <> 1 Then
                                        If $array [$i] = $array [$j] Then
                                                ReDim $res [$res [0][0]+2][2]
                                                $res [0][0] = $res [0][0] +1
                                                $res [$res [0][0]][0] = $j
                                                $res [$res [0][0]][1] = $array [$j]
                                                $flags [$j] = 1
                                        EndIf
                                EndIf
                        Next
                EndIf
        Next
        Return $res
        _ArraySort ($res, 0, 1, 0, 2)
EndFunc

Цитата:

чтобы за каждое твоё оставленное сообщение (пусть даже по всему форуму), автоматом оно обозначалось бы как “Полезное сообщение” - оно так и есть
не переживай - это пройдет... :)

Creat0R 09-11-2006 10:20

1 вложений
amel27
Тоже есть трабла :( .

Оказывается :) , иногда некоторых пунктов в этом блоке нету\есть, они не присутствует\присутствуют в том случае, либо, если у закладки нет\есть описании (DESCRIPTION), либо нет\есть код посещения (VISITED=), либо нет\есть код активвности (ACTIVE=). Вот как выглядит самый полный блок (т.е больше этих пунктов нет) :

Код:

#URL
        ID=1
        NAME=AutoIt скрипты .:[общие вопросы]:.
        URL=http://forum.oszone.net/post-508967.html
        CREATED=1163050009
        VISITED=1163050722
        DESCRIPTION=AutoIt скрипты .:[общие вопросы]:.
        ICONFILE=forum.oszone.net.gif
        ACTIVE=YES

А вот как будет выглядеть блок с минимальными пунктами (меньше чем это не может быть) :


Код:

#URL
        ID=21
        NAME=Yahoo!
        URL=http://www.yahoo.com/
        CREATED=1163050735
        ICONFILE=www.yahoo.com.ico

Я бы конечно мог просчитать все варианты, т.е если есть допустим пункт DESCRIPTION=, и нету пункта VISITED=, то делаем одно действие, а если есть первое и нет второго, то делаем другое, и т.д... но это получится слишком громоздко, вот начало этого...

Код:

For $i=$DupLines [0][0] To 1 Step -1
        If StringLeft(FileReadLine($File, $DupLines [$i][0] +3), 13) = @TAB & "DESCRIPTION=" and StringLeft(FileReadLine($File, $DupLines [$i][0] +2), 9) = @TAB & "VISITED=" Then
                _FileWriteToLine ($File, $DupLines [$i][0] +4, "", 1)
                _FileWriteToLine ($File, $DupLines [$i][0] +3, "", 1)
                _FileWriteToLine ($File, $DupLines [$i][0] +2, "", 1)
                _FileWriteToLine ($File, $DupLines [$i][0] +1, "", 1)
                _FileWriteToLine ($File, $DupLines [$i][0]  , "", 1)
                _FileWriteToLine ($File, $DupLines [$i][0] -1, "", 1)
                _FileWriteToLine ($File, $DupLines [$i][0] -2, "", 1)
                _FileWriteToLine ($File, $DupLines [$i][0] -3, "", 1)
                _FileWriteToLine ($File, $DupLines [$i][0] -4, "", 1)
        ElseIf StringLeft(FileReadLine($File, $DupLines [$i][0] +2), 13) = @TAB & "DESCRIPTION=" and StringLeft(FileReadLine($File, $DupLines [$i][0] +5), 8) = @TAB & "ACTIVE="
                _FileWriteToLine ($File, $DupLines [$i][0] +5, "", 1)
                _FileWriteToLine ($File, $DupLines [$i][0] +4 "", 1)
                _FileWriteToLine ($File, $DupLines [$i][0] +3, "", 1)
                _FileWriteToLine ($File, $DupLines [$i][0] +2, "", 1)
                _FileWriteToLine ($File, $DupLines [$i][0] +1, "", 1)
                _FileWriteToLine ($File, $DupLines [$i][0]  , "", 1)
                _FileWriteToLine ($File, $DupLines [$i][0] -1, "", 1)
                _FileWriteToLine ($File, $DupLines [$i][0] -2, "", 1)
                _FileWriteToLine ($File, $DupLines [$i][0] -3, "", 1)
                _FileWriteToLine ($File, $DupLines [$i][0] -4, "", 1)
        EndIf
Next

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

amel27 09-11-2006 12:57

Creat0R
Цитата:

Тоже есть трабла
на то и вышло... :) чтобы удалить блок нужно определить его конец и начало:
Код:

#include <File.au3>
#include <Array.au3>

$File = "c:\test.txt"

Dim $FileLines
_FileReadToArray ($file, $FileLines)
; Возвращаем массив из дублирующихся записей
$DupLines = _DupURLsInArray ($FileLines)
; Страховка от пустого массива если дублей нет
If $DupLines [0][0] >0 Then
    For $i=$DupLines [0][0] To 1 Step -1
        ; ищем начало следующего блока
        $iNext = _ArraySearch ($FileLines, "#URL", $DupLines [$i][0])
        ; если не нашли, то конец файла
        If @Error=6 Then $iNext=_FileCountLines ($File) +1
        Do
            $iNext=$iNext-1
            _FileWriteToLine ($File, $iNext, "", 1)
        Until $FileLines [$iNext] = "#URL"
    Next
EndIf

EDIT: исправил ошибку с уловием (выделено красным), спутал с функцией _ArrayBinarySearch

Creat0R 10-11-2006 00:21

amel27
Удаляются не все дублирующиеся блоки :( - и как ни странно, не удалился дубль именно закладки этого поста :) (эксперементировал на прикреплённом мной раньше файле).

amel27 10-11-2006 09:32

Creat0R
Цитата:

Удаляются не все дублирующиеся блоки
ёлы-палы, такую грубую ошибку прозевал!... :blush: функция _DupURLsInArray возвращала неотсортированные данные, а это как известно перепутывает индексы при удалении, профиксил.

Ладно, коли такое дело :) переделал функцию - теперь она возвращает начало и конец продублированных блоков (от содержания строки отказался, т.к. невостребовано). Далее - предыдущий вариант страдал нелогичностью по отношению к операциям ввода-вывода, то смотрим в массив, то в файл.... зачем тогда было его загружать?.. Поэтому все операции с файлом (в т.ч. удаление строк) переделал для массива, в заключении готовый массив выгружается поверх старого файла:
Код:

#include <File.au3>
#include <Array.au3>

$File = "c:\test.txt"

Dim $FileLines
_FileReadToArray ($file, $FileLines)
; Возвращаем данные о дублирующихся блоках
$DupLines = _DupBLKsInArray ($FileLines, '#URL', @TAB & 'URL=')
; Страховка от пустого массива если дублей нет
If $DupLines [0][0] >0 Then
    For $i=$DupLines [0][0] To 1 Step -1
        For $j=$DupLines [$i][1] To $DupLines [$i][0] Step -1
            _ArrayDelete ($FileLines, $j)
        Next
    Next
    _FileWriteFromArray($File, $FileLines, 1)
EndIf

; Возвращает отсортированный двумерный массив со счетчиком, содержащий
; начало и конец продублированных блоков, в качестве параметров принимаются
; строки, отмечающие начало блока и начало ключевой строки
Func _DupBLKsInArray (ByRef $array, $BlkStartLine, $BlkKeyLine)
    Local $i, $i, $BlkStart, $res [1][2] = [[0,0]]
    Local $BlkStartLen= StringLen ($BlkStartLine)
    Local $BlkKeytLen = StringLen ($BlkKeyLine)
    ; рабочий массив для отметки обработанных дублей
    Local $flags [$array [0] +1]
    For $i=1 To $array [0]
        If StringLeft ($array [$i], $BlkKeytLen) = $BlkKeyLine Then
            For $j=$i+1 To $array [0]
                If StringLeft ($array [$j], $BlkStartLen) = $BlkStartLine Then
                    ; отмечаем начало текущего блока
                    $BlkStart = $j
                    ; если у текущего дубля нет конца, значит это он и есть
                    If $res [$res [0][0]][1] =0 Then $res [$res [0][0]][1] = $BlkStart -1
                EndIf
                If $flags [$j] <> 1 Then
                    If $array [$i] = $array [$j] Then
                        ReDim $res [$res [0][0]+2][2]
                        $res [0][0] = $res [0][0] +1
                        ; вспоминаем начало текущего блока
                        $res [$res [0][0]][0] = $BlkStart
                        $res [$res [0][0]][1] = 0
                        $flags [$j] = 1
                    EndIf
                EndIf
            Next
            ; если конца до сих пор не нашли, значит этот блок последний
            If $res [$res [0][0]][1] =0 Then $res [$res [0][0]][1] = $j-1
        EndIf
    Next
    ; сортировка массива по возрастанию
    _ArraySort ($res, 0, 1, 0, 2)
    Return $res
EndFunc


TERMINAL 10-11-2006 12:20

:help: :help: :help: H E L P ! ! ! :help: :help: :help:
Написал кучу скриптов с помощью AutoIt и тут вдруг обновляется Dr.WEB и начинает запрещать работать с этим прекрасным редактором.
Начал проверять свои рабочие скрипты-на половину все заражённые вирусом BackDoor.Hengto :vampire:.Скачал с оф.сайта опять эту прогу-проверил (в ней вирусы зашиты). Так почему же тогда раньше ВЕБ не кричал и почему не все тогда скрипты заражены??!! или у меня на компе просто глюк???

XXXler 10-11-2006 14:52

TERMINAL, у меня Nod32 одно время обзывал скрипт для генерации Inf как Trojan.Autoit.A - потом прошло... Хотя хз, мож ты чего-то и хватанул

Sanja Alone 10-11-2006 14:58

TERMINAL
Цитата:

в ней вирусы зашиты
Нет в AutoIt вируса (для очистки совести проверил Dr.Web-ом, обновленным сегодня). Это у тебя на компе зараза поселилась и уже расползается...

Цитата:

почему не все тогда скрипты заражены
Ну, наверное здоровые скрипты ты компилировал до заражения компа вирусягой.

TERMINAL 10-11-2006 15:02

Да не должен подхватить-2 антивирусника стоят...
Облазил весь инет, попровирял разными антивирусниками-все отвечают что файл ОК - незаражон...,а ВЕБ орёт и блокирует.
Может это у него такая реакция на скрипт??????,правда он не может сказать что файл якобы ВОЗМОЖНЫЙ ВИРУС-просто берёт и блокирует....У кого то такое было????????просто хочется быть уверенным что это из-за скрипта, а не вирус...

TERMINAL 10-11-2006 15:41

Sanja Alone Я скачиваю повторно файл установки AutoIt с оф.сайта-начинаю устанавливать и ВЕБ начинает орать опять на установочные файлы.
НАРОД ПЛЗ !
Пришлите мне какой нибудь скрипт "ехе" упакованый с "au3" на trm6@mail.ru , а я его проверю....

Creat0R 11-11-2006 02:02

amel27
Всё работает как по маслу! Огромное Мерсий! :pray:

TERMINAL
У меня тоже на несколько закомпилированных скриптов, Dr.Web ругается на вирус BackDoor.Hengto - Наверно это из за структуры самого скрипта. Но это не значит что там есть вирус, это значит что Dr.Web (и ему подобные) не достаточно “умный” (при всё уважении к нему :) ), чтобы определить является ли это действительно вирусром, и просто напросто перестроаховывается. У меня стоит последний Kaspersky, он молчит, также молчат проверки online, так что это глюк в этой базе данных доктора ;) (имхо).

Creat0R 12-11-2006 23:58

amel27
Есть небольшая пролблема с функцией, которую ты написал для проверки подключённости к интернету :( ...

При проверке синтаксиса в SciTE, выдаётся ошибка, а именно, эта строка подчёркнута как ошибочная:

Код:

SetError(err.number)
Мне нужно чтобы в случае не подключения, функция лишь возвращала уровень ошибочности (@Error = 1), и чтобы также можно былло проверть, если @error = 1, значит вывожу сообщение (не в функции, а в теле скрипта), и в нём сообщаю о том какая ошибка произошла (значение ошибки должно тоже возвращаться из функции).

amel27 13-11-2006 13:26

Creat0R
опечатку исправил... только почему-то на моем компе она перестала работать - вываливает ошибку таймаута и все тут, хотя точно знаю что все работало!... уже и PROXYCFG проверил - ничего не помогает... ладно, сейчас некогда ковыряться может позже разберусь в чем причина.
Цитата:

если @error = 1, значит вывожу сообщение (не в функции, а в теле скрипта), и в нём сообщаю о том какая ошибка произошла (значение ошибки должно тоже возвращаться из функции)
Обычно делается так: в норме функция возвращает "0" или там еще что по контексту, если ошибка то "-1" или типа того, при необходимости номер ошибки можно восстановить через @error. Это особенно удобно если функция по задумке должна возвращать полезную информацию - в этом случае возможности передать тип ошибки весьма ограничены...

Creat0R 14-11-2006 03:22

amel27
Если я сделаю так (см. ниже), будет ли это являться корректной проверкой подключения?

Код:

;Установка функции перехвата COM-ошибок
 $oMyError = ObjEvent("AutoIt.Error","MyErrFunc")

 If IsNotConnect() Then MsgBox (48,"Проверка связи","Интернет-соединение отсутствует по причине:" & @CRLF & $oMyError.description)

;Функция проверки на отсутствие соединения
 Func IsNotConnect()
    Local $oHTTP=ObjCreate("winhttp.winhttprequest.5.1")
    $oHTTP.Open("GET","http://www.google.com")
    $oHTTP.Send()

    Return @error
 EndFunc

;Обработчик COM-ошибок
Func MyErrFunc()
    Select
        Case $oMyError.source = "WinHttp.WinHttpRequest"
            SetError($oMyError.number)
        Case Else
            Return $oMyError.description
    EndSelect
Endfunc


P.S:

Просто интересно, как ты разукрасил код скрипта? :) неужели каждую команду (и разделители) обрамлял тегом цветов и выделения?

amel27 14-11-2006 07:21

Creat0R
Если речь про функцию MyErrFunc () то она построена некорректно, посуди сам что выходит: если ошибку вызвал модуль "WinHttp.WinHttpRequest" - устанавливаем только код ошибки и ничего не возвращаем, а если любой другой - только возвращаем текст ошибки... Если скрипт не отслеживает другие возможные ошибки кроме HTTP и тебе нужен не только номер, но и текст ошибки лучше сделать иначе
Код:

;Установка функции перехвата COM-ошибок
$oMyError = ObjEvent("AutoIt.Error","MyErrFunc")
; ...

;Обработчик COM-ошибок
Func MyErrFunc()
    SetError($oMyError.number)
    Return $oMyError.description
Endfunc

... Хотя учитывая, что с одной стороны эта функция единственная для всех возможных событий, а с другой - коды ошибок для любого модуля вполне известны, ключевой информацией является не текст ошибки, а ее номер и источник. Исходя из этой инфы и строятся обработчики ошибок - внутри самой функции MyErrFunc () или в других местах...

P.S. шалость удалась (c) :) ... конечно скриптом - больше ради прикола чем по необходимости,
заодно разобрался с тегами форума и погонял функции StringRegExp*, если есть интерес то могу запостить...
на самом деле все гораздо проще чем кажется. ;)

Creat0R 14-11-2006 09:25

amel27
В принципе, мне не нужен код ошибки, нужно только описание, т.е если и была ошибка (не важно какая), то нужно сообщать что она была, и по возможности выводить описание этой самой ошибки. И как я понял, используя пример из кода твоего поста (последнего), это оптимальное решение.
Если честно, я смутно понимаю всю работу этой функции, для меня вообще много что связанно с интернетом, пока не очень ясно, я в сети не более полу года нахожусь, и тем более что тут не только о самих понятиях интернета идёт речь, но ещё и о модулях, о которых я только начинаю что то узнавать.

Цитата:

если есть интерес то могу запостить
Конечно есть - Я открыл соответствующий раздел в справке, но мне сразу захотелось её (справку) закрыть. Очень там всё страшно для меня (пока?). Буду благодарен если направиш меня на путь верный :) - У меня получилось корректировать только скобки, точки, запятые, и знаки разделителей и ровно...


Код:

$File = @ScriptFullPath
$FileContent = FileRead($File, FileGetSize($File))

$Result = StringRegExpReplace($FileContent, "[=]", "[color=red]=[/color]")
$Result = StringRegExpReplace($Result, "[(]", "[color=red]([/color]")
$Result = StringRegExpReplace($Result, "[)]", "[color=red])[/color]")
$Result = StringRegExpReplace($Result, "[.]", "[color=red].[/color]")
$Result = StringRegExpReplace($Result, "[,]", "[color=red],[/color]")
$Result = StringRegExpReplace($Result, "[&]", "[color=red]&[/color]")


MsgBox(0, "", $Result)

FileWrite($File & ".res", $Result)


amel27 14-11-2006 11:31

1 вложений
Creat0R
По поводу раскраски кода (поскольку это решение на AutoIT то имхо не оффтоп) ... Замечу, что лобовое решение требует последовательного разбора всего текста кода по словарю, а это слишком большой объем работ... Но зачем изобретать велосипед, если SciTE4 уже делает это и весьма успешно? Одна из его возможностей - экспорт кода в HTML/XML-формат с сохранением всех стилей, осталось только определить соответствия между стилями XML и форума и произвести замену. Поэтому обработка проходит в два шага: экспорт кода в XML-файл и последующая обработка его скриптом - содержимое полученного TXT-файла (уже с тегами кода) можно публиковать в форуме. Поскольку текст скрипта напичкан всевозможными тегами вынужден прикрепить его отдельным файлом...

P.S. Как видно из текста скрипта я определил еще не все стили (например пропущены 2, 10, 12, 13) и наверняка не все спецсимволы... они мне просто еще не попадались, на этот случай я оставил проверку на полноту замены... если кто обнаружит их раньше просьба сообщить в личку.

линк: http://www.sendspace.com/file/wjwk9r
--------
нормальные герои всегда идут в обход (c) :)

Creat0R 15-11-2006 01:25

amel27
Файл не скачивается :( - т.е скачивается, но архиватор ругается на то что архив повреждён... может зальёшь на http://www.sendspace.com/ - и\или мне на мыло?

Sanja Alone 15-11-2006 02:48

Отвечаю на повторяющийся по мылу вопрос. Итак, "Как же определить букву дисковода по маркерному файлу?"
  1. Способ "В лоб":
    Код:

    $TagFile="маркерный файл"
    $i = 67
    While FileExists( Chr($i) & ":\" & $TagFile )=0 AND $i<=90
        $i = $i + 1
    WEnd
    ;искомый дисковод (буква с двоеточием)
    $drive=$i & ":"

  2. Способ "В лоб, но с размышлением :)":
    Код:

    $TagFile="маркерный файл"
    ;на какого типа дисководах искать маркерный файл
    ;возможные варианты: "ALL", "CDROM", "REMOVABLE", "FIXED", "NETWORK", "RAMDISK", или "UNKNOWN"

    $type="CDROM"
    $drvlst=DriveGetDrive ( $type )
    If not @error Then
        For $i = 1 to $drvlst[0]
            If FileExists( $drvlst[$i] & "\" & $TagFile ) Then
                ;искомый дисковод (буква с двоеточием)
                $drive=$drvlst[$i]
                ExitLoop
            EndIf
        Next
    EndIf

Ес-но, это далеко не все возможные варианты. В зависимости от исходных данных, для решения подобной задачи, весьма полезными могут оказаться ф-ции DriveGetLabel, DriveGetFileSystem, DriveGetSerial, DriveGetType, DriveStatus.

Lodoss 16-11-2006 19:05

2amel27
Цитата:

Зато теперь можно смело замахнуться на всю линейку NetApi32
(страница 44)
весь сыр бор был из-за GUI авторизации запуска от имени админа.

повторю задачу:
1.Требуется запустить какой либо setup.exe, если пользователь не админ - нарисовать GUI с полем имени и пароля для авторизации запуска (конечно можно воспользоваться стандартным запуском нажав shift но хочется реализовать задачу при помощи AutoIt)
2.В комбо боксе приводим список учёток обладающими правами для установки т. е. админов
3.При неправильном вводе пароля - выдать сообщение об ошибке НЕ закрыв GUI
повторю код

Код:

#include <GUIConstants.au3>
Opt("RunErrorsFatal",0)
;что запускать
$what_to_run="setup.exe"
If IsAdmin() Then
        ;запуск программы
        Run($what_to_run)
Else
        ;если не админ, то "рисуем" GUI
        _GUI()
EndIf
Func _GUI()
GUICreate("Авторизация", 198, 125)
;фон окна
GUISetBkColor (0x00E0FFFF)
;лейблы
GUICtrlCreateLabel("Имя администратора", 25, 5)
GUICtrlCreateLabel("Пароль администратора", 25, 50)
;запуск и отмена скрипта
$ok = GUICtrlCreateButton("Ok", 25, 98, 70,20)
$cancel = GuiCtrlCreateButton ("Cancel",105,98,70,20)
;ввод имени
$us = @UserName
$in1 =GUICtrlCreateCombo ($us, 25, 25, 150, 20)
GUICtrlSetData($in1, "admin|qwerty|Администратор|Винни-Пух")
GUICtrlSetTip(-1,"введите имя любой учётной записи" & @CRLF & "имеюшей права Администратора")
;ввод пароля
$in2 = GUICtrlCreateInput ("solo11",  25, 70, 150, 20, 0x20)
GUICtrlSetTip(-1,"введите пароль")
GUISetState(@SW_SHOW)
While 1
$msg = GUIGetMsg()
;считываем введённые данные
$out1 = GUICtrlRead($in1)
$out2 = GUICtrlRead($in2)
Global $user = $out1, $pass = $out2
Select
        Case $msg = $ok
                ;инициализация запуска от имени админа
                RunAsSet($user, "", $pass)
                ;проверка верны ли введённые записи на право обладания правами админа
                if IsAdmin() Then
                        ;запуск программы
                        Run($what_to_run)
                        If @error Then
                                MsgBox(16, "Ошибка", "Введен неправильный пароль или отсутствует файл "&$what_to_run&@LF&@LF&"Попробуйте еще раз.",5)
                        EndIf
EndIf
                ;закрытие окна
        Case $msg = $cancel
                ExitLoop
    Case $msg = $GUI_EVENT_CLOSE
                ExitLoop
EndSelect
WEnd
EndFunc

третий пункт не выполняется :(
PS с оболочками только только начал разбираться, многое не понимаю. Помогите PLS

Creat0R 16-11-2006 20:57

Lodoss
Цитата:

третий пункт не выполняется
Что значит не выполняется? не выводится сообщение?

Вот немного изменил - добавил проверку (отдельную) на проавильность ввода пароля (это при условии что пароль заранее известен):

Код:

#include <GUIConstants.au3>
Opt("RunErrorsFatal",0)
;что запускать
$what_to_run="setup.exe"

If Not IsAdmin() Then
    ;запуск программы
    Run($what_to_run)
Else
    ;если не админ, то "рисуем" GUI
    _GUI()
EndIf

Func _GUI()
    GUICreate("Авторизация", 198, 125)
    ;фон окна
    GUISetBkColor (0x00E0FFFF)
    ;лейблы
    GUICtrlCreateLabel("Имя администратора", 25, 5)
    GUICtrlCreateLabel("Пароль администратора", 25, 50)
    ;запуск и отмена скрипта
    $ok = GUICtrlCreateButton("Ok", 25, 98, 70,20)
    $cancel = GuiCtrlCreateButton ("Cancel",105,98,70,20)
    ;ввод имени
    $us = @UserName
    $in1 =GUICtrlCreateCombo ($us, 25, 25, 150, 20)
    GUICtrlSetData($in1, "admin|qwerty|Администратор|Винни-Пух")
    GUICtrlSetTip(-1,"введите имя любой учётной записи" & @CRLF & "имеюшей права Администратора")
    ;ввод пароля
    $in2 = GUICtrlCreateInput ("solo11",  25, 70, 150, 20, 0x20)
    GUICtrlSetTip(-1,"введите пароль")
    GUISetState(@SW_SHOW)

    While 1
        $msg = GUIGetMsg()
        ;считываем введённые данные
        $out1 = GUICtrlRead($in1)
        $out2 = GUICtrlRead($in2)
        Global $user = $out1, $pass = $out2

                Select
            Case $msg = $ok
                ;инициализация запуска от имени админа
                RunAsSet($user, "", $pass)
                ;проверка верны ли введённые записи на право обладания правами админа
                If IsAdmin() Then
                    ;проверка правильноти пароля
                    If $pass <> "solo11" Then
                        MsgBox(16, "Ошибка", "Введен неправильный пароль"&@LF&@LF&"Попробуйте еще раз.",5)
                        ContinueLoop
                    EndIf
                    ;запуск программы
                    Run($what_to_run)
                    If @error Then
                        MsgBox(16, "Ошибка", "Отсутствует файл "&$what_to_run&@LF&@LF&"Попробуйте еще раз.",5)
                        ContinueLoop
                    EndIf
                EndIf
            ;закрытие окна
            Case $msg = $cancel or $msg = $GUI_EVENT_CLOSE
            ExitLoop
        EndSelect
    WEnd
EndFunc


Creat0R 17-11-2006 01:20

amel27
Класный скрипт, как видно в посте чуть выше, я его уже приминил :) - Я тут немного повазился, и немного автоматизировал этот процесс, так что вот, залил ;)



ПРИМЕЧАНИЕ: После завершения обработки, в первую и вторую строку самого скрипта, прописываются пути к файлу обработки (*.xml) и к выходному файлу (*.txt), и при повторном запуске скрипта, эти значения будут подставляться в соответствующие поля, так что эти строки лучше не трогать (для удобства).

Можно было бы ещё лучше автоматизировать этот процесс, если бы можно было автоматичкский экспортировать указанный скрипт в *.xml формат - может можно как то задать параметры для SciTE, чтобы там в тихом режиме указанный файл экспортировался в нужный формат? Тогда можно было бы сразу указывать скрипт (*.au3), и всё бы происходило автоматом - минимальное вмешательство юзера ;)

Lodoss 17-11-2006 07:17

Цитата:

Вот немного изменил - добавил проверку (отдельную) на проавильность ввода пароля (это при условии что пароль заранее известен):
Ни учётка администратора ни его пароль НЕ ДОЛЖНЫ быть прописаны в скрипте.
Это я тут в комбо списке написал "Администратор,admin.....так не должно быть. решение КАК выдать список учёток обладающими правами админа есть от amel27 (осталось только разобраться как это привинтить к комбо списку пользователей %) ) а пароль должен ввести только админ.

Цитата:

Что значит не выполняется? не выводится сообщение?
итак снова
1.заходим под обычным пользователем в систему если вводим правильные данные (админа)- запускается сценарий run("setup.exe")....
2.если вводим неправильный пароль то выдаётся сообщение "ошибка" и предлагается ввести пароль заново

в существующем сценарии ошибка выдаётся даже если правильно ввёл пароль и файл setup.exe существует
либо вообще ничего не происходит по нажатии кнопки ОК

Creat0R 17-11-2006 10:34

Lodoss
Вот рабочий (у меня) вариант (в нём уже включено помещение списка юзеров в combo) :

Код:

#include <Array.au3>
#include <GUIConstants.au3>
Opt("RunErrorsFatal",0)

;Узнаём список пользователей
$admins = _AdminUsers()

Dim $AdminList
;Подготавливаем список пользователей для использования в combo
If IsArray($admins) Then
  For $i = 1 to $admins[0]
          Do
                  $AdminList = $admins[$i] & "|" & $AdminList
          Until $admins[$i] <> $admins[0]
  Next
EndIf

;что запускать
$what_to_run="setup.exe"

If IsAdmin() Then
  ;запуск программы
    Run($what_to_run)
Else
    ;если не админ, то "рисуем" GUI
    _GUI()
EndIf

Func _GUI()
    GUICreate("Авторизация", 198, 125)
    ;фон окна
    GUISetBkColor (0x00E0FFFF)
    ;лейблы
    GUICtrlCreateLabel("Имя администратора", 25, 5)
    GUICtrlCreateLabel("Пароль администратора", 25, 50)
    ;запуск и отмена скрипта
    $ok = GUICtrlCreateButton("Ok", 25, 98, 70,20)
    $cancel = GuiCtrlCreateButton ("Cancel",105,98,70,20)
    ;ввод имени
    $us = @UserName
    $in1 =GUICtrlCreateCombo ($us, 25, 25, 150, 20)
    GUICtrlSetData($in1, $AdminList)
    GUICtrlSetTip(-1,"введите имя любой учётной записи" & @CRLF & "имеюшей права Администратора")
    ;ввод пароля
    $in2 = GUICtrlCreateInput ("",  25, 70, 150, 20, 0x20)
    GUICtrlSetTip(-1,"введите пароль")
    GUISetState(@SW_SHOW)

    While 1
        $msg = GUIGetMsg()
        ;считываем введённые данные
        $User = GUICtrlRead($in1)
        $Password = GUICtrlRead($in2)

                Select
                        Case $msg = $ok
                                ;Проверка был ли введён пароль вообще
                                If $Password = "" Then
                                        MsgBox(48, "Ошибка", "Не был введён пароль")
                                        ContinueLoop
                                EndIf
                               
                                ;инициализация запуска от имени админа
                                RunAsSet($User, "", $Password)
                                ;проверка верны ли введённые записи на право обладания правами админа
                                If IsAdmin() Then
                                        ;запуск программы
                                        Run($what_to_run)
                                       
                                        If @error Then
                                                MsgBox(16, "Ошибка", "Введен неправильный пароль или отсутствует файл "&$what_to_run&@LF&@LF&"Попробуйте еще раз.",5)
                                                ContinueLoop
                                        EndIf
                                        Exit
                                EndIf
            ;закрытие окна
            Case $msg = $cancel or $msg = $GUI_EVENT_CLOSE
                                ExitLoop
        EndSelect
    WEnd
EndFunc

; Возвращает массив со счетчиком - состав локальной группы "Администраторы"
Func _AdminUsers()
        Local $i, $res [1] = [0]
        ; читаем состав группы
        Local $members = _NetLocalGroupGetMembers (@ComputerName, 'Администраторы')
        ; проверка на ошибки
        If @error Then
                MsgBox (16, 'Ошибка выполнения', 'Код ошибки:' & @error)
                Exit
        EndIf
        If $members [0] >0 Then
                ; фильтруем только локальные учетные записи
                For $i=1 To $members [0]
                        If StringRegExp ($members [$i], '^' & @ComputerName & '\\') Then
                                ReDim $res [$res[0]+2]
                                $res [0] = $res [0]+1
                                $res [$res[0]] = StringRegExpReplace ($members [$i], '^' & @ComputerName & '\\', '')
                        EndIf
                Next
        EndIf
        Return $res
EndFunc

; Возвращает массив со счетчиком- состав локальной группы произвольного компьютера
Func _NetLocalGroupGetMembers($server, $group)
        Local $i, $string, $res [1] = [0], $pointer= DllStructCreate ("ptr")
        ; Выполняем запрос к базе SAM
        Local $ret = DllCall ("netapi32.dll", "int", "NetLocalGroupGetMembers", _
                "wstr", "\\" & StringRegExpReplace ($server, '^\\+', ''), _
                "wstr", $group, _
                "int", 3, _
                "ptr", DllStructGetPtr ($pointer), _
                "int", -1, _
                "int_ptr", 0, _
                "int_ptr", 0, _
                "int_ptr", 0 )
        ; Если произошла ошибка, то выход с кодом ошибки
        If $ret[0]>0 Then
                SetError ($ret)
                Exit
        EndIf
        ; Если есть результат, то обрабатываем каждый отдельно
        If $ret[6]>0 Then
                Local $buffer = DllStructCreate ("ptr[" & $ret[6] & "]", DllStructGetData ($pointer,1) )
                For $i=1 To $ret[6]
                        $ret = DllCall("kernel32.dll", "int", "WideCharToMultiByte", _
                                "int", 0, _
                                "int", 0, _
                                "ptr", DllStructGetData ($buffer, 1, $i), _
                                "int", -1, _
                                "str", "", _
                                "int", 0, _
                                "int", 0, _
                                "int", 0 )
                        $string = DllStructCreate("char[" & $ret[0] & "]")
                        $ret = DllCall("kernel32.dll", "int", "WideCharToMultiByte", _
                                "int", 0, _
                                "int", 0, _
                                "ptr", DllStructGetData ($buffer, 1, $i), _
                                "int", -1, _
                                "ptr", DllStructGetPtr ($string), _
                                "int", $ret[0], _
                                "int", 0, _
                                "int", 0 )
                        ReDim $res [$res[0]+2]
                        $res [0] = $res [0]+1
                        $res [$res[0]] = DllStructGetData ($string,1)
                Next
        EndIf
        ; Чистим временные системные структуры
        DllCall ("netapi32.dll", "int" ,"NetApiBufferFree", _
                "ptr" , DllStructGetData ($pointer,1) )
        Return $res
EndFunc


amel27 17-11-2006 12:28

Цитата:

решение КАК выдать список учёток обладающими правами админа есть от amel27
существенно обновил функцию _NetLocalGroupGetMembers, теперь если группа не включает доменных учеток достаточно вызвать функцию с параметрами:

_NetLocalGroupGetMembers ("Администраторы", "", 0, 1)

...справедливости ради приведу еще один вариант функции через COM (взял с форума AutoIT):
Код:

Func _NetLocalGroup ($HOST, $LocalGroup)
    Global $Members[1]
    $Administrators = ObjGet("WinNT://" & $HOST & "/" & $LocalGroup)
    $MemberList=$Administrators.Members
    for $Account in $MemberList
        $FullName=StringUpper(StringRight($Account.Parent, StringLen($Account.Parent)-8))
        if (StringRight($FullName, StringLen($HOST)+1))=("/" & StringUpper($HOST)) then
            $FullName=$Account.Name
        else
            $FullName=$FullName & "\" & $Account.Name
        EndIf
        ReDim $Members[UBound($Members) + 1]
        $Members[UBound($Members) - 1]=$FullName
    next
    $Members[0]=UBound($Members)-1
    Return $Members
EndFunc

P.S. предупреждаю, что через COM работает намного медленней!

Creat0R 18-11-2006 06:29

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

Код:

#include <File.au3>

_ReplaceTextInFiles(@ScriptDir & "\Test", "123", "321", "*.txt")

Func _ReplaceTextInFiles($Path, $OldText, $NewText, $Mask="*.*")
    $FileList = _FileListToArray($Path, $Mask)
    If IsArray($FileList) Then
        For $i = 1 to $FileList[0]
            _ReplaceStringInFile($Path & "\" & $FileList[$i], $OldText, $NewText)
        Next
    EndIf
EndFunc


Всё, нашёл свою ошибку :) - См. подчёркнуты текст в коде - Там было $NewText.

Craager 18-11-2006 15:22

Sanja Alone, а можешь обновить свой скрипт для CuteFTP 8.0.3 с новым патчем (165 кб который)! Очень надо )))

Sanja Alone 18-11-2006 19:43

Craager
Цитата:

можешь обновить свой скрипт
Скрипт работает и с этой версией и с упомянутым патчем. Нужно было просто попробовать произвести установку (и прочитать комментарии в "шапке" скрипта, по ум. патчем считается файл Crack.exe - это именно тот, 165Кб-товый).

Yozhegg 21-11-2006 18:21

в AutoIt как лучше захватить системную дату? Есть ли вообще такая возможность (не прибегая к хитростным изворотам и изворотливым ухищрениям?)

в идеале интересует дата в опр. формате (напр. YYYYMMDD или MMDDYY), для дальнейшего использования в качестве переменной.

Michail77 21-11-2006 23:45

Нужна помощь.
Вот скрипт.Автор его Creat0R за что ему ОГРОМНАЯ БЛАГОДАРНОСТЬ.
Нужно чтобы при отметке установки нескольких программ они запускались поочерёдно. Как это сделать?

Код:

#NoTrayIcon
#Include <GuiConstants.au3>
Opt("RunErrorsFatal", 0)

$Title = "Menu"

If WinExists($Title) Then Exit

GuiCreate($Title, 148, 300)

GUISetFont(13)
GUICtrlCreateLabel("Выбор комплектов",2, 5)

GUISetFont(9)
$Complect1 = GUICtrlCreateCheckbox("AcrReader 4.0.5", 35, 25)
$Complect2 = GUICtrlCreateCheckbox("Office 2003", 35, 50)
$Complect3 = GUICtrlCreateCheckbox("WinRar 3.61", 35, 75)
$Complect4 = GUICtrlCreateCheckbox("DIVX 5.11", 35, 100)
$Complect5 = GUICtrlCreateCheckbox("LightAlloy 4.0", 35, 125)
$Complect6 = GUICtrlCreateCheckbox("WINDVD 7", 35, 150)
$Complect7 = GUICtrlCreateCheckbox("WinAmp 5.08", 35, 175)
$Complect8 = GUICtrlCreateCheckbox("Nero 6.6.0.8", 35, 200)
$Complect9 = GUICtrlCreateCheckbox("DrWeb 4.33", 35, 225)
$Complect10 = GUICtrlCreateCheckbox("Kav 5.338", 35, 250)

$Next = GUICtrlCreateButton("Next>>", 0, 276, 50)
$Cancel = GUICtrlCreateButton("Cancel", 99, 276, 50)

GUISetState()

While 1
$Msg = GUIGetMsg()

Select
 
  Case $Msg = $Gui_Event_Close or $Msg = $Cancel
    Exit

  Case $Msg = $Next
        If GUICtrlRead($Complect1) <> 1 and GUICtrlRead($Complect2) <> 1 and GUICtrlRead($Complect3) <> 1 and GUICtrlRead($Complect4) <> 1 and GUICtrlRead($Complect5) <> 1 and GUICtrlRead($Complect6) <> 1 and GUICtrlRead($Complect7) <> 1 and GUICtrlRead($Complect8) <> 1 and GUICtrlRead($Complect9) <> 1 and GUICtrlRead($Complect10) <> 1 Then
                GUISetState(@SW_DISABLE)
                MsgBox(262144+48, "Attention", "Выберите как минимум одну птичку ;-)")
                GUISetState(@SW_ENABLE)
                WinActivate($Title, "")
                ContinueLoop
        EndIf

    If GUICtrlRead($Complect1) = $Gui_Checked Then
                Run ("AcrReader\Acrobat.exe")
                If @error Then
                  MsgBox(48, "error", "Не могу запустить <Acrobat.exe>")
                  ContinueLoop
                EndIf
  ;Тут должна выполняться установка комплекта № 1
    EndIf
   
    If GUICtrlRead($Complect2) = $Gui_Checked Then
                Run ("Office\AutoOffice.exe")
                If @error Then
                        MsgBox(48, "error", "Не могу запустить <AutoOffice.exe>")
                        ContinueLoop
                EndIf
        ;Тут должна выполняться установка комплекта № 2
    EndIf
   
    If GUICtrlRead($Complect3) = $Gui_Checked Then
                Run ("WinRar\Autowinrar.exe")
                If @error Then
                        MsgBox(48, "error", "Не могу запустить <AutoWinRar.exe>")
                        ContinueLoop
                EndIf
        ;Тут должна выполняться установка комплекта № 3
    EndIf

    If GUICtrlRead($Complect4) = $Gui_Checked Then
                Run ("DIVX\DivX511.exe")
                If @error Then
                        MsgBox(48, "error", "Не могу запустить <DivX.exe>")
                        ContinueLoop
                EndIf
        ;Тут должна выполняться установка комплекта № 4
    EndIf

    If GUICtrlRead($Complect5) = $Gui_Checked Then
                Run ("LightAlloy\LA.exe")
                If @error Then
                        MsgBox(48, "error", "Не могу запустить <LA.exe>")
                        ContinueLoop
                EndIf
        ;Тут должна выполняться установка комплекта № 5
    EndIf

    If GUICtrlRead($Complect6) = $Gui_Checked Then
                Run ("WINDVD\AutoWINDVD7.exe")
                If @error Then
                        MsgBox(48, "error", "Не могу запустить <AutoWinDVD.exe>")
                        ContinueLoop
                EndIf
        ;Тут должна выполняться установка комплекта № 6
    EndIf

    If GUICtrlRead($Complect7) = $Gui_Checked Then
                Run ("WinAmp\AutoWinAmp.exe")
                If @error Then
                        MsgBox(48, "error", "Не могу запустить <AutoWinAmp.exe>")
                        ContinueLoop
                EndIf
        ;Тут должна выполняться установка комплекта № 7
    EndIf

    If GUICtrlRead($Complect8) = $Gui_Checked Then
                Run ("Nero\Nero6608a.exe")
                If @error Then
                        MsgBox(48, "error", "Не могу запустить <Nero.exe>")
                        ContinueLoop
                EndIf
        ;Тут должна выполняться установка комплекта № 8
    EndIf

    If GUICtrlRead($Complect9) = $Gui_Checked Then
                Run ("DrWebAut\AutoDrWeb.exe")
                If @error Then
                        MsgBox(48, "error", "Не могу запустить <AutoDrWeb.exe>")
                        ContinueLoop
                EndIf
        ;Тут должна выполняться установка комплекта № 9
    EndIf

    If GUICtrlRead($Complect10) = $Gui_Checked Then
                Run ("kav\AutoKav.exe")
                If @error Then
                        MsgBox(48, "error", "Не могу запустить <AutoKav.exe>")
                        ContinueLoop
                EndIf
        ;Тут должна выполняться установка комплекта № 10
    EndIf

        GUISetState(@SW_HIDE)

ExitLoop

EndSelect

Wend


Sanja Alone 22-11-2006 01:21

Yozhegg
Цитата:

дата в опр. формате (напр. YYYYMMDD или MMDDYY)
Просто возьми макросы даты/времени и поставь в нужной тебе последовательности:
Код:

@SEC        - Значение секунд на часах. От 00 до 59
@MIN        - Значение минут на часах. От 00 до 59
@HOUR        - Значение часов на часах в 24-часовом формате. От 00 до 23
@MDAY        - Текущий день месяца. От 01 до 31
@MON        - Текущий месяц. От 01 до 12
@YEAR        - Текущий год в четырехзначном формате
@WDAY        - День недели в числовом представлении. От 1 до 7 - от воскресенья до субботы
@YDAY        - Текущий день года. От 1 до 366 (или 365 для невисокосного года)

Вот тебе пример - дата в виде YYYYMMDD:
Код:

MsgBox (0,"Текущая дата",@YEAR & @MON & @MDAY)

Yozhegg 22-11-2006 17:14

To Sanja Alone: Благодарю за ответ. Спустя 24 часа оценил некоторую поспешность вопроса. Покопавшись в хелпе нашёл эти макросы, но меня смущало отсутствие
возможности форматирования.. мне нужно было (ГГММДД)...

Код:

Global $y = @YEAR
Global $mon = @MON
Global $mday = @MDAY 
Global $e_year = @YEAR - 2000 
Global $_Total = (0 & $e_year & $mon & $mday )

- коряво, но в моём случае работает.

Yozhegg 22-11-2006 17:30

А как в AutoIt снять показание с RadioButton(OptionButton)?

Ischecked -это параметр, или макрос, которым можно проверить отмечена радиокнопка 1 или радиокнопка 2?

Sanja Alone 23-11-2006 00:54

Yozhegg
Цитата:

смущало отсутствие возможности форматирования
См. в сторону ф-ции StringFormat ( "format control", var1 [, ... var32] ).

Цитата:

как в AutoIt снять показание с RadioButton
Код:

If BitAnd(GUICtrlRead($Radio_1),$GUI_CHECKED) Then
        msgbox(0,"","Отмечена кнопка 1")
Else
        msgbox(0,"","Кнопка 1 НЕ отмечена")
EndIf

Цитата:

Ischecked -это параметр, или макрос
Это переменная, описывающая состояние н-рого эл-та управления.

Creat0R 24-11-2006 12:39

Michail77
Цитата:

чтобы при отметке установки нескольких программ они запускались поочерёдно. Как это сделать?
Очень просто :) ... нужно вместо Run (запуска приложения), прописать RunWait (Запуск приложения с ожиданием его завершения). Т.е просто везде где у тебя в скрипте есть Run(....) Замени на RunWait(...).

И ещё, если установка того или иного приложения, “запускает” внешние модули\приложения, то нужно определить какие именно, т.е какие процессы, или окна появляются, и в соответствии с этим делать проверку на окончание процесса установки. Если же всё обходится (заканчивается) одним процессом (не запуская внешние\дополнительные процессы\окна), то досаточно того метода который я упомянул чуть выше.

----------------------
2 ALL

Есть такая проблема - Я хочу сделать проверку на нажатие определённой клавиши, кнопки мышки, или любого другого действия со стороны пользователя. Известно что есть функция _IsPressed - Но она проверяет каждый раз ввод\нажатие одной клавиши\кнопки, а мне нужно чтобы проверялось любое вхождение при одной (или даже нескольких) проверке... я сделал это для нескольких вхождении, но предусмотреть все, мне не удалось...

Код:

For $i = 01 to 91
    If _IsPressed($i, $dll) Then
        ........
    EndIf
Next

Хотелось чтобы были предусмотрены все нажатия на клавиатуре и на мышке, но, кроме одного - SHIFT (с обоих сторон).

----------------------
P.S

Переделал полностью (кроме самой главной функции от amel27) скрипт для перекодировки скриптов в целях помещения их в форуме (в разукрашенном виде :) )... получилось полностью автоматизировать весь процессс - теперь не нужно самому экспортировать скрипт au3 в xml формат, это сделает автоматический сам скрипт, нужно всего лишь указать файл скрипта (*.au3), и в процессе (до процесса) обработки, он будет экспортирован в xml формат - Для этого редактор SciTE должен быть в дефолтной папке AutoIt'а, т.е путь берётся относительно @AutoItExe:
Код:

$SciTEPath = StringTrimRight(FileGetShortName(@AutoItExe), StringLen(StringRegExpReplace(@AutoItExe, "^.*\\", ""))) & "SciTE\SciTE.exe"
Также вместо того, чтобы открывать файл с результатом, результат выводится в гуи (в Edit поле), а также есть возможность очистить результат (не закрывая гуи), и выбрать другой скрипт для обработки... имхо, получилось довольно оригинально!

И ещё, теперь данные для последнего используемого скрипта (и файла в который будет помещён результат), вписываются в конец самого скрипта, и считываются как с файла конфигурации (*.ini), мне кажется так надёжнее. Так что компилировать скрипт нет смысла, а если есть желание, то лучше исключить из скрипта эту функцию.

Скачать архив со скриптом можно тут

Michail77 24-11-2006 21:51

2 Creat0R
БИГ СЕНКС.
И ещё вопросик.как запустить на установку файл *msi. речь идёт про касперского антивирус 6.0.300
с 5х проблем не было. run-ом всё нормально ставилось а тут....

Sanja Alone 25-11-2006 01:13

Michail77
Цитата:

как запустить на установку файл *msi
В начале темы это уже обсуждалось - посты #79, #80, #82, #89, #90. Если запуск будет производиться в тихом режиме, то нужно исп-ть RunWait вместо Run.

P.S. Не забываем юзать поиск по теме...

Michail77 26-11-2006 13:41

2 Creat0R
Спасибо.
Приведи пожалуйста пример с “запускает” внешние модули\приложения...

2 Sanja Alone
Спасибо,помогло.

Creat0R 27-11-2006 17:30

Michail77
Цитата:

пример с “запускает” внешние модули\приложения...
Просто имел в виду, что нужно убедиться, что запущенный тобой процесс (екзешник к примеру), не запускает другие процессы. Т.е например, ты запускаешь Setup.exe, запустил допустим так - RunWait("Setup.exe", "", @SW_HIDE), но этот установщик построен так, что на каком то этапе, он запускает какой то внутренний его процесс (заранее распоковав файлы во временный каталог), а сам закрывается, и тогда скрипт будет “считать” что запущены им процесс окончен, и не будет “ждать”, ведь ему не известно что запустился другой процесс... поэтому желательно проверить так ли это (просто запусти нужный установщик, и смотри в менеджере процессов какие дополнительные процессы запускаются), и если да, то нужно соответственно прописать определение в скрипте...

Код:

RunWait("Setup.exe", "", @SW_HIDE) ;Запуск главного установщика
ProcessWait("Имя_допол._процесса", 120) ;Ожидание дополнительного процесса (120 секунд) - это если мы определили что он запускается
If ProcessExists("Имя_допол._процесса") Then ProcessWaitClose("Имя_допол._процесса") ;Если процесс запустился, то ждём его окончания (закрытия)


Sanja Alone 27-11-2006 22:47

Michail77
Creat0R
Цитата:

запускает другие процессы
В тему - посмотрите, как пришлось извратиться в скрипте установки Photoshop CS2 по причине подобных выкрутасов.

Michail77 28-11-2006 12:03

Вопрос.Можно ли сделать так чтобы в Msgbox была фоновая картинка,т.е есть примитивный код:
Msgbox (0, ".........................." &@CRLF& "............................." и т.д
Нужно чтобы была фоновая картинка а поверх неё писался бы текст как в обычом Msgbox-е
Как это сделать?

И ещё такой вопрос.Как запустить *.bat? Сделал компактный Office 2003. занимает 105мб места.
Если пишу так Run(RunWait) ("office/setup.bat") то появляется и сразу исчезает окно Dos-эмулятора.
Как сделать правильно чтобы всё работало?
Заранее спасибо.

Creat0R 28-11-2006 13:46

Michail77
Цитата:

Можно ли сделать так чтобы в Msgbox была фоновая картинка
Не думаю что это возможно... для таких задачь есть гуи, в котором довольно просто можно построить тот же MsgBox, и гараздо функциональнее.

Цитата:

Как запустить *.bat?
Как обычное приложение...

Цитата:

Если пишу так Run(RunWait) ("office/setup.bat") то появляется и сразу исчезает окно Dos-эмулятора
Попробуй писать полный путь, и\или изменить рабочий каталог (FileChangeDir("Папка_батника")), ну или писать рабочий каталог во втором параметре команды Run ("Setup.bat", "путь_к_папке_батника").

Я обычно запускаю батник (хотя стараюсь выполнять его функции в самом скрипте) таким образом:

Код:

RunWait(@ScriptDir & "\Batnik.bat", "", @SW_HIDE)
Или можно просто выполнить нужные команды сразу используя переменную ком. строки (cmd.exe)...

Код:

Run(@ComSpec & " /c start .....", "", @SW_HIDE)
------------------------

По поводу MsgBox'ов (и не только), у меня тоже есть один вопрос...

-Возможно ли привязать MsgBox, или любое из окон вызываемое для выбора/сохранения файла/папки (FileSelectFolder к примеру), к окну гуи? т.е чтобы при вызове одного их этих окон, оно было уже как бы дочерним окном гуи, и чтобы не было доступа к родительскому окну (гуи) до тех пор пока не закроется это-дочернее окно. Знаю что для обычных, гуивских дочерних окон, можно прописать как последний параметр переменную определяющую относительность к родительскому гуи, и также нужно неитрализовать родительский гуи макросом @SW_DISABLE, но как такое же сделать с окнами вызыванными по FileSelectFolder, FileOpenDialog, FileSaveDialog или даже тот же MsgBox? для этих окон вроде нет такого параметра, который определял бы их относительность к гуи.

Dentel 30-11-2006 16:26

Всем добрый день!

Господа, вопрос, возможно, глупый, но может ли скрипт написаный с помощью AutoIt работать на компьютере к которому не подключен монитор?

qeraser 30-11-2006 17:14

Dentel
Будет.

Dentel 30-11-2006 17:42

qeraser

Не работает. У меня есть сервер, к которому не подключен монитор. На сервере установлена WinXP. Захожу на этот сервер с помощью "Подключение к удаленному рабочему столу" через локальную сеть. На сервере вылажен скрипт. Если "подключение" активно, то скрипт работает и делает то, что надо. Если "подключение" закрыто, скрипт глохнет в самом начале, а именно: началом работы скрипта является запуск программы (вылезает окно авторизации), далее с помощью WinWaitActive определяем, что это окно активно и дальше понеслась (ввод пароля, логина ну т.д. и т.п.). В случае если "подключение" не активно, то скрипт "не видит" это окно авторизации и оно просто висит и ничего не происходит.

amel27 01-12-2006 06:17

Creat0R
А чем не устраивает простое отключение/включение родительского окна?
Код:

#include <GUIConstants.au3>

GUICreate("My GUI")

Opt("GUICoordMode",2)
$Button_1 = GUICtrlCreateButton ("Open File",  10, 30, 100)
GUISetState ()

While 1
    $msg = GUIGetMsg()
    Select
        Case $msg = $GUI_EVENT_CLOSE
            ExitLoop
        Case $msg = $Button_1
            WinSetState ("My GUI", "", @SW_DISABLE)
            $a = FileOpenDialog ( "FileOpenDialog", "c:\", "All (*.*)")

            WinSetState ("My GUI", "", @SW_ENABLE)
            WinActivate ("My GUI")
    EndSelect
Wend


Creat0R 01-12-2006 10:06

amel27
Цитата:

чем не устраивает простое отключение/включение родительского окна?
Ну например, в панели задачь появляется дополнительная вкладка :) , или если сделать поверх всех окон гуи, то вызываемое окно буде за ним... можно конечно выкрутится функцией WinSetOnTop, но это, имхо, не удобно...
В идеале, хочется чтобы можно было вызвать окно сохранения (к примеру), и нажимая на окно гуи, чтобы вызванное окно мигало, точно также как это происходит если вызвать дочернее окно гуи... вот пример:

Код:

#include <GUIConstants.au3>

$ParentWin = GUICreate("Parent GUI", 250, 250)
$Button = GUICtrlCreateButton("Child", 20, 50)

GUISetState()

$ChildWin = GUICreate("Child GUI", 200, 200, -1, -1, -1, -1, $ParentWin)

While 1
    $msg1 = GUIGetMsg()

        Select
        Case $msg1 = $GUI_EVENT_CLOSE
            Exit
        Case $msg1 = $Button
            GUISetState(@SW_DISABLE, $ParentWin)
            GUISetState(@SW_SHOW, $ChildWin)
            While 1
                $msg2 = GUIGetMsg()
                Select
                    Case $msg2 = $GUI_EVENT_CLOSE
                        GUISetState(@SW_RESTORE, $ParentWin)
                        GUISetState(@SW_ENABLE, $ParentWin)
                        GUISetState(@SW_HIDE, $ChildWin)
                        ExitLoop
                EndSelect
            Wend
    EndSelect
WEnd

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

P.S
Вместо WinSetState лучше GuiSetState, и порядок таких объявлении очень важен... если именно для дочернего гуи, то так как я привёл в посте (@SW_HIDE в конце), это идеальный способ (таким образом не мигает окно родительского гуи в момент его активации).
И ещё, вместо WinActivate("Title") лучше WinSetState("Title", "", @SW_RESTORE), это если для гуи, оно быстрее срабатывает.

P.S.S.
А ты не знаешь случам как решить задачку про проверку на нажатие определённой клавиши, кнопки мышки, или любого другого действия со стороны пользователя? (Которую я тоже привёл в посте со скриптом для разукрашивания).

amel27 01-12-2006 10:43

Dentel
Цитата:

У меня есть сервер, к которому не подключен монитор. На сервере установлена WinXP. Захожу на этот сервер с помощью "Подключение к удаленному рабочему столу" через локальную сеть. На сервере вылажен скрипт. Если "подключение" активно, то скрипт работает и делает то, что надо. Если "подключение" закрыто, скрипт глохнет
При отключении рабочий стол блокируется, для нормальной работы его нужно разблокировать удаленно или с локальной консоли... Поэтому связка AutoLogon+VNC удобней для администрирования серверов нежели RDP. ИМХО.

amel27 02-12-2006 11:23

Creat0R
Цитата:

В идеале, хочется чтобы можно было вызвать окно сохранения (к примеру), и нажимая на окно гуи, чтобы вызванное окно мигало, точно также как это происходит если вызвать дочернее окно гуи
Можно самому написать аналогичные функции, пример:
Код:

#include <GUIConstants.au3>
#include <Constants.au3>

$GUIParent = GUICreate("My GUI", 290, 70)

Opt("GUICoordMode",2)
$Button_1 = GUICtrlCreateButton ("Message Box",  30, 25, 100)
$Button_2 = GUICtrlCreateButton ("File Open",  30, -1)
GUISetState ()

While 1
    $msg = GUIGetMsg()
    Select
        Case $msg = $GUI_EVENT_CLOSE
            ExitLoop
        Case $msg = $Button_1
            _MsgBox ($GUIParent, "Сообщение", "Текст сообщения", $MB_OK + $MB_ICONASTERISK)
        Case $msg = $Button_2
            $file = _FileOpenDialog ($GUIParent, "Выбор файла", "C:\WINDOWS", "Документы (*.DOC)|Все (*.*)")
            _MsgBox ($GUIParent, "Сообщение", "Выбран файл: " & $file, $MB_OK + $MB_ICONASTERISK)
    EndSelect
Wend

Func _MsgBox ($mainGUI, $MsgBoxTitle, $MsgBoxText, $MsgBoxType)
    $ret = DllCall ("user32.dll", "int", "MessageBox", _
            "hwnd", $mainGUI, _
            "str", $MsgBoxText , _
            "str", $MsgBoxTitle, _
            "int", $MsgBoxType)
    Return $ret [0]
EndFunc

Func _FileOpenDialog ($mainGUI, $sTitle, $sInitDir, $sFilter = 'All (*.*)')
    Local $aFilter = StringSplit ( $sFilter, '|')
    Local $aCSTR [$aFilter [0] *2+1]
    Local $i, $iStart, $iFinal, $sCStruct = '', $sWStruct = ''
    $aCSTR [0] = $aFilter [0] *2
    For $i=1 To $aFilter [0]
        $iStart = StringInStr ($aFilter [$i], '(', 0, 1)
        $iFinal = StringInStr ($aFilter [$i], ')', 0,-1)
        $aCSTR [$i*2-1] = StringStripWS (StringLeft ($aFilter [$i], $iStart-1), 3)
        $aCSTR [$i*2] = StringStripWS (StringTrimRight (StringTrimLeft ($aFilter [$i], $iStart), StringLen ($aFilter [$i]) -$iFinal+1), 3)
        $sCStruct = $sCStruct & 'byte[' & StringLen ($aCSTR [$i*2-1])+1 & '];byte[' & StringLen ($aCSTR [$i*2])+1 & '];'
        $sWStruct = $sWStruct & 'byte[' & StringLen ($aCSTR [$i*2-1])*2+2 & '];byte[' & StringLen ($aCSTR [$i*2])*2+2 & '];'
    Next
    Local $uCSTR = DllStructCreate ($sCStruct & 'byte[1]')
    Local $uWSTR = DllStructCreate ($sWStruct & 'byte[2]')
    For $i=1 To $aCSTR [0]
        DllStructSetData ($uCSTR, $i, $aCSTR [$i])
    Next
    $ret = DllCall ("kernel32.dll", "int", "MultiByteToWideChar", _
        "int", 0, _
        "int", 0, _
        "ptr", DllStructGetPtr ($uCSTR), _
        "int", DllStructGetSize ($uCSTR), _
        "ptr", DllStructGetPtr ($uWSTR), _
        "int", DllStructGetSize ($uWSTR) )
    $ret = DllCall("Shell32.dll", "int", 'GetFileNameFromBrowse', _
            'hwnd', $mainGUI, _
            'wstr', '', _
            'int', 255, _
            'wstr', $sInitDir, _
            'wstr', '', _
            'ptr', DllStructGetPtr ($uWSTR), _
            'wstr', $sTitle )
    Return $ret [2]
EndFunc


amel27 02-12-2006 12:00

Creat0R
Цитата:

А ты не знаешь случам как решить задачку про проверку на нажатие определённой клавиши, кнопки мышки, или любого другого действия со стороны пользователя? (Которую я тоже привёл в посте со скриптом для разукрашивания).
- AutoIT не годится для программ типа "клавиатурных шпионов" - такие программы работают на уровне ядра, а не в пользовательском режиме;
- нет надежных средств для снятия состояния клавиатуры, пользовательские программы работают с виртуальной, а не реальной клавиатурой;
- существуют API-функции, позволяющие снимать состояние всех клавиш виртуальной клавиатуры за один вызов, т.е. возможно отслеживать все действия пользователя, но пока активно окно приложения.

biork 03-12-2006 06:05

Помогите пожалуйста. Нужен маленький скриптик для решения некоторых рутинных задачь.
Вот что нужно сделать последовательно:

1) в папке DIR1 находим и удаляем файлы в названии которых присутствует text_1
2) в папке DIR2 находим xxx.sif и удаляем строки, в которых присутствует text_1
3) в папке DIR3 находим xxx.inf и добавляем в его секцию [XXX] несколько строчкек (text_2, text_3, ..., text_n)
4) в папке DIR4 находим yyy.inf ищем в его секции [YYY] text_4 и заменяем его на text_5
5) сохраняем все изменения и выводим отчёт о проделанной работе :-)

Заранее благодарен.

amel27 03-12-2006 09:21

biork
п.п.1-4, точно в соответствии с формулировкой (см. примечания):
Код:

#include <File.au3>
#include <Array.au3>

$DIR1 = 'C:\DIR1'
_FilesDelete ($DIR1, '*text_1*')
$DIR2 = 'C:\DIR2'
_FileLinesDelete ($DIR2 & '\' & 'xxx.sif', 'text_1')
$DIR3 = 'C:\DIR3'
Dim $Lines3 [3] = ['text_2', 'text_3', 'text_n']
_InfSectionAddLines ($DIR3 & '\' & 'xxx.inf', 'XXX', $Lines3)
$DIR4 = 'C:\DIR4'
_InfSectionReplaceText ($DIR4 & '\' & 'yyy.inf', 'YYY', 'text_4', 'text_5')

; Удаление файлов в заданном каталоге по маске.
; Возвращает количество удаленных файлов.
Func _FilesDelete ($sPath, $sFilter)
    Local $aFiles, $i
    $aFiles = _FileListToArray ($sPath, $sFilter, 1)
    If IsArray ($aFiles) Then
        For $i=1 To $aFiles [0]
            FileDelete ($sPath & '\' & $aFiles [$i])
        Next
        Return $i-1
    Else
        Return 0
    EndIf
EndFunc

; Удаление строк файла по условию вхождения заданного текста
; Возвращает: 1 - успех, 0 - ошибка. Коды ошибок:
;  1 - ошибка чтения файла;
;  2 - ошибка сохранения файла.
Func _FileLinesDelete ($sFilePath, $sEntry)
    Local $aFileLines, $i
    If _FileReadToArray ($sFilePath, $aFileLines) Then
        For $i = $aFileLines [0] To 1 Step -1
            If StringInStr ($aFileLines [$i], $sEntry) Then _ArrayDelete ($aFileLines, $i)
        Next
        If _FileWriteFromArray ($sFilePath, $aFileLines, 1) Then
            Return 1
        Else
            SetError (2)
            Return 0
        EndIf
    Else
        SetError (1)
        Return 0
    EndIf
EndFunc

; Добавление заданного массива строк в секцию INF-файла
; Возвращает: 1 - успех, 0 - ошибка. Коды ошибок:
;  1 - переданный параметр не является массивом;
;  2 - выход за границы индекса;
;  3 - ошибка чтения файла;
;  4 - не найдена секция;
;  5 - ошибка сохранения файла.
Func _InfSectionAddLines ($sFilePath, $sSectionName, ByRef $aNewLines, $iStartIndex=0)
    Local $aFileLines, $i
    If Not IsArray ($aNewLines) Then
        SetError (1)
        Return 0
    EndIf
    If $iStartIndex >= UBound($aNewLines) Then
        SetError (2)
        Return 0
    EndIf
    If _FileReadToArray ($sFilePath, $aFileLines) Then
        Local $iStart = _ArraySearch ($aFileLines, '[' & $sSectionName & ']', 1)
        If $iStart = -1 Then
            SetError (4)
            Return 0
        EndIf
        For $i = UBound ($aNewLines)-1 To $iStartIndex Step -1
            _ArrayInsert ($aFileLines, $iStart+1, $aNewLines [$i])
        Next
        If _FileWriteFromArray ($sFilePath, $aFileLines, 1) Then
            Return 1
        Else
            SetError (5)
            Return 0
        EndIf
    Else
        SetError (3)
        Return 0
    EndIf
EndFunc

; Замена текста в пределах заданной секции INF-файла
; Возвращает: 1 - успех, 0 - ошибка. Коды ошибок:
;  1 - ошибка чтения файла;
;  2 - не найдена секция;
;  3 - ошибка сохранения файла.
Func _InfSectionReplaceText ($sFilePath, $sSectionName, $sTextFrom, $sTextTo)
    Local $aFileLines, $i
    If _FileReadToArray ($sFilePath, $aFileLines) Then
        Local $iStart = _ArraySearch ($aFileLines, '[' & $sSectionName & ']', 1)
        If $iStart = -1 Then
            SetError (2)
            Return 0
        EndIf
        Local $iFinal = _ArraySearch ($aFileLines, '[', $iStart +1)
        If $iFinal = -1 Then $iFinal = $aFileLines [0]
        If $iFinal > $iStart Then
            For $i = $iStart+1 To $iFinal
                $aFileLines [$i] = StringReplace ($aFileLines [$i], $sTextFrom, $sTextTo)
            Next
            If _FileWriteFromArray ($sFilePath, $aFileLines, 1) Then
                Return 1
            Else
                SetError (3)
                Return 0
            EndIf
        EndIf
    Else
        SetError (1)
        Return 0
    EndIf
EndFunc

З.Ы. несколько замечаний по формулировке задачи:

- INF-файл не просто текст, поэтому корректней говорить о переопределении параметров секции, а не "замене текста";
- соответственно, по п.4 возможно имелась ввиду замена строк целиком, а не вхождений текста;
- секции могут не отличаться от INI-файлов, в этом случае можно задействовать встроенные ф-ции AutoIT INI*.

Michail77 04-12-2006 09:30

2Creat0R
Не совсем так,точнее совсем не так :)
Дать ссылку на картинку(системную,т.е на ту которая находится в системе по умолчанию,например в папке system32) это легко.
Мне надо чтобы картинка интегрировалась внутрь скрипта,с расположением которое ей указано и всегда была там,независимо от того есть такая картинка в системе или нет.

biork 04-12-2006 11:24

1 вложений
amel27

Большое спасибо.

Ошибочка выпадает (см. файл)

... и что такое?
Код:

#include <File.au3>
#include <Array.au3>


amel27 04-12-2006 13:47

biork
Цитата:

и что такое?
Подключение дополнительных (пользовательских) функций, файлы расширений находятся в папке \Include установочного каталога. Так как файлы не загружены, то и функция (соответственно) неопознана.

biork 05-12-2006 09:50

amel27

С пользовательскими функциями разобрался. Пришлось, всего-лишь, переустановить AutoIt...
Что касаеися самого скрипта:

1) Удаление файлов в заданном каталоге по маске - работает!
1.2) Возвращает количество удаленных файлов - где и как посмотреть?

2) Удаление строк файла по условию вхождения заданного текста - работает!
2.1) Возвращает: 1 - успех, 0 - ошибка. Коды ошибок - так же не знаю где их увидеть.

3) Добавление заданного массива строк в секцию INF-файла - не работает...
3.1) Возвращает: 1 - успех, 0 - ошибка. Коды ошибок - очень хотелось бы их посмотреть...

4) Замена текста в пределах заданной секции INF-файла - не работает...
4.1) В чём ошибка - так же не видно...

Я понимаю, что всё от криворукости... но всё же? :-)

Ещё вопрос: строки text_2, text_3, text_n, а так же text_4 и text_5 содержат всякие знаки припинания (запятаи, кавычки, скобки и пр.). Может, нужно принимать какие то дополнительные меры, что бы всё это правильно было интерпритировано?

в 4 пункте, действительно можно бы было не менять текст, а изменить значение параметра.

Yozhegg 05-12-2006 10:41

А нет ли для AutoIt какой-нибудь рисовалки форм?
А то очень долго координаты с "дизайн-макета" списывать..

amel27 05-12-2006 12:22

biork
Цитата:

Возвращает: 1 - успех, 0 - ошибка. Коды ошибок - очень хотелось бы их посмотреть
Пример с выводом результата на экран:
Код:

; ...
$DIR3 = 'C:\DIR3'
Dim $Lines3 [3] = ['text_2', 'text_3', 'text_n']
$ret = _InfSectionAddLines ($DIR3 & '\' & 'xxx.inf', 'XXX', $Lines3)
If $ret Then
    MsgBox (64, 'Собщение', 'Операция завершена без ошибок.')
Else
    MsgBox (16, 'Ошибка', "Код ошибки: " & @error)
EndIf
; ...

Yozhegg
Цитата:

А нет ли для AutoIt какой-нибудь рисовалки форм?
А то очень долго координаты с "дизайн-макета" списывать..
Думаю если бы был, то за него пришлось бы платить...

biork 05-12-2006 13:38

amel27

Код:

1 - переданный параметр не является массивом;
2 - выход за границы индекса;
3 - ошибка чтения файла;
4 - не найдена секция;
5 - ошибка сохранения файла.

Код ошибки - 0! :-)


amel27 05-12-2006 14:11

biork
Извиняюсь, очепятку исправил...

Creat0R 05-12-2006 16:04

amel27
Цитата:

Можно самому написать аналогичные функции
Приогромнейшее спасибо! и представить себе не мог что на аутоите это реально :)

В связи с этим есть вопрос:

Что в функции нужно поменять, чтобы вместо открытия фалов, был выбор каталога (FileSelectFolder), и также хотелось бы чтобы была функция сохранения файлов (FileSaveDialog) - Буду очень благодарен если поможешь с этими функциями...

И ещё (не принципиально) - при выборе файлов, возможно сделать массовый выбор? т.е чтобы можно было выбирать несколько файлов.
--------------------------------
По поводу самого гуи, я немогу понять одной вещи - чтобы создать гуи, необходимо построить цикл, но на сколько известно, безпрерывный цикл “заставляет” сильно загружать ЦП... т.е если мы сделаем такой цикл:

Код:

While 1

Wend

То загрузка ЦП будет 100% - Но если поставить задержку в этом цикле (Sleep(100)), то загрузки ЦП не будет. НО, в гуи ставить задержку нельзя, это портит функциональность нажатия кнопок и т.п.... но с другой стороны, даже если поставить подобную задержку в гуи, и при этом создать горячую клавишу (HotKeySet()), то по её вызову (по вызову её функции) всё нормально срабатывает... как сделать чтобы и функциональность сохранить (не используя клавиши), и предотвратить загрузку ЦП?
Просто дело в том, что хотел сворачивать скрипт в трей, затем в трее вывести меню, но если ставлю задержку в цикле скрипта (для трея), то пункты в трее не срабатывают, а если не ставить задержку, то процессор сильно грузится (бывает до 80-90%) - Как это решить?

Creat0R 05-12-2006 16:18

Michail77
Цитата:

Мне надо чтобы картинка интегрировалась внутрь скрипта,с расположением которое ей указано и всегда была там,независимо от того есть такая картинка в системе или нет.
Для этого нужно установить файл в скрипте, чтобы перед запуском он расспаковывал изображение во временную папку, и затем считывал его оттуда (это при компилляции) - а вбить намертво изображение в скрипт, не получится.

Для установки файла исользуй такую команду:

Код:

FileInstall("Полный\путь\к\изображению\для\установки\image.png", "Путь\куда\будет расспаковано\изображение\image.png", 1)
А для использования просто указывай путь который ты прописал как назначения для помещения изображения...

Код:

GUICtrlCreatePic("Путь\куда\будет расспаковано\изображение\image.png",0,0, 300,40)

VelDmi 05-12-2006 17:21

Creat0R
Цитата:

По поводу самого гуи, я немогу понять одной вещи - чтобы создать гуи, необходимо построить цикл,
Гуи не грузит проц, это даже в справке написано. Разве у тебя нет русской справки?

Насчет:

While 1
Sleep(100)
Wend

(применительно к другому случаю) сам бы хотел знать, какую оптимальную задержку выставлять.

Yozhegg
Цитата:

А нет ли для AutoIt какой-нибудь рисовалки форм?
А то очень долго координаты с "дизайн-макета" списывать..
Здрасте, а как же koda designer?

Michail77 05-12-2006 20:08

2 Creat0R
Спасибо,всё получилось :)))

Vadikan 06-12-2006 00:44

All
В теме уже свыше 500 сообщений и поиск нужной информации в ней усложняется. Есть предложение собрать все решения (скрипты) и разместить их на Wiki по принципу "один скрипт - одна статья wiki", добавляя статьи в категорию Autoit. Речь, в принципе, идет об общих решениях, а не о скриптах для установки конкретной программы. Название статьи, очевидно, должно отражать назначение скрипта. Затем можно в шапке просто разместить ссылки на статьи Wiki.

prokazzza 06-12-2006 01:43

Sanja Alone

Слушай помнишь ты давал мне вот такой скрипт, я тут не нашел куда вставить имя rar архива и что будет если убрать из скрипта строчку ProcessWaitClose('INSTALL.exe') она мне не нужна.

Код:

If $CmdLine[0]=1 Then
        $sfx=$CmdLine[1]
Else
        MsgBox(16,'Ошибка',"Недопустимое содержимое командной строки",7)
        Exit
EndIf
;пароль (берется из 3-й строки)
$password=FileReadLine(@ScriptDir&'\пароль.ini',3)
$pid=Run('"'&$sfx&'" -s')
WinWait('Ввод пароля')
ControlSetText('Ввод пароля','','Edit1',$password)
ControlClick('Ввод пароля','','Button1')
ProcessWaitClose($pid)
ProcessWaitClose('INSTALL.exe')


amel27 06-12-2006 07:05

Vadikan
Цитата:

Речь, в принципе, идет об общих решениях, а не о скриптах для установки конкретной программы
Вот-вот.... С категориями путаница получается - я в смятении. Во-первых, есть две принципиально разных версии AutoIT (причем старая v.2.64 совместима по синтаксису с AutoHotKey) - в названии категории это не указано, хотя иконка недвусмысленно указывает на 3-ю версию. Во-вторых, на данный момент эта категория подчинена автоустановке, т.е. содержание ограничено скриптами, решающими те или иные Unattend-задачи хотя сфера применения AutoIT гораздо шире. В третьих, именование категорий по алфавиту может и оправдано в пределах темы (как в автоустановке), но необосновано и неудобно в общем случае - ИМХО требуется тематическое деление по категориям (тут нужно подумать).

Далее - где-то надо обсудить какие сабжи и в какой форме нужно выносить на WIKI, все-таки выдернуть скрипт из контекста обсуждения не так просто - придется приводить его к более универсальному виду, добавить комментарии, поработать с именами переменных.

З.Ы. Либо я еще не понял WIKI либо одно из двух, но без древовидной структуры от категорий мало толку.

biork 06-12-2006 09:42

amel27

Я извиняюсь, уже, наверное жутко надоел, но...

...скрипт ни как не может найти секцию...

может с синтаксисом чего?

Код:

$ret = _InfSectionAddLines ($DIR1 & '\' & 'HIVESYS.INF', 'AddReg', $Lines)
Код:

$ret = _InfSectionReplaceText ($DIR1 & '\' & 'HIVESFT.INF', 'Strings', $text_4, $text_5)

amel27 06-12-2006 11:12

Creat0R
Цитата:

Что в функции нужно поменять, чтобы вместо открытия фалов, был выбор каталога (FileSelectFolder), и также хотелось бы чтобы была функция сохранения файлов (FileSaveDialog) - Буду очень благодарен если поможешь с этими функциями...
Вполне реально, но быстро не получится - соответствующие API-аналоги посложней будут...

Цитата:

безпрерывный цикл “заставляет” сильно загружать ЦП
Для этого в AutoIT есть метод "OnEvent" - альтернатива методу "MessageLoop". Смотри пример в HELP к GUICtrlSetOnEvent .

biork
файл и путь в личку

prokazzza 06-12-2006 16:40

amel27

Можешь доделать вот такой скрипт, я тут не нашел куда вставить имя rar архива и что будет если убрать из скрипта строчку ProcessWaitClose('INSTALL.exe') она мне не нужна.

Код:

If $CmdLine[0]=1 Then
        $sfx=$CmdLine[1]
Else
        MsgBox(16,'Ошибка',"Недопустимое содержимое командной строки",7)
        Exit
EndIf
;пароль (берется из 3-й строки)
$password=FileReadLine(@ScriptDir&'\пароль.ini',3)
$pid=Run('"'&$sfx&'" -s')
WinWait('Ввод пароля')
ControlSetText('Ввод пароля','','Edit1',$password)
ControlClick('Ввод пароля','','Button1')
ProcessWaitClose($pid)
ProcessWaitClose('INSTALL.exe')


Yozhegg 06-12-2006 18:14

VelDmi
Цитата:

Yozhegg
Цитата:
А нет ли для AutoIt какой-нибудь рисовалки форм?
А то очень долго координаты с "дизайн-макета" списывать..



Здрасте, а как же koda designer?
А что это такое ( koda designer? )? к AutoIt отношение имеет?

TERMINAL 06-12-2006 21:02

1.Как сделать чтобы после 1 января нельзя было запускать, допустим, некий файл Test.exe?
2.Как следать чтобы выезжал диск из CD-Roma?

Creat0R 07-12-2006 03:57

VelDmi
Цитата:

Гуи не грузит проц
А я и не писал что он грузит...

Цитата:

чтобы создать гуи, необходимо построить цикл, но на сколько известно, безпрерывный цикл “заставляет” сильно загружать ЦП
Цитата:

Разве у тебя нет русской справки?
Есть :) - Но я юзаю английскую, мне так легче.


amel27
Цитата:

Смотри пример в HELP к GUICtrlSetOnEvent .
“Даже у безвыходного положения, есть выход!” ©
Ещё раз Спасибо, очень выручил :)

TERMINAL
Цитата:

Как сделать чтобы после 1 января нельзя было запускать, допустим, некий файл Test.exe?
Примерно так:

Код:

$Proga = "test.exe"
If @MDAY >= 01 and @MON >= 01 and @YEAR >= 2007 Then
  MsgBox(16, "", "Невозможно запустить программу " & $Proga & @CR & " срок истёк ;) " & @MDAY&"/"&@MON&"/"&@YEAR)
  Exit
EndIf

Правда если поменять дату в настройках времени (Свойства: Дата и Время), то можно будет запустить программу (если перевести дату назад).

Но можно например в этот день, создать файл, и упрятать его куда нибудь подальше, а ещё лучше, запись в реестре, и тогда можно будет проверять уже не дату, а существование файла\записи в реестре... примерно так:

Код:

$Proga = "test.exe"
If (@MDAY >= 01 and @MON >= 01 and @YEAR >= 2007) or FileExists("~5luyubd.dy6") or RegRead("HKLM", "...") <> "" Then
  MsgBox(0, "", "Can not start the program " & $Proga & @CR & "today it's " & @MDAY&"/"&@MON&"/"&@YEAR)
  $Path = "C:\windows\system32\sytemf8qqe\765ujyuj\ytyyhj69wc\341jj3567jg\hufghfg7r568"
  If Not FileExists($Path & "\~5luyubd.dy6") Then
      DirCreate($Path)
      FileWrite($Path & "\~5luyubd.dy6", "")
      FileSetAttrib($Path & "\~5luyubd.dy6", "RSH")
  EndIf
  Exit
EndIf

Но и это тоже не очень надёжный способ.

prokazzza
Цитата:

я тут не нашел куда вставить имя rar архива
Я так понимаю, имя архива берётся из командной строки... т.е если запустить программу с ком. строкой ровняющейся имени архиву, то переменной $sfx будет присвоенно это значение (имя архива).

Цитата:

что будет если убрать из скрипта строчку ProcessWaitClose('INSTALL.exe')
Ничего :) - Просто скрипт не будет “ждать” завершения процесса Install.exe

amel27 07-12-2006 04:10

Yozhegg
Цитата:

А что это такое ( koda designer? )? к AutoIt отношение имеет?
http://www.autoitscript.com/fileman/...ormdesign.html

prokazzza
Цитата:

Можешь доделать вот такой скрипт, я тут не нашел куда вставить имя rar архива и что будет если убрать из скрипта строчку ProcessWaitClose('INSTALL.exe') она мне не нужна.
Доделать не могу, так как не знаю цели мероприятия... Имя архива передается в командной строке и заносится в переменную $sfx, причем это SFX-архив. Убрать строчку можно, но тогда скрипт завершит работу раньше установщика.

TERMINAL1. 1 января какого года? При условии, что Test.exe это AU3-скрипт:
Код:

#Include <Date.au3>

$point = StringReplace(_NowCalcDate (), '/', '')
If $point > '20060101' Then
    MsgBox (16, 'Ошибка', 'Время пробной эксплуатации истекло!')
    Exit
EndIf
; ...

2. В "маленьких хитростях": http://forum.oszone.net/post-520629-95.html

VelDmi 07-12-2006 07:05

Yozhegg
Цитата:

А что это такое ( koda designer? )? к AutoIt отношение имеет?
Для AutoIt есть отличный редактор, называется SciTe. В нем если полазить по меню найдешь несколько дизайнеров форм, в том числе и koda.

Sanja Alone 07-12-2006 12:30

VelDmi
Цитата:

Для этого в AutoIT есть метод "OnEvent" - альтернатива методу "MessageLoop".
Кстати, весьма полезная вещь. Именно этим методом реализован ГУИ в OEsr

prokazzza
Цитата:

что будет если убрать из скрипта строчку ProcessWaitClose('INSTALL.exe') она мне не нужна.
В той задаче, к-рую ты мне формулировал, это приведет к завершению скрипта раньше окончания процесса установки. Если тебя это устроит, то можешь убрать...

Dentel 07-12-2006 15:57

Всем здравствуйте!

amel27

Спасибо за помощь, только теперь, соотвественно, вопрос, а как удаленно разблокировать рабочий стол?
(Это к вопросу о работе скрипта, если к ПК не подключен монитор)

desperate 08-12-2006 03:18

Вопрос для настоящих знатаков:
создаю AutoIT скрипт, который автоматически создает VPN подключение (эта часть поддалась без проблем) и потом его настраивает(прописывает IP,DNS и прочие настройки в свойства адаптера). Вопрос: Как открыть свойства конкретного сетевого подключения(в моем случае это VPN) и как связать это с autoIT.
заранее всем спасибо.

VelDmi 08-12-2006 08:43

desperate
У меня сделано через netsh interface, если нужно подробнее попозже напишу.

desperate 08-12-2006 11:03

VelDmi
буду очень благодарен и думаю другим это тоже будет интересно.

desperate 08-12-2006 11:20

Да забыл указать самое главное, мне надо не только вкладку Сеть -> свойства TCP/IP настроить, но и другие параметры, шифрование, WINS и проче.... вообщем пройтись по всем вклдкам свойств определенного адаптера (т.к. VPN создается для работы с провайдером спутникового интернета)

amel27 09-12-2006 08:11

Creat0R
Цитата:

Что в функции нужно поменять, чтобы вместо открытия фалов, был выбор каталога (FileSelectFolder), и также хотелось бы чтобы была функция сохранения файлов (FileSaveDialog) - Буду очень благодарен если поможешь с этими функциями... И ещё (не принципиально) - при выборе файлов, возможно сделать массовый выбор? т.е чтобы можно было выбирать несколько файлов.
Все что касается FileOpenDialog и FileSaveDialog удалось осуществить... и даже чуть больше - новые UDF полностью совместимы с AutoIT-овскими, плюс новые возможности:

- новый флаг: 32 = Hide places bar (не отображать панель с иконками);
- новый параметр: Default Extension (если пользователь не вбил расширение, то автоматом добавляет указанный);
- новый параметр: HWND головного окна GUI (из-за чего собственно весь сыр-бор).
Код:

Func _FileOpenDialog ($sTitle, $sInitDir, $sFilter = 'All (*.*)', $iOpt = 0, $sDefaultFile = "", $sDefaultExt = "", $mainGUI = 0)
    Local $iFileLen = 65536 ; Max chars in returned string
    ; API flags prepare
    Local $iFlag = BitOR ( _
        BitShift (BitAND ($iOpt, 1),-12), BitShift (BitAND ($iOpt, 2),-10), BitShift (BitAND ($iOpt, 4),-7 ), _
        BitShift (BitAND ($iOpt, 8),-10), BitShift (BitAND ($iOpt, 4),-17) )
    ; Filter string to array convertion
    Local $asFLines = StringSplit ( $sFilter, '|'), $asFilter [$asFLines [0] *2+1]
    Local $i, $iStart, $iFinal, $suFilter = ''
    $asFilter [0] = $asFLines [0] *2
    For $i=1 To $asFLines [0]
        $iStart = StringInStr ($asFLines [$i], '(', 0, 1)
        $iFinal = StringInStr ($asFLines [$i], ')', 0,-1)
        $asFilter [$i*2-1] = StringStripWS (StringLeft ($asFLines [$i], $iStart-1), 3)
        $asFilter [$i*2] = StringStripWS (StringTrimRight (StringTrimLeft ($asFLines [$i], $iStart), StringLen ($asFLines [$i]) -$iFinal+1), 3)
        $suFilter = $suFilter & 'byte[' & StringLen ($asFilter [$i*2-1])+1 & '];byte[' & StringLen ($asFilter [$i*2])+1 & '];'
    Next
    ; Create API structures
    Local $uOFN = DllStructCreate ('dword;int;int;ptr;ptr;dword;dword;ptr;dword' & _
        ';ptr;int;ptr;ptr;dword;short;short;ptr;ptr;ptr;ptr;ptr;dword;dword' )
    Local $usTitle  = DllStructCreate ('byte[' & StringLen ($sTitle) +1 & ']')
    Local $usInitDir= DllStructCreate ('byte[' & StringLen ($sInitDir) +1 & ']')
    Local $usFilter = DllStructCreate ($suFilter & 'byte')
    Local $usFile  = DllStructCreate ('byte[' & $iFileLen & ']')
    Local $usExtn  = DllStructCreate ('byte[' & StringLen ($sDefaultExt) +1 & ']')
    For $i=1 To $asFilter [0]
        DllStructSetData ($usFilter, $i, $asFilter [$i])
    Next
    ; Set Data of API structures
    DllStructSetData ($usTitle, 1, $sTitle)
    DllStructSetData ($usInitDir, 1, $sInitDir)
    DllStructSetData ($usFile, 1, $sDefaultFile)
    DllStructSetData ($usExtn, 1, $sDefaultExt)
    DllStructSetData ($uOFN,  1, DllStructGetSize($uOFN))
    DllStructSetData ($uOFN,  2, $mainGUI)
    DllStructSetData ($uOFN,  4, DllStructGetPtr ($usFilter))
    DllStructSetData ($uOFN,  7, 1)
    DllStructSetData ($uOFN,  8, DllStructGetPtr ($usFile))
    DllStructSetData ($uOFN,  9, $iFileLen)
    DllStructSetData ($uOFN, 12, DllStructGetPtr ($usInitDir))
    DllStructSetData ($uOFN, 13, DllStructGetPtr ($usTitle))
    DllStructSetData ($uOFN, 14, $iFlag)
    DllStructSetData ($uOFN, 17, DllStructGetPtr ($usExtn))
    DllStructSetData ($uOFN, 23, BitShift (BitAND ($iOpt, 32), 5))
    ; Call API function
    $ret = DllCall ('comdlg32.dll', 'int', 'GetOpenFileName', _
            'ptr', DllStructGetPtr ($uOFN) )
    If $ret [0] Then
        If BitAND ($iOpt, 4) Then
            $i = 1
            While 1
                If DllStructGetData ($usFile, 1, $i) =0 Then
                    If DllStructGetData ($usFile, 1, $i+1) Then
                        DllStructSetData ($usFile, 1, 124, $i)
                    Else
                        ExitLoop
                    EndIf
                EndIf
                $i += 1
            Wend
        EndIf
        Return DllStructGetData ($usFile, 1)
    Else
        SetError (1)
        Return ""
    EndIf
EndFunc

Func _FileSaveDialog ($sTitle, $sInitDir, $sFilter = 'All (*.*)', $iOpt = 0, $sDefaultFile = "", $sDefaultExt = "", $mainGUI = 0)
    Local $iFileLen = 65536 ; Max chars in returned string
    ; API flags prepare
    Local $iFlag = BitOR (BitShift (BitAND ($iOpt, 2),-10), BitShift (BitAND ($iOpt,16), 3 ))
    ; Filter string to array convertion
    Local $asFLines = StringSplit ( $sFilter, '|'), $asFilter [$asFLines [0] *2+1]
    Local $i, $iStart, $iFinal, $suFilter = ''
    $asFilter [0] = $asFLines [0] *2
    For $i=1 To $asFLines [0]
        $iStart = StringInStr ($asFLines [$i], '(', 0, 1)
        $iFinal = StringInStr ($asFLines [$i], ')', 0,-1)
        $asFilter [$i*2-1] = StringStripWS (StringLeft ($asFLines [$i], $iStart-1), 3)
        $asFilter [$i*2] = StringStripWS (StringTrimRight (StringTrimLeft ($asFLines [$i], $iStart), StringLen ($asFLines [$i]) -$iFinal+1), 3)
        $suFilter = $suFilter & 'byte[' & StringLen ($asFilter [$i*2-1])+1 & '];byte[' & StringLen ($asFilter [$i*2])+1 & '];'
    Next
    ; Create API structures
    Local $uOFN = DllStructCreate ('dword;int;int;ptr;ptr;dword;dword;ptr;dword' & _
        ';ptr;int;ptr;ptr;dword;short;short;ptr;ptr;ptr;ptr;ptr;dword;dword' )
    Local $usTitle  = DllStructCreate ('byte[' & StringLen ($sTitle) +1 & ']')
    Local $usInitDir= DllStructCreate ('byte[' & StringLen ($sInitDir) +1 & ']')
    Local $usFilter = DllStructCreate ($suFilter & 'byte')
    Local $usFile  = DllStructCreate ('byte[' & $iFileLen & ']')
    Local $usExtn  = DllStructCreate ('byte[' & StringLen ($sDefaultExt) +1 & ']')
    For $i=1 To $asFilter [0]
        DllStructSetData ($usFilter, $i, $asFilter [$i])
    Next
    ; Set Data of API structures
    DllStructSetData ($usTitle, 1, $sTitle)
    DllStructSetData ($usInitDir, 1, $sInitDir)
    DllStructSetData ($usFile, 1, $sDefaultFile)
    DllStructSetData ($usExtn, 1, $sDefaultExt)
    DllStructSetData ($uOFN,  1, DllStructGetSize($uOFN))
    DllStructSetData ($uOFN,  2, $mainGUI)
    DllStructSetData ($uOFN,  4, DllStructGetPtr ($usFilter))
    DllStructSetData ($uOFN,  7, 1)
    DllStructSetData ($uOFN,  8, DllStructGetPtr ($usFile))
    DllStructSetData ($uOFN,  9, $iFileLen)
    DllStructSetData ($uOFN, 12, DllStructGetPtr ($usInitDir))
    DllStructSetData ($uOFN, 13, DllStructGetPtr ($usTitle))
    DllStructSetData ($uOFN, 14, $iFlag)
    DllStructSetData ($uOFN, 17, DllStructGetPtr ($usExtn))
    DllStructSetData ($uOFN, 23, BitShift (BitAND ($iOpt, 32), 5))
    ; Call API function
    $ret = DllCall ('comdlg32.dll', 'int', 'GetSaveFileName', _
            'ptr', DllStructGetPtr ($uOFN) )
    If $ret [0] Then
        Return DllStructGetData ($usFile, 1)
    Else
        SetError (1)
        Return ""
    EndIf
EndFunc

З.Ы. Из-за превышения лимита на количество символов оформление пришлось отключить

VelDmi 09-12-2006 13:20

Код:

$ip = '192.168.100.' & $ComputerNumber
If @IPAddress1 <> $ip Then
        RunWait (@COMSPEC & ' /c chcp 1251 && ' & @SystemDir & '\netsh.exe interface ip dump > netsh.cfg', @ScriptDir, @SW_HIDE)
        FileWriteLine(@ScriptDir & "\error.log", StringFormat("%s:%s:%s %s-%s-%s  Старый IP %s, надо менять", @HOUR, @MIN, @SEC, @MDAY, @MON, @YEAR, @IPAddress1))
        $file = FileOpen(@ScriptDir & '\netsh.cfg', 0)

        ; Check if file opened for reading OK
        If $file = -1 Then
                FileWriteLine(@ScriptDir & "\error.log", StringFormat("%s:%s:%s %s-%s-%s  Не могу открыть файл netsh.cfg", @HOUR, @MIN, @SEC, @MDAY, @MON, @YEAR))
                Exit
        EndIf

        ; Read in lines of text until the EOF is reached
        For $i = 1 To 60
                $line = FileReadLine($file)
                If StringInStr($line, 'set address name="') = 1 Then ExitLoop
                If $i = 60 Then Shutdown (6)
                Sleep (1000)
        Next

        $line = StringTrimLeft( $line, 17 )       
        $line = StringTrimRight( $line, StringLen($line) - StringInStr($line, 'source') + 2)
       
        FileClose($file)
       
        RunWait (@SystemDir & '\netsh.exe interface ip set address name=' & $line & ' source=static addr=' & $ip & ' mask=255.255.255.0 gateway=none', @SystemDir, @SW_HIDE)
        FileWriteLine(@ScriptDir & "\error.log", StringFormat("%s:%s:%s %s-%s-%s  Сменили IP на: %s", @HOUR, @MIN, @SEC, @MDAY, @MON, @YEAR, $ip))
        $Restart = 'Yes'  ; требуется перезагрузка
EndIf


VelDmi 09-12-2006 13:44

Первый запуск netsh.exe нужен для того, чтобы выяснить имя сетевого интерфейса, т.к. оно может изменяться.
Второй запуск уже устанавливает для подключения необходимый мне ИП, gateway и проч.

desperate 09-12-2006 16:36

VelDmi
хороший скрипт, спасибо, но как настроить остальные параметры шифрования,Wins и прочих на других вкладках окна свойств???

amel27 09-12-2006 20:40

biork
Цитата:

скрипт ни как не может найти секцию
Файл получил, все ясно - у тебя INF-файлы из локализованной Windows, а значит в Unicode-кодировке... я подправил пару функций для поддержки файлов в юникоде. Добавь в конец скрипта прилагаемый текст функций и замени по тексту FileReadToArray и FileWriteFromArray на _FileReadUnicodeToArray и _FileWriteUnicodeFromArray соответственно:
Код:

Func _FileReadUnicodeToArray ($sFilePath, ByRef $aArray)
    Local $hFile = FileOpen ($sFilePath, 0)
    If $hFile = -1 Then
        SetError (1)
        Return 0
    EndIf
    Local $uData = FileRead ($hFile, FileGetSize($sFilePath))
    Local $sData = _WCStrToString ($uData)
    If @error Then
        SetError (2)
        Return 0
    EndIf
    $aArray = StringSplit (StringStripCR ($sData), @LF)
    FileClose ($hFile)
    Return 1
EndFunc

Func _FileWriteUnicodeFromArray ($sFilePath, ByRef $a_Array, $i_Base = 0, $i_UBound = 0)
    Local $hFile
    If Not IsArray ($a_Array) Then
        SetError (2)
        Return 0
    EndIf
    Local $last = UBound ($a_Array) - 1
    If $i_UBound < 1 Or $i_UBound > $last Then $i_UBound = $last
    If $i_Base < 0 Or $i_Base > $last Then $i_Base = 0
    $hFile = FileOpen ($sFilePath, 2)
    If $hFile = -1 Then
        SetError (1)
        Return 0
    EndIf
    FileWrite ($hFile, _StringToWCStr ($a_Array [$i_Base], 1))
    For $x = $i_Base +1 To $i_UBound
        $a_Array [$x] = @CRLF & $a_Array [$x]
        FileWrite ($hFile, _StringToWCStr ($a_Array [$x]))
    Next
    FileClose($hFile)
    Return 1
EndFunc

Func _StringToWCStr (ByRef $sString, $mark = 0)
    Local $len = StringLen ($sString), $wcl= BitShift ($len, -1)
    Local $buf, $ptr
    If $len =0 Then
        If $mark Then Return Chr(0xFF) & Chr(0xFE)
        Return ''
    EndIf
    If $mark Then
        $buf = DllStructCreate ("byte[" & $wcl +2 & "]")
        DllStructSetData ($buf, 1, Chr(0xFF) & Chr(0xFE))
        $ptr = DllStructGetPtr ($buf) +2
    Else
        $buf = DllStructCreate ("byte[" & $wcl & "]")
        $ptr = DllStructGetPtr ($buf)
    EndIf
    Local $ret = DllCall ("Kernel32.dll", "int", "MultiByteToWideChar", _
        "int", 0, _
        "int", 0, _
        "str", $sString, _
        "int", $len,  _
        "ptr", $ptr,  _
        "int", $wcl )
    If $ret [0] Then
        Return DllStructGetData ($buf, 1)
    Else
        $ret = DllCall ("Kernel32.dll", "int", "GetLastError")
        SetError ($ret [0])
    EndIf
EndFunc

Func _WCStrToString (ByRef $wcString)
    Local $wcl = StringLen ($wcString), $len = BitShift ($wcl, 1)
    If $wcl =0 Then Return ''
    Local $out = DllStructCreate ("char[" & $len & "]")
    Local $buf = DllStructCreate ("byte[" & $wcl  & "]")
    Local $ptr = DllStructGetPtr ($buf)
    DllStructSetData ($buf, 1, $wcString)
    If DllStructGetData ($buf, 1, 1) =-1 AND DllStructGetData ($buf, 1, 2) =-2 Then
        $ptr +=2
        $len -=1
    EndIf
    Local $ret = DllCall ("Kernel32.dll", "int", "WideCharToMultiByte", _
        "int", 0, _
        "int", 0, _
        "ptr", $ptr, _
        "int", $len, _
        "ptr", DllStructGetPtr ($out), _
        "int", $len, _
        "int", 0, _
        "int", 0 )
      If $ret [0] Then
        Return DllStructGetData ($out, 1)
    Else
        $ret = DllCall ("Kernel32.dll", "int", "GetLastError")
        SetError ($ret [0])
    EndIf
EndFunc


VelDmi 10-12-2006 09:06

desperate
Цитата:

хороший скрипт, спасибо, но как настроить остальные параметры шифрования,Wins и прочих на других вкладках окна свойств???
А ты посмотри хелп к netsh.exe, наверняка он много чего еще может.
Код:

Чтобы получить справку по команде, введите эту команду,
затем пробел и "?"

netsh>interface ip show

Применимы следующие команды:

Команды в этом контексте:
show address  - Отображение конфигурации IP-адресов.
show config    - Отображение IP-адреса и дополнительных сведений.
show dns      - Отображение адресов DNS-сервера.
show icmp      - Отображение статистики ICMP.
show interface - Отображение статистики IP-интерфейса.
show ipaddress - Отображение текущих IP-адресов.
show ipnet    - Отображение сопоставления сетей IP и физических носителей.
show ipstats  - Отображение статистики IP.
show joins    - Отображение присоединенных многоадресных групп.
show offload  - Отображает информацию разгрузки.
show tcpconn  - Отображение TCP-подключений.
show tcpstats  - Отображение статистики TCP.
show udpconn  - Отображение UDP-подключений.
show udpstats  - Отображение статистики UDP.
show wins      - Отображение адресов WINS-сервера.


desperate 10-12-2006 20:46

VelDmi
без вариантов, не получилось с помощью netsh настроить все параметры.
Поэтому мой вопрос по поводу автоматического открытия Properties определенного сетевого подключения остается открытым.

amel27 11-12-2006 13:17

desperate
Цитата:

не получилось с помощью netsh настроить все параметры
CMAK пробовал?

desperate 11-12-2006 15:49

Снимаю свой вопрос, проблема решиласт сама собой, когда набрел на форуме а статью про автоматическое создание dial-up соединения.
у кого будет подобная проблема пишити в личку и тогда создам отдельный топик, в котором будем развиваться и совершенствоваться.

Sanja Alone 11-12-2006 18:43

desperate
Цитата:

тогда создам отдельный топик
Думаю, что лучше дополнить уже существующую тему Соединение по dial-up автоматом.

biork 12-12-2006 11:59

amel27
Огромное спасибище! Всё работает!

Heaven 14-12-2006 10:09

Извините пожалуйста, а существует ли такая команда с помощью которой можно было бы закрыть определенное окно!

Например я сделал так что при открытии моего диска(autorun)он сначало записывает мой шрифт в директорию %windir%\Fonts и
Я сделал так
поместил explorer.exe в директорию диска и написал в cmd файле
%CDROM%\Autoplay\explorer.exe %windir%\Fonts
Это мне нужно чтобы он открывался
А как сделать так чтобы она вслед за этим закрывалась автоматически
Пожалуйста напишите мне

DenchikK 14-12-2006 19:00

А можно ли средствами AutoIT (навеоняка можно, только придумать не
могу как) удалить файл с фиксированным именем во всех неопределенных
деррикториях - имена, количество, уровни которых заранее неизвестны?

Допустим имеем файл который надо удалить - 1.txt
Имеем каталог в котором его надо удалять - 2

И вот в этом то каталоге может быть любое количество каталогов,
подкаталогов, подподкаталогов - какие - не понятно, имена их - не
известно, количество - то же, уровней вложения - тем более.

Мозг опухают - в хелпе пока ничего не смог отыскать.

Creat0R 14-12-2006 21:59

amel27
Цитата:

Все что касается FileOpenDialog и FileSaveDialog удалось осуществить... и даже чуть больше - новые UDF полностью совместимы с AutoIT-овскими, плюс новые возможности:
Абалдеть!!! Спасибо! осталось только для FileSelectFolder придумать функцию, и будет суперь счастье :)

Есть вопрос - а можно чтобы вместо (как опция) прикрепления гуи, можно было также прикреплять любое другое окно (по его заголовку)?

P.S
При разукрашивании скрипта, если поставить Send("{...}") то скрипт ругается на неопознанные стили, а точнее, это если только есть кривые круглые ораньжевые скобки :)

Heaven
Цитата:

существует ли такая команда с помощью которой можно было бы закрыть определенное окно!
WinClose("Заголовок окна", "Текст окна")
Цитата:

как сделать так чтобы она вслед за этим закрывалась автоматически
Ты имеешь в виду папка Fonts? - WinClose("Fonts")

DenchikK
Цитата:

А можно ли средствами AutoIT (навеоняка можно, только придумать не
могу как) удалить файл с фиксированным именем во всех неопределенных
деррикториях - имена, количество, уровни которых заранее неизвестны?
Можно (использовал функцию by amel27) :

Код:


#include <File.au3>
#include <Array.au3>

$Path = @ScriptDir & "\2"
$FileName = "1.txt"

$DirsList = _DirListToArray ($Path)
For $i = 1 to $DirsList[0]
    FileDelete($DirsList[$i] & "\" & $FileName)
Next
FileDelete($Path & "\" & $FileName)

Func _DirListToArray ($sPath)
    Local $i, $j, $rlist[1]=[0], $blist, $alist=_FileListToArray ($sPath, '*', 2)
    If IsArray ($alist) Then
        For $i=1 To $alist [0]
            _ArrayAdd ($rlist, $sPath & "\" & $alist [$i])
            $blist = _DirListToArray ($sPath & "\" & $alist [$i])
            If $blist[0]>0 Then
                For $j=1 To $blist [0]
                    _ArrayAdd ($rlist, $blist [$j])
                Next
            EndIf
        Next
    EndIf
    $rlist [0] = UBound ($rlist) - 1
    Return $rlist
EndFunc


DenchikK 16-12-2006 05:15

Creat0R
Извините пожалуйста за глупый вопрос - скопировал скрипт в файл au3,
переписал в тот каталог откуда запускаю - 2 файла include. Запускаю -
а мне выдается ошибка - Error: Unknown function name. на строчке
Local $i, $j, $rlist[1]=[0], $blist, $alist=_FileListToArray ($sPath, '*', 2)

amel27 16-12-2006 12:01

DenchikK
проверь наличие в заголовке скрипта строчек:
Код:

#include <File.au3>
#include <Array.au3>

Creat0R
Цитата:

Есть вопрос - а можно чтобы вместо (как опция) прикрепления гуи, можно было также прикреплять любое другое окно (по его заголовку)?
я не спец в ГУИ, но думаю в общем случае это неосуществимо
Цитата:

скрипт ругается на неопознанные стили
стиль для скобок добавил

DenchikK 16-12-2006 12:41

amel27
Есть эти строчки - один в один все как указано у Creat0R

amel27 16-12-2006 13:11

DenchikK
Цитата:

переписал в тот каталог откуда запускаю - 2 файла include
а разве со штатного INCLUDE эти файлы не подтягиваются?... Из справки по Include - если AutoIT установлен штатным установщиком то файлы берутся из установочного каталога\Include, в противном случае в каталоге скрипта нужно создавать папку с именем Include и туда пихать UDF-файлы или править реестр (хотя последние варианты не пробовал).

DenchikK 17-12-2006 04:44

Цитата:

а разве со штатного INCLUDE эти файлы не подтягиваются?
Это я уже от безысходности. Варианты пробую. AutoIT версий 3.1.0 и 3.1.1 ставил. В
Цитата:

установочного каталога\Include
они существуют, пихал эти файлы и рядом со скриптом, и рядом со скриптом каталогом - не работает! Что такое может быть?
Добавлено:
Нашел в скрипте Sanja Alone функцию _FileListToArray и поместил
её в файл \Include\Array.au3 (ибо этой функции ни в одно файле
каталога \Include не было), вот код:
Код:

Func _FileListToArray($sPath, $sFilter = "*", $iFlag = 0)
        Local $hSearch, $sFile, $asFileList[1]
        If Not FileExists($sPath) Then
                SetError(1)
                Return ""
        EndIf
        If (StringInStr($sFilter, "\")) or (StringInStr($sFilter, "/")) or (StringInStr($sFilter, ":")) or (StringInStr($sFilter, ">")) or (StringInStr($sFilter, "<")) or (StringInStr($sFilter, "|")) or (StringStripWS($sFilter, 8) = "") Then
                SetError(2)
                Return 0
        EndIf
        If Not ($iFlag = 0 Or $iFlag = 1 Or $iFlag = 2) Then
                SetError(3)
                Return ""
        EndIf
        $asFileList[0] = 0
        $hSearch = FileFindFirstFile($sPath & "\" & $sFilter)
        If $hSearch = -1 Then
                SetError(0)
                Return 0
        EndIf
        While 1
                $sFile = FileFindNextFile($hSearch)
                If @error Then ExitLoop
                If $iFlag = 1 Then
                        If StringInStr(FileGetAttrib($sPath & "\" & $sFile), "D") <> 0 Then ContinueLoop
                EndIf
                If $iFlag = 2 Then
                        If StringInStr(FileGetAttrib($sPath & "\" & $sFile), "D") = 0 Then ContinueLoop
                EndIf
                ReDim $asFileList[UBound($asFileList) + 1]
                $asFileList[0] = $asFileList[0] + 1
                $asFileList[UBound($asFileList) - 1] = $sFile
        WEnd
        FileClose($hSearch)
        SetError(0)
        If $asFileList[0] = 0 Then Return ""
        Return $asFileList
EndFunc  ;==>_FileListToArray

теперь ошибка выдается такая:
Local $i, $j, $rlist[1]=[0], $blist, $alist=_FileListToArray ($sPath, '*', 2)
Local $i, $j, $rlist[1] ERROR
Error: No virriable given for "Dim", "Local", "Global" or "Const" statement.

mpn 17-12-2006 10:30

Всем привет!
Поможите, кто может.
Задача простая. Необходимо периодически на удаленном компьютере (под Unix) выполнять ряд команд с дальнейшей обработкой выводимой в консоль информации. Хочу использовать для этого строку $t=Run("telnet","",@SW_HIDE,3) и далее при помощи StdinWrite, StdoutRead работать с открытой консолью. Но почему-то процесс telnet.exe закрывается сразу же после запуска. Где ошибка?

Creat0R 17-12-2006 11:16

amel27
Цитата:

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

Цитата:

стиль для скобок добавил
Thnx! ;)

mpn
Цитата:

почему-то процесс telnet.exe закрывается сразу же после запуска. Где ошибка?
Может этот процесс требует чтобы рабочий каталог был тот в котором он находится?
Попробуй перед запускам сменить рабочий каталог FileChangeDir("путь\к telnet.exe\"), или указать путь в самой сроке запуска...

Код:

$t=Run("telnet.exe","путь\к telnet.exe\",@SW_HIDE,3)
Или просто с полным путём запустить...

Код:

$t=Run("путь\к telnet.exe\telnet.exe","",@SW_HIDE,3)
DenchikK

Пиши скрипт так, и ненужно никаких Include ;) :

Код:

$Path = @ScriptDir & "\2"
$FileName = "1.txt"

$DirsList = _DirListToArray ($Path)
For $i = 1 to $DirsList[0]
    FileDelete($DirsList[$i] & "\" & $FileName)
Next
FileDelete($Path & "\" & $FileName)

Func _DirListToArray ($sPath)
    Local $i, $j, $rlist[1]=[0], $blist, $alist=_FileListToArray ($sPath, '*', 2)
    If IsArray ($alist) Then
        For $i=1 To $alist [0]
            _ArrayAdd ($rlist, $sPath & "\" & $alist [$i])
            $blist = _DirListToArray ($sPath & "\" & $alist [$i])
            If $blist[0]>0 Then
                For $j=1 To $blist [0]
                    _ArrayAdd ($rlist, $blist [$j])
                Next
            EndIf
        Next
    EndIf
    $rlist [0] = UBound ($rlist) - 1
    Return $rlist
EndFunc

Func _FileListToArray($sPath, $sFilter = "*", $iFlag = 0)
    Local $hSearch, $sFile, $asFileList[1]
    If Not FileExists($sPath) Then Return SetError(1,1,"")
    If (StringInStr($sFilter, "\")) or (StringInStr($sFilter, "/")) or (StringInStr($sFilter, ":")) or (StringInStr($sFilter, ">")) or (StringInStr($sFilter, "<")) or (StringInStr($sFilter, "|")) or (StringStripWS($sFilter, 8) = "") Then Return SetError(2,2,"")
    If Not ($iFlag = 0 Or $iFlag = 1 Or $iFlag = 2) Then Return SetError(3,3,"")
    $hSearch = FileFindFirstFile($sPath & "\" & $sFilter)
    If $hSearch = -1 Then Return SetError(4,4,"")
    While 1
        $sFile = FileFindNextFile($hSearch)
        If @error Then
            SetError(0)
            ExitLoop
        EndIf
        If $iFlag = 1 And StringInStr(FileGetAttrib($sPath & "\" & $sFile), "D") <> 0 Then ContinueLoop
        If $iFlag = 2 And StringInStr(FileGetAttrib($sPath & "\" & $sFile), "D") = 0 Then ContinueLoop
        ReDim $asFileList[UBound($asFileList) + 1]
        $asFileList[0] = $asFileList[0] + 1
        $asFileList[UBound($asFileList) - 1] = $sFile
    WEnd
    FileClose($hSearch)
    Return $asFileList
EndFunc

Func _ArrayAdd(ByRef $avArray, $sValue)
    If IsArray($avArray) Then
        ReDim $avArray[UBound($avArray) + 1]
        $avArray[UBound($avArray) - 1] = $sValue
        SetError(0)
        Return 1
    Else
        SetError(1)
        Return 0
    EndIf
EndFunc


Creat0R 17-12-2006 11:26

amel27
Цитата:

стиль для скобок добавил
По прикреплённому файлу...
Цитата:

Архив повреждён или имеет неизвестный формат
По ссылке в посте...

Цитата:

Sorry, the file you requested is not available.


:(

mpn 17-12-2006 11:52

Creat0R

Уже перепробовал все варианты. При этом, если если вместо telnet поставить, например, cmd - все работает.

DenchikK 17-12-2006 13:23

Creat0R
Спасибо большое, но всё равно ошибка выдается:
Local $i, $j, $rlist[1]=[0], $blist, $alist=_FileListToArray ($sPath, '*', 2)
Local $i, $j, $rlist[1] ERROR
Error: No virriable given for "Dim", "Local", "Global" or "Const" statement.

Creat0R 17-12-2006 17:06

mpn
Цитата:

Уже перепробовал все варианты
Используя ком. строку пробовал?
Код:

FileChangeDir("Путь к проге")
Run(@ComSpec, " /c start telnet.exe", "", @SW_HIDE)

DenchikK
Цитата:

ошибка выдается
Какая у тебя версия AutoIt?

DenchikK 17-12-2006 20:16

Creat0R
Цитата:

Какая у тебя версия AutoIt?
Цитата:

AutoIT версий 3.1.0 и 3.1.1 ставил.
Добавлено:
Всё, спасибо! Заработало! Зашел на сайт - а там версия новее. Скачал - всё замечательно! Ещё раз спасибо!

mpn 18-12-2006 06:50

Creat0R
Пробовал и с командной строкой. При этом первым запускается процесс cmd.exe, именно он становится доступным для ввода/вывода (последний параметр в команде run =3). Запускающийся следом telnet.exe не принимает команды, отправленные при помощи StdinWrite, даже при правильно указанном PID.
Поясню еще. Программу необходимо запускать в т.ч. и ночью на заблокированном компьютере. Поэтому использование send, отправляющей символы в активное DOS-окно, отпадает. Различные Control.. не работают с такими окнами. Пробовал вместо telnet запускать hyperterm.exe, но при его закрытии (на заблокированном ПК) Windows ругается: "...неизвестная ошибка...", и больше его запускать не хочет. Использование экзотических терминальных программ ограничивает мобильность скрипта.
Выход где-то должен быть!

DenchikK 18-12-2006 09:34

Creat0R
А можно Вас ещё побеспокоить? Никак не могу изменить скрипт так, чтоб
удалялись несколько файлов, и с нескольких путей. Приходится для
каждого файла и каждого пути писать отдельный скрипт, при компиляции
каждый скрипт начинает весить 180 kb, и несколько - уже весят за 2
мегабайта!
Заранее спасибо!

Creat0R 18-12-2006 15:16

mpn
А утилиту telnet пробовал ставить в тот же каталог вместе со скриптом? (или наоборот, скрипт в ту папку в которой telnet) - может что-то блокирует запуск программы? файрвол? какие то другие ограничители доступа в сеть?

DenchikK
Цитата:

изменить скрипт так, чтоб
удалялись несколько файлов, и с нескольких путей.
Для каждого файла, добавляй соответственно такой блок кода:

Код:

$Path = @ScriptDir & "\имя другого каталога"
$FileName = "имя другого файла.txt"

$DirsList = _DirListToArray ($Path)
For $i = 1 to $DirsList[0]
    FileDelete($DirsList[$i] & "\" & $FileName)
Next
FileDelete($Path & "\" & $FileName)

А ещё лучше, если действительно много таких "процедур" нужно делать, создать для этого процесса отдельно функцию:

Код:

Func _DeleteFileInFolders($FileName, $Path)
    $DirsList = _DirListToArray ($Path)
    For $i = 1 to $DirsList[0]
        FileDelete($DirsList[$i] & "\" & $FileName)
    Next
    FileDelete($Path & "\" & $FileName)
EndFunc

И тогда можно использовать её каждый раз при необходимости....


Код:

_DeleteFileInFolders("File1.txt", "C:\Dir1")

_DeleteFileInFolders("File2.txt", "C:\Dir2")

_DeleteFileInFolders("File3.txt", "C:\Dir3")

И т.д.


P.S
Функцию поместить в конец скрипта (после трёх существующих функции - _FileListToArray, _ArrayAdd и _DirListToArray).

Creat0R 19-12-2006 03:50

Переделал немного функцию для удаления файлов из подкаталогов, чтобы она ещё возвращала значения...
если все файлы были найдены, то возвращается сообщение о том что всё прошло успешно, если какого-то файла не удалось удалить, то возвращается список тех файлов которых не удалось удалить :) - если каталоги небыли найдены, или сам путь не сущестсвует, то также возвращается сообщение об ошибке.

P.S.

Хотелось бы узнать, как можно построить функцию так, чтобы возвращалось значение в массиве (через _ArrayAdd полагаю), я пробовал сделать, но у меня почему то возвращается только первое значение (из $Results[1]) - если кто-то может показать как правильно строить массив на примере с этой функцией (для удаления), то буду очень признателен.

Код:

$Results = _DeleteFileInFolders($FileName, $Path)

MsgBox(64, "Results", "Results of deleting:" & @CR & $Results)

Func _DeleteFileInFolders($FileName, $Path)
    Local $ErrDelList
    If Not FileExists($Path) Then Return "The destination folder <" & $Path & "> was not found"
    $ErrDelete1 = FileDelete($Path & "\" & $FileName)
    $DirsList = _DirListToArray($Path)
    If IsArray($DirsList) Then
        If $DirsList[0] = 0 And $ErrDelete1 = 0 Then Return "There is no file <" & $FileName & "> in the destination folders, and  in there is no folders in the destination path <" & $Path & ">"
        For $i = 1 to $DirsList[0]
            $ErrDelete2 = FileDelete($DirsList[$i] & "\" & $FileName)
            If $ErrDelete2 = 0 And FileExists($DirsList[$i] & "\" & $FileName) Then
                If $ErrDelete1 = 0 And FileExists($Path & "\" & $FileName) And StringInStr($ErrDelList, $Path & "\" & $FileName) = 0 Then $ErrDelList = $ErrDelList & @CR & "Can not delete the file <" & $Path & "\" & $FileName & ">"
                $ErrDelList = $ErrDelList & @CR & "Can not delete the file <" & $DirsList[$i] & "\" & $FileName & ">"
            ElseIf $ErrDelete2 = 0 And Not FileExists($DirsList[$i] & "\" & $FileName) Then
                If $ErrDelete1 = 0 And Not FileExists($Path & "\" & $FileName) And StringInStr($ErrDelList, $Path & "\" & $FileName) = 0 Then $ErrDelList = $ErrDelList & @CR & "File <" & $Path & "\" & $FileName & "> not found"
                $ErrDelList = $ErrDelList & @CR & "File <" & $DirsList[$i] & "\" & $FileName & "> not found"
            EndIf
        Next
        If $ErrDelList <> "" Then
            Return $ErrDelList
        ElseIf $ErrDelete1 = 0 Then
            Return "There is no file <" & $FileName & "> in the destination path <" & $Path & ">"
        Else
            Return "All files in the destination folder (and in his subfolders) was secceseful deleted!"
        EndIf
    Else
        Return ""
    EndIf
EndFunc


Sla8ak 19-12-2006 17:45

Доброго времени суток!

Интересует следующее - можно ли при помощи AutoIt скрипта сделать следуюющее.
Пользователь входит в систему, появляэтся переменная окружения %USERNAME%=zzz_aaa, где zzz - группа пользователя, aaa - инициалы пользователя.
Нужно получить только группу пользователя, и ввести в систему новую переменную set USERGROUP=zzz.
Вопрос каким образом можно взять из имени пользоваетля только группу.

Спасибо.
З.Ы. Имя пользователя находится в актив директори.

Creat0R 19-12-2006 18:56

Sla8ak
Цитата:

каким образом можно взять из имени пользоваетля только группу
Нужно разделить значение переменной по разделителю _, и взять первое значение из массива - а прописать новую переменную, думаю можно через EnvSet()...


Код:

$SplitUserName = StringSplit(@UserName, "_")

If IsArray($SplitUserName) Then
    $UserGroup = $SplitUserName[1]
Else
    $UserGroup = @UserName
EndIf

EnvSet("USERGROUP", $UserGroup)
EnvUpdate()


sattva 20-12-2006 21:30

С помощью какой команды можно переименовывать файлы!!? Например wgatray.exe в wgatray.exe.old.

Creat0R 21-12-2006 14:41

sattva
Цитата:

С помощью какой команды можно переименовывать файлы!!?
Как таковой, команды для переименования нет. Но для этой цели используется команда перемещения файла (FileMove()) в том же каталоге...

Код:

FileMove("wgatray.exe", "wgatray.exe.old")

-----------------------------------------
У меня есть такой вопрос:

-Возможно ли в GUI, построить реальную ссылку, на которую можно было бы нажать, и она открывалась в браузере (желательно чтобы был выбор с каким браузером запускать)?

Sla8ak 22-12-2006 14:37

Доброго времени суток.

Интересует следуюющий вопрос: каким образом при помощи AutoIt-скрипта можно перенаправить (переназначить) папку "Мои документы" в другое место, например на сетевой ресурс.

Заранее спасибо.

Djons 23-12-2006 18:38

Vadikan

Как конвертировать в код AutoIt v3 вот такой CMD скрипт?
Будь добр, приведи код готового скрипта.
Код:

FOR %%I IN (C D E F G H I J K L M N O P Q R S T U V W X Y Z) DO IF EXIST %%I:\PROG.EXE SET path=%%I:\;%path%
reg add "HKLM\SYSTEM\ControlSet001\Control\Session Manager\Environment" /v Path /t REG_SZ /d %path% /f
reg add "HKCU\Environment" /v Path /t REG_SZ /d %path% /f


Creat0R 23-12-2006 23:54

Sla8ak
Цитата:

каким образом при помощи AutoIt-скрипта можно перенаправить (переназначить) папку "Мои документы" в другое место
Можно через реестер...

Код:

$NewMyDocsPath = "C:\MyDocs"
RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\DocFolderPaths", @UserName, "REG_SZ", $NewMyDocsPath)

Djons
Цитата:

Как конвертировать в код AutoIt v3 вот такой CMD скрипт?
Конвертировать, как мне самому недавно выяснилось (тут я тоже задавал подобный ворос), нет возможности, но можно написать что-то подобное...

Код:

$AllDrivesVar = DriveGetDrive("all")

For $i = 1 to $AllDrivesVar[0]
    If $AllDrivesVar[$i] <> "a:" And $AllDrivesVar[$i] <> "b:" And FileExists($AllDrivesVar[$i] & "\PROG.EXE") Then EnvSet("PATH", $AllDrivesVar[$i] & "\;" & EnvGet("PATH"))
Next

Если PROG.EXE будет существовать в нескольких дисках, то и эти диски будут добавлены в переменную PATH.

bes1de 24-12-2006 00:06

есть скрипт autoit_KIS.exe .для запуска нужен еще и AutoIt3.exe ? или скрипт сам по себе?

Creat0R 24-12-2006 01:02

bes1de
Цитата:

.для запуска нужен еще и AutoIt3.exe ? или скрипт сам по себе?
Закомпелированный скрипт не нуждается ни в каких компонентах со стороны AutoIT.

Djons 24-12-2006 01:13

Creat0R

Спасибо, буду пробовать.

Djons 24-12-2006 09:46

Creat0R

Код:

$AllDrivesVar = DriveGetDrive("all")

For $i = 1 to $AllDrivesVar[0]
    If $AllDrivesVar[$i] <> "a:" And $AllDrivesVar[$i] <> "b:" And FileExists($AllDrivesVar[$i] & "\PROGPE.WIM") Then EnvSet("PATH", $AllDrivesVar[$i] & "\;" & EnvGet("PATH"))
Next

Эта конструкция ничего не дала. В реестре запись диск не добавлен.
Подскажи как точно нужно написать скрипт.
Я то в этих скриптах ни бум-бум.

Creat0R 24-12-2006 16:13

Djons
Цитата:

Эта конструкция ничего не дала
Странно, должна была прописаться переменная... вот вроде рабочий вариант:

Код:

$AllDrivesVar = DriveGetDrive("all")

For $i = 1 to $AllDrivesVar[0]
    If $AllDrivesVar[$i] <> "a:" And $AllDrivesVar[$i] <> "b:" And FileExists($AllDrivesVar[$i] & "\PROGPE.WIM") Then
        RegWrite("HKLM\SYSTEM\ControlSet001\Control\Session Manager\Environment", "Path", "REG_EXPAND_SZ", $AllDrivesVar[$i] & "\;" & EnvGet("Path"))
        RegWrite("HKCU\Environment", "Path", "REG_SZ", $AllDrivesVar[$i] & "\;" & EnvGet("Path"))
    EndIf
Next
EnvUpdate()


Последняя строка предназначена для обновления переменных сред.

S377 25-12-2006 15:12

помогите, пожалуйста такая проблема автоит версия 3,2
пытаюсь эмулировать клики мыши по касперскому 5
Код:

WinWaitActive("Антивирус Касперского Personal", "Настройка")
ControlClick("Антивирус Касперского Personal", "Настройка", "Обновления")

и тишина...

Creat0R 25-12-2006 18:14

S377
Используй AutoIt Window Information Tool (Aut3info.exe) чтобы определить заголовок окна, его текст, и класс кнопки ( ClassNameNN: ) на которую нужно нажать. Также учти, заголовок окна (и, наверное текст), чувствителен к регистру, попробуй ставить в начале скрипта Opt("WinTitleMatchMode", 4) .

S377 27-12-2006 10:24

использую AutoIt Window Information Tool (Aut3info.exe)
но она чтото часто гонит может изза того что в виртуальном компе отлаживаю скрипты
видимо в виртуальном компе и добром ControlClick не работает?
что скажете по этому?
и еще можно сделать клик мыши (координаты мыши ОТНОСИТЕЛЬНО ОКНА) ?

Creat0R 27-12-2006 10:51

S377
Цитата:

можно сделать клик мыши (координаты мыши ОТНОСИТЕЛЬНО ОКНА) ?
Для относительных координатов, поставь в Aut3info.exe опцию Options - Coord mode - Client - и тогда при наведении курсора координаты будут отображаться относительно границам активного окна.

А в начало скрипта такую строку нужно ставить:

Код:

Opt("MouseCoordMode", 0) ;или вместо 0 -> 2 - тога будет относительно клиентским участкам окна

S377 27-12-2006 12:19

Благодарствую за совет!
не знал про: Opt("MouseCoordMode", 0) ;или вместо 0 -> 2
это очень удобно

DenchikK 29-12-2006 00:39

Хотел спросить, можно ли такое осуществить на примере установки
соединения и настройки модема. А именно - список установленных модемов
как я поонимаю, сортируется по алфавиту. Предугадать заранее, на каком
месте он окажется, разумеется не возможно. Можно всё таки как то
установить курсор на нужный мне модем (тот, который заранее знаешь как
называется)?
Список модемов в "Телефонах и Модемах" определяется как
SysListView322, при установке соединения - SysListView321

Djons 29-12-2006 01:54

Creat0R

Вот так работает:

Код:

For $i = 1 to $AllDrivesVar[0]
    If $AllDrivesVar[$i] <> "a:" And $AllDrivesVar[$i] <> "b:" And FileExists($AllDrivesVar[$i] & "\GEB.CD") Then
    RegWrite("HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Session Manager\Environment", "Path", "REG_SZ", $AllDrivesVar[$i] & "\;" & EnvGet("PATH"))
    RegWrite("HKEY_CURRENT_USER\Environment", "Path", "REG_SZ", $AllDrivesVar[$i] & "\;" & EnvGet("PATH"))
EndIf
Next


TERMINAL 29-12-2006 12:48

1.У меня вопрос такой...
Можно ли в скрипте написать такую прогу которая будет определять дату записи диска (например, дата записи диска 30.12.2006 программой НЕРО) и если дата не соответствует то выполняется например перезагрузка машины а если дата соответствует, то выполняется к примеру старт файла SETUP.exe?

Creat0R 30-12-2006 05:28

Кто нибудь сталкивался с _GuiCtrlStatusBarGetText? оно не работает в GUI :(

Берём тот же пример из справки:


Код:

opt("MustDeclareVars", 1)

#include <GUIConstants.au3>
#Include <GuiStatusBar.au3>

Local $gui, $StatusBar1, $msg, $lbl_Info
Local $a_PartsRightEdge[3] = [100, 350, -1]
Local $a_PartsText[3] = ["New Text", "More Text", "Even More Text"]

$gui = GUICreate("Status Bar Get Text", 500, -1, -1, -1, $WS_SIZEBOX)
$lbl_Info = GUICtrlCreateLabel("", 10, 10, 150, 50, $SS_SUNKEN)
$StatusBar1 = _GUICtrlStatusBarCreate ($gui, $a_PartsRightEdge, $a_PartsText)

GUICtrlSetData($lbl_Info, "1st Part: " & _GUICtrlStatusBarGetText ($StatusBar1, 0) & @LF & _
        "2nd Part: " & _GUICtrlStatusBarGetText ($StatusBar1, 1) & @LF & _
        "3rd Part: " & _GUICtrlStatusBarGetText ($StatusBar1, 2))

GUISetState(@SW_SHOW)


While 1
    $msg = GUIGetMsg()
    Select
        Case $msg = $GUI_EVENT_RESIZED
            _GUICtrlStatusBarResize ($StatusBar1)
        Case $msg = $GUI_EVENT_CLOSE
            ExitLoop
        Case Else
            ;;;;;
    EndSelect
   
WEnd

По идее, в верхнем левом углу должны отображаться значения текста взятого из статус бара, но текст не отображается.

Как получить текст из статус-бара?

Diamond 30-12-2006 15:17

Поздравляю Всех С Наступающим Новым Годом!
Я тут написал небольшую функцию, возможно кому ни-будь она пригодится...
Код:

; Преобразовывает десятичное число в другие системы счисления
; Использование:    encode($val,$type)
; $val - конвертируемое десятичное число
; $type - система счисления в которую требуется преобразовать число
Global Const $Heh=16
Global Const $Oct=8
Global Const $Bin=2

$num=987
msgbox(0,"",encode($num,$Heh))

Func encode($val,$type)
$string=""
While $val
        $MB=_Mod($val,$type)
        Select
                Case $MB=10
                $MB="A"
                Case $MB=11
                $MB="B"
                Case $MB=12
                $MB="C"
                Case $MB=13
                $MB="D"
                Case $MB=14
                $MB="E"
                Case $MB=15
                $MB="F"
        EndSelect
        $val=Int($val/$type)
        $string=$MB & $string
WEnd
Return $string
EndFunc

; Альтернатива функции Mod():
; $A - Делимое
; $B - Делитель
Func _Mod($A,$B)
        $Q=$A/$B
        $ret=($Q-Int($Q))*$B
        Return $ret
EndFunc


Diamond 31-12-2006 06:22

Обратное преобразование в десятичное число.
Код:

; Преобразовывает числа из различных систем счисления в привычные нам десятичные
; Использование:    decode($val,$type)
; $val - конвертируемое число
; $type - система счисления из которой требуется преобразовать число
Global Const $Heh=16
Global Const $Oct=8
Global Const $Bin=2

$num="11111111"
MsgBox(0,"",decode($num,$Bin))

Func decode($val,$type)
$string=0
$step=StringLen($val)
While $step
$MB=StringLeft($val,1)
        Select
                Case $MB="A"
                $MB=10
                Case $MB="B"
                $MB=11
                Case $MB="C"
                $MB=12
                Case $MB="D"
                $MB=13
                Case $MB="E"
                $MB=14
                Case $MB="F"
                $MB=15
        EndSelect
        For $i=2 To $step
                $MB=$MB*$type
        Next
        $string=$string+$MB
        $val=StringRight($val,StringLen($val)-1)
        $step=$step-1
WEnd
Return $string
EndFunc


Creat0R 31-12-2006 08:30

Всех с новым годом!

Вопрос опять по гуи (непомню задавал ли уже, по поиску вроде не нашел)...

Возможно ли внедрить ссылку в гуи? т.е чтобы был подчёркнуты текст как ссылка, и при нажатии выполнялось какое то действие (запуск браузера с ссылкой - но это я знаю как сделать).

Diamond 31-12-2006 14:18

Creat0R
Можно внедрить целую HTML страницу:
Код:

#include <GUIConstants.au3>
Opt("GUIOnEventMode", 1)
$oIE = ObjCreate("Shell.Explorer.2")
GUICreate( "Внедренная HTML-страница",640,480)
$GUIActiveX=GUICtrlCreateObj( $oIE,0,0,640,480 )
GUISetOnEvent($GUI_EVENT_CLOSE,"closed")
GUISetState ()
$oIE.navigate("C:\Моя страничка.html")
While 1
Sleep(1000)
Wend
Func closed()
        Exit
EndFunc

Или сделать имитацию ссылки, вроде этой:
Код:

#include <GUIConstants.au3>
Opt("GUIOnEventMode", 1)
$title="Имитация ссылки"
$test= GUICreate($title,"320","240")
GUISetOnEvent($GUI_EVENT_CLOSE,"closed")
$label=GUICtrlCreateLabel("Ссылка",10,10,80,20)
GUICtrlSetCursor (-1,0 )
GUICtrlSetColor(-1,0x0000ff)
GUICtrlSetFont(-1,14,400,6)
GUICtrlSetOnEvent(-1,"event")
GUISetState()
While 1
        Sleep(1000)
WEnd
Func closed()
        Exit
EndFunc
Func event()
        GUICtrlSetColor($label,0xAC00A9)
        Run("explorer.exe http://forum.oszone.net/")
EndFunc


Creat0R 01-01-2007 00:16

Diamond_m
Цитата:

сделать имитацию ссылки
Гинеально!!! я и не думал что это так просто! С новым Годом тебя и всех всех всех!!!

biggreeder 01-01-2007 23:38

Вопрос знатокам AutoIt:
как при помощи этой программы изменить права доступа NTFS к отдельному файлу (в WinXP естесственно)?

Sanja Alone 02-01-2007 02:46

biggreeder
Цитата:

изменить права доступа NTFS к отдельному файлу
%SystemRoot%\system32\cacls.exe + RunWait

biggreeder 02-01-2007 23:47

Sanja Alone
А можно "по-пензенски"?
Как конкретно команду прописать, чтобы запретить запись "C:\Путь_к_файлу\Имя_файла" для групп SYSTEM и администраторы?

Sanja Alone 03-01-2007 17:30

biggreeder
Цитата:

А можно "по-пензенски"?
cmd:
Код:

cacls "C:\Путь_к_файлу\Имя_файла" /E /G SYSTEM:R Администраторы:R
AutoIt:
Код:

RunWait(@comspec & ' /c cacls "C:\Путь_к_файлу\Имя_файла" /E /G SYSTEM:R Администраторы:R','',@SW_HIDE)

biggreeder 03-01-2007 23:09

Sanja Alone
Спасибо, думал я не так что-то делаю. Но именно такие команды на срабатывают. В смысле права доступа остаются прежними.
И разные варианты команд пробовал и разные файлы. Ничего не помогает... :(

Creat0R 04-01-2007 04:32

Как можно деактивировать гуи (GuiSetState(@SW_DISABLE)), но чтобы можно было перетаскивать окно (через заголовок)? или хотябы как деактивировать элементы гуи (кнопки, поля ввода и т.д.), но чтобы они не затемнялись, а в обычном их виде были недоступны для использования?

Diamond 04-01-2007 11:09

Creat0R
Цитата:

Как можно деактивировать гуи
Тебе нужно блокировать не само GUI а скорее обработку событий...
Ведь если запретить обработку событий ВСЕХ кнопок и элементов то это и будет по сути заблокированное GUI.
В функции которая обрабатывает событие кнопки надо поставить условие:
Код:

Dim $zapret=False
; Пока функция MainEvent() работает кнопка не среагирует
Func MainEvent()
        $zapret=True
                Sleep(3000)
        $zapret=False
EndFunc
; функция кнопки:
Func PressButton()
        If $zapret=False Then
                Msgbox(0,"","Функция кнопки Выполнена")
        Endif
EndFunc

Например оставить $zapret=True пока пользователь не введёт верный пароль и т.п.

Creat0R 04-01-2007 11:39

Diamond_m
Цитата:

Тебе нужно блокировать не само GUI а скорее обработку событий...
Нет, именно гуи (или кнопки - т.е элементы), мне нужно чтобы небыло возможности нажать на кнопку, ввести текст в поле ввода, или зажать чекбокс... т.е другими словами - заблокировать с точки зрения интерфейса а не функциональности... и, кстати, хотелось бы также блокировать не только гуи, но и внешние окна, т.е блокировать то можно, но нужно так, чтобы была при этом возможность перетаскивать окно, сворачивать его, или (если есть возможность) разворачивать.

И даже если и подойдёт такой ввариант, у меня слишком много чекбоксов в гуи (более 30-ти), и ставить их всех на условия не очень практичное решение... хотелось бы просто заблокировать элемент (чекбокс к примеру), и чтобы небыло возможности зажать галку, но и вид чтобы оригинальный оставался. Я думал что может есть какой то стиль который это делает, но в справке уже замучался искать :(

Спасибо за попытку помочь... но мне кажется моей задумке (как и многим другим моим задумкам :) ), в AutoIt'е просто нет решения :(

Diamond 04-01-2007 16:13

Creat0R
Цитата:

чтобы небыло возможности зажать галку, но и вид чтобы оригинальный оставался.
Могу предложить такое решение.
Код:

#include <GUIConstants.au3>
Opt("GUIOnEventMode", 1)
$test= GUICreate("TestCover","400","300")
GUISetOnEvent($GUI_EVENT_CLOSE,"closed")
$cover=GUICtrlCreateLabel("",0, 0, 400,300)
GUICtrlSetState($cover,$GUI_DISABLE)
Dim $status=0
$CTRL_btn1 = GUICtrlCreateButton ("Заблокировать GUI", 180, 130, 120, 22,$BS_DEFPUSHBUTTON)
GUICtrlSetOnEvent($CTRL_btn1,"CoverGui")
$CTRL_Checkbox = GUICtrlCreateCheckbox ("Checkbox",80,5,66,15)
GUICtrlCreateGroup ("RadioGroup", 5, 5, 70, 60)
$radio0 = GUICtrlCreateRadio ("radio1", 10, 20, 50, 15)
$radio1 = GUICtrlCreateRadio ("radio2", 10, 40, 50, 15)
GUICtrlSetState ($radio0,$GUI_CHECKED)
GUICtrlCreateGroup ("",-99,-99,1,1)
$CTRL_edit = GUICtrlCreateEdit ("0", 10, 80, 34, 18,$ES_NUMBER)
GUISetState()
While 1
        Sleep(1000)
WEnd
Func closed()
        Exit(0)
EndFunc
Func CoverGui()
        If $status=1 Then
                GUICtrlSetState($cover,$GUI_DISABLE)
                $status=0
        Else
                GUICtrlSetState($cover,$GUI_ENABLE)
                $status=1
        EndIf
EndFunc


Creat0R 04-01-2007 23:01

Diamond_m
Цитата:

Могу предложить такое решение
Решение отличное :yes: - но нет "защиты от дурака" :no: - нажимаем пробел (или перед этим таб), и кнопка снова нажимается... :(

Может можно как то блокировать доступ клавиатуры именно в гуи (BlockInput() не предлагать :) )?

Diamond 05-01-2007 11:12

Creat0R
Сначала я решил что дело только в стиле кнопки $BS_DEFPUSHBUTTON, который я вставил умышленно для удобства тестирования. К сожалению о пробеле и TAB я не подумал. :sorry: А что если в функцию CoverGui() после условия Else добавить строчку: ControlFocus("TestCover","",$cover) а в шапке добавить: HotKeySet("{TAB}","nul") где nul() это пустая функция которая ничего ни делает (её так-же придётся дописать). Это сработает! Минус только в том что мы получаем неработающую клавишу {TAB} в системе. Ну и конечно убрать стиль: $BS_DEFPUSHBUTTON с кнопки, чтобы ее нельзя было нажать с помощью ENTER.

Diamond 05-01-2007 12:47

Creat0R
Ещё проще... Ничего в шапке писать не надо, потребуется только изменить функцию.
Это хотя бы позволит отключить {TAB} только на момент блокировки GUI.
Код:

Func CoverGui()
        If $status=1 Then
                GUICtrlSetState($cover,$GUI_DISABLE)
                $status=0
                HotKeySet("{TAB}") ;снимаю блокировку {TAB}
                HotKeySet("^{TAB}")
                HotKeySet("+{TAB}")
        Else
                GUICtrlSetState($cover,$GUI_ENABLE)
                $status=1
                ControlFocus("TestCover","",$cover)
                HotKeySet("{TAB}","nul") ; блокирую возможные комбинации {TAB}
                HotKeySet("^{TAB}","nul")
                HotKeySet("+{TAB}","nul")
        EndIf
EndFunc
Func nul()
EndFunc


Creat0R 05-01-2007 14:03

Diamond_m
Цитата:

Минус только в том что мы получаем неработающую клавишу {TAB} в системе
И Space (если и её таким образом "отключить")....

Ладно, ничего не поделать, придётся деактивировать "некрасиво" ;) ($GUI_DISABLE - или 128).

Есть у меня друга задумка, но она тоже не работает :( - нужно поставить прогресс бар, и потом отменить его... вот гуи, и не пойму почему не работает такая конструкция:

Код:

Opt("GuiOnEventMode", 1)
#include <GUIConstants.au3>

Global $ExitLoop
$gui = GUICreate("Abort GUI", 420, 140, -1, -1, $WS_SIZEBOX)
$Button = GUICtrlCreateButton("Start", 180, 20, 70)
GUICtrlSetOnEvent($Button, "Button")
GUISetOnEvent(-3, "ExitScript")

$Progress = GUICtrlCreateProgress(60, 60, 300, 15)

GUISetState(@SW_SHOW)

While 1
  Sleep(100)
WEnd

Func Button()
    GUICtrlSetData($Button, "Abort")
    GUICtrlSetOnEvent($Button, "SetExitLoop")
    While $ExitLoop = 0
        For $i = 10 To 100
            Sleep(10)
            GUICtrlSetData($Progress, $i)
        Next
    WEnd
    GUICtrlSetData($Button, "Start")
EndFunc

Func SetExitLoop()
    $ExitLoop = 1
EndFunc

Func ExitScript()
    Exit
EndFunc


kalikanzaros 05-01-2007 17:03

есть ли у кого нибудь красивое решение установки alcohol120 а потом сразу lingvo11?
так как пока что у меня все это выглядит достаточно сложно и некрасиво... :(

запускаю autoit скрипты из wpi 5.6, который в свое очередь стартует из RunOnceEx.cmd который стартует с CD...
надеюсь про запуск строчка будет понятна :)

вот как сейчас это работает у меня: скрипт alcohol120 отрабатывает, а потом команда %reboot%, wpi перезагружает комп, я наивный думал что потом продолжится установка alcohol120, и только затем стартанет lingvo11, но нет, wpi запускается раньше и не дает закончить установку....
конечно можно сделать в 3 строки, что-то типа:
alcoho120.exe (без добавления в автозагрузку скрипта после перезагрузки)
%reboot%
alchol120.exe (скрипт закончит установку)

и потом начнется установка lingvo11, скрипт lingvo11 первым делом запустит установленный alcohol и даст ему секунд 5-10 для создания виртуального CD, после чего alcohol будет закрыт, а установка lingvo11 продолжена...

но мне кажется есть решение проще и красивее, нет ни у кого идей?

Diamond 05-01-2007 18:24

Creat0R
Ты наверное заметил что во время работы цикла также недоступна обработка системного события (т.е. Выход из GUI). Я думаю, единственный путь привязать функцию к основному циклу. Может кто-то считает по другому? :)
Код:

Opt("GuiOnEventMode", 1)
#include <GUIConstants.au3>
Global $StartProgress=0, $i=0
$gui = GUICreate("Abort GUI", 420, 140, -1, -1, $WS_SIZEBOX)
$Button = GUICtrlCreateButton("Start", 180, 20, 70)
GUICtrlSetOnEvent($Button, "SetExitLoop")
GUISetOnEvent(-3, "ExitScript")
$Progress = GUICtrlCreateProgress(60, 60, 300, 15)
GUISetState(@SW_SHOW)

While 1
  Sleep(10)
If $StartProgress = 1 Then
        Button()
EndIf
WEnd

Func Button()
$i=$i+1
If $i=101 Then
        $i=0
EndIf
GUICtrlSetData($Progress, $i)
EndFunc

Func SetExitLoop()
If $StartProgress=1 Then
        $StartProgress = 0
    GUICtrlSetData($Button, "Start")
Else
        $StartProgress = 1
        GUICtrlSetData($Button, "Abort")
EndIf
EndFunc

Func ExitScript()
    Exit
EndFunc


Creat0R 06-01-2007 01:06

Diamond_m
Цитата:

привязать функцию к основному циклу.
Это в каком то роде решает проблему, спасибо!

НО!, ах это "но"...

Проблема в том, что основной цикл не удобно использовать, у меня на кнопку старта, повешаны многие операции (функции, и статус бар ещё). Т.е запускается скрипт, нажимаем кнопку Старт, пускается по событию функция кнопки, в этой функции существует цикл, т.е в самом конце цикла происходит выход с него ExitLoop (обязательно), и мне нужно сделать так, чтобы в процессе выполнения всего этого цикла (показа статус бара, прогресс бара, выполнения разных функции и т.п), можно было нажать на кнопку "Аборт", и тогда должен происходить выход из цикла (не закрывая программу) - а точнее, должно выводиться сообщение с вопросом, мол хочет ли юзерь прервать операцию, и если ответить положительно, то выходим из цикла, если отрецательно, ничего не делаем, продолжаем с того же места на котором была нажата кнопка "Аборт" (тот же "Старт" переименованный)...

Нужно каким то образом, заставить вызвать событие (функцию) из самого цикла, преостановив этот самый цикл...

В приведённом тобой примере, функция которая вызывается по нажатию кнопки, как бы вызывается без прерывно, т.e постоянно начинается с начала, а мне нужно чтобы начало функции не происходило, при нажатии на "Аборт" просто приостанавливалось её (функции) выполнение.

Кстати, вот если не убирать иконку в трее, и оставить её функциональность по умолчанию, то при нажатии на неё появяется меню, там можно выбрать пункт Script Paused, и скрипт полностью преостанавливается - вот может можно как то точно также имитировать подобную паузу (вызвать функцию во время паузы)?

P.S
Надеюсь не запутался в объяснениях, просто уже голова пухнет от того что не могу никак сообразить, как решить эту, кажется простую задачку.
:wacko:

Creat0R 06-01-2007 02:59

ВО! такой вариант работает по нажатию на горячую клавишу (Ctrl S), почему же событие не срабатывает при нажатии на кнопку? :idontnow:


Код:

Opt("GuiOnEventMode", 1)
#include <GUIConstants.au3>
HotKeySet("^s", "SetExitLoop")

Global $ExitLoop, $Mark = 10
$gui = GUICreate("Abort GUI", 420, 140, -1, -1, $WS_SIZEBOX)
$Button = GUICtrlCreateButton("Start", 180, 20, 70)
GUICtrlSetOnEvent($Button, "Button")
GUISetOnEvent(-3, "ExitScript")

$Progress = GUICtrlCreateProgress(60, 60, 300, 15)
GUISetState(@SW_SHOW)

While 1
  Sleep(100)
WEnd

Func Button()
    GUICtrlSetData($Button, "Abort")
    While $ExitLoop = 0
        For $i = $Mark To 100
            If $i = 100 Then $i = 0
            GUICtrlSetData($Progress, $i)
            If $ExitLoop = 1 Then
                $Mark = $i
                ExitLoop
            EndIf
            Sleep(10)
        Next
    WEnd
    GUICtrlSetData($Button, "Start")
    $ExitLoop = 0
EndFunc

Func SetExitLoop()
    $ExitLoop = 1
EndFunc

Func ExitScript()
    Exit
EndFunc


Diamond 06-01-2007 05:21

Creat0R
Цитата:

Нужно каким то образом, заставить вызвать событие (функцию) из самого цикла
Чтобы реализовать это, придётся отказаться от Opt("GuiOnEventMode", 1), тогда опрос событий GUIGetMsg() можно будет проводить непосредственно в твоём цикле. Другого выхода не вижу. :idontnow: Возможно это не удобно с точки зрения программиста но с точки зрения функциональности скрипта - вполне приемлемо.

RemoteAdmin 06-01-2007 14:16

Всем привет! Помогите новичку.
Вообщем возникла такая проблема. Мне нужно заменить один текст внутри exe файла, на свой.

Ну например, текст: This program cannot be run in DOS mode
Заменить на текст: <----------------AutoIT RuleZ---------------->

Я пытался использовать вот эту функцию:
Код:

Func ReplaceText($FileNameT, $OldText, $NewText)
        $hFile = FileOpen($FileNameT, 0)
        $aArray = StringSplit(FileRead($hFile, FileGetSize($FileNameT)), @LF)
        If Not @error Then
                FileClose($hFile)
                $hFilew = FileOpen($FileNameT, 2)
                For $iaar = 1 To $aArray[0] - 1
                        $ReplStrT = StringReplace($aArray[$iaar], $OldText, $NewText)
                        FileWrite($hFilew, $ReplStrT & @LF)
                Next
                FileClose($hFilew)
        EndIf
EndFunc

Текст заменяется, но из конца файла отрезается маленький кусок, т.е. как я понимаю, он после разбиения файла на подстроки, не может его обратно собрать.

Я также пытался, передавать ему не простые строки текста, но и в HEX, Binary формате (BinaryString), всё равно не может ничё сделать.
На офф, форумах AutoIT нашёл функции BinaryWrite/BinaryRead, но так и не смог в них разобратся.

Не могли бы вы помочь мне, в реализации моей затеи, желательно с примерами. Спасибо.

Creat0R 06-01-2007 17:46

Diamond_m
Цитата:

Чтобы реализовать это, придётся отказаться от Opt("GuiOnEventMode", 1), тогда опрос событий GUIGetMsg() можно будет проводить непосредственно в твоём цикле.
В принципе это даже очень подходит, просто отменяем проверку событии (Opt("GuiOnEventMode", 0)) перед началом цикла, а в начало цикла ставим $Msg = GuiGetMsg() - ну и потом всё что нужно обрабатываем на основе $Msg = $ID ... а в конце цикла просто включаем обратно обработку событии - вобщем, вроде проблема решена :) - спасибо.

Diamond 06-01-2007 20:55

Creat0R
Цитата:

а в конце цикла просто включаем обратно обработку событии
Отлично придумал!!! :victory: Это позволит не переписывать большую часть скрипта заново, а также добавит ему гибкости.

Creat0R 08-01-2007 00:32

RemoteAdmin
Цитата:

из конца файла отрезается маленький кусок
Это можно поправить убрав - 1 от общего числа массива (For $iaar = 1 To $aArray[0]), но тогда в конец файла всегда будет дописываться новая строка...

Могу предложить такой вариант на функцию замены текста в файле:

Код:

Func ReplaceText($FileName, $OldText, $NewText)
    If $OldText <> "" Then
        $hFile = FileOpen($FileName, 0)
        $VarToWrite = FileRead($hFile, FileGetSize($FileName))
        $ReplStr = StringReplace($VarToWrite, $OldText, $NewText)
        FileClose($hFile)
        $hFilew = FileOpen($FileName, 2)
        FileWrite($hFilew, $ReplStr)
        FileClose($hFilew)
    EndIf
 EndFunc

Diamond_m
Цитата:

Отлично придумал!!!
Это благодаря твоим наводкам ;) - спасибо ещё раз!

Creat0R 09-01-2007 07:05

Написал две примитивные функции - Одна предназначена для не совсем точного подсчёта скорости закачки (по InetGet), а друга на основе этой скорости закачки высчитывает сколько времени осталось до окончания (в секундах)...
НО! я полагаю что есть более точное решение этой задумке, ведь по идее, должны учитываться не просто полученные данные в интервале одной секунды, а ещё и скорость модема, скорость отдачи на сервере и т.п... вот как бы всё это расчитать, и построить точную функцию для подсчёта скорости закачки и оставшееся время до окончания? :idontnow:

Вот эти две функции и пример их применения:

Код:

;Заносим в переменную $URL ссылку на закачку.
$URL = "http://www.autoitscript.com/cgi-bin/getfile.pl?autoit3/autoit-v3.2.2.0-setup.exe"

;Берём из ссылки только имя файла.
$FileName = StringRegExpReplace($URL, "^.*/", "")

;Ставим ссылку на закачку в фоновом режиме.
InetGet($URL, "C:\" & $FileName, 1, 1)

;Получаем общий размер файла по ссылке (в байтах).
$InetGetSize = InetGetSize($URL)

;Пока файл закачивается, проверяем размер, оставшееся время, и выводим в трее результаты.
While @InetGetActive
    $BytesCheckBefore = @InetGetBytesRead
    Sleep(1000)
    $BytesCheckAfter = @InetGetBytesRead
    $SpeedByBytes = _InetGetSpeed($BytesCheckAfter, $BytesCheckBefore)
    TrayTip("Download", "Approximately Remained Time (seconds): " & Round(_InetGetRemained(@InetGetBytesRead, $InetGetSize, $SpeedByBytes)), 0, 1)
WEnd

;Функция возвращает скорость скачивания на основе полученных данных (до, и после секунды) - возвращаются байты в секунду (b/s).
Func _InetGetSpeed($BytesCheckAfter, $BytesCheckBefore)
    $RetSpeedByBytes = $BytesCheckAfter - $BytesCheckBefore
    If $RetSpeedByBytes < 0 Then Return 0
    Return $RetSpeedByBytes
EndFunc

;Функция возвращает оставшееся время в секундах (за счёт вычесления из общего размера файла и деления на скорость скачивания).
Func _InetGetRemained($Bytes, $TotalBytesSize, $SpeedByBytes)
    $RemainedBytes = $TotalBytesSize - $Bytes
    If $RemainedBytes <= 0 Then Return 0
    Return $RemainedBytes / $SpeedByBytes
EndFunc


P.S.
Если файл около 2-ух 3-ёх MB, то функции подсчитывают довольно точно, но если речь идёт уже о 5-ти и более MB, то счётчик начинает показыать результаты в хаотичном порядке.

timon_90 09-01-2007 13:53

Привет народ... Я в этом деле новичок, но мне нужно сделать автоматизацию не из самых простых (как для меня) :) Вообщем помогите плиз чем сможете... Что собственно нужно:
Есть кейген...
1) Нужно его запустить (сделал)
2) Нажать на кнопку Generate (не получилось, но это впринципе не обязательно)
3) Скопировать текст(ключ), который он выдал (тоже непонятно)
4) Затем создать новую запись в реестре по заданному мной пути (ну в данном случае это HKEY_LOCAL_MACHINE\SOFTWARE\Electronic Arts\EA Games\Battlefield 2\ergc)
5) Создать там параметр со стандартным именем (строковый, REG_SZ)
6) Изменить его значение на такое - x9392тотсерийникбезчёрточек
вот собственно и конец... Если никто не сможет помочь по каким либо причинам то расскажите хотя бы как делать вышеперечисленные операции :) Заранее спасибо !!!

Sanja Alone 09-01-2007 16:29

timon_90
Для начала, прочти FAQ

2). Пункт 7 раздела Вввод данных / работа с элементами управления FAQ - ф-ция ControlClick();
3). Ф-ция ControlGetText();
4,5,6). Пункт 2 раздела Импорт данных из reg-файла в реестр FAQ - ф-ция RegWrite(). Заменить черточки пустотой - StringReplace("серийник с черточками","-","").

P.S. Во многих моих скриптах выполняются подобные действия - используй их в кач-ве примера (посмотри скрипт для Alcohol, FR7, SoundForge 6 и др.)

timon_90 09-01-2007 16:43

Сенк большой!) Если будет чёто не понятно то напишу)

Diamond 09-01-2007 18:26

Для тех кто хочет использовать трекерную музыку в проектах AutoIt.
Трекерная музыка фактически не загружает CPU и из-за её малых размеров, пользуется популярностью программистов при написании кейгенов, кряков, трайнеров, а также инсталяторов.
Для проигрывания трекерных модулей в AutoIt я использую библиотеку BASSMOD.dll.
BASSMOD.dll (не путать с bass.dll) можно скачать c оф. сайта http://www.un4seen.com весит 33,5 КБ
Много трекерной музыки можно найти на сайте http://www.keygenmusic.net а также на http://www.websound.ru

Размещаем в папку \AutoIt3\Include\ скрипт(bassmod.au3) следующего содержания:
Код:

#include-once
; Поддерживает: .mod .xm .it .s3m .mtm
; P.S. Глобальные константы добавлены исключительно для удобства...
;---------------------------------
; Music flags:
Global Const $BASS_MUSIC_RAMP = 1 ; normal ramping
Global Const $BASS_MUSIC_RAMPS = 2 ; sensitive ramping
Global Const $BASS_MUSIC_LOOP = 4 ; loop music
Global Const $BASS_MUSIC_FT2MOD = 16 ; play .MOD as FastTracker 2 does
Global Const $BASS_MUSIC_PT1MOD = 32 ; play .MOD as ProTracker 1 does
;Global Const $BASS_MUSIC_POSRESET = 256 ; stop all notes when moving position
Global Const $BASS_MUSIC_SURROUND = 512 ;surround sound
Global Const $BASS_MUSIC_SURROUND2 = 1024 ;surround sound (mode 2)
Global Const $BASS_MUSIC_STOPBACK = 2048 ;stop the music on a backwards jump effect
;Global Const $BASS_MUSIC_CALCLEN        = 8192 ;calculate playback length
Global Const $BASS_MUSIC_NONINTER = 16384 ; non-interpolated mixing
;---------------------------------
Func BassMod($dllPath,$sPath,$flag)
        If $dllPath="" Or $dllPath="-1" Then
                $dllPath="BASSMOD.dll"
        EndIf
        If Not FileExists($dllPath) Then
                If Not SysFileExist($dllPath) Then
                        MsgBox(16,"Error","Не найден BASSMOD.dll")
                        Exit
                EndIf
        EndIf
        Global $music_handle = -1
        Global $BassModDll = DllOpen($dllPath)
        $init = DllCall($BassModDll, "int", "BASSMOD_Init", "int", -1, _  ;device
                                                        "int", 44100, _  ;freq Hz
                                                        "int", 0)      ;flag
        $fName = DllStructCreate("char[255]")
        DllStructSetData($fName, 1, $sPath)
        $load = DllCall($BassModDll, "int", "BASSMOD_MusicLoad", "int", False, _  ;loading from memory
                                                        "ptr", DllStructGetPtr($fName), _ ;file
                                                        "int", 0, _  ;offset
                                                        "int", 0, _  ;length
                                                        "int", $flag) ;flag
        $music_handle = $load[0]
        $fName = 0
        DllCall($BassModDll, "int:cdecl", "BASSMOD_MusicPlay", "int", $music_handle)
EndFunc
Func BassModClose()
        If IsDeclared("BassModDll") Then
                DllCall($BassModDll, "int:cdecl", "BASSMOD_Free", "int", $music_handle) ;clear resource
                DllClose($BassModDll)
        EndIf
EndFunc
; Проверка наличия указанного файла в путях переменной %Path%
Func SysFileExist($sFile)
        $old=@WorkingDir
        $array = StringSplit(EnvGet("PATH"),";")
        For $i=1 To $array[0]
                FileChangeDir($array[$i])
                $get=FileExists($sFile)
                If $get=1 Then ExitLoop
        Next
        FileChangeDir($old)
        Return $get
EndFunc

Синтаксис:
BassMod($dllPath,$sPath,$flag)
$dllPath - Путь к BASSMOD.dll (Если в качестве пути указать (-1 или "") функция поищет BASSMOD.dll в текущем директории а также в путях определённых для системной переменной %path% )
$sPath - Путь к трекерному модулю
$flag - Метод обработки (см. предыдущий код: Music flags)
BassModClose() - закрывает BASSMOD.dll и выгружает музыку из памяти (Эту функцию следует вызывать при выходе из GUI)
Пример использования:
Код:

#include <GUIConstants.au3>
#include <bassmod.au3>
Opt("GUIOnEventMode", 1)
$title="BASSMOD_TEST"
$test=GUICreate($title,320,240)
GUISetOnEvent($GUI_EVENT_CLOSE,"ExitGui")
GUISetState()

BassMod(-1,"Music.xm",512+4)

While 1
Sleep(1000)
WEnd

Func ExitGui()
        BassModClose()
        Exit(0)
EndFunc


Creat0R 10-01-2007 01:54

Diamond_m
Спасибо! давно искал подобное решение - оно позволяет проигрывать мелодию в фоновом режиме, и многое другое...

Примечание и вопрос:

Примечание - Если путь к BASSMOD.dll не указать полный (просто "BASSMOD.dll"), то мелодия не играет. Это можно исправить изменив немного первое условие функции BassMod, и добавив после него такую строку:

Код:

If StringRegExpReplace($dllPath, "^.*\\", "") = $dllPath Then $dllPath = @ScriptDir & "\" & $dllPath
Т.е первые две строки будут выглядеть так:

Код:

If $dllPath = "" Or $dllPath = -1 Then $dllPath = @ScriptDir & "\BASSMOD.dll"
If StringRegExpReplace($dllPath, "^.*\\", "") = $dllPath Then $dllPath = @ScriptDir & "\" & $dllPath

Вопрос:
-Я в системной папке нашёл файл BassMod.dll, возможно ли как то использовать его?

Diamond 10-01-2007 08:53

Creat0R
Цитата:

Если путь к BASSMOD.dll не указать полный (просто "BASSMOD.dll"), то мелодия не играет.
Странно... У меня почему-то играет... Использую "AutoIt v 3.2.0.1" Может произошла ошибка инициализации самой библиотеки? Даже не знаю что и подумать.
Цитата:

Я в системной папке нашёл файл BassMod.dll, возможно ли как то использовать его?
...если при вызове функции вместо пути к BASSMOD.dll указать -1 или "" AutoIt в первую очередь поищет библиотеку в директории скрипта и не найдя его там, продолжит поиск в путях переменной %path% (обычно это WINDOWS и WINDOWS\system32) т.е. попытается инициализировать найденную тобой библиотеку. Это не желательно поскольку "неизвестный" BassMod.dll вполне может оказаться устаревшим или что нибудь ещё...
Я считаю что лучше указывать полный путь, чтобы уж знать наверняка, что играет правильный BASSMOD.dll.
P.S.
Скорее всего какая нибудь программа временно извлекла BASSMOD.dll для одноразового проигрывания музыки, а в последствии не стала его удалять. Лично я считаю такое поведение некорректным для программы, поскольку это засоряет системную папку.

Вот ещё вариант для скомпилированного скрипта с применением FileInstall() (по крайней мере как это вижу я)
Все ресурсные файлы извлекаются в @TempDir только после запуска окна справки, а после его закрытия сразу удаляются.
Код:

#include <GUIConstants.au3>
#include <bassmod.au3>
Opt("GUIOnEventMode", 1)
$title="BASSMOD_TEST"
$test=GUICreate($title,320,240)
GUISetOnEvent($GUI_EVENT_CLOSE,"ExitGui")
$CTRL_help = GUICtrlCreateButton ("", 260, 20, 30, 30,$BS_ICON)
GUICtrlSetImage($CTRL_help,"shell32.dll",23,1)
GUICtrlSetOnEvent($CTRL_help,"help")
Global $HelpStart=0
Global $lib=@TempDir & "\BASSMOD.dll"
Global $sound=@TempDir & "\moon trip.xm"
GUISetState()

While 1
        Sleep(100)
WEnd

Func ExitGui()
BassModClose()
FileDelete($lib)
If @GUI_WINHANDLE = $help Then
        GUIDelete()
        $HelpStart=0
Else
        Exit(0)
EndIf
EndFunc

Func help()
Local $size = WinGetPos("")
If $HelpStart=0 Then
        Local $HelpInfo="На этом месте могла бы быть ваша реклама..." & @CRLF & _
        "Но её здесь точно не будет!"
        Global $help=GUICreate("О программе...",240,180,$size[0]+40,$size[1]+40,-1,$WS_EX_TOOLWINDOW,$test)
        $label_help=GUICtrlCreateLabel($HelpInfo,0,0,240,180)
        GUICtrlSetBkColor(-1,0x000000)
        GUICtrlSetColor(-1,0x000000)
        GUISetOnEvent($GUI_EVENT_CLOSE,"ExitGui")
        GUISetState()
        $HelpStart=1 ;защита от повторного запуска help'а
        $color=0
        Sleep(120)
        Do
                Sleep(40)
                $color=$color+5
                $H=StringRight(Hex($color),2)
                GUICtrlSetColor ($label_help,"0x" & $H & $H & $H)
        Until $color=255
FileInstall("BASSMOD.dll",$lib,1)
FileInstall("moon trip.xm",$sound,1)
BASSMOD($lib,$sound,1024+4)
; Т.к. музыка загружена в память, файл модуля можно сразу же удалить
FileDelete($sound)
EndIf
EndFunc


nadge 10-01-2007 14:51

AutoIt, "защита от пользователя", как?
 
Добрый день.


Проблема такая. Некоторые пользователи любят во время установки программ крутить и тыкать во все стороны мышью :) У меня довольно много программ настраиваются при помощи скриптов автоит. Пользователи от этого офигевают - мышка сама ездит :)

Вобщем нужно на время установки запретить использование мыши и клавиатуры. Кто-нибудь делал так? Как это можно реализовать?

godoo 10-01-2007 16:24

nadge все вопросы по AutoIt задавайте пожалуйста в соответствующей теме http://forum.oszone.net/thread-60616.html
Если почитать эту тему, то ответ на Ваш вопрос уже давно есть:
Код:

;блокируем мышь и клаву
If @OSType="WIN32_NT" Then BlockInput ( 1 )

включить
Код:

BlockInput ( 0 )

nadge 10-01-2007 18:19

Цитата:

nadge все вопросы по AutoIt задавайте пожалуйста в соответствующей теме http://forum.oszone.net/thread-60616.html
Сорри, тему заметил только после создания своей.


Спасибо за ответ.

Creat0R 14-01-2007 15:57

Хотел было спросить, как переделать функцию для поиска в файле, чтобы искать можно было исключительно слово целиком (Match whole word only), но сначала решил немного поковыряться в ней (функция от Sanja Alone), и на моё же удивление, у меня получилось это осуществить... :yes:
Не знаю пока корректный ли мой способ, но вроде работает:


Код:

Func _FindTextInFile($iFile, $Text, $MtchWholeWrdFlag = 0, $CaseSense = 0)
    If Not FileExists($iFile) Then Return -1
    Dim $ret[2]
    Local $File = FileOpen($iFile, 0)
    $a = StringSplit(FileRead($File, FileGetSize($iFile)), @LF)
    FileClose($File)

    If StringIsASCII($Text) Then
        For $i = 1 To UBound($a, 1) - 1
            If StringInStr($a[$i], $Text, $CaseSense) Then
                $ret[0] = $i
                $ret[1] = $a[$i]
                If $MtchWholeWrdFlag = 1 Then
                    $StrPos = StringInStr($ret[1], $Text)
                    If StringStripWS(StringMid($ret[1], $StrPos - 1, 1), 2) <> "" Or StringStripWS(StringMid($ret[1], $StrPos + StringLen($Text), 1), 2) <> "" Then $ret = 0
                EndIf
                Return $ret
            EndIf
        Next
    Else
        For $i = 1 To UBound($a, 1) - 1
            If StringInStr(StringLower($a[$i]), StringLower($Text)) Then
                $ret[0] = $i
                $ret[1] = $a[$i]
                If $MtchWholeWrdFlag = 1 Then
                    $StrPos = StringInStr(StringLower($ret[1]), StringLower($Text))
                    If StringStripWS(StringMid($ret[1], $StrPos - 1, 1), 2) <> "" Or StringStripWS(StringMid($ret[1], $StrPos + StringLen($Text), 1), 2) <> "" Then $ret = 0
                EndIf
                Return $ret
            EndIf
        Next
    EndIf
EndFunc

Если у 3-го параметра указать 1, то поиск будет осуществляться с учётом слова целиком, если опустить этот параметр (или указать 0), то поиск будет обычный :) .

Немного переделал функцию, тепрь если искать кириллицу, то чувствительность к целому слову учитывается... но вот если проверять учитывая регистр, то для кириллицы не действует... также добавил в функцию 4-ты параметр, который определяет чувствительность к регистру букв. А также в начале функции поставил проверку на существование файла, если не существует, то возвращается -1.

P.S.
Если кто-то знает более правильный способ, или более эффективный, то буду рад узнать его ;)

Creat0R 15-01-2007 19:55

Никак не могу разобраться со всем что связанно с кодировками...

При проверке на существование файла, если проверяемы путь в кодировке UTF-8, и содержит кериллицу (русские буквы), то файл не найден, перекодировать то можно, но что делать если заранее не известно какая будет кодировка (путь к примеру берётся из файла конфигурации)?

Можно ли написать функцию, которая будет определять кодировку строки?

А таже проблема с отображением кодировки в гуи, если язык в системе не русский и не английски, то ни одна функция не помагает нормально отобразить кириллицу. Есть функция _Utf8ToAnsi() (от amel27), но она тут не помагает (помагает если системный язык русский), есть также функция StringToUTF(), и она тоже не помагает... как сделать уникальное отображение кириллицы в гуи, чтобы на любом языке (установленном в системе), нормально всё отображалось?

i_mihal 15-01-2007 21:41

написал скрипт на AutoIt для установки Office 2000.
серийник там в SETUP.INI никак не задается,
поэтому серийный номер ввожу вот так:

Send('FXWX9QCJ4FGHCRYH9Y8FXQP6G')

но срабатывает это далеко не всегда. есть две проблемы:

1) если в винде язык по умолчанию - русский, то вместо латинских букв
скрипт вводит в поле ввода русские: АЧЦЧ9 ЙСО4А итд, то есть
те русские буквы, которые написаны на соответствующих клавишах.
2) иногда что-то протормаживает и вообще вводится мешанина из букв,
как будто из этой строки Send('FXWX9QCJ4FGHCRYH9Y8FXQP6G')
выбрали 7-9 букв, через каждые 2-3 буквы и разбавили их буквой "Ж",
которой вообще по-идее там быть не может, ведь она соответствует
на клавиатуре знаку ";"

сейчас попробую сделать ввод серийника с помощью ControlSetText,
но мне непонятно, почему так странно работает 'Send' если язык в винде
по умолчанию задан русский? может подскажет кто-нибудь?

спасибо.

p.s. с помощью 'ControlSetText' вроде получилось, хотя учитывая непонятность
работы 'Send' нет уверенности, что все и всегда будет работать корректно :(
пока работает...

Diamond 15-01-2007 22:34

i_mihal
Да, есть такая проблема... Я её решаю с помощью вставки из буфера обмена:
ClipPut("FXWX9QCJ4FGHCRYH9Y8FXQP6G")
Send("^м")
Цитата:

почему так странно работает 'Send'
Вопрос, скорее всего, относиться к разработчикам AutoIt. :not-me:

Всем:
Оказывается, с помощью WinApi можно проделывать интересные манипуляции с окнами...
Анимация окон GUI, с помощью WinApi
Использование:
DllCall("User32.dll","long","AnimateWindow","hwnd",Идентификатор окна,"long",Продолжительность в миллисекундах,"long",Эффект)
Эффекты:
Эффекты имеет смысл задавать в качестве констант: Const $AW_ACTIVATE = 0x20000
AW_ACTIVATE = 0x20000 (Активирует окно, конфликтует с AW_HIDE)
AW_BLEND = 0x80000 (Постепенное исчезновение-появление)
AW_CENTER = 0x10 (Разворачивает окно из центра)
AW_HOR_POSITIVE = 0x1 (Слева направо)
AW_HOR_NEGATIVE = 0x2 (Справа налево)
AW_SLIDE = 0x40000 (Прокрутка)
AW_VER_POSITIVE = 0x4 (Сверху в низ)
AW_VER_NEGATIVE = 0x8 (Снизу в верх)
AW_HIDE = 0x10000 (Скрывает окно)
Эффекты по умолчанию ориентированны на появление окна, для скрытия окна используйте их совместно с AW_HIDE.
Можно получить интересные результаты комбинируя эффекты между собой. Например: 0x4 + 0x1 (анимация по диагонали)

Рабочий пример:
Код:

#include <Guiconstants.au3>
Opt("GUIOnEventMode",1)
$test=GUICreate("WinApi_test",400,300)
GUISetOnEvent($GUI_EVENT_CLOSE,"ExitGui")
DllCall("User32.dll","long","AnimateWindow","hwnd",$test,"long",700,"long",0x8+0x40000)
GUISetState()

While 1
Sleep(100)
WEnd

Func ExitGui()
DllCall("User32.dll","long","AnimateWindow","hwnd",$test,"long",500,"long",0x10+0x10000)
Exit
EndFunc


Creat0R 16-01-2007 00:04

i_mihal
ControlCommand вроде будет всегда срабатывать:

Код:

ControlCommand("Title", "", "Edit1", "EditPaste", "FXWX9QCJ4FGHCRYH9Y8FXQP6G")
На счёт Send(), решение для смены раскладки клавиатуры вроде есть в Faq'е (см. “Как с помощью AutoIt сменить раскладку клавиатуры”)

Diamond

Красиво! :UP: но рамка всего гуи как бы нарисованна, т.е углы не округлённые как должны быть в XP, даже немного затемнённые, это можно поправить?

P.S
Цитата:

Я её решаю с помощью вставки из буфера обмена
Это тоже не всегда надёжно, буфер обмена может неправильно отдавать текст (при вставке в него текста Аутоитом).

Creat0R 16-01-2007 00:42

:yahoo:
Оказывается, возможно привязать функцию _MsgBox() (от amel27), и любое окно гуи к другому окну (не обязательно к гуи)....

На мысль меня навёл пример из Faq'а о переключении раскладки клавиатуры (а именно, пременная $hWnd):


Код:

Opt("WinTitleMatchMode", 4)
Run("notepad.exe")
$NotPadTitle = "classname=Notepad"

WinWait($NotPadTitle, "", 5)
$hWnd = WinGetHandle($NotPadTitle)

WinSetState($NotPadTitle, "", @SW_DISABLE)
GuiCreate("Attach To Window Gui", 300, 400, -1, -1, -1, -1, $hWnd)
GuiSetState()

$Msg = 0
While $Msg <> -3
    $Msg = GuiGetMsg()
    Sleep(10)
Wend

WinSetState($NotPadTitle, "", @SW_ENABLE)


Diamond 16-01-2007 02:25

Creat0R
Цитата:

углы не округлённые как должны быть в XP
Я тоже заметил этот дефект. Честно говоря, не знаю... :sorry: Других вариантов или комбинаций для "AnimateWindow" пока найти не удалось. Разве что попытаться использовать другие стили окна... Во ещё что: Если окно имеет тень, анимация может происходить "рывками".
Цитата:

буфер обмена может неправильно отдавать текст (при вставке в него текста Аутоитом)
Наверное имелось ввиду: "буфер обмена может неправильно принимать текст"? Насколько неправильно? При копировании-вставке обычного текста, у меня ошибок пока не случалось...
Спасибо, приму к сведению. :)

Creat0R 16-01-2007 04:24

Diamond
Цитата:

Разве что попытаться использовать другие стили окна
Перепробовал почти все, один только справляется почти нормально с задачей - $WS_EX_TOOLWINDOW - но как известно, это не совсем обычное окно ;) - но всё же неплохая вещь которую ты привёл в студию :) спасибо!

Цитата:

Наверное имелось ввиду: "буфер обмена может неправильно принимать текст"?
Скорее так.

Цитата:

Насколько неправильно?
Ну возьмём к примеру кириллицу из ком. строки...

Вставляем так:

ClipPut($CmdLine[1])

Если Ком. строка содержит кириллицу, то когда пытаемся куда то вставить текст из буфера обмена, то уже вставляется в неверном формате... кстати я даже не знаю как перекодировать его, кто знает плиз подскажите, давно хотел узнать :blush2:

Т.е вот к примеру если такой скрипт закомпилировать:

Код:

ClipPut($CmdLine[1])
MsgBox(0, "", ClipGet())

А потом запустить его к примеру из батника так:

Код:

Start ClipTest.exe тест
То в сообщении мы увидим ЄхёЄ (крякозябры) :)

Creat0R 16-01-2007 04:55

Ещё один способ получить список существующих дисков на компьютере:

Код:

$Drives = ""
For $iDrv = 65 to 90
    If DriveGetType(Chr($iDrv) & ":\") <> "" Then $Drives = $Drives & @CR & Chr($iDrv) & ":\"
Next
MsgBox(262144+64, "Existing Drives List", $Drives)


VelDmi 16-01-2007 19:22

Creat0R
Цитата:

Оказывается, возможно привязать функцию _MsgBox() (от amel27)
Где эту функцию взять?

Diamond 16-01-2007 22:37

Creat0R
Цитата:

всё же неплохая вещь которую ты привёл в студию
Спасибо. Мне тоже очень понравилось. :)
Цитата:

Если Ком. строка содержит кириллицу
Через командную строку проблема решается так:
graftabl 1251 | echo %username%>MyName.txt
Хотя конкретно для твоего случая это не сработает. При создании пакетного Файла возьми за привычку конвертировать текст в Dos(oem), например c помощью текстового редактора: BRED - хороший заменитель блокнота, или любой другой доступный редактор который умеет работать с кодировками, в самом крайнем случае открываешь пакетный файл в WordPad ( > Сохранить как > Текстовой документ MS-DOS), а затем меняешь расширение на *.bat

Diamond 17-01-2007 00:09

Creat0R
Цитата:

Ещё один способ получить список существующих дисков на компьютере:
Интересный вариант! Как-то мне пришлось использовать перебор A-Z, но только в пакетном файле, поскольку другой альтернативы в батниках просто нет.
Вот ещё один способ, сделано через VBScript
Код:

#CS
тип ресурса:
0 - неизвестное устройство
1 - устройство со сменным носителем.
2 - жёсткий диск.
3 - сетевой диск.
4 - CD-ROM.
5 - RAM-диск.
#CE

Dim $fso, $d, $dc, $s
$fso = ObjCreate("Scripting.FileSystemObject")
$dc = $fso.Drives
        For $d In $dc
                If $d.DriveType = "2" Then
                        $s = $s & $d.DriveLetter & ": "
                EndIf
        Next
MsgBox(0,"",$s)




Creat0R 17-01-2007 05:05

VelDmi
Цитата:

Где эту функцию взять?
Вот:

Код:

Func _MsgBox ($mainGUI, $MsgBoxTitle, $MsgBoxText, $MsgBoxType)
    $ret = DllCall ("user32.dll", "int", "MessageBox", _
            "hwnd", $mainGUI, _
            "str", $MsgBoxText , _
            "str", $MsgBoxTitle, _
            "int", $MsgBoxType)
    Return $ret [0]
EndFunc


В первом параметре задаётся идентификатор гуи (как выяснилось можно и от WinGetHandle), во втором заголовок, в следующем текст, и в последнем тип (иконка, кол-во кнопок и т.д.)...

Вот рабочий пример с этой функцией:

Код:

Opt("WinTitleMatchMode", 4)
Run("notepad.exe")
$NotPadTitle = "classname=Notepad"

WinWait($NotPadTitle, "", 5)
$hWnd = WinGetHandle($NotPadTitle)

_MsgBox($hWnd, "Attached MsgBox to Notepad", "I am attached to notepad, you must close me before continue work in notepad ;-)", 64)

Func _MsgBox($mainGUI, $MsgBoxTitle, $MsgBoxText, $MsgBoxType)
    $ret = DllCall ("user32.dll", "int", "MessageBox", _
            "hwnd", $mainGUI, _
            "str", $MsgBoxText , _
            "str", $MsgBoxTitle, _
            "int", $MsgBoxType)
    Return $ret [0]
EndFunc


P.S.
Я когда то писал:

Цитата:

надеюсь что когда нибудь и с этим делом вяснится что мы ошибаемся
Так и выяснилось! :)


Diamond
Цитата:

При создании пакетного Файла
Я только для примера привёл запуск с пакетника :) - это происходит не только с батника, например, в браузере Opera, если выделить текст, и запустить программу (из меню) с параметром %T (идентификатор выделенного текста в браузере), то содержащий кириллицу текст будет также криво помещён в буфер обмена. Очень хотелось бы это решить, но я уже многое перепробовал, и решения так и не нашл :(

VelDmi 17-01-2007 09:33

Creat0R
Цитата:

то содержащий кириллицу текст будет также криво помещён в буфер обмена.
Если не ошибаюсь, предварительно нужно переключить раскладку клавиатуры на русский, тогда будет помещен нормально.

mpn 17-01-2007 10:49

Народ!
Я повторяюсь, но очень интересует ответ на простой вопрос: у кого нибудь выполняется корректно строка $f=Run("telnet","",@SW_MAXIMIZE,3) ? У меня, если ее выполнить без последнего параметра, открывается окно telnet, в противном случае процесс закрывается через 0,5 сек после запуска. AutoIt v.3.2.0.1.

Dicken 17-01-2007 11:40

Цитата:

процесс закрывается через 0,5 сек после запуска. AutoIt v.3.2.0.1.
нет неработает!

Diamond 17-01-2007 13:51

Creat0R
Пробовал через WinApi - kernel32.dll там вроде бы должна быть нужная функция... В общем совсем запутался - ничего не получается. :(
Если у тебя проблемы только с Dos-кодировкой, то можно побить кракозябру её же собственным оружием.
Код:

$ret="ЄхёЄ"
MsgBox(0,"",OEM_Decode($ret))

Func OEM_Decode($string)
$foo = Run(@ComSpec & " /c @echo " & $ret,"", @SW_HIDE, 2)
$line = StdoutRead($foo)
Return $line
EndFunc


Creat0R 17-01-2007 15:22

Diamond
Цитата:

можно побить кракозябру её же собственным оружием
Оригинально! :victory: Спасибо.

По поводу режима чтения из консоли (StdoutRead), если я ставлю 2 как последний параметр у команды Run, влияет ли это на то как будут выполняться команды ком. строки? т.е на что вообще это повлияет (кроме как на возможность чтения изх консоли)?

Diamond 17-01-2007 21:48

Creat0R
Эта Функция в её текущем виде не предназначена для чтения из консоли, она задумана мной только для преобразования искажённого текста.
Т.е я заставляю консоль испортить кирилический текст, как она это делает обычно, но только в нужную нам сторону. Но если ты хочешь использовать StdoutRead() непосредственно по назначению, т.е для чтения стандартного потока из консоли...

Пример кода был взят из справки AutoIt v 3.2.2.0
$STDOUT_CHILD = 2 Необходима для получения StdoutRead() в первом цикле
$STDERR_CHILD = 4 Необходима для получения StderrRead() во втором цикле
Имена констант очевидно говорят об их предназначении (см. справка: StdoutRead и StderrRead)
Константы влияют только на возможность чтения потока из консоли. При этом возможность сохраняется до тех пор, пока ты делаешь запросы StdoutRead(), вплоть до закрытия самой консоли.
Код:

; Demonstrates StdoutRead()
#include <Constants.au3>

$foo = Run(@ComSpec & " /c dir foo.bar", @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)

While 1
    $line = StdoutRead($foo)
    If @error Then ExitLoop
    MsgBox(0, "STDOUT read:", $line)
Wend

While 1
    $line = StderrRead($foo)
    If @error Then ExitLoop
    ;MsgBox(0, "STDERR read:", $line)
Wend

MsgBox(0, "Debug", "Exiting...")

Понятно, что разработчики при написании справки не подумали о нас русских и, как следствие, о существовании кирилицы.
Исправляем этот недостаток заменой первой строки в коде:
Код:

$foo = Run(@ComSpec & " /c graftabl 1251 | dir foo.bar", @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)

Creat0R 17-01-2007 22:12

Как можно изменить функцию _ChooseColor(), чтобы можно было прикрепить окно выбора цвета к гуи?
Я пробовал в DllCall добавить параметр ..."hwnd", $Gui...., но функция ругается на сбой в скрипте и не хочет запускаться :( - возможно ли это как то решить?

Diamond
Цитата:

Эта Функция в её текущем виде не предназначена для чтения из консоли
Я вкурсе :) , пример из справки я уже иследовал, поэтому и появился вопрос, влияет ли запуск ком. строки в режиме чтения, на выполнение команд ком. строки (без всякой связи с кириллицей, это был не касающийся этого вопрос).

Diamond 18-01-2007 02:14

Три способа определить - является ли файл папкой:
P.S.
Возможно, для многих это не новость, и всё-таки...
Код:

;~ Путём получения атрибутов
;~ Возвращает положительное число если папка существует, иначе 0
Func FolderExist($name)
$Folder=StringInStr(FileGetAttrib($name),"D")
Return $Folder
EndFunc

;~ С помощью файла "nul" присутствующего в каждой папке
;~ Возвращает 1 если папка существует, иначе 0
Func _FolderExist($name)
$Folder=FileExists($name & "\nul")
Return $Folder
EndFunc

;~ С помощью функции VBScript
;~ Возвращает 1 если папка существует, иначе 0
Func VbFolderExist($name)
$fso=ObjCreate("scripting.filesystemobject")
$Folder=Abs($fso.FolderExists($name))
Return $Folder
EndFunc

Creat0R
Цитата:

без всякой связи с кириллицей, это был не касающийся этого вопрос
В любом случае, исправленный код может оказаться полезным и для других участников форума. :)
А всё-таки кракозябры были не связаны с буфером обмена или AutoIt. :no: А то, я уж чуть было не усомнился в эфективности способа который я предложил i_mihal :tomato:

papik_bat 18-01-2007 11:47

Здрасьте всем.
Вот история моей болезни:
я написал батник для автоматической рассылки писем, когда он срабатывает, то появляеться окно аутглюк с предуприждением, что программа пытаеться сама отправить письмо и т.д.. На нужную кнопку в этом окне я нажимал скриптом Autoit.

[code]Opt("TrayIconHide", 1)
WinWaitActive("Microsoft Office Outlook")
Sleep(6000)
ControlClick("Microsoft Office Outlook", "", "Button4")
Send("{ENTER}")

Все работало нормально, но последнее время если компьютер заблакированн мой "нажиматель" не срабатывает, так как окно аутглюка стало теперь не активным. на писал такой скрипт:

Код:

Opt("TrayIconHide", 1)
If WinWait("Microsoft Office Outlook") then
WinActivate("Microsoft Office Outlook","")
WinWaitActive("Microsoft Office Outlook")
Sleep(6000)
ControlClick("Microsoft Office Outlook", "", "Button4")
Send("{ENTER}")
EndIf

Но проблема не решилась, если комп заблокированн окно не активируеться и кнопка не нажимаеться.

Кто виноват? Что делать?

Creat0R 18-01-2007 14:08

Diamond
Цитата:

Три способа определить - является ли файл папкой
Ещё один (который я до сих пор юзал):
;Возвращает -1 если файл вовсе не существует, 1 если папка, и 0 если файл....

Код:

Func _IsDir($FileName)
    If FileExists($FileName) Then
        $FCheck = FileOpen($FileName, 0)
        If $FCheck = -1 Then
            Return 1
        Else
            FileClose($FCheck)
            Return 0
        EndIf
    Else
        Return -1
    EndIf
EndFunc

Но видимо начну юзать один из твоих примеров, тот что проверяет атрибуты, пожалуй это надёжнее.


Цитата:

В любом случае, исправленный код может оказаться полезным и для других участников форума.
Безусловно :)


papik_bat
Цитата:

если компьютер заблакированн
Что значит заблокирован? AutoIt'ом?

У тебя второй пример весь держится на условии что “скрипт будет дожидаться” окна, попробуй опустить условие и ограничить дожидание:

Код:

#NoTrayIcon ;Так надёжнее ;)

WinWait("Microsoft Office Outlook", "", 10)
;Иногда один раз не срабатывает (глюк аутоита), пробуем два раза подряд...
WinActivate("Microsoft Office Outlook")
WinActivate("Microsoft Office Outlook")
WinWaitActive("Microsoft Office Outlook", "", 10)
Sleep(6000)
ControlClick("Microsoft Office Outlook", "", "Button4")
Send("{ENTER}")


papik_bat 18-01-2007 14:43

Продолжаем беседу...

CreatoR

Компьютер заблокирован = Ctrl+Alt+Delete -> Блокировка, либо когда блокировка включаеться автоматически.
Попробывал предложенный код, не идет...

После разблокировки окно аутлука свернуто.

papik_bat 18-01-2007 16:58

Вот нашел описание команды которая могла бы, я думаю, решить мою беду WinRestore, но у себя в Autoit 3, ее не нахожу. Как быть?

Creat0R 18-01-2007 20:25

papik_bat
Цитата:

у себя в Autoit 3, ее не нахожу.
Она относится к аутоиту Version 2.63, Version 2.64

Теперь (в 3.2.2) нужно так:

Код:

WinSetState("Microsoft Office Outlook", "", @SW_RESTORE)

papik_bat 19-01-2007 11:54

CreatOR
Цитата:


WinSetState("Microsoft Office Outlook", "", @SW_RESTORE)
все ровно не работает.
Попробую пойти другим путем, не дам компютеру блокироваться написал скрипт Autoit "мышка летит на юг" :-)!
Через каждые 10 минут мышка двигаеться в южном направлении. Просто отключить блокировку нельзя.

Diamond 19-01-2007 18:55

Creat0R
Цитата:

тот что проверяет атрибуты, пожалуй это надёжнее
На самом деле все три способа надёжны!
Тот что на основе VBScript запрашивает напрямую ($fso.FolderExists() куда уж надёжней...). Там я сделал только одну поправочку. Дело в том что в VBScript, значение False понятно 0, а вот значение True = -1, поэтому я добавил Abs() для совместимости с AutoIt.

Файл "nul" - неотъемлемый элемент папки и он никуда не денется, так что тоже можно пользоваться смело. :)

Respect 19-01-2007 21:15


Уважаемые, подскажите пожалуйста, может кто знает как реализовать на AutoIt v 3 следующее:
(Что-то сам никак не могу придумать)

1. Как вызвать меню программы, которое вызывается только по клику правой кнопкой мыши на иконку программы в трее ?
(Другого интерфейса программа не имеет...) Или как кликнуть нужную иконку программы в трее ?

Creat0R 20-01-2007 04:08

Respect
Цитата:

как кликнуть нужную иконку программы в трее ?
Мне кажется только по координатам - используй Au3Info.exe, и нажми на нужную иконку, затем посмотри координаты которые выдаст этот инструмент (под надписью >>>Mouse Details <<< - X: и Y: ), далее используй их примерно так:

Код:

#NoTrayIcon
$X = 930
$Y = 717
MouseClick("right", $X, $Y, 1, 0)

Первая строка обязательна, иначе появится икона самого скрипта, и тогда координаты уже будут не актуальны (не верны).

Diamond
Цитата:

все три способа надёжны!
А если работа Vbscript нарушена в системе? ;) (у меня такое бывало)
А по поводу файла Nul, видимо он гинерируется (по крайней мере имитируется его присутствие) если существует файл с таким же имененм без расширения...
Т.е к примеру, создаём файл Test в папке C:\ (без расширения), и проверяем является ли он папкой:

Код:

$TestName = "C:\test"

MsgBox(0, "", _FolderExist($TestName))

Func _FolderExist($name)
    $Folder = FileExists($name & "\nul")
    Return $Folder
EndFunc

Получаем 1 (хотя это не папка) :) .

Creat0R 20-01-2007 04:31

У меня есть такой вопрос:
-Возможно ли проверить функцию BlockInput()? т.е есть способ узнать, включена ли (или отключена) такая блокировка (от самого скрипта)?
Мне нужно включить BlockInput(1), и в течении того времни пока всё заблокированно, проверять были ли нажаты клавиши Alt Ctrl Del (что и вызывает отключение блокировки) - или хотябы как проверить нажатие этих клавишь, _IsPressed не помагает, не получается проверить нажатие сразу трёх клавишь :(


P.S.

И ещё такой между прочный вопрос - почему в справке нет (у меня) описании команд StringRegExp, StringRegExpReplace? где можно почитать описания, и желательно примеры этих функции? может мне справка попалась бракованная? (она шла вместе с дистрибютивом AutoIt'а).

Respect 20-01-2007 19:20

Цитата:

To CreatOR
К сожалению это единственный вариант, который приходит в голову и мне. Но это уже не имеет никакого отношения к автоматизации, ибо необходим универсальный способ, а на разных машинах с различным набором установленных программ
координаты конкретной иконки будут однозначно отличаться !?...

Вопрос № 2.

Как определить какая в текущий момент раскладка клавиатуры RU or EN и как переключать раскладку клавиатуры, не применяя эмуляцию нажатия клавиш ?

Наверняка не сложный вопрос, просто нет времени разбираться. Извините, если эти вопросы уже обсуждались в форуме. Хочется услышать именно ответы.
Спасибо.

Diamond 21-01-2007 10:53

Creat0R
Цитата:

почему в справке нет (у меня) описании команд StringRegExp, StringRegExpReplace?
В папке AutoIt я нашёл 4 файла справки, все шли вместе с дистрибутивом v3.2.2.0
AutoIt, AutoIt3, AutoIt3Help, и наконец UDFs3 - (User Defined Function). В первых трёх, есть описания этих команд (у меня). :)
Цитата:

А если работа Vbscript нарушена в системе?
В этом плане, полностью с тобой согласен, любой объектно-ориентированный язык зависим от библиотек, их регистрации в системе и т.д. Но думаю что написанный на AutoIt'е код, так же не защищён от различных неприятностей, особенно если использует внешние dll библиотеки. Например применение функций ObjCreate() и DllCall() я считаю одинаково ненадёжным. С другой стороны... если отказаться от их использования, AutoIt будет выглядеть пустым. ;)
Цитата:

по поводу файла Nul
Беру свои слова обратно. :pray: Странно... проверяется путь "C:\test\nul" и возвращается True, хотя на самом деле такого пути не существует - мистика. Раньше я использовал этот способ в батниках - как единственно возможный. А проверить его подобным образом, просто в голову не приходило... :idontnow:

Creat0R 22-01-2007 06:06

Respect
Цитата:

необходим универсальный способ
Такого как мне кажется, в Аутоите, для этой задачи, увы нет :( .

Цитата:

как переключать раскладку клавиатуры, не применяя эмуляцию нажатия клавиш ?
См. в шапке AutoIt скрипты - введение и FAQ (Как с помощью AutoIt сменить раскладку клавиатуры).

Diamond
Цитата:

все шли вместе с дистрибутивом v3.2.2.0
Интересно, я установил эту версию, но поверх старой (v3.2.0.1), неужели файлы справки в таком случае не заменяются? :dont-know (в самих справках написанно v3.2.0.1).

Цитата:

проверяется путь "C:\test\nul" и возвращается True, хотя на самом деле такого пути не существует - мистика.
Ну это не совсем мистика, просто видимо Nul, интерпритируется как “Ничто” (также как и при проверке If FileExists("") ... ), т.е учитывается только путь до Nul (в случае с FileExists("") это путь к скрипту, ну или к рабочему каталогу).

Цитата:

использовал этот способ в батниках - как единственно возможный
Кстати, в батниках тоже можно “атрибутным” (почти) способом проверять :) :

Код:

@echo off
Set Dir=c:\D
If Not Exist "%Dir%" Goto ExitMsg
Attrib %Dir% > "%temp%\~6456t56iu.tmp"
For /f "delims= " %%a in (%temp%\~6456t56iu.tmp) Do If /i %%a==%Dir% (
Echo "%Dir%" Is a folder!  ---^> Exit in 7 seconds ;-^) ) Else (
Echo "%Dir%" Is Not a folder!  ---^> Exit in 7 seconds ;-^) )
Goto Exit
:ExitMsg
Echo This file ^<%Dir%^> was not found  ---^> Exit in 7 seconds ;-)

:Exit
ping -n 7 localhost > nul
Del "%temp%\~6456t56iu.tmp"

Хотя тоже не очень наджёжно, но это уже другая тема, сорри за офтоп :blush2:



Diamond 22-01-2007 13:16

Вопрос:
Можно ли как-то заставить GUI, игнорировать (установленый в системе по умолчанию) стиль Windows XP. Т.е чтобы окно отбражалось в классическом виде (как в 98-м) не зависимо от системного стиля?
Второй вопрос:
Сущесвует ли какой нибудь простой способ претаскивания окна стиля $WS_POPUP или это возможно только за счёт слежения за позицией курсора? Кому нибудь уже удавалось двигать такое окно с помощью мыши? Я написал код, окно двигается без проблем, только вот я не уверен что это правильный способ.
Код:

#include <Guiconstants.au3>
Opt("GUIOnEventMode",1)
$test=GUICreate("",400,300,-1,-1,$WS_POPUP+$WS_BORDER)
GUISetBkColor(0xBEFFBE)
GUISetOnEvent($GUI_EVENT_CLOSE,"ExitGui")
$Closed_button=GUICtrlCreateButton("X",377,3,18,18)
GUICtrlSetFont(-1,10,700,0,"Tahoma")
GUICtrlSetOnEvent(-1,"ExitGui")
$Mim_button=GUICtrlCreateButton("-",337,3,18,18)
GUICtrlSetFont(-1,13,700,0,"Arial Black")
GUICtrlSetOnEvent(-1,"MimimizeGui")
$Max_button=GUICtrlCreateButton(CHR(152),357,3,18,18)
GUICtrlSetFont(-1,9,700,0,"Tahoma")
GUICtrlSetState(-1,$GUI_DISABLE)
$panel=GUICtrlCreateGraphic(0,0,400,24)
GUICtrlSetOnEvent(-1,"MoveWindow")
$text=GUICtrlCreateLabel("TEST",5,5,100,18)
GUICtrlSetFont(-1,12,700,0,"Courier New")
GUICtrlSetColor(-1,0xBEFFBE)
GUICtrlSetBkColor(-1,0x000000)
DllCall("User32.dll","long","AnimateWindow","hwnd",$test,"long",300,"long",0x10)
GUICtrlSetBkColor($panel,0x000000)
GUISetState()

While 1
        Sleep(100)
WEnd

Func MoveWindow()
Opt("GUIOnEventMode",0)
        $Win=WinGetPos("")
        $Mouse=MouseGetPos()
        $fix_X=$Mouse[0]-$Win[0]
        $fix_Y=$Mouse[1]-$Win[1]
        Do
                $msg=GUIGetMsg()
                $move=MouseGetPos()
                $x=$move[0]-$fix_X
                $y=$move[1]-$fix_Y
                WinMove("","",$x,$y)
        Until $msg=$GUI_EVENT_PRIMARYUP
Opt("GUIOnEventMode",1)
EndFunc

Func MimimizeGui()
GUISetState(@SW_MINIMIZE)
EndFunc

Func ExitGui()
DllCall("User32.dll","long","AnimateWindow","hwnd",$test,"long",300,"long",0x10+0x10000)
Exit
EndFunc

Creat0R
Цитата:

Кстати, в батниках тоже можно “атрибутным” (почти) способом проверять
Да ты оказывается Спец в батниках. :UP: Т.е. папка определяется по отсутствию отрибутов... действительно работает, спасибо!!! :)
Цитата:

я установил эту версию, но поверх старой (v3.2.0.1), неужели файлы справки в таком случае не заменяются?
Ну, либо так как ты предположил, либо они обновили дистрибутив уже после того как ты его скачал. Я посмотрел, у меня в заголовках 3-x справок написано: v3.2.2.0 (скачивал я его, где-то после 10.01.2007)

DenchikK 22-01-2007 19:24

Хочется узнать, как бы сделать так, чтоб скрипт искал файл qip.exe во
всём каталоге Program Files, и если таковой найдется - возвратил бы
тот каталог, в котором он лежит и запихнул бы в реестр полный путь к
катлогу (не к файлу). Это вообще осуществимо?
Заранее спасибо!

Creat0R 23-01-2007 01:41

Diamond
Цитата:

Можно ли как-то заставить GUI, игнорировать (установленый в системе по умолчанию) стиль Windows XP
Такого конкретного стиля (кажется) нет, но можно вручную это делать, почти также как ты это сделал с примером для следующего вопроса ;)

Цитата:

Сущесвует ли какой нибудь простой способ претаскивания окна стиля $WS_POPUP
Есть стил $GUI_WS_EX_PARENTDRAG, его нужно “вешать” например на GuiCtrlCreateLabel, и тогда можно перетаскивать окно тягая этот контроль:

Код:

#include <Guiconstants.au3>
Opt("GUIOnEventMode",1)
$test=GUICreate("",400,300,-1,-1,$WS_POPUP+$WS_BORDER)
GUISetBkColor(0xBEFFBE)
GUISetOnEvent($GUI_EVENT_CLOSE,"ExitGui")
$Closed_button=GUICtrlCreateButton("X",377,4,18,18)
GUICtrlSetFont(-1,10,700,0,"Tahoma")
GUICtrlSetOnEvent(-1,"ExitGui")
$Mim_button=GUICtrlCreateButton("-",337,4,18,18)
GUICtrlSetFont(-1,13,700,0,"Arial Black")
GUICtrlSetOnEvent(-1,"MimimizeGui")
$Max_button=GUICtrlCreateButton(CHR(152),357,4,18,18)
GUICtrlSetFont(-1,9,700,0,"Tahoma")
GUICtrlSetState(-1,$GUI_DISABLE)
$text=GUICtrlCreateLabel("Manual GUI Drag",5,5,325,18, $SS_Center, $GUI_WS_EX_PARENTDRAG)
GUICtrlSetFont(-1,12,700,0,"Courier New")
GUICtrlSetColor(-1,0xBEFFBE)
GUICtrlSetBkColor(-1,0x000000)
DllCall("User32.dll","long","AnimateWindow","hwnd",$test,"long",300,"long",0x10)
GUISetState()

While 1
      Sleep(100)
WEnd

Func MimimizeGui()
      GUISetState(@SW_MINIMIZE)
EndFunc

Func ExitGui()
      DllCall("User32.dll","long","AnimateWindow","hwnd",$test,"long",300,"long",0x10+0x10000)
      Exit
EndFunc


Цитата:

либо они обновили дистрибутив уже после того как ты его скачал
Ладно, спасибо, попробую ещё раз перекачать и установить.

Creat0R 23-01-2007 02:06

DenchikK
Цитата:

чтоб скрипт искал файл qip.exe во
всём каталоге Program Files, и если таковой найдется - возвратил бы
тот каталог, в котором он лежит и запихнул бы в реестр полный путь к
катлогу (не к файлу).
Вот рабочий пример, путь в реестре куда писать, поменяешь у переменной $RegKey, а имя значения у переменной $RegValueName:

Код:

#include <File.au3>
#include <Array.au3>

$PathForSearch = @ProgramFilesDir
$FileToFind = "Qip.exe"
$RegKey = "HKEY_CURRENT_USER\Software\QIP"
$RegValueName = "Path"

ProgressOn("Please wait...", "Getting Folders Structure...", $PathForSearch, -1, -1, 16)
$SearchResults = _FileFind($PathForSearch, $FileToFind)
ProgressOff()
If $SearchResults <> -1 Then
      RegWrite($RegKey, $RegValueName, "REG_SZ", $SearchResults)
      MsgBox(262144+64, "Done!", "File <" & $FileToFind & "> was found in this path <" & $SearchResults & ">, and the path was writen to registry key <" & $RegKey & "> under <" & $RegValueName & "> valuename.")
Else
      MsgBox(262144+48, "Attention!", "File <" & $FileToFind & "> was not found on <" & $PathForSearch & "> and it subfolders." & @CR & @CR & "OK ---> EXIT")
EndIf

Func _FileFind($Path, $FileToFind)
      Local $RetPath = $Path
      If FileExists($Path & "\" & $FileToFind) Then Return $Path
      $SubFoldersArr = _DirListToArray($Path)
      If IsArray($SubFoldersArr) Then
            $PrgrsDelim = 100 / $SubFoldersArr[0]
            $Prgrrs = $PrgrsDelim
            ProgressSet($Prgrrs, $Path, "Search for <" & $FileToFind & "> is in process...")
            For $iF = 1 To $SubFoldersArr[0]
                  ProgressSet($Prgrrs, $SubFoldersArr[$iF])
                  $Prgrrs = $Prgrrs + $PrgrsDelim
                  If FileExists($SubFoldersArr[$iF] & "\" & $FileToFind) Then
                        $RetPath = $SubFoldersArr[$iF]
                        ExitLoop
                  EndIf
            Next
      EndIf
      If $RetPath <> $Path Then
            Return $RetPath
      Else
            Return -1
      EndIf
EndFunc

Func _DirListToArray ($sPath)
    Local $i, $j, $rlist[1]=[0], $blist, $alist=_FileListToArray ($sPath, '*', 2)
    If IsArray ($alist) Then
      For $i=1 To $alist [0]
            _ArrayAdd ($rlist, $sPath & "\" & $alist [$i])
            $blist = _DirListToArray ($sPath & "\" & $alist [$i])
            If $blist[0] > 0 Then
                  $PrgrsDelim = 100 / ($blist[0] + $alist[0])
                  $Prgrrs = $PrgrsDelim
                  For $j=1 To $blist[0]
                        ProgressSet($Prgrrs, $blist[$j])
                        $Prgrrs = $Prgrrs + $PrgrsDelim
                        _ArrayAdd ($rlist, $blist[$j])
                  Next
            EndIf
        Next
    EndIf
    $rlist [0] = UBound ($rlist) - 1
    Return $rlist
EndFunc

Если ненужен вывод прогресса, просто убери строчки связанные с Progress ;)

Diamond 23-01-2007 06:31

DenchikK
Creat0R
К сожалению, а может и к радости, мне не удалось найти уже готового решения и я решил написать функцию поиска сам.
А сейчас захожу на форум и, вот тебе раз, опоздал... Ну да ладно... как вам такой вариант, вроде бы тоже ничего? :blush2:
P.S. Есть ещё перебор через VBScript с помощью ObjCreate(). Если интересно - выложу. :)
Код:

$ret = find(@ProgramFilesDir,"qip.exe")
If Not $ret=0 Then
        MsgBox(0,"",$ret)
        ; Записываем значение $ret в реестр...
Else
        MsgBox(0,"","Файл не найден.")
EndIf

;=================================

; $Path - Путь поиска. ( Не должен заканчиваться слэшем!!! )
; $FileName - Имя искомого файла.
; Возвращает полный путь к каталогу (не к файлу), если файл осутствует возвращает 0

Func find($Path,$FileName)
If Not IsDeclared("GetPath") Then
        Global $GetPath=0
EndIf

$ModPath=$Path & "\*" ; Формирую строку поиска (толко для инициализации)
$file=FileFindFirstFile($ModPath) ; Инициализация поиска
While 1
        $get=FileFindNextFile($file) ; Поиск...
        If @error Then ExitLoop
        $string=$Path & "\" & $get ; Формирую новый путь
        If Not StringInStr(FileGetAttrib($string),"D") Then ;Если не является папкой тогда:
                If $get=$FileName Then
                        $GetPath=$Path
                        ExitLoop
                EndIf
        Else
                find($string,$FileName) ; Запуск подфункции для поиска в подпапке
        EndIf
WEnd
FileClose($file) ;Завершение инициализации
Return $GetPath
EndFunc

Исправлено!

Creat0R 23-01-2007 06:47

Такой вопрос:
-Возможно ли получить иконку из файла, в случае если расширение файла не зарегистрированно в системе? Т.е мне нужно сделать GuiCtrlSetImage(), и указать так, чтобы та иконка которая отображается на файле, была считана для контроля ($CtrlID).
К примеру, есть файл Program.exe, известно что далеко не все исполняемые файлы (и другие) содержат иконку, и нужно каким то образом определить, содержит ли этот файл иконку, если не содержит, то естественно путь к иконке можно указать к Shell32.dll, 2 (где 2 это ID иконки для екзешников не содержащих иконки), если содержит, то к самому файлу, и как ID ставить 0. А если файл не исполняемы, то можно по расширению читать из реестра путь к иконке.

Вобщем-то сам вопрос - Как узнать, содержит ли файл иконку? и по возможности, получить путь к иконке для не зарегистрированных типов файлов.

Creat0R 23-01-2007 07:38

Diamond
Цитата:

вроде бы тоже ничего?
Вроде бы? :o а теперь засекай время поиска моей функции (часть которой является также и функция от amel27 - _DirListToArray()), и время для поиска которое уходит у твоей функции, результат шокирующий (меня) - Мой скрипт ищет (у меня на компе, с моей кучей программ) ровно 16 секунд, твой, ровно в два раза быстрее! 8 секунд! :UP: я понимаю что ProgressSet занимает время, но я сравнивал “голые” функции в действии, и тоже в два раза твоя оказалась быстрее.
Правда есть пару минусов - нет возможности заранее получить общее количество найденых папок (для точного подсчёта прогрессбара, или вывода прочей информации), также нельзя искать по маске, или ставить случайно слеш после пути :tongue: . Но в данном случае, если требуется произвести исключительно поиск, то этот (твой) вариант идеальный! :up:

P.S.
Немного изменил гуи для перетаскивания, и код для поиска (там в самой функции случайно указал \qip.exe :blush2: ).

Creat0R 23-01-2007 08:51

Diamond
А функция не работает то :( - нужно Global $GetPath = 0 ставить вне функции, т.к каждый вызов подфункции, вне зависимости от того найден ли файл, задаёт переменной $GetPath значение 0, таким образом цикл не прирывается, и пока не проверяются все файлы функция действует...

Вот немного изменил её (сорри если что), а также добавил в неё определение файла в корневом каталоге (в $Path):

Код:

Global $GetPath=0
$ret = find(@ProgramFilesDir,"qip.exe")
If Not $ret=0 Then
        MsgBox(0,"",$ret)
        ; Записываем значение $ret в реестр...
Else
        MsgBox(0,"","Файл не найден.")
EndIf

;=================================

; $Path - Путь поиска. ( Не должен заканчиваться слэшем!!! )
; $FileName - Имя искомого файла.
; Возвращает полный путь к каталогу (не к файлу), если файл осутствует возвращает 0

Func find($Path,$FileName)
$ModPath=$Path & "\*" ; Формирую строку поиска (толко для инициализации)
$file=FileFindFirstFile($ModPath) ; Инициализация поиска
While 1
; Условие для прерывания всех циклов - чтобы быстро выйти из функции
        If $GetPath <> 0 Then ; Если нужный нам файл уже найден тогда
                ExitLoop ; Прерываю циклы всех подфункций
        EndIf
        $get=FileFindNextFile($file) ; Поиск...
        If @error Then ExitLoop
        $string=$Path & "\" & $get ; Формирую новый путь
        If Not StringInStr(FileGetAttrib($string),"D") Then ;Если не является папкой тогда:
                If $get=$FileName Then
                        $GetPath=$Path
                        ExitLoop
                EndIf

        Else
                find($string,$FileName) ; Запуск подфункции для поиска в подпапке
        EndIf
WEnd
FileClose($file) ;Завершение инициализации
Return $GetPath
EndFunc

Файл в корневом каталоге и раньше определялся (если убрать Global $GetPath = 0 из функции), но так быстрее ;)
P.S. всё изменённое выделенно.

Creat0R 23-01-2007 09:44

Diamond
Немного “гуинизировал” твою функцию для поиска файла :biggrin: - в первом поле задаём путь в котором нужно искать, а в нижнем запрос (имя файла) - неверно набранный путь (если не существует или содержит слеш на конце) определяется, а также определяется если набранное имя файла содержит непозволенные символы (< > | ? : * / \ "):

Код:

Opt("GuiOnEventMode", 1)

Global $Progress = 0.1, $GetPath = 0
$PathForSearch = @ProgramFilesDir
$FileToFind = "FileName.exe"

$Gui = GUICreate("File Finder", 300, 170, -1, -1, -1, 0x00000088)
GUISetOnEvent(-3, "ExitScript")

GUICtrlCreateLabel("Path to search on:", 20, 30)
$PathInput = GUICtrlCreateInput($PathForSearch, 20, 50, 270)

GUICtrlCreateLabel("File to find:", 20, 90)
$FileNameInput = GUICtrlCreateInput($FileToFind, 20, 110, 270)

$SearchButton = GUICtrlCreateButton("Search", 70, 140, 60, 20)
GUICtrlSetOnEvent(-1, "SearchButton")
$CancelButton = GUICtrlCreateButton("Cancel", 180, 140, 60, 20)
GUICtrlSetOnEvent(-1, "ExitScript")

GUISetState()

While 1
    Sleep(100)
WEnd

Func _FindFile($Path, $FileName)
    $ModPath = $Path & "\*" ; Формирую строку поиска (толко для инициализации)
    $File = FileFindFirstFile($ModPath) ; Инициализация поиска
    While 1
        ; Условие для прерывания всех циклов - чтобы быстро выйти из функции
        If $GetPath <> 0 Then ExitLoop ; Прерываю циклы всех подфункций
        $Get = FileFindNextFile($File)
        If @error Then ExitLoop
        $String = $Path & "\" & $Get ; Формирую новый путь
        ProgressSet($Progress, $Path & @CR & $Get)
        $Progress = $Progress + 0.1
        If $Progress >= 100 Then $Progress = 0.1
        If Not StringInStr(FileGetAttrib($String), "D") Then ;Если не является папкой тогда:
            If $Get = $FileName Then
                $GetPath = $Path
                ExitLoop
            EndIf
        Else
            _FindFile($String, $FileName) ; Запуск подфункции для поиска в подпапке
        EndIf
    WEnd
    FileClose($File) ;Завершение инициализации
    Return $GetPath
EndFunc

Func SearchButton()
    If Not FileExists(GUICtrlRead($PathInput)) Then
        _MsgBox(16, "Error", "You must type an existing path", $Gui)
    ElseIf StringRight(GUICtrlRead($PathInput), 1) = "\" Then
        _MsgBox(48, "Attention!", "The path must not have a slash (\) at the end of it.", $Gui)
    ElseIf GUICtrlRead($FileNameInput) = "" Then
        _MsgBox(16, "Error", "You must type a file name", $Gui)
    ElseIf Not _IsFileName(GUICtrlRead($FileNameInput)) Then
        _MsgBox(16, 'Error', 'The file name include an invalid characters' & @CR & '< > | ? : * / \ "', $Gui)
    Else
        $PathForSearch = GUICtrlRead($PathInput)
        $FileToFind = GUICtrlRead($FileNameInput)
        GUISetState(@SW_HIDE, $Gui)
        ProgressOn("Please wait...", "Search is in progress...", $PathForSearch, -1, -1, 16)
        $SearchResults = _FindFile($PathForSearch, $FileToFind)
        ProgressOff()
        If Not $SearchResults = 0 Then
            MsgBox(262144+64, "Done!", "File <" & $FileToFind & "> was found in this path <" & $SearchResults & ">.")
        Else
            MsgBox(262144+48, "Attention!", "File <" & $FileToFind & "> was not found on <" & $PathForSearch & "> and it subfolders." & @CR & @CR & "OK ---> EXIT")
        EndIf
        GUISetState(@SW_SHOW, $Gui)
    EndIf
EndFunc

Func _IsFileName($Test)
    If StringRegExp($Test, '[<>|?:"*/\\]') <> 0 Then
        Return False
    Else
        Return True
    EndIf
EndFunc

Func _MsgBox ($MsgBoxType, $MsgBoxTitle, $MsgBoxText, $mainGUI=0)
    $ret = DllCall ("user32.dll", "int", "MessageBox", _
            "hwnd", $mainGUI, _
            "str", $MsgBoxText , _
            "str", $MsgBoxTitle, _
            "int", $MsgBoxType)
    Return $ret [0]
EndFunc

Func ExitScript()
    Exit
EndFunc


Diamond 23-01-2007 10:30

Creat0R
Цитата:

Такого конкретного стиля (кажется) нет
Вот и я так подумал что в самом AutoIt классического стиля нет. Мне кажется, что это сама система навязывает свой стиль(Windows XP). Т.е. это как например если не указать конкретно цвет фона для GUI, то цвет фона по умолчанию становится системный(BtnFace). Вот если бы это дело можно было как-то "блокировать", думаю нужно копать в сторону WinApi.
Цитата:

тогда можно перетаскивать окно тягая этот контроль:
Отлично! Что-то вроде этого я как раз и искал. :) Спасибо! Жалко только что GuiCtrlCreateLabel перекрывает мои кнопки.
Цитата:

твой, ровно в два раза быстрее!
Я считаю что мой скрипт значительно уступает твоему по функциональности. :not-me:
Цитата:

цикл не прирывается, и пока не проверяются все файлы функция действует
Да действительно... я добавил Global $GetPath=0 в самый последний момент, и видимо как следует не протестировал, :blush: а до того у меня стоял Global $GetPath без всяких нулей - соответственно, при отсутствии файла возвращалось пусто (""). В принципе, $GetPath можно оставить и внутри функции (только не приравнивать нулю или, проверять переменную на декларирование), а на скорости я думаю это сильно не отразится. Кстати протестировал на скорость у меня разница где-то 1,5 раза. Спасибо что указал на ошибку! :)
А вот ExitLoop что ты добавил, никак не влияет на прерывание! :nono:

Creat0R 23-01-2007 11:27

Diamond
Цитата:

ExitLoop что ты добавил, никак не влияет на прерывание!
Создай в C:\program files файл test.txt, и задай вместо qip.exe - test.txt, теперь запусти функцию без ExitLoop (засеки время поиска), и запусти с ExitLoop, файл найден почти сразу же ;)

Diamond 24-01-2007 03:45

Creat0R
Цитата:

запусти функцию без ExitLoop (засеки время поиска), и запусти с ExitLoop, файл найден почти сразу же
Твой способ проверки (сравнение по времени) оказался не стабилен. Я долго гонял:maniac:скрипт и, во многих случаях получалось как раз то всё наоборот. Но я решил подставлять Msgbox() в разных места и при различных вариантах. Получается что ты прав! И даже больше!!! :UP:

Когда дочерняя подфункция находит файл, она завершаясь возвращает контроль родительской функции, которая в свою очередь (как я понял) продолжает работу с того места откуда последний раз запускала дочернюю подфукцию, а вот тут-то :moderator её будет поджидать твой ExitLoop. Исходя из всего выше сказаного, я думаю (моё) "условие для прерывания всех циклов" - абсолютно лишнее!
Т.е. когда стоит твой ExitLoop, то до моего условия (прерывания), дело вообще не доходит!!! Уф-ф... В общем, я убираю его (условие)... :)

Creat0R 24-01-2007 18:36

Нашёл в аутоите баг (или это так задуманно?) - При BlockInput(1), вроде всё кроме Ctrl Alt Del должно быть заблокированно, но срабатывает нажатие и на Sleep и на Power.
Собственно вопрос: Возможно ли перед блокировкой, назначить другое действие для этих клавиш? (т.е чтобы при их нажатии ничего не происходило) - Очень очень нужно :( .

P.S
Задать клавишу Sleep можно, но она почему то продолжает работать (как Sleep)

Creat0R 24-01-2007 22:47

Давно искал способ сделать “плавающее окошко”, чтобы ещё при “плавании” :), перемещалось хаотично по экрану. Когда ещё только начинал разбирать гуи в AutoIt'е, думал это не реально, и забросил эту затею, но вот тут ни с того ни с сего, я вдруг вспомнил об этом, и решил попробовать реализовать (всё же знании уже побольше), и, реализовал! (довольно без проблем, и быстро)...

Вот Пример:

Код:

#include <GuiConstants.au3>
Opt("GuiOnEventMode", 1)

;Создаём стильны гуи для показа ;-)
GUICreate("Fading GUI", 200, 100, -1, -1, $WS_POPUP+$WS_DLGFRAME, $WS_EX_CLIENTEDGE+$WS_EX_TOPMOST)
GUISetOnEvent(-3, "ExitScript")
GUISetBkColor(0xC1C9FD)
;Активируем гуи в скрытом режиме, в целях избежания мерцания окна при первом запуске
GUISetState(@SW_HIDE)
;Устанавливаем самый высокий уровень (0) прозрачности окна гуи
WinSetTrans("Fading GUI", "", 0)
;Показываем обратно гуи в невидемом состоянии (100 % прозрачности)
GUISetState(@SW_SHOW)

$Close = GUICtrlCreateButton("Close", 70, 40, 60, 20)
GUICtrlSetOnEvent(-1, "ExitScript")

;Включаем функцию утухания и перемещения окна каждые 100 м"с
AdlibEnable("GUIFad", 100)
While 1
    Sleep(10)
WEnd

Func GUIFad()
    ;Задаём интервал исчезновения окна и проходимся по нему
    For $i = 0 To 255
        Sleep(10)
        WinSetTrans("Fading GUI", "", $i)
    Next
    Sleep(50)
    ;Задаём интервал появления окна и проходимся по нему (в обратном порядке)
    For $j = 255 To 0 Step -1
        Sleep(10)
        WinSetTrans("Fading GUI", "", $j)
    Next
    ;Двигаем окно в хаотичном порядке (хм, парадокс получается ;) ), в соответствии с координатами разрешения экрана
    WinMove("Fading GUI", "", Random(0, @DesktopWidth-200), Random(0, @DesktopHeight-200))
EndFunc

Func ExitScript()
    Exit
EndFunc

Очень подходит если нужно сделать своего рода призентацию, или просто слайдшоу картинок или ещё чего нибудь :blush2: .

Creat0R 26-01-2007 04:48

Оказывается, можно вызвать MsgBox не в стильном виде (не испоьзуя стиль WinXP) - т.е сообщение будет выглядеть как системное в Win98...

Нужно просто перед основным флагом, ставить стиль 0x20000:

Код:

MsgBox(0x20000+64, "Hello!", "I am styleless MsgBox ;) ")
Я вот только не знаю как убрать атрибут “поверх всех окон”, перепробовал кучу номеров, но так и не нашёл подходящий.

borzoy 27-01-2007 02:32

Привет всем!!!
Помогите пожалуйста с скриптом для установкой Fraps и Runpad Shell.
Для тихой установки уже наверное все ключики перепробывал, но не помогает, всеравно вылазиет табличка с уведомлением установить программу.

Creat0R 27-01-2007 11:28

borzoy
Цитата:

Для тихой установки уже наверное все ключики перепробывал
Эта инфа, я полагаю должна сопоставляться с установщиком...
А вообще, нужно было создавать отдельный топик:

Цитата:

Данная тема предназначена для общих вопросов по AutoIt. Вопросы по установке приложений при помощи AutoIt следует задавать в соответствии с правилами форума "Автоматическая установка приложений". Таким образом, если вы хотите узнать как установить Winamp 5.x при помощи AutoIt, то создайте тему [autoit] Winamp 5.х (если таковой еще нет на форуме). Проверить наличие тем можно при помощи поиска или фильтров.

borzoy 27-01-2007 20:12

Creat0R
Цитата:

Таким образом, если вы хотите узнать как установить Winamp 5.x при помощи AutoIt, то создайте тему [autoit] Winamp 5.х (если таковой еще нет на форуме).
Видимо Модераторы плохо знают правила раз сами их не знают. Сделал как и написано было тему [autoit]Fraps и Punpad Shell4 но какой то модератор удалил эту тему!!!

jameszero 28-01-2007 01:39

borzoy
Я отправил вам оповещение, что ваша тема [autoit] Fraps и Punpad Shell4, с просьбой помочь создать скрипт, перенесена в созданную вами же тему Помогите с тихой установкой Fraps и Runpad Shell, в которой уже начато обсуждение.
Зачем создавать одинаковые темы? ОПК - пункт 2.1
(Тема переименована в [autoit] Fraps и Runpad Shell, ни один пост не удалён)

Creat0R 29-01-2007 19:44

В AutoIt'е плохо (а точнее не корректно) работает функция FileDelete - например если написать её так:

Код:

FileDelete(@TempDir & "\")
То в папке @TempDir будут удалены все файлы (не папки), т.е если я укажу файл для удаления в виде переменной, и каким то образом эта переменная окажется пуста (""), то может произойти нежеланная катастрофа :blush2: - будьте очень остарожны, я на днях попал на эту удочку (правда к счастью у меня был бекап уалившихся файлов).

Diamond 30-01-2007 07:28

Creat0R
Цитата:

В AutoIt'е плохо (а точнее не корректно) работает функция FileDelete
Здесь, если даже не включать проверку на существование файла, то (в случае с пустой переменной или отсутствием файла) скрипт завершиться с ошибкой, но ничего удалено не будет! :tongue:
Думаю всё же, такой способ надёжней в плане безопасности, чем мучаться и придумывать разные хитрости, пытаясь исправить баг AutoIt'а. :)
Код:

Dim $fso
;~ Создание объекта
$fso = ObjCreate("scripting.filesystemobject")

;~ Удаление файла
Func DeleteFile($FileSpec)
If $fso.FileExists($FileSpec) Then
        $fso.DeleteFile($FileSpec, True)
EndIf
EndFunc

;~ Удаление папки
Func DeleteFolder($FolderSpec)
If $fso.FolderExists($FolderSpec) Then
        $fso.DeleteFolder($FolderSpec, True)
EndIf
EndFunc


Creat0R 04-02-2007 07:38

Diamond
Да, это неплохой способ, спасибо, возьмём его пожалуй в арсенал функции аутоита ;)




Я что-то не нашёл функции, которая проверяла бы данное число на чётность/не чётность, и решил её сам сделать (понадобилась сея функция), но не уверен что это правильное решение, может уже есть подобная функция, или у кого то есть более универсальное предложение? :shuffle:

Код:

$iNumber = 2075674

If _IsEven($iNumber) Then
    MsgBox(64, "Even check", "The given number <" & $iNumber & "> is an Even number")
Else
    MsgBox(64, "Even check", "The given number <" & $iNumber & "> is not an Even number (it is Odd)")
EndIf

Func _IsEven($NumString)
    If $NumString < 1 Then
        $NumStrArr = StringSplit($NumString, ".")
        If IsArray($NumStrArr) And $NumStrArr[0] > 1 Then $NumString = $NumStrArr[2]
    EndIf
    If IsFloat($NumString / 2) Then
        Return 0
    Else
        Return 1
    EndIf
EndFunc

.........
И ещё, заметил вроде ещё багу в аутоите, проверить очень просто:

Код:

MsgBox(0, "", 0.00001)
Получаем 1e-005 - и это так должно быть? я понимаю что можно заключить в кавычки, и тогда будет отображать дословно, но просто интересно, почему это происходит? :blink:

amel27 04-02-2007 08:18

Creat0R
Привет, на самом деле все гораздо проще:
Код:

Func _IsEven ($num)
    If Mod($num,2)=0 Then
        Return 1
    Else
        Return 0
    EndIf
EndFunc

...хотя твои манипуляции с точкой наводят на мысль что обычной четности тебе мало (имеет смысл только для целых чисел).
Цитата:

И ещё, заметил вроде ещё багу в аутоите
Это не баг, это фича. ;) ...Это разное представление одного числа, поэтому все вполне корректно.
Для однозначного представления используй StringFormat:
Код:

MsgBox (0,'',StringFormat('%.5f',0.00001))

amel27 04-02-2007 09:29

Creat0R
Diamond


Красивый способ для FileDelete с форума поддержки:
Код:

Func _FileDelete ($file)
    If Not StringInStr(FileGetAttrib($file),'D') Then
        FileDelete($file)
    EndIf
EndFunc


Diamond 04-02-2007 21:34

Подскажите, как с помощью WinApi поменять частоту обновления экрана?
В интернете есть множество примеров с использованием библиотеки: user32.dll функция: ChangeDisplaySettingsA, но как реализовать это в AutoIt совершенно не представляю. Очень надо!!!

Creat0R 05-02-2007 01:51

amel27
Цитата:

на самом деле все гораздо проще
Действительно, а главное, этот пример есть и в справке, как я его упустил :) спасибо!

Цитата:

твои манипуляции с точкой наводят на мысль что обычной четности тебе мало
Просто хотел проверять и чётность дробных чисел.

Цитата:

Красивый способ для FileDelete с форума поддержки
Хм, это видимо самый верный способ, просто проверяется если это не папка, тогда удаляется файл... а разработчики вкурсе об этом? почему не сделают “офицеальную” команду в таком же духе ;)




Такой вопрос:
Как послать обычное нажатие клавишы Windows (с изображением окон)? нужно отдельно в експлорере вызвать контекстное меню, и единственны способ который мне пришел в голову, так это нажать эту клавишу...
Пробую так:
Код:

Send("#")
Ничего не происходит, в полукруглые скобки заключать пробовал, тоже никакого эффекта, есть идеи?

Или, как можно обновить окно експлорера, но не посыланием F5, а именно полноценным обновлением (в некоторых случаях F5 не помагает).

Creat0R 06-02-2007 05:32

Ещё способ удаления файла:

Код:

Func _FileDelete($Path, $FileName)
    If StringLen($FileName) >= 1 Then FileDelete($Path & "\" & $FileName)
EndFunc

А также способ подсчёта количества символов в файле:

Код:

$FileName = @ScriptDir & "\test.txt"
$FileCharCount = _FileCountChar($FileName, 0)
If $FileCharCount <> -1 Then
    MsgBox(64, "File Characters Count", "In the file <" & $FileName & "> was found [" & $FileCharCount & "] characters (including Carriage Returns and Line Feeds)")
Else
    MsgBox(16, "Error!", "The file <" & $FileName & "> was not found")
EndIf

Func _FileCountChar($FileName, $Flag=0)
    If Not FileExists($FileName) Then Return -1
    Local $CharsCount = 0
    $fRead = FileRead($FileName, FileGetSize($FileName))
    $fReadArr = StringSplit($fRead, "")
    If IsArray($fReadArr) Then
        For $i = 1 To $fReadArr[0]
            If ($Flag = 1 And $fReadArr[$i] <> @CR And $fReadArr[$i] <> @LF) Or ($Flag = 2 And $fReadArr[$i] <> @CR) Or ($Flag = 3 And $fReadArr[$i] <> @LF) Or $Flag = 0 Then $CharsCount += 1
        Next
        Return $CharsCount
      EndIf
EndFunc


Если поставить последний параметр как 1 ($Flag=1), то подсчёт не будет учитывать возврат каретки и перевод строки (@CRLF), если поставить параметр на 2, то будут учитываться все символы кроме @CR, ну а если поставит параметр $Flag = 3, то будут учитываться все символы за исключением символа перевода строки (@LF).

amel27 06-02-2007 12:35

Diamond
Цитата:

Подскажите, как с помощью WinApi поменять частоту обновления экрана?
Код:

; Пример использования функции
_DisplaySetRes (1024, 768, 32, 75)

; Функция изменения видеорежима (для одного монитора)
Func _DisplaySetRes ($width, $height, $depth, $freq)
    Local $dev = DllStructCreate ("byte[32];int[10];byte[32];int[6]")
    ; Возвращаем текущее состояние устройства
    Local $ret = DLLCall ('user32.dll', 'int', 'EnumDisplaySettings', _
        'ptr' , 0, _
        'long', 0, _
        'ptr' , DllStructGetPtr ($dev) )
    If @error Then Return 0
    If $ret[0]=0 Then Return 0
    ; Правим нужные элементы структуры
    DllStructSetData ($dev, 4, $depth, 1)
    DllStructSetData ($dev, 4, $width, 2)
    DllStructSetData ($dev, 4, $height, 3)
    DllStructSetData ($dev, 4, $freq, 5)
    ; Проверяем корректность параметров
    $ret = DllCall ('user32.dll', 'int', 'ChangeDisplaySettings', _
        'ptr', DllStructGetPtr ($dev), _
        'int', 2 )
    If @error Then  Return 0
    ; Если все ОК - применяем новые параметры
    If $ret[0] =0 Then
        $ret = DllCall ('user32.dll', 'int', 'ChangeDisplaySettings', _
            'ptr', DllStructGetPtr ($dev), _
            'int', 1 )
        If @error Then  Return 0
        Return 1
    Else
        Return -1
    EndIf
EndFunc


amel27 06-02-2007 13:13

Creat0R
Цитата:

А также способ подсчёта количества символов в файле
Альтернативный вариант. Правда пришлось сдвинуть значения флагов, чтобы одному биту соответствовал один пропускаемый символ: @CR - Bit 1 ; @LF - Bit 2.
Код:

Func _FileCharCount ($file, $flag=1)
    Local $str = FileRead ($file)
    If BitAND ($flag, 1) Then $str = StringStripCR ($str)
    If BitAND ($flag, 2) Then $str = StringReplace ($str, @LF, '')
    Return StringLen ($str)
EndFunc


Diamond 06-02-2007 19:29

amel27
По поводу частоты обновления
Отлично! Всё работает! :UP: Если честно, я и не надеялся что вообще кто нибудь ответит, иначе задал бы этот вопрос ещё месяц назад. Большое спасибо!
P.S.
Была проблема с видеокартой, в некоторых играх частота сбрасывалась с 85 Гц. на 60 Гц. Перепробовал уже (наверное) все известные утилиты и ни одна из них не помогла. Теперь проблема решилась. :victory: Ещё раз спасибо!

i_mihal 12-02-2007 02:19

Есть фирменная YAMAHA'овская программа для конвертирования звуковых WAV-файлов
в формат MMF (используется в сотовых телефонах Samsung, LG, Pantech, etc...)
Называется WSC-MA2, сайт http://smaf-yamaha.com/

Это, похоже, единственая программа, которая может конвертировать WAV->MMF.
Но она не работает из командной строки, у нее нет меню, она не работат в пакетном режиме.
Для того чтоб сконвертировать WAV в MMF надо схватить WAV-файл мышкой,
перетащить и бросить его на маленькое, красивенькое окошко этой программы.

Можно ли с помощью AutoIt проделать такую операцию?
То есть "взять некий WAV-файл мышкой" и "кинуть его на окошко этой проги"
(в перспективе взять по-очереди в цикле все файлы с расширением WAV
и покидать их на окошко программы)

Реализуемо ли это в рамках Auto-It?
или вообще как-нибудь, кроме как вручную.

спасибо.


amel27 12-02-2007 07:36

i_mihal
обычно перетаскивание можно заменить на копировать/вставить через буфер обмена...

amel27 12-02-2007 08:05

Чтение параметров локализации средствами API:
Код:

$sys = DllCall ("kernel32.dll", "int", "GetSystemDefaultLCID")
$usr = DllCall ("kernel32.dll", "int", "GetUserDefaultLCID")
MsgBox (0,'Default locale ID','Пользователи: ' & @TAB & @TAB & $usr[0] & @CRLF & _
    'Системные службы: ' & @TAB  & $sys[0])


Creat0R 12-02-2007 11:59

Написал давно желанную функцию, но она работает как бы наполовину - она должна заменять стандартную функцию FileSelectFolder, но проблема в том, что у меня не получается - А) либо создать все вкладки (в TreeView) для всех существующих папок (это также займёт кучу времени на их генерацию), Б) либо создавать их “находу” (т.е в момент вызова/раскрытия той или иной вкладки) - в принципе, проблема со вторым вариантом такая - нужно узнать как очистить одну выделенную вкладку от её подвкладок (не удаляя её саму).
Для чего нужна такая функция? во-первых для того чтобы можно было прикреплять это окно к другому приложению (или к родительскому гуи) - эта одна из основных причин (даже самая) - далее можно также используя подобную функцию, просто создавать это окно с разными размерами, с разными кнопками и возвращаемой информацией, также будет возможность задать этому окну атрибут “поверх всех окон” и т.д и т.п...

Вот в принципе сам скрипт с примером:

Код:

#include <GUIConstants.au3>
#include <GUITreeView.au3>
#include <File.au3>

$Parent = GUICreate("test", 200, 200)
$Select = GUICtrlCreateButton("Select", 50, 50)

GUISetState()

While 1
        $Msg = GUIGetMsg()
        If $Msg = -3 Then ExitLoop
        If $Msg = $Select Then
                GUISetState(@SW_DISABLE)
                $Path = _FileSelectFolder("Select Folder", "Choose needed Path:", 300, 300, 1, $Parent)
                If Not @error Then MsgBox(64, "Path", "The selected path is: <" & $Path & ">")
                GUISetState(@SW_RESTORE)
                GUISetState(@SW_ENABLE)
        EndIf
WEnd

GUIDelete()

Func _FileSelectFolder($Title, $Dialog_Text, $Width=300, $Heght=300, $OnTop=0, $Hwnd="")
        Opt("GuiOnEventMode", 1)
        Global $IsExit = 0, $IsCancel = 0, $PathInput, $MainTreeViewID, $TOPMOST
        If $OnTop = 1 Then $OnTop = 8
        GUICreate($Title, $Width, $Heght, -1, -1, $WS_SYSMENU+$WS_CAPTION+$WS_SIZEBOX, $WS_EX_CONTEXTHELP+$OnTop, $Hwnd)
        GUISetOnEvent(-3, "Cancel")
       
        GUICtrlCreateLabel($Dialog_Text, 10, 5)

        $ButtonOK = GUICtrlCreateButton("OK", $Width-180, $Heght-25, 70, 20)
        GUICtrlSetOnEvent(-1, "OK")
       
        $ButtonCancel = GUICtrlCreateButton("Cancel", $Width-80, $Heght-25, 70, 20)
        GUICtrlSetOnEvent(-1, "Cancel")
       
        $PathInput = GUICtrlCreateInput("", 10, $Heght-50, $Width-20)

        $MainTreeViewID = GUICtrlCreateTreeView(10, 30, $Width-20, $Heght-90, BitOr($TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS), $WS_EX_CLIENTEDGE)

        GUISetState()

        $DrivesArr = _DrivesListToArray("all")
        If IsArray($DrivesArr) Then
                Dim $MainDriveID[$DrivesArr[0]+1], $CurrentIcon, $CurrentIcID
                For $i = 1 To $DrivesArr[0]
                        $CurrentDrive = $DrivesArr[$i]
                        If $CurrentDrive <> "a:" And $CurrentDrive <> "b:" Then
                                $CurrentIcon = $CurrentDrive & "\" & IniRead($CurrentDrive & "\Autorun.inf", "Autorun", "Icon", "")
                                $CurrentIcID = 0
                        EndIf
                        If Not FileExists($CurrentIcon) Then
                                $CurrentIcon = "shell32.dll"
                                $CurrentIcID = 8
                        EndIf
                        $MainDriveID[$i] = GUICtrlCreateTreeViewItem(StringUpper($CurrentDrive) & "\", $MainTreeViewID)
                        GUICtrlSetOnEvent(-1, "GetText")
                       
                        If $CurrentDrive = "a:" Or $CurrentDrive = "b:" Then
                                GUICtrlSetImage(-1, "shell32.dll", 6, 0)
                        ElseIf DriveGetType($CurrentDrive) = "CDROM" Then
                                GUICtrlSetImage(-1, "shell32.dll", 11, -1)
                        Else
                                GUICtrlSetImage(-1, StringStripWS($CurrentIcon, 3), $CurrentIcID, -1)
                        EndIf
                       
                        If $CurrentDrive <> "a:" And $CurrentDrive <> "b:" Then
                                $DirsArr = _FileListToArray($CurrentDrive, "*", 2)
                                If IsArray($DirsArr) Then
                                        For $j = 1 To $DirsArr[0]
                                                $CurrentDir = $DirsArr[$j]
                                                GUICtrlCreateTreeViewItem($CurrentDir, $MainDriveID[$i])
                                                GUICtrlSetOnEvent(-1, "GetText")
                                                _GUICtrlTreeViewSetIcon($MainTreeViewID, -1, "shell32.dll", 4)
                                        Next
                                EndIf
                        EndIf
                Next
        EndIf

        While $IsExit = 0
                Sleep(10)
        WEnd
        $Path = StringReplace(_GUICtrlTreeViewGetTree($MainTreeViewID, "\"), "\\", "\")
        GUIDelete()
        Opt("GuiOnEventMode", 0)
        If $IsCancel = 1 Then
                SetError(1)
                Return ""
        Else
                Return $Path
        EndIf
EndFunc

Func GetText()
        GUICtrlSetData($PathInput, GUICtrlRead(@GUI_CtrlId, 1))
EndFunc

Func OK()
        Global $IsExit = 1
EndFunc

Func Cancel()
        Global $IsExit = 1, $IsCancel = 1
EndFunc

Func Quit()
        Exit
EndFunc

Func _DrivesListToArray($Type)
        $DrivesArr = DriveGetDrive($Type)
        If IsArray($DrivesArr) Then
                Dim $DrivesListArr[$DrivesArr[0]+1]
                $DrivesListArr[0] = $DrivesArr[0]
                For $iDrive = 1 To $DrivesArr[0]
                        $CurrentDrive = $DrivesArr[$iDrive]
                        $DrivesListArr[$iDrive] = $CurrentDrive
                Next
        EndIf
        Return $DrivesListArr
EndFunc

И ещё хотелось бы сделать чтобы можно было задать при вызове функции исходную папку (Init Dir) - но увы я только сегодня начал разбирать основы TreeView, и поэтому не знаю как заставить раскрыться вкладкам на том месте где находится указанное имя (т.е имя вкладки).

biggreeder 12-02-2007 22:42

Вопрос знатокам.
А можно ли как-нибудь "раскомпилировать" .exe файл обратно в .au3?

Creat0R 12-02-2007 23:39

biggreeder
Цитата:

можно ли как-нибудь "раскомпилировать" .exe файл обратно в .au3?
Посмотри в папке с установленным AutoIt'ом - C:\Program Files\AutoIt3\Extras\Exe2Aut - но этолько если в момент компилляции опция позволяющая декомпилировать была утановлена, а также если был задан пароль, то без него никак не декомпилировать.

biggreeder 13-02-2007 00:52

Creat0R
Спасибо, дружище. Выручил. Винт накрылся. Думал пропали все мои скрипты (на диск записывал только exe-файлы)

Dicken 13-02-2007 08:07

День добрый,
интересует следующий вопрос:
Можно ли запускать IT скрипт с какимилибо параметрами, например мне нужен скрипт который бы выводи мне 2 значения из командной строки
т.е. скрипт я запускаю
Код:

RUN.exe параметр1 параметр2
и в результате скрипт выдал мне мессаге в котором мне былибы выданы 1 и 2 параметры
заранее спасибо

Positiv 13-02-2007 09:13

Вообщем такой трабл, при установке Agnitum Outpost Firewall выдает 2 окна с ошибками Microsoft Visual C++ Runtime Library. Я написал в скрипте функцию отлова этих окон с ошибками, но когда закрывается первое окно с ошибкой установка стопорится на Мастере Настройки, т.е дальше только вручную нажимать кнопки приходится. Посмотрите скрипт, мож че подскажите, или из-за чего такие ошибки вылетают, вроде библиотеки Си стоят.
СИНИМ выделено то, что добавил я, все остальное исходный скрипт от Sanja Alone
Код:

#cs
----------------------
Приложение: Agnitum Outpost
На какой(их) версии(ях) тестировалось: 3.5 (ru); 3.51 (ru)

Автор скрипта: Sanja Alone (http://forum.oszone.net/member.php?userid=28800)
----------------------
#ce
;предотвращение возможности множественного запуска скрипта
If WinExists(@ScriptName) Then Exit
AutoItWinSetTitle(@ScriptName)
;блокируем мышь и клаву
;AutoItSetOption("TrayIconHide", 1)
;Отображать текущую строку сценария с помощью индикатора системной панели в режиме отладки.
AutoItSetOption("TrayIconDebug", 1)
AutoItSetOption("SendKeyDelay", 15)
If ProcessExists ( "ps.exe" )<>0 Then
    ProcessClose ( "ps.exe" )
    ProcessWaitClose ( "ps.exe" )
EndIf
;нельзя блокировать при находящемся в памяти Punto Switcher-е - не будет работать установка
;блокируем мышь и клаву
;If @OSType="WIN32_NT" Then BlockInput ( 1 )
#cs
----------------------
объявление переменных
----------------------
$file - установочный файл
$serial - если имеете рабочий ключ, то введите его сюда
$programgroup - в какую программную группу положить ярлыки программы
$delfromautorun - удалить Outpost из автозапуска (1 - удалить (по ум.), любое другое значение - не удалять)

----------------------
#ce
Global $file='OutpostProInstall.exe', $serial='XXXXX', $programgroup='Agnitum Outpost Firewall', $delfromautorun=1
AdlibEnable("wfp",1000)
If FileExists ( @ProgramFilesDir & '\Agnitum\Outpost Firewall\outpost.exe' ) Then
    MsgBox (64, 'Сообщение', 'Agnitum Outpost Firewall уже установлен', 5)
    Exit
  Else
    Run ( @ScriptDir & '\' & $file & ' /LANG="ru" /NOAUTOUPDATE /NORESTART /VERYSILENT' )
EndIf
WinWait ( 'Мастер настройки' )
WinActivate ( 'Мастер настройки' )
WinWaitActive ( 'Мастер настройки' )
Send ( '{ENTER}' )
While ControlCommand ( 'Мастер настройки', '', '< &Назад', 'IsEnabled', '')=0
WEnd
WinActivate ( 'Мастер настройки' )
WinWaitActive ( 'Мастер настройки' )
;Далее
Send ( '{ENTER}' )
WinWait ( 'Ручная настройка' )
WinActivate ( 'Ручная настройка' )
WinWaitActive ( 'Ручная настройка' )
;Готово
Send ( '{ENTER}' )
#cs
----------------------
Крякнутые dll-ки и настройки программы поместите в самораспаковывающиеся архивы
        settings.exe - настройки
        opst_ui.exe - крякнутые dll-ки (если нет рабочего серийника)

команды SFX-сценария (для обоих архивов, winrar):
       
        Path=Agnitum\Outpost Firewall
        SavePath
        Silent=1
        Overwrite=1

----------------------
#ce

If WinWait("Microsoft Visual C++ Runtime Library") Then
WinActivate("Microsoft Visual C++ Runtime Library")
WinWaitActive("Microsoft Visual C++ Runtime Library")
Send("{ENTER}")
EndIf

If FileExists ( @ScriptDir & '\settings.exe' ) Then RunWait ( @ScriptDir & '\settings.exe' )
;регистрация
If $serial<>'' Then
RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Agnitum\Outpost Firewall","Key","REG_SZ",$serial)
ElseIf FileExists ( @ScriptDir & '\opst_ui.exe' ) Then
RunWait ( @ScriptDir & '\opst_ui.exe' )
EndIf


;перенос ярлыков
DirCopy ( @ProgramsCommonDir & '\Agnitum\Outpost Firewall', @ProgramsCommonDir & '\' & $programgroup, 1 )
DirRemove ( @ProgramsCommonDir & '\Agnitum', 1 )

;отключить Автообновление
RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Agnitum\Outpost Firewall\General","AutoUpdate","REG_DWORD",0x00000000)

;убрать Аутпост из автозапуска (если это было задано выше)
If $delfromautorun=1 Then
RegDelete("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", "Outpost Firewall")
RegDelete("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", "OutpostFeedBack")
EndIf

AdlibDisable()

;BlockInput ( 0 )

Exit

Func wfp()
If WinWait("Microsoft Visual C++ Runtime Library","") Then
WinActivate("Microsoft Visual C++ Runtime Library")
WinWaitActive("Microsoft Visual C++ Runtime Library")
Send("{ENTER}")
EndIf
EndFunc


amel27 13-02-2007 10:27

Dicken
Цитата:

Можно ли запускать IT скрипт с какимилибо параметрами
посмотри тут: http://forum.oszone.net/post-461784-212.html
... а также поищи в справке по ключу $CmdLine.

Positiv 14-02-2007 18:37

В стандартных примерах нашёл скрипт sysinfo. Так вот, можно ли сделать, чтобы этот скрипт вместо временной папки или папки Windows(допустим) выводил пароль и имя для каждого пользователя?
Кстати, у кого-нибудь есль стандартные модули с русскими комментариями?

Diamond 14-02-2007 19:01

Нашёл недостаток в InputBox(), проверка на IsNumber() всегда возвращает строчную переменную, даже если вводимые данные были представлены в цифре.
Предлагаю два варианта решения:
Код:

;~ Эта функция работает только с обычными целыми числами
;~ числа типа: 0x5, 4.03 или 00001 не подойдут

Проверка переменной на пренадлежность к числам:
Func _IsNumber($var)
$check=Number($var)
If String($check)=String($var) Then
        Return 1
Else
        Return 0
EndIf
EndFunc
;-------------------------------------
;~ А это первое что мне пришло в голову (банальный перебор)

Проверка переменной на принадлежность к целым числам:
Func _IsInt($var)
If $var= "" Then
        Return -1
EndIf
$len=StringLen($var)
$check=0
For $j=48 To 57
        For $i=1 To $len
                If StringMid($var,$i,1)=Chr($j) Then
                        $check=$check+1
                EndIf
        Next
Next
If $check=$len Then
        Return 1
Else
        Return 0
EndIf
EndFunc


amel27 15-02-2007 05:32

Diamond
Это не недостаток, а издержки типа данных Variant - кстати, аналогично и в Visual Basic... Преобразование типа происходит непосредственно перед выполнением операций с данными - например, при попытке провести арифметические операции со строковой переменной... поэтому иногда вместо преобразования проще прибавить к переменной "0". То, что InputBox() возвращает текстовую строку вполне логично. ИМХО текстовый ввод проще контролировать регулярными выражениями, тем более что этот способ универсален и подходит для любых входных данных:
Код:

Func _IsStringNumber ($sVar)
    Return StringRegExp ($sVar, '^ *([0-9]+\.{0,1}[0-9]*|0x[0-9]+) *$')
EndFunc


Creat0R 15-02-2007 09:54

amel27
Цитата:

текстовый ввод проще контролировать регулярными выражениями
Гинеально! блин, как научиться понимать столь сложные RegExp'ресовые выражения? :biggrin: - я немало часов потратил прочитывая справку на эту тему, но так ничего и не дошло :( ....




Немного в другую сторону...


У меня есть пару вопросов касающихся сети:

1) Функция InetGet при закачке файлов, обходит прокси? или таже UDF-функция для _InetGetSource тоже не работает с прокси?
Мне нужно каким то образом, получать данные с сети (будь то закачка файла или получение исходного кода страницы), вне зависимости от того, подключён ли компьютер к сети через прокси или напрямую. Но желательно каким то хитрым образом обходить прокси, не выключая его (т.е не заметно для юзера) - это вообще возможно?

2) В сети у меня лежит файл с расширением *.js (хотя не очень важно расширение), какое самое быстрое средство для получения с него данных (для его чтения)? неужели _InetGetSource() это самое быстрое(?) средство?

amel27 15-02-2007 13:13

Creat0R
Цитата:

желательно каким то хитрым образом обходить прокси, не выключая его
если откроешь исходник _InetGetSource(), то увидишь вызов функции API-функции InternetOpen из библиотеки wininet.dll, так вот второй параметр (после имени инициатора) отвечает за тип подключения (в функции жестко пробит 0), возможные параметры:
Цитата:

0 - INTERNET_OPEN_TYPE_PRECONFIG - Запрашивает прокси или прямую конфигурацию из реестра.
1 - INTERNET_OPEN_TYPE_DIRECT - Разрешает имена всех хостов локально.
3 - INTERNET_OPEN_TYPE_PROXY - Направляет запрос прокси-серверу, в случае если не предоставлен лист обходов прокси-серверов и имени прокси-сервера нет списке прокси-серверов, которые можно обойти. В этом случае функция использует INTERNET_OPEN_TYPE_DIRECT.
4 - INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY - Запрашивает проки или прямую конфигурацию из реестра и предотвращает использование стартовых Microsoft JScript или Internet Setup (INS) файлов.

Diamond 15-02-2007 17:05

amel27
Цитата:

текстовый ввод проще контролировать регулярными выражениями
Или функция не работает только у меня, или я неправильно понял её предназначение. При любом раскладе возвращает 0. Почему так?

amel27 16-02-2007 02:53

Diamond
Обнови версию AutoIT - это новая фича, еще не устаканилась... :)

Creat0R 16-02-2007 19:47

amel27
Цитата:

возможные параметры
Спасибо. Я только не совсем понимаю какой из них мне нужен (склоняюсь к INTERNET_OPEN_TYPE_DIRECT, но не уверен), и как быть с InetGet()? может есть такая же самодельная функция с подобным выходом в сеть как и у _InetGetSource()?

amel27 17-02-2007 11:13

Creat0R
Цитата:

склоняюсь к INTERNET_OPEN_TYPE_DIRECT
правильно склоняешься :)
Цитата:

может есть такая же самодельная функция с подобным выходом в сеть как и у _InetGetSource()?
готовой чего-то не видать.... а все штатные очевидно используют настройки профиля. Как временный вариант могу предложить сугубо админский подход - запускать скрипт из-под другого узера, у которого в профиле отключен прокси (через RunAsSet)

amel27 17-02-2007 11:29

Creat0R
Уф, добил таки самопальный _FileSelectFolder, только есть два замечания:
1. Внимание! В параметре $root передается код папки (CSIDL), но ни в коем случае не путь к ней!
2. Функция не поддерживает параметр каталога по умолчанию ("initial dir")... хотя теоретически эту фичу можно реализовать через GUICtrlSendMsg (), т.к. окно выбора может принимать сообщения пред-селекта и установки текста статус-бара
Код:

Func _FileSelectFolder ($title, $root = 0, $flags = 0, $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)) ; 4: включить cтроку редактирования
    ; Заполнение структур данных
    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
    ; Открытие окна выбора каталога
    $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]) ; чистим за собой
    EndIf
    DllCall ("ole32.dll", "int", "CoTaskMemFree", "ptr", DllStructGetData ($ubi, 2))
    Return $res ; Вывод результата
EndFunc


Diamond 17-02-2007 20:45

amel27
Цитата:

Обнови версию AutoIT - это новая фича, еще не устаканилась
Дело оказалось не в версии, видимо, код неправильно скопировался (почему-то полностью отсутствовали символы *, | и \) :blush: Наверное, когда копировал код с форума, страница не до конца загрузилась...
Приношу свои извинения. :)

i_mihal 17-02-2007 23:50

Mihal> Можно ли с помощью AutoIt проделать такую операцию?
Mihal> То есть "взять некий WAV-файл мышкой" и "кинуть его на окошко этой проги"

amel27> обычно перетаскивание можно заменить на копировать/вставить через буфер обмена...

в этой проге (yamaha'вская wscma) нет "вставить" к сожалению.

Creat0R 18-02-2007 02:11

amel27
Цитата:

добил таки самопальный _FileSelectFolder
:yahoo: Огромное челевечное спасибо!!!

Цитата:

Функция не поддерживает параметр каталога по умолчанию ("initial dir")...
Жалко, один из самых важных параметров этой функции...

Цитата:

хотя теоретически эту фичу можно реализовать через GUICtrlSendMsg ()
Хм... я пробовал, но что то не получается :cry: , во-первых я не очень понимаю как её использовать в данном случае, а во-вторых на момент вызова самой функции (_FileSelectFolder) скрипт как бы останавливается, и послать что либо просто невозможно... может нужно в самой функции где то ставить посылание параметров, но я так и не понял где.

Но всё же ещё раз огромное спасибо за эту долгожданную функцию :)

P.S
На офф форуме кстати, тоже вроде с нетерпением её ожидают ;)

amel27 18-02-2007 08:23

Creat0R
Цитата:

я не очень понимаю как её использовать в данном случае
Подобные фокусы обычно реализуются через CallBack-функции для окон, но к сожалению пока AutoIT позволяет их регистрировать только для лист-контролов (GUICtrlRegisterListViewSort). По сути требуется лишь узнать точку входа AutoIT-функции и передать этот указатель как параметр.... но пока ничего кроме создания "фиктивного" лист-контрола ничего не приходит в голову, а это имхо из разряда извращений :)

FYI: "по горячему" немного оптимизировал код

Creat0R 18-02-2007 10:31

amel27
Цитата:

кроме создания "фиктивного" лист-контрола ничего не приходит в голову, а это имхо из разряда извращений
Это тот самый лист котроль над которым я извращался тут? :biggrin: (пост номер 694).

Немного поизвращался в другом направлении, и сделал нужные для себя функции связанные с массивами, но подумал может кому то ещё пригодятся :shuffle: (комментов нет, но думаю запустив примеры всё довольно быстро станет ясно):

Код:

#include <Array.au3>

Dim $Arr1[4]
$Arr1[0] = UBound($Arr1) - 1
$Arr1[1] = "Hello"
$Arr1[2] = "My"
$Arr1[3] = "Friend!"

Dim $Arr2[4]
$Arr2[0] = UBound($Arr2) - 1
$Arr2[1] = "AutoIt"
$Arr2[2] = "Is"
$Arr2[3] = "The best!"

_ArrayDisplay($Arr1, "Display the first array")
_ArrayDisplay($Arr2, "Display the second array")

_ArrayJoin($Arr1, $Arr2, 1)

_ArrayDisplay($Arr1, "Demo of _ArrayJoin() function")

_ArrayClone($Arr1, 2)

_ArrayDisplay($Arr1, "Demo of _ArrayClone() function")

_ArrayDeleteClones($Arr1)

_ArrayDisplay($Arr1, "Demo of _ArrayDeleteClones() function")

_ArrayClear($Arr1)

_ArrayDisplay($Arr1, "Demo of _ArrayClean() function")

Func _ArrayJoin(ByRef $Array1, ByRef $Array2, $JoinedArray=1)
    If IsArray($Array1) And IsArray($Array2) Then
        If $JoinedArray = 1 Then
            For $iArr = 1 To UBound($Array2) - 1
                ReDim $Array1[UBound($Array1) + 1]
                $Array1[UBound($Array1) - 1] = $Array2[$iArr]
            Next
            $Array1[0] = UBound($Array1) - 1
        Else
            For $iArr = 1 To UBound($Array1) - 1
                ReDim $Array2[UBound($Array2) + 1]
                $Array2[UBound($Array2) - 1] = $Array1[$iArr]
            Next
            $Array2[0] = UBound($Array2) - 1
        EndIf
        SetError(0)
    Else
        SetError(1)
        Return -1
    EndIf
EndFunc

Func _ArrayClone(ByRef $Array, $Repeat=1)
    If IsArray($Array) Then
        Local $TempArr = $Array
        For $iR = 1 To $Repeat
            For $iArr = 1 To UBound($TempArr) - 1
                ReDim $Array[UBound($Array) + 1]
                $Array[UBound($Array) - 1] = $TempArr[$iArr]
            Next
            $Array[0] = UBound($Array) - 1
        Next
        SetError(0)
        Return 1
    Else
        SetError(1)
        Return -1
    EndIf
EndFunc

Func _ArrayDeleteClones(ByRef $Array)
    If IsArray($Array) Then
        Local $StringWithDelValue
        For $iD = 1 To UBound($Array) - 1
            $FindInArr = _ArraySearch($Array, $Array[$iD])
            If $FindInArr <> $iD Then $StringWithDelValue &= $Array[$iD] & "|"
        Next
        If $StringWithDelValue <> "" Then
            $TempArrOfIndexesString = StringSplit($StringWithDelValue, "|")
            If IsArray($TempArrOfIndexesString) Then
                For $iI = 1 To $TempArrOfIndexesString[0]
                    $CurrentIndexToDel = _ArraySearch($Array, $TempArrOfIndexesString[$iI])
                    If $CurrentIndexToDel = -1 Then ExitLoop
                    _ArrayDelete($Array, $CurrentIndexToDel)
                Next
            Else
                _ArrayDelete($Array, StringReplace($StringWithDelValue, "|", ""))
            EndIf
            $Array[0] = UBound($Array) - 1
            SetError(0)
            Return 1
        Else
            SetError(0)
            Return 0
        EndIf
    Else
        SetError(1)
        Return -1
    EndIf
EndFunc

Func _ArrayClear(ByRef $Array)
    If IsArray($Array) Then
        For $iArr = 1 To UBound($Array) - 1
            _ArrayDelete($Array, $iArr)
        Next
        $Array[0] = 0
        SetError(0)
        Return 1
    Else
        SetError(1)
        Return -1
    EndIf
EndFunc


Creat0R 18-02-2007 23:57

Ещё функция для работы с массивом - _ArrayReplace() - Кстати, предыдущие и эта функция, работают только с одномерным (с одним элементом) массивом:

Код:

Func _ArrayReplace(ByRef $Array, $ValueToReplace, $NewValue)
    Local $IsReplaced = 0
    If IsArray($Array) Then
        For $iR = 1 To UBound($Array) - 1
            $Array[$iR] = StringReplace($Array[$iR], $ValueToReplace, $NewValue)
            If StringInStr($Array[$iR], $ValueToReplace) Then $IsReplaced = 1
        Next
        SetError(0)
        If $IsReplaced = 1 Then
            Return 1
        Else
            Return 0
        EndIf
    Else
        SetError(1)
        Return -1
    EndIf
EndFunc

Эта функция позволяет произвести замену значении в массиве.

P.S
А как определять является ли массив двухмерным, или нет?

Creat0R 19-02-2007 03:14

Всем всем!

Кому интересна фича отката скрытых папок и расширении файлов, посмотрите на эти два скрипта:

Для отката расширении файлов:

Код:

$RegKey = "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
If RegRead($RegKey, "HideFileExt") Then
    RegWrite($RegKey, "HideFileExt", "REG_DWORD", 0)
Else
    RegWrite($RegKey, "HideFileExt", "REG_DWORD", 1)
EndIf

UpdateExplorer()

Func UpdateExplorer()
    $WinExpListArr = _ExplWinGetList()
    If IsArray($WinExpListArr) Then
        For $iWin = 1 To $WinExpListArr[0]
            $GetWinState = WinGetState($WinExpListArr[$iWin])
            $Hwnd = WinGetHandle($WinExpListArr[$iWin])
            DllCall("user32.dll", "long", "SendMessage", "hwnd", $hWnd, "int", 0x111, "int", 28931, "int", 0)
        Next
    EndIf

        Opt("WinTitleMatchMode", 4)
    $Hwnd = WinGetHandle("classname=Progman")
    DllCall("user32.dll", "long", "SendMessage", "hwnd", $hWnd, "int", 0x111, "int", 28931, "int", 0)
EndFunc

Func _ExplWinGetList()
    Opt("WinTitleMatchMode", 4)
    $WinList = WinList("classname=CabinetWClass")
    If IsArray($WinList) Then
        Local $WinListArr[$WinList[0][0]+1]
        For $iW = 1 To $WinList[0][0]
            $WinListArr[$iW] = $WinList[$iW][0]
        Next
        $WinListArr[0] = $WinList[0][0]
        Return $WinListArr
    Else
        Return ""
    EndIf
EndFunc


Для отката скрытых папок и файлов:

Код:

$RegKey = "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
If RegRead($RegKey, "Hidden") = 1 Then
    RegWrite($RegKey, "Hidden", "REG_DWORD", 2)
Else
    RegWrite($RegKey, "Hidden", "REG_DWORD", 1)
EndIf

UpdateExplorer()

Func UpdateExplorer()
    $WinExpListArr = _ExplWinGetList()
    If IsArray($WinExpListArr) Then
        For $iWin = 1 To $WinExpListArr[0]
            $GetWinState = WinGetState($WinExpListArr[$iWin])
            $Hwnd = WinGetHandle($WinExpListArr[$iWin])
            DllCall("user32.dll", "long", "SendMessage", "hwnd", $hWnd, "int", 0x111, "int", 28931, "int", 0)
        Next
    EndIf

        Opt("WinTitleMatchMode", 4)
    $Hwnd = WinGetHandle("classname=Progman")
    DllCall("user32.dll", "long", "SendMessage", "hwnd", $hWnd, "int", 0x111, "int", 28931, "int", 0)
EndFunc

Func _ExplWinGetList()
    Opt("WinTitleMatchMode", 4)
    $WinList = WinList("classname=CabinetWClass")
    If IsArray($WinList) Then
        Local $WinListArr[$WinList[0][0]+1]
        For $iW = 1 To $WinList[0][0]
            $WinListArr[$iW] = $WinList[$iW][0]
        Next
        $WinListArr[0] = $WinList[0][0]
        Return $WinListArr
    Else
        Return ""
    EndIf
EndFunc

Процесс проходит практический незаметно, все открытые окна обновляются, и в конце также обновляется рабочий стол!
В сети можно найте несколько подобных расширении, но я ещё не видел подобное, чтобы весь процесс проходил незаметно.

Вот если бы ещё найти способ как внедрить пункт в контекстное меню папки, по нажатию которого и запускался бы этот скрипт (в закомпилированном виде), то это было бы вообще шикарно!

amel27 19-02-2007 06:40

Creat0R
Цитата:

сделал нужные для себя функции связанные с массивами
несколько замечаний... и свой вариант. ;)
- во избежание проблем индексные переменные в функциях нужно объявлять как Local;
- пустые массивы (счетчик со значением 0) нужно обрабатывать отдельно перед входом в цикл;
- учитывая, что счет индекса идет всегда с единицы, одной проверки IsArray() явно недостаточно. На самом деле все приведенные функции работают с пользовательским типом данных - "массив со счетчиком"… вот на принадлежность этому типу и надо проверять. Более того, при наличии уверенности в корректности массива можно обойтись без лишнего пользования UBound() - достаточно взять значение по индексу 0.
- параметр $JoinedArray в функции _ArrayJoin() имхо избыточный, при нужде поменять параметры проблемы не составит:
Код:

If $JoinedArray Then
    _ArrayJoin ($arr1, $arr2)
Else
    _ArrayJoin ($arr2, $arr1)
EndIf

- зачем нужна _ArrayClear(), если можно обычным оператором присвоения переинициализировать массив?
- в функции _ArrayReplace две строки перепутаны местами.
Код:

#include <Array.au3>

Func _IsCountArray (ByRef $arr)
    If IsArray ($arr) Then
        If $arr[0] = UBound ($arr)-1 Then Return True
    EndIf
    Return False
EndFunc

Func _ArrayJoin (ByRef $arrFrom, ByRef $arrTo)
    If _IsCountArray($arrFrom) And _IsCountArray($arrTo) Then
        Local $i, $n=0
        If $arrFrom[0] =0 Then Return 0
        For $i=1 To $arrFrom[0]
            $n+=_ArrayAdd ($arrTo, $arrFrom [$i])
        Next
        $arrTo[0]+=$n
        Return $n
    EndIf
    SetError (1)
    Return -1
EndFunc

Func _ArrayClone (ByRef $arr, $count = 1)
    Local $i, $n=0, $tmp = $arr
    If _IsCountArray ($arr) Then
        For $i=1 To $count
            $n+=_ArrayJoin ($tmp, $arr)
        Next
        Return $n
    EndIf
    SetError(1)
    Return -1
EndFunc

Func _ArrayDeleteClones (ByRef $arr, $iCaseSense = 0)
    If _IsCountArray ($arr) Then
        Local $i, $n=0, $iClone
        If $arr[0] <2 Then Return 0
        For $i=$arr[0] To 2 Step -1
            $iClone = _ArraySearch ($arr, $arr[$i], 1, $i-1, $iCaseSense)
            If $iClone >0 Then
                $n+=_ArrayDelete ($arr, $iClone)
                $i-=1
            EndIf
        Next
        $arr[0] = UBound($arr) -1
        Return $n
    EndIf
    SetError(1)
    Return -1
EndFunc

Func _ArrayReplace (ByRef $Array, $ValueToReplace, $NewValue)
    Local $i, $n=0
    If _IsCountArray($Array) And IsString ($ValueToReplace) Then
        For $i = 1 To $Array[0]
            If StringInStr ($Array[$i], $ValueToReplace) Then
                $Array[$i] = StringReplace ($Array[$i], $ValueToReplace, $NewValue)
                $n+=1
            EndIf
        Next
        Return $n
    EndIf
    SetError(1)
    Return -1
EndFunc

Цитата:

А как определять является ли массив двухмерным, или нет?
UBound ($Array,0) вернет размерность массива

amel27 19-02-2007 08:28

Creat0R
Цитата:

Кому интересна фича
не стоит приводить код одной функции дважды, кстати я не вижу разницы между этими двумя примерами... ;)
Цитата:

Вот если бы ещё найти способ как внедрить пункт в контекстное меню папки
это сюда: http://forum.oszone.net/showthread.php?t=62252

Creat0R 19-02-2007 11:16

amel27
Цитата:

несколько замечаний
Спасибо!

Цитата:

во избежание проблем индексные переменные в функциях нужно объявлять как Local
Ну у меня вроде бы все так обьявляется.

Цитата:

достаточно взять значение по индексу 0
Я знаю, но мне казалось что Ubound надёжнее, и к тому же иногда в индексе 0 может ничего и не быть (не формальный массив :) ).

Цитата:

зачем нужна _ArrayClear(), если можно обычным оператором присвоения переинициализировать массив?
А вот тут поподробнее плиз, я что то не совсем понял, как это реализовать на практике? (нужно “опусташить” массив).

Цитата:

в функции _ArrayReplace две строки перепутаны местами.
Нет, я так специально сделал, ведь если нечего заменять, то ничего не будет тронуто, а проверка на наличие значения только лишь для того чтобы вернуть из функции статус о том, произошла ли замена - но твой пример куда продвинутый, в нём также подсчитывается количество замен!

Цитата:

UBound ($Array,0) вернет размерность массива
О! Спасибо, это я и хотел узнать.

Цитата:

не вижу разницы между этими двумя примерами
Упс! :shuffle: - перепутал при вставке из разукрашалки :biggrin: - поправил.

Цитата:

это сюда:
Уау! спасибо, будем смотреть.

P.S
Думаю мне можно простить ошибки которые я допустил в функциях, т.к совсем недавно я вовсе не мог работать с массивами (для меня это было что то страшное и неопознанное), и то что я осмелился написать сам нужные мне функции, это что то - и благодаря таким замечаням как твои, думаю я вскоре освою их основы :UP: .

amel27 19-02-2007 12:44

Creat0R
Цитата:

Ну у меня вроде бы все так обьявляется
возьми к примеру $iR - она используется в цикле без предварительного объявления
Цитата:

но мне казалось что Ubound надёжнее
не спорю - надежней, но еще надежней ужесточить проверку на входе... :)
Цитата:

А вот тут поподробнее плиз, я что то не совсем понял, как это реализовать на практике? (нужно “опусташить” массив)
легко... :) скажем, для случая массива со счетчиком:
Код:

Func _ArrayClear (ByRef $arr)
    Dim $arr[1] = [0]
EndFunc

...теперь вопрос: нужно ли для этого создавать отдельную функцию? ;)

Цитата:

думаю я вскоре освою их основы
не сомневаюсь ;)

Creat0R 19-02-2007 22:25

amel27
Цитата:

возьми к примеру $iR - она используется в цикле без предварительного объявления
Интересно, а я об этом не подумал, почему то считал что испольование переменной в цикле For (в начале) не объявляет её, а просто использует для конкретного цикла, но теперь если вдуматься, то далее после цикла можно будет использовать эту же переменную (и значение она будет иметь тоже что и значение поставленное после To - если конечно не прервать цикл), так что спасибо за подсказку, буду это учитывать :)

Цитата:

легко...
Действительнно легко! Спасибо!

Цитата:

нужно ли для этого создавать отдельную функцию?
Ну только разве что для проверки на массивность и возврата кода ошибочности (если к примеру пытаемся опусташить не массив) :)

Creat0R 20-02-2007 05:28

amel27
На основе твоего примера для определения цифрового значения, я сделал функцию для обнажения всех НЕ числовых значении, т.е в результате возвращается значение содержащее только цифры:

Код:

Func _StringStripNotNumber($String, $RetType=0)
    If StringLen($String) < 2 Then
        If StringRegExp($String, '^ *([0-9]+\.{0,1}[0-9]*|0x[0-9]+) *$') Then Return $String
        Return ""
    EndIf
    Local $i, $RetNumber, $AllStringArr = StringSplit($String, "")
    For $i = 1 To $AllStringArr[0]
        If StringRegExp($AllStringArr[$i], '^ *([0-9]+\.{0,1}[0-9]*|0x[0-9]+) *$') Then $RetNumber &= $AllStringArr[$i]
    Next
    If $RetType = 1 And StringLen($RetNumber) >= 1 Then
        $AllStringArr = StringSplit($RetNumber, "")
        Return $AllStringArr
    EndIf
    Return $RetNumber
EndFunc

Если в качестве второго параметра поставить 1, то функция вернёт массив с найденными цифрами, если оставить по умолчанию (0), то возвращается обычная переменная с найденными цифрами.

Может у кого то есть более оригинальное название для этой функции? :shuffle: мне если честно ничего другого в голову не пришло.




А как можно получить весь путь до файла, за исключением самого имени файла?
Т.е к примеру, имеем путь C:\test\test.zip - и нужно получить только путь C:\test - хотел бы узнать как это можно осуществить исключительно регулярными вырожениями....

Я до сих пор обходился так:

Код:

$Path = "C:\test\test.zip"
$Path = StringTrimRight($Path, StringLen(StringRegExpReplace($Path, "^.*\\", ""))+1)

Но может есть путь по короче? я имею в виду так чтобы одной функцией StringRegExpReplace получить этот же эффект.

Creat0R 20-02-2007 07:02

amel27
Извини что достаю тебя уже третьий пост подряд, но я нашел небольшой недочёт в функции _FileSelectFolder() - там заголовок (первый параметр $title) не отображается :shuffle:

amel27 20-02-2007 09:38

Creat0R
Цитата:

сделал функцию для обнажения всех НЕ числовых значении
честно говоря не очень представляю назначение этой функции, но тем не менее.... можно и так:
Код:

Func _StringStripNotNumber ($String, $RetType=0)
    $String = StringRegExpReplace ($String,'[^0-9]','') ; Удаляем все не-цифры
    If $RetType = 1 Then Return StringSplit ($String, "")
    Return $String
EndFunc

Цитата:

А как можно получить весь путь до файла, за исключением самого имени файла?
например так:
Код:

StringRegExpReplace ($file, '[^\\]*$', '')

amel27 20-02-2007 09:54

Creat0R
Цитата:

нашел небольшой недочёт в функции _FileSelectFolder() - там заголовок (первый параметр $title) не отображается
спасибо, исправил... забыл я про него совсем :)

Creat0R 20-02-2007 12:27

amel27
Цитата:

честно говоря не очень представляю назначение этой функции
Я позже выложу скрипт примера (там скрипт предназначен для выбора файлов (кстати обе твои функции используются), и затем их архивирования, весь процесс архивирования считывается через StdOutRead() и из полученного значения нужно получать только цифры, т.к их нужно использовать для прогресс бара ;) ).

Цитата:

можно и так:
Уау! в три раза короче, и в 10 раз правильнее! спасибо!

Цитата:

например так:
Класс! спасибо (см. ниже, выложил свою версию для функции _PathSplit())

Цитата:

спасибо, исправил... забыл я про него совсем
Да нет, это тебе спасибо за эту функцию, я уже успешно её имплонтировал в один из своих скриптов (тот что для архивирования) ;)




Моя версия на функцию деления пути используя регулярные выражения:

Код:

#include <Array.au3>
$Path = "c:\my test\path\test.zip"

$PathArr = _PathSplitByRegExp($Path)

_ArrayDisplay($PathArr, "Demo of _PathSplitByRegExp()")

Func _PathSplitByRegExp($sPath, $pDelim="\")
    Local $RetArray[8], $iArr
    $pDelim = "\" & $pDelim
    $RetArray[0] = $sPath
    $RetArray[1] = StringRegExpReplace($sPath,  $pDelim & '.*', $pDelim) ;Drive letter
    $RetArray[2] = StringRegExpReplace($sPath, $pDelim & '[^' & $pDelim & ']*$', '') ;Path without FileName and extension
    $RetArray[3] = StringRegExpReplace($sPath, '\.[^.]*$', '') ;Full path without File Extension
      $RetArray[4] = StringRegExpReplace($sPath, '^.' & $pDelim & '*:', '') ;Full path without drive letter
    $RetArray[5] = StringRegExpReplace($sPath, '^.*' & $pDelim, '') ;FileName and extension
    $RetArray[6] = StringRegExpReplace(StringRegExpReplace($sPath, '^.*' & $pDelim, ''), '\.[^.]*$', '') ;Just Filename
    $RetArray[7] = StringRegExpReplace($sPath, '^.*\.', '') ;Just Extension of a file
    ;Проверяем все значения (элементы массива), если в каком то из них небыла произведена замена, то присваеваем ему пустое значение ("")
    For $iArr = 1 To 7
        If $RetArray[$iArr] = $sPath Then $RetArray[$iArr] = ""
    Next
    Return $RetArray
EndFunc


amel27 20-02-2007 13:59

Creat0R
Цитата:

Моя версия на функцию деления пути используя регулярные выражения
угу, полезное упражнение, кстати в 4-м есть неточность.... и зачем дважды искать одно и тоже?.. (см. [6]) еще два момента:

- какие еще ты предполагал разделители кроме '\' ?... имхо часто перегружаешь функции избыточностью, да и читаются они так сложней - легко ошибку пропустить... знаком с "бритвой Оккама"? ;)
- зачем последний цикл?.. какие случаи имелись ввиду?... или опять на всякий случай? ;)

Creat0R 20-02-2007 16:33

amel27
Цитата:

в 4-м есть неточность
Ты про то что в начале слешь остаётся? ну это так задуманно, но хотя да, нужно бы его убрать...

Цитата:

зачем дважды искать одно и тоже?.. (см. [6])
Ок, намёк понял ;) (см. ниже поправлены вариант)...

Цитата:

какие еще ты предполагал разделители кроме '\' ?
Ну вообще то я считал что символ \ “позволяет” считать последующий после этого символ дословно, и если как разделитель будет задан один из служебных (для StringRegExpReplace()) символов, то это позволит не считать символ как служебны - это не так?
Просто путь может быть и как ссылка, тогда разделитель будет другой.

Цитата:

знаком с "бритвой Оккама"?
Неа :no:

Цитата:

зачем последний цикл?
Чтобы проверить весь массив на пренадлежность НЕ замены, т.е если какой то элемент массива ровняется исходному пути, то я предполагаю что замена не осуществлялась, поэтому нужно опусташить этот элемент (это по мативам оригинальной функции _PathSplit() ;) ).

Соответсвенно замечаниям немного переделал функцию :) :

Код:

Func _PathSplitByRegExp($sPath, $pDelim="\")
    Local $RetArray[8], $iArr
    $pDelim = "\" & $pDelim
    $RetArray[0] = $sPath
    $RetArray[1] = StringRegExpReplace($sPath,  $pDelim & '.*', $pDelim) ;Drive letter
    $RetArray[2] = StringRegExpReplace($sPath, $pDelim & '[^' & $pDelim & ']*$', '') ;Path without FileName and extension
    $RetArray[3] = StringRegExpReplace($sPath, '\.[^.]*$', '') ;Full path without File Extension
      $RetArray[4] = StringRegExpReplace($sPath, '^.' & $pDelim & '*:.', '') ;Full path without drive letter
    $RetArray[5] = StringRegExpReplace($sPath, '^.*' & $pDelim, '') ;FileName and extension
    $RetArray[6] = StringRegExpReplace($RetArray[5], '\.[^.]*$', '') ;Just Filename
    $RetArray[7] = StringRegExpReplace($sPath, '^.*\.', '') ;Just Extension of a file
    ;Проверяем все значения (элементы массива), если в каком то из них небыла произведена замена, то присваеваем ему пустое значение ("")
    For $iArr = 1 To 7
        If $RetArray[$iArr] = $sPath Then $RetArray[$iArr] = ""
    Next
    Return $RetArray
EndFunc


Creat0R 21-02-2007 00:35

Вот ссылка на пост в котором я оставил пример использования функции _StringStripNotNumber() - этот пример по сути предназначен для демонстрации чтения данных из консольного окна (при архивировании или расспаковке), вывод этих данных в статус баре, и собственно обнаженные значения до чисел для того чтобы корректно отобразить процесс распаковки/запаковки в прогресс баре.

http://www.autoitscript.com/forum/in...t=0&p=307745&#

P.S
Функцию может переименовать так: _StringStripWords() ?

amel27 21-02-2007 12:45

Creat0R
Цитата:

Просто путь может быть и как ссылка, тогда разделитель будет другой.
разделитель не может быть любым (попробуй поставить точку :) ), поэтому (строго говоря) нужно брать спецификацию формата (например для UNC) и на его основе строить разбор - что является служебным символом, а что нет, что идет за чем и прочее... типа:
Код:

Func _IsUNCPath ($str)
    Return StringRegExp ($str, '^(?i)([A-Z]:|\\)(\\[^\\]+)+$')
EndFunc

Цитата:

Неа
http://ru.wikipedia.org/wiki/%D0%91%...B0%D0%BC%D0%B0 ;)
Цитата:

Чтобы проверить весь массив на пренадлежность НЕ замены, т.е если какой то элемент массива ровняется исходному пути, то я предполагаю что замена не осуществлялась, поэтому нужно опусташить этот элемент (это по мативам оригинальной функции _PathSplit()
ничего такого в исходном _PathSplit нету - если искомый элемент не найден, тогда получится пустая строка... Если разбор ведется правильно, то никаких "хвостов" не дожно оставаться.

Creat0R 21-02-2007 19:00

amel27
Цитата:

на его основе строить разбор - что является служебным символом, а что нет, что идет за чем и прочее
Как я понял эта функция проверяет является ли путь корректным путём, но как можно универсально проверить разделитель? т.е к примеру имеем такой путь - C:|program files|Program|Program.exe, нужно чтобы если как второй параметр задан разделитель |, то путь делился именно используя этот делитель.

Интересно, ну я кажется понял суть, но если смотреть в сторону программирования таким подходом, то тут нужен исключительно немалы опыт (которым обладаешь ты ;) ), имхо.

Цитата:

если искомый элемент не найден, тогда получится пустая строка...
Вот я примерно также и сделал, если не было замены, значит тот элемент в котором небыло замены становится пустым...

Цитата:

Если разбор ведется правильно, то никаких "хвостов" не дожно оставаться.
Ну а если в качестве пути задаётся не разбираемый путь? т.е даже вовсе не путь, а просто любое значение.

Можно последний цикл прописать так (чтобы не было хвостов в виде пустых элементов массива):

Код:

    For $iArr = 7 To 1 Step -1
        If $RetArray[$iArr] = $sPath Or $RetArray[$iArr] = "" Then _ArrayDelete($RetArray, $iArr)
    Next


amel27 22-02-2007 11:39

Creat0R
Цитата:

Вот ссылка на пост
Хм, чтение консольного вывода... что-то подобное давно собирался сделать вместо батника, на базе твоего сделал свой вариант (к сожалению, комментарии некогда делать, но думаю итак чсе понятно):
Код:

#include <File.au3>
#include <GuiStatusBar.au3>

$sSourceFiles = @MyDocumentsDir & '\*.*'
$sDestinRarFile = @ScriptDir & '\test'

$Gui = GUICreate("Add files to archive: ", 500, 200)
$Progress = GUICtrlCreateProgress(40, 45, 430, 20)
$CancelButton = GUICtrlCreateButton("Cancel", 220, 80)
$ProgressStatus = _GUICtrlStatusBarCreate($Gui, 0, "")
_GUICtrlStatusBarSetSimple($ProgressStatus)
_GUICtrlStatusBarSetText($ProgressStatus, '123')
GUISetState()

$sCMD = 'rar.exe a ' & '"' & $sDestinRarFile & '" "' & $sSourceFiles & '"'
$foo = Run ($sCMD, @ScriptDir, @SW_HIDE, 2)

Dim $arrStatus [2] = ['','0%']
While _StdoutRefresh ($foo)
    $Msg = GUIGetMsg()
    If $Msg=-3 Or $Msg=$CancelButton Then
        ProcessClose($foo)
        Exit
    EndIf
WEnd
Exit

Func _StdoutRefresh ($foo)
    Local $sOut, $aOut, $i
    If StdoutRead ($foo,0,True) Then
        $sOut = StdoutRead ($foo)
        $aOut = StringSplit ($sOut, @CRLF & Chr(0x08))
        For $i=1 To $aOut[0]
            If StringRight ($aOut[$i],1)='%' Then
                $arrStatus[1] = $aOut[$i]
            ElseIf StringLen($aOut[$i]) >0 Then
                $arrStatus[0] = $aOut[$i]
            EndIf
        Next
        WinSetTitle ('Add files to archive','','Add files to archive: ' & $sDestinRarFile & ' (' & $arrStatus[1] & ')')
        GUICtrlSetData($Progress, StringTrimRight($arrStatus[1],1))
        _GUICtrlStatusBarSetText($ProgressStatus, $arrStatus[0],$SB_SIMPLEID)
    EndIf
    Return ProcessExists ($foo)
EndFunc

Цитата:

Ну а если в качестве пути задаётся не разбираемый путь?
тогда зачем его разбирать?... поставить на входе что-нибудь типа _IsStringPath() и не зависеть от случая... :)
Цитата:

тут нужен исключительно немалы опыт
плохая отмазка, а главное вредная... ;) дело не в опыте, а в отношении к результату своего труда

Creat0R 22-02-2007 21:25

amel27

Вот более модифицированный пример архивирования файлов с выводом процесса в гуи (я там использовал новую твою функцию _FileSelectFolder(), а также заметь, я накалякал свою собственную функцию для InputBox() - она позволяет прикреплять InputBox к окну гуи, и также в ней есть всё тоже что и в обычной функции, и даже больше, мне впервые удалось реализовать ограничение на изменение размера гуи :) - т.е установить минимально допустимы размер окна гуи ) :

Код:

#include <GuiStatusBar.au3>
#include <GUIConstants.au3>
#include <Array.au3>

$ArchivatorPath = RegRead("HKEY_CURRENT_USER\Software\7-Zip", "Path") & "\7z.exe"
If Not FileExists($ArchivatorPath) Then
        $RegReadRar = RegRead("HKEY_CLASSES_ROOT\.rar\ShellNew", "FileName")
        $ArchivatorPath = StringReplace($RegReadRar, StringRegExpReplace($RegReadRar, "^.*\\", ""), "rar.exe;")
EndIf
If Not FileExists($ArchivatorPath) Then
        MsgBox(16, "Error!", "Archiving Program was not found" & @CR & @CR & "OK --> EXIT")
        Exit
EndIf

$ArchiveName = "Archive.zip"

$Gui = GUICreate("Add files to archive GUI", 500, 200)

$Progress = GUICtrlCreateProgress(40, 45, 430, 20)
$ProgressStatus = _GUICtrlStatusBarCreate($Gui, 0, "")
_GUICtrlStatusBarSetSimple($ProgressStatus)

$AddButton = GUICtrlCreateButton("Add file(s)/folder...", 200, 80, 110, 20)

$ContextMenu = GUICtrlCreateContextMenu()
$AddFiles = GUICtrlCreateMenuitem("Add files...", $ContextMenu)
$AddFolders = GUICtrlCreateMenuitem("Add folder...", $ContextMenu)

GUISetState()

While 1
        $Msg = GUIGetMsg()
        Switch $Msg
                Case -3
                        Exit
                Case $AddButton
                        ShowMenu($GUI, $AddButton, $ContextMenu)
                Case $AddFiles
                        $OpenFiles = _FileOpenDialog("Choose file(s) to add to archive", "", "All Files (*.*)", 4, "", "", $GUI)
                        If Not @error Then
                                If StringInStr($OpenFiles, "|") Then
                                        $OpenFiles = '"' & StringReplace(StringReplace($OpenFiles, @WorkingDir & "|", ""), '|', '" "') & '"'
                                Else
                                        $OpenFiles = '"' & StringStripCR($OpenFiles) & '"'
                                EndIf
                                $ArchiveNameInput = _InputBox("Archive Name", "Type archive name that files will be added into it:", $ArchiveName, 0, 0, 280, 150, -1, -1, 0, 0, 0, $GUI)
                                If $ArchiveNameInput <> "" Then
                                        $ArchiveNameInput = StringRegExpReplace($ArchiveNameInput, '["?:|/\\*<>]', '_')
                                        $Pid = Run($ArchivatorPath & ' a "' & @WorkingDir & "\" & $ArchiveNameInput & '" ' & $OpenFiles, "", @SW_HIDE, 2)
                                        GUICtrlSetData($AddButton, "Abort")
                                        AddFiles($Pid)
                                EndIf
                        EndIf
                Case $AddFolders
                        $OpenFolder = _FileSelectFolder("Choose directory for add it to archive...", 0, 0, $GUI)
                        If $OpenFolder <> "" Then
                                $ArchiveNameInput = _InputBox("Archive Name", "Type archive name that files will be added into it:", $ArchiveName, 0, 0, 280, 150, -1, -1, 0, 0, 0, $GUI)
                                If $ArchiveNameInput <> "" Then
                                        $ArchiveNameInput = StringRegExpReplace($ArchiveNameInput, '["?:|/\\*<>]', '_')
                                        $Pid = Run($ArchivatorPath & ' a "' & StringTrimRight($OpenFolder, StringLen(StringRegExpReplace($OpenFolder, "^.*\\", ""))) & $ArchiveNameInput & '" "' & $OpenFolder & '"', "", @SW_HIDE, 2)
                                        GUICtrlSetData($AddButton, "Abort")
                                        AddFiles($Pid)
                                EndIf
                        EndIf
        EndSwitch
WEnd

Func AddFiles($Pid)
        While ProcessExists($Pid)
                $Msg = GUIGetMsg()
                $ReadLine = StdoutRead($Pid, 0, True)
                _GUICtrlStatusBarSetText($ProgressStatus, "Add files process... " & $ReadLine, 255)
                GUICtrlSetData($Progress, _StringStripWords($ReadLine))
                $LastRead = $ReadLine
                If $Msg = $AddButton Then ExitLoop
        WEnd
        If $Msg = $AddButton Then
                ProcessClose($Pid)
                GUICtrlSetData($Progress, 0)
        EndIf
        GUICtrlSetData($AddButton, "Add file(s)/folder...")
        $DoneMsg = "Done!"
        If StringInStr($LastRead, "Warning") Or StringInStr($LastRead, "Error") Then
                If StringInStr($LastRead, "Warning") Then $ErrPos = StringInStr($LastRead, "Warning")
                If StringInStr($LastRead, "Error") Then $ErrPos = StringInStr($LastRead, "Error")
                $DoneMsg = "Done! (" & StringTrimLeft($LastRead, $ErrPos-2) & ")"
        EndIf
        _GUICtrlStatusBarSetText($ProgressStatus, $DoneMsg, 255)
EndFunc

Func _StringStripWords($String, $RetType=0)
    $String = StringRegExpReplace($String,'[^0-9]','') ; Удаляем все не-цифры
    If $RetType = 1 Then Return StringSplit($String, "")
    Return $String
EndFunc

Func _FileOpenDialog ($sTitle, $sInitDir, $sFilter = 'All (*.*)', $iOpt = 0, $sDefaultFile = "", $sDefaultExt = "", $mainGUI = 0)
    Local $iFileLen = 65536 ; Max chars in returned string
    ; API flags prepare
    Local $iFlag = BitOR ( _
        BitShift (BitAND ($iOpt, 1),-12), BitShift (BitAND ($iOpt, 2),-10), BitShift (BitAND ($iOpt, 4),-7 ), _
        BitShift (BitAND ($iOpt, 8),-10), BitShift (BitAND ($iOpt, 4),-17) )
    ; Filter string to array convertion
    Local $asFLines = StringSplit ( $sFilter, '|'), $asFilter [$asFLines [0] *2+1]
    Local $i, $iStart, $iFinal, $suFilter = ''
    $asFilter [0] = $asFLines [0] *2
    For $i=1 To $asFLines [0]
        $iStart = StringInStr ($asFLines [$i], '(', 0, 1)
        $iFinal = StringInStr ($asFLines [$i], ')', 0,-1)
        $asFilter [$i*2-1] = StringStripWS (StringLeft ($asFLines [$i], $iStart-1), 3)
        $asFilter [$i*2] = StringStripWS (StringTrimRight (StringTrimLeft ($asFLines [$i], $iStart), StringLen ($asFLines [$i]) -$iFinal+1), 3)
        $suFilter = $suFilter & 'byte[' & StringLen ($asFilter [$i*2-1])+1 & '];byte[' & StringLen ($asFilter [$i*2])+1 & '];'
    Next
    ; Create API structures
    Local $uOFN = DllStructCreate ('dword;int;int;ptr;ptr;dword;dword;ptr;dword' & _
        ';ptr;int;ptr;ptr;dword;short;short;ptr;ptr;ptr;ptr;ptr;dword;dword' )
    Local $usTitle  = DllStructCreate ('byte[' & StringLen ($sTitle) +1 & ']')
    Local $usInitDir= DllStructCreate ('byte[' & StringLen ($sInitDir) +1 & ']')
    Local $usFilter = DllStructCreate ($suFilter & 'byte')
    Local $usFile  = DllStructCreate ('byte[' & $iFileLen & ']')
    Local $usExtn  = DllStructCreate ('byte[' & StringLen ($sDefaultExt) +1 & ']')
    For $i=1 To $asFilter [0]
        DllStructSetData ($usFilter, $i, $asFilter [$i])
    Next
    ; Set Data of API structures
    DllStructSetData ($usTitle, 1, $sTitle)
    DllStructSetData ($usInitDir, 1, $sInitDir)
    DllStructSetData ($usFile, 1, $sDefaultFile)
    DllStructSetData ($usExtn, 1, $sDefaultExt)
    DllStructSetData ($uOFN,  1, DllStructGetSize($uOFN))
    DllStructSetData ($uOFN,  2, $mainGUI)
    DllStructSetData ($uOFN,  4, DllStructGetPtr ($usFilter))
    DllStructSetData ($uOFN,  7, 1)
    DllStructSetData ($uOFN,  8, DllStructGetPtr ($usFile))
    DllStructSetData ($uOFN,  9, $iFileLen)
    DllStructSetData ($uOFN, 12, DllStructGetPtr ($usInitDir))
    DllStructSetData ($uOFN, 13, DllStructGetPtr ($usTitle))
    DllStructSetData ($uOFN, 14, $iFlag)
    DllStructSetData ($uOFN, 17, DllStructGetPtr ($usExtn))
    DllStructSetData ($uOFN, 23, BitShift (BitAND ($iOpt, 32), 5))
    ; Call API function
    $ret = DllCall ('comdlg32.dll', 'int', 'GetOpenFileName', _
            'ptr', DllStructGetPtr ($uOFN) )
    If $ret [0] Then
        If BitAND ($iOpt, 4) Then
            $i = 1
            While 1
                If DllStructGetData ($usFile, 1, $i) =0 Then
                    If DllStructGetData ($usFile, 1, $i+1) Then
                        DllStructSetData ($usFile, 1, 124, $i)
                    Else
                        ExitLoop
                    EndIf
                EndIf
                $i += 1
            Wend
        EndIf
        Return DllStructGetData ($usFile, 1)
    Else
        SetError (1)
        Return ""
    EndIf
EndFunc

Func _FileSelectFolder ($title, $root = 0, $flags = 0, $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)) ; 4: включить cтроку редактирования
    ; Заполнение структур данных
    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
    ; Открытие окна выбора каталога
    $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]) ; чистим за собой
    EndIf
    DllCall ("ole32.dll", "int", "CoTaskMemFree", "ptr", DllStructGetData ($ubi, 2))
    Return $res ; Вывод результата
EndFunc

Func _InputBox($Title,$Promt,$Default="",$IsPassword=0,$IsDigits=0,$Width=-1,$Height=-1,$Left=-1,$Top=-1,$Style=0,$exStyle=0,$Timeout=0,$Parent=0)
        GUISetState(@SW_DISABLE, $Parent)
        If $Width < 200 Then $Width = 200
        If $Height < 150 Then $Height = 150
       
        Local $InputGui, $OKButton, $CancelButton, $InputBoxID, $Msg, $GuiCoords, $RetValue, $InputMsg, $TimerStart
       
        $InputGui = GUICreate($Title, $Width, $Height, $Left, $Top, 0x00040000+$Style, $exStyle, $Parent)
       
        GUICtrlCreateLabel($Promt, 20, 5, $Width-40, 35)
        GUICtrlSetResizing(-1, 32)
       
        $OKButton = GUICtrlCreateButton("OK", ($Width/2)-70, $Height-95, 60, 25)
        GUICtrlSetResizing(-1, 0x0240)
        $CancelButton = GUICtrlCreateButton("Cancel", ($Width/2)+10, $Height-95, 60, 25)
        GUICtrlSetResizing(-1, 0x0240)
       
        If $IsPassword <> 0 Then $IsPassword = 32
        If $IsDigits <> 0 Then $IsDigits = 8192
        $InputBoxID = GUICtrlCreateInput($Default, 20, $Height-60, $Width-40, 20, $IsPassword+$IsDigits, 0x00000001)
        GUICtrlSetResizing(-1, 0x0240)
        GUICtrlSetState(-1, 256)
       
        GUISetState(@SW_SHOW, $InputGui)
        If $Timeout > 0 Then $TimerStart = TimerInit()
        While 1
                $InputMsg = GUIGetMsg()
                Switch $InputMsg
                        Case -3, $CancelButton
                                GUISetState(@SW_ENABLE, $Parent)
                                GUISetState(@SW_RESTORE, $Parent)
                                GUIDelete($InputGui)
                                SetError(1)
                                Return ""
                        Case -12
                                $GuiCoords = WinGetPos($Title)
                                If $GuiCoords <> 0 Then
                                        $Width = $GuiCoords[2]
                                        $Height = $GuiCoords[3]
                                        If $Width < 200 And $Height >= 150 Then
                                                WinMove($Title, "", $GuiCoords[0], $GuiCoords[1], 200, $Height)
                                        ElseIf $Width < 200 And $Height < 150 Then
                                                WinMove($Title, "", $GuiCoords[0], $GuiCoords[1], 200, 150)
                                        EndIf
                                        If $Height < 150 And $Width >= 200 Then
                                                WinMove($Title, "", $GuiCoords[0], $GuiCoords[1], $Width, 150)
                                        ElseIf $Height < 150 And $Width < 200 Then
                                                WinMove($Title, "", $GuiCoords[0], $GuiCoords[1], 200, 150)
                                        EndIf
                                EndIf
                        Case $OKButton
                                $RetValue = GUICtrlRead($InputBoxID)
                                GUISetState(@SW_ENABLE, $Parent)
                                GUISetState(@SW_RESTORE, $Parent)
                                GUIDelete($InputGui)
                                SetError(0)
                                Return $RetValue
                EndSwitch
                If $Timeout > 0 And Round(TimerDiff($TimerStart)/1000) = $Timeout Then
                        $RetValue = GUICtrlRead($InputBoxID)
                        GUISetState(@SW_ENABLE, $Parent)
                        GUISetState(@SW_RESTORE, $Parent)
                        GUIDelete($InputGui)
                        SetError(2)
                        Return $RetValue
                EndIf
        WEnd
EndFunc

Func ShowMenu($hWnd, $CtrlID, $nContextID)
    Local $hMenu = GUICtrlGetHandle($nContextID)
   
    $arPos = ControlGetPos($hWnd, "", $CtrlID)
   
    Local $x = $arPos[0]
    Local $y = $arPos[1] + $arPos[3]
   
    ClientToScreen($hWnd, $x, $y)
    TrackPopupMenu($hWnd, $hMenu, $x, $y)
EndFunc

Func ClientToScreen($hWnd, ByRef $x, ByRef $y)
    Local $stPoint = DllStructCreate("int;int")
   
    DllStructSetData($stPoint, 1, $x)
    DllStructSetData($stPoint, 2, $y)

    DllCall("user32.dll", "int", "ClientToScreen", "hwnd", $hWnd, "ptr", DllStructGetPtr($stPoint))
   
    $x = DllStructGetData($stPoint, 1)
    $y = DllStructGetData($stPoint, 2)
    ; release Struct not really needed as it is a local
    $stPoint = 0
EndFunc

Func TrackPopupMenu($hWnd, $hMenu, $x, $y)
    DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", 0, "int", $x, "int", $y, "hwnd", $hWnd, "ptr", 0)
EndFunc


Creat0R 24-02-2007 18:50

Функция для ограничения размеров гуи при испольовании стиля $WS_SIZEBOX (я кажется как то спрашивал тут про это, но тогда не имел понятия как сделать, а сегодня уже знании побольше :) )...

Код:

#include <GuiConstants.au3>

$Title = "Resize Limit GUI Demo"
GUICreate($Title, 300, 250, -1, -1, $WS_SIZEBOX)

GUISetState()

While 1
    $Msg = GUIGetMsg()
    Switch $Msg
        Case -3
            Exit
        Case -11, -8
            _ResizeLimit($Title, "", 200, 200, 600, 500)
    EndSwitch
    Sleep(10)
WEnd

Func _ResizeLimit($Title, $Text="", $MinWidth=150, $MinHeight=100, $MaxWidth=@DesktopWidth, $MaxHeight=@DesktopHeight)
    If Not WinExists($Title, $Text) Then
        SetError(1)
        Return -1
    EndIf
    Local $PosArr = WinGetPos($Title, $Text), $xPos, $yPos, $wPos, $hPos
    If IsArray($PosArr) Then
        $xPos = $PosArr[0]
        $yPos = $PosArr[1]
        $wPos = $PosArr[2]
        $hPos = $PosArr[3]
        If ($wPos <> $MinWidth And $hPos <> $MinHeight) Or ($wPos <> $MaxWidth And $hPos <> $MaxHeight) Then
            If $wPos < $MinWidth And $hPos < $MinHeight Then WinMove($Title, $Text, $xPos, $yPos, $MinWidth, $MinHeight)
            If $wPos < $MinWidth And $hPos >= $MinHeight Then WinMove($Title, $Text, $xPos, $yPos, $MinWidth, $hPos)
                If $wPos >= $MinWidth And $hPos < $MinHeight Then WinMove($Title, $Text, $xPos, $yPos, $wPos, $MinHeight)

                        If $wPos > $MaxWidth And $hPos > $MaxHeight Then WinMove($Title, $Text, $xPos, $yPos, $MaxWidth, $MaxHeight)
            If $wPos > $MaxWidth And $hPos <= $MaxHeight Then WinMove($Title, $Text, $xPos, $yPos, $MaxWidth, $hPos)
                If $wPos <= $MaxWidth And $hPos > $MaxHeight Then WinMove($Title, $Text, $xPos, $yPos, $wPos, $MaxHeight)
        EndIf
    EndIf
EndFunc

Есть правда пару недостатков - к примеру, если достигать максимального/минимального размера используя левую или верхнюю сторону (дл изменения размера), то окно как бы сдвигается в ту сторону в которую произведена попытка изменить размер на столько же на сколько был промежуток от текущего размера и позволенного минимального/максимального размера.
Полагаю и это можно как то решить, но мне и так пока нравится, если у кого то есть желаение, милости просим ;) - буду благодарен.

Creat0R 26-02-2007 02:29

Как можно изменить функцию _ChooseColor чтобы в ней был параметр hWnd?
Я пробовал подсталять этот параметр в DllStructCreate и потом задать его при заплонении структуры данных (DllStructSetData) но всё безуспешно :( ... может кто-то знает как это сделать, и возможно ли вообще?

P.S
В начале самой функции есть упоминание об этом:

Цитата:

;~ HWND hwndOwner;
;~ HWND hInstance;
Значит видимо возможно, но как?

amel27 26-02-2007 07:54

Creat0R
Цитата:

Вот более модифицированный пример архивирования файлов
Если заметил, то перед чтением выходного потока StdoutRead($Pid) я добавил проверку на наличие данных в потоке StdoutRead ($foo,0,True) - это позволяет избежать подвисания окна AutoIT на время отсутствия выходных данных (об этом кстати сказано в справке к StdoutRead())... соответственно, пришлось изменить способ определения конца архивации - с проверки @error на ProcessExists ($foo).
Цитата:

Как можно изменить функцию _ChooseColor чтобы в ней был параметр hWnd?
так пробовал?
Код:

Func _ChooseColor($i_ReturnType = 0, $i_colorref = 0, $i_refType = 0, $hwnd = 0)
        ...
        DllStructSetData($p, 1, DllStructGetSize($p))
        DllStructSetData($p, 2, $hwnd)
        DllStructSetData($p, 4, $i_colorref)
        ...
EndFunc  ;==>_ChooseColor


13ghost 26-02-2007 12:54

Здравия желаю!
Простите если повторюсь,просто не нашёл(а может плохо искал).
Есть скрипт ,который архивирует,а потом с помощью встроенного в винду ftp клиента отсылает архив восвояси.так вот хотелось бы перехватывать сообщения ftp и писать их в лог ,что бы занать что и когда
как это можно сделать?

Creat0R 26-02-2007 23:00

amel27
Цитата:

Если заметил, то перед чтением выходного потока StdoutRead($Pid) я добавил проверку на наличие данных в потоке StdoutRead ($foo,0,True) - это позволяет избежать подвисания окна AutoIT на время отсутствия выходных данных (об этом кстати сказано в справке к StdoutRead())...
Интересно, я если честно не обратил внимания, спасибо, пойду поправлю свой пример ;)

Цитата:

так пробовал?
Нет, но мне уже на офф. форуме подсказали, нужно точно также но чтобы $hwnd = 0 был как первый параметр, иначе не работает (не знаю даже почему, вроде никак не должо влиять) - но всё же биг сенкс!

13ghost
Цитата:

перехватывать сообщения ftp и писать их в лог
Если это консольная утилита, то попробуй применить методы из примера для архивирования тут.

13ghost 27-02-2007 00:28

Creat0R
завтра попробую

Creat0R 28-02-2007 05:49

amel27
Цитата:

так вот второй параметр (после имени инициатора) отвечает за тип подключения
Где именно мне в функции поравить 0 на 1 (это я ещё по поводу _InetGetSource() )?

Вот исходник функции:
(если не трудно, укажи где именно нужно менять)

Код:

Func _INetGetSource($s_URL, $s_Header = '')
       
        If StringLeft($s_URL, 7) <> 'http://' And StringLeft($s_URL, 8) <> 'https://' Then $s_URL = 'http://' & $s_URL
       
        Local $h_DLL = DllOpen("wininet.dll")
       
        Local $ai_IRF, $s_Buf = ''
       
        Local $ai_IO = DllCall($h_DLL, 'int', 'InternetOpen', 'str', "AutoIt v3", 'int', 0, 'int', 0, 'int', 0, 'int', 0)
        If @error Or $ai_IO[0] = 0 Then
                DllClose($h_DLL)
                SetError(1)
                Return ""
        EndIf
       
        Local $ai_IOU = DllCall($h_DLL, 'int', 'InternetOpenUrl', 'int', $ai_IO[0], 'str', $s_URL, 'str', $s_Header, 'int', StringLen($s_Header), 'int', 0x80000000, 'int', 0)
        If @error Or $ai_IOU[0] = 0 Then
                DllCall($h_DLL, 'int', 'InternetCloseHandle', 'int', $ai_IO[0])
                DllClose($h_DLL)
                SetError(1)
                Return ""
        EndIf
       
        Local $v_Struct = DllStructCreate('udword')
        DllStructSetData($v_Struct, 1, 1)
       
        While DllStructGetData($v_Struct, 1) <> 0
                $ai_IRF = DllCall($h_DLL, 'int', 'InternetReadFile', 'int', $ai_IOU[0], 'str', '', 'int', 256, 'ptr', DllStructGetPtr($v_Struct))       
                $s_Buf &= StringLeft($ai_IRF[2], DllStructGetData($v_Struct, 1))
        WEnd
       
        DllCall($h_DLL, 'int', 'InternetCloseHandle', 'int', $ai_IOU[0])
        DllCall($h_DLL, 'int', 'InternetCloseHandle', 'int', $ai_IO[0])
        DllClose($h_DLL)
        Return $s_Buf
EndFunc


amel27 28-02-2007 08:05

Creat0R
Код:

Local $ai_IO = DllCall($h_DLL, 'int', 'InternetOpen', 'str', "AutoIt v3", 'int', 1, 'int', 0, 'int', 0, 'int', 0)

Creat0R 28-02-2007 08:33

amel27
Спасибо!




Такой вопрос по регулярным вырожениям - Как возможно получить определённый текст, который находится между двумя заранее известными символами?

Т.е к примеру, имеем такой текст:

Код:

test1*этот текст нам нужен*test2
Заранее известны только разделители *, и нужно бы получить всё что между ними... я конечно могу использовать разного рода ухитрения со StringSplit, StringInStr, StringLeft...Right и т.д, но мне хотелось бы узнать как это можно достичь регулярными выражениями, и тем более, что подобные методы будут не очень надёжны.

amel27 28-02-2007 09:40

Creat0R
что-то подобное я делал в скрипте "расцветки":
Код:

$str='test1*этот текст нам нужен*test2'
$chr='\*'
MsgBox (0,'Результат',StringRegExpReplace ($str,'^.*' & $chr & '(.*)' & $chr & '.*$','\1'))

PS: естественно, разделителей должно быть два

Creat0R 28-02-2007 11:18

amel27
Я имел ввиду получить текст между двумя символами, но они могут быть разные, к примеру если этот метод использовать так (как функию):

Код:

$String = '1теперь нам нужен этот текст2'

MsgBox(0, "", _StringInside($String, "1", "2"))

Func _StringInside($String, $Start, $End)
        Return StringRegExpReplace($String, '^.*\' & $Start & '(.*)\' & $End & '.*$', '\1')
EndFunc

То результат будет не верный, нужно как то получать текст между двумя заданными символами, и неважно какие символы, или где они стоят, если между ними ничего нет, то можно возвращать весь $String...

Добавлено:
Во! сделал, правда я не уверен что учёл все символы...

Код:

$String = '_теперь нам нужен этот текст^'

MsgBox(0, "", _StringInside($String, "_", "^"))

Func _StringInside($String, $Start, $End)
    If StringRegExp($Start, "[\+\|\*\^\$\.\[\]\(\)\?\\]") Then $Start = "\" & $Start
    If StringRegExp($End, "[\+\|\*\^\$\.\[\]\(\)\?\\]") Then $End = "\" & $End
    Local $Ret = StringRegExpReplace($String, '^.*' & $Start & '(.*)' & $End & '.*$', '\1')
    If $Ret = "" Then Return $String
    Return $Ret
EndFunc

Спасибо!

Хм, но теперь другая проблема - если более чем два совпадения символов, то возвращается последнее межсимвольное значение, а нужно чтобы в таком случае возвращалось первое совпадение (с левой стороны, т.е сначала).

amel27 28-02-2007 12:29

Creat0R
ну... вот еще вариант, выбирающий фрагмент от первого вхождения 1-го символа до первого вхождения 2-го:
Код:

$String = '_теперь нам нужен этот текст^'

MsgBox(0, "", _StringInside($String, "_", "^"))

Func _StringInside($String, $Start, $End)
    $Start = StringRegExpReplace ($Start, '([\+\|\*\^\$\.\[\]\(\)\?\\])', '\\\1')
    $End = StringRegExpReplace ($End, '([\+\|\*\^\$\.\[\]\(\)\?\\])', '\\\1')
    Local $pattern = '^[^' & $Start & ']*' & $Start & '([^' & $End & ']*)' & $End & '.*$'
    Return StringRegExpReplace($String, $pattern, '\1')
EndFunc


Creat0R 28-02-2007 12:56

amel27
Цитата:

вот еще вариант
Во! это то что нужно (правда Local там лишних два раза встречается ;) ), спасибо большое (см. ниже полный пример для подобной функции, я её уже переименовал :) )...

Поздравляю со статусом Ветерана! :4u:

Код:

$String = 'Это нам не нужно. Нам нужен этот текст, :и этот тоже:, а :этот нам не нужен:'

MsgBox(0, "", _StringMidle($String, ".", ","))

MsgBox(0, "", _StringMidle($String, ":", ":"))

Func _StringMidle($String, $Start, $End)
    $Start = StringRegExpReplace ($Start, '([\+\|\*\^\$\.\[\]\(\)\?\\])', '\\\1')
    $End = StringRegExpReplace ($End, '([\+\|\*\^\$\.\[\]\(\)\?\\])', '\\\1')
    Local $pattern = '^[^' & $Start & ']*' & $Start & '([^' & $End & ']*)' & $End & '.*$'
    Return StringRegExpReplace($String, $pattern, '\1')
EndFunc


13ghost 28-02-2007 21:50

Объясните пожалуйста,а то я не догоняю,не могу понять что в справке написано:
что делает ConsoleWrite? и для чего её можно применить?
зарание благодарен

amel27 01-03-2007 06:22

13ghost
Штатное применение - отладка скриптов средствами SciTE, кстати неплохая альтернатива MsgBox() ;). Выводит заданный тект (например, значения переменных) в экран вывода - тот, что включается по F8. Из нештатных - запись данных в STDOUT при запуске скрипта через CMD.

Creat0R
Цитата:

Local там лишних два раза встречается
гы-гы, а я исправил раньше твоего замечания ;)
Цитата:

Поздравляю со статусом Ветерана!
упс, а кем я был? :o

Vadikan 01-03-2007 08:00

Цитата:

упс, а кем я был
Ты можешь быть кем хочешь, изменяя статус в профиле, - это привелегия участников, входящих в группу Contributors.

Creat0R 01-03-2007 11:35

amel27
Цитата:

а я исправил раньше твоего замечания
Ивени, не заметил...

Цитата:

а кем я был?
Старожил'ом кажется :shuffle:

belonesox 02-03-2007 22:09

Вопрос про чтение stdout'а AutoItом - наблюдаю эффект, что для некоторых программ, stdout то читается, то не читается (в зависимости от опций).
Например, рассмотрим следующий код:

Код:

Func ShowStdout($cmd)
        $stdout=""
        $foo = Run($cmd, @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
        While 1
                $line = StdoutRead($foo)
                If @error Then ExitLoop
                $stdout=$stdout & $line
        Wend
        MsgBox(0,$cmd,$stdout)
EndFunc

$cmd=@ComSpec & " /c " & " java  "
ShowStdout($cmd) ; Показывает STDOUT нормально
$cmd=@ComSpec & " /c " & " java -version "
ShowStdout($cmd) ; Показывает пустой STDOUT
$cmd=@ComSpec & " /c " & " python -h "
ShowStdout($cmd) ; Показывает STDOUT нормально
$cmd=@ComSpec & " /c " & " python -V "
ShowStdout($cmd) ; Показывает пустой STDOUT
Exit(0)

Если ли у кого-то идеи, с чем это может быть связано или обусловлено?

C уважением, Стас.

Evgeniy15 03-03-2007 02:10

Иногда название окна не меняется. Получается, что посылая следующий {ENTER} нажимаешь на {Cancel}. Команда sleep не очень эффективна, т.к. она нормально отрабатывается на одном компе, на другом с заметной задержкой а на третьем задержки не хватает. Как быть в таком случае?

Creat0R 03-03-2007 10:28

belonesox
Цитата:

с чем это может быть связано или обусловлено?
Если возращается пустое значение, значит произошла ошибка при первой попытке чтения, вот эту ошибку (а точнее пустое значение) можно и улавливать:

Код:

Func ShowStdout($cmd)
    $stdout=""
    $foo = Run($cmd, @SystemDir, @SW_HIDE, $STDERR_CHILD+$STDOUT_CHILD)
    While 1
        $line = StdoutRead($foo)
        If @error Then ExitLoop
        $stdout &= $line
    Wend
    If $stdout = "" Then $stdout = StderrRead($foo)
    MsgBox(0, $cmd, $stdout)
EndFunc


Evgeniy15
Цитата:

Как быть в таком случае?
В каком случае? я, как и многие другие, увы, гадать не умею :(

amel27 03-03-2007 11:18

belonesox
попробуй следующий вариант (проверил только для java, python под рукой нет):
Код:

#include <Constants.au3>

$cmd=@ComSpec & " /c " & " java  2>&1"
ShowStdout($cmd) ; Показывает STDOUT нормально
$cmd=@ComSpec & " /c " & ' java -version 2>&1'
ShowStdout($cmd) ; Показывает пустой STDOUT
 $cmd=@ComSpec & " /c " & " python -h  2>&1"
ShowStdout($cmd) ; Показывает STDOUT нормально
$cmd=@ComSpec & " /c " & " python -V  2>&1"
ShowStdout($cmd) ; Показывает пустой STDOUT

 Func ShowStdout($cmd)
    Local $stdout
    $foo = Run ($cmd, @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDERR_CHILD + $STDOUT_CHILD)
    While 1
        $line = StdoutRead($foo)
        If @error Then ExitLoop
        $stdout=$stdout & $line
    Wend
    MsgBox(0,$cmd,$stdout)
EndFunc

ALL
просьба не забывать добавлять в скрипты необходимые строчки #include !

Creat0R 03-03-2007 13:32

Как можно получить загрузку ЦП определённого процесса? не важно, по имени образа, пути к файлу процесса, или по Pid. Это возможно узнать? (AutoIt'ом естественно ;) ).

amel27 03-03-2007 14:39

Creat0R
что-то типа такого:
Код:

MsgBox (0, '', _GetCPUUsageProcess ('winrar'))

Func _GetCPUUsageProcess ($proc, $ticks = 1000)
    Local $aCount[3], $strProc = 'Name="' & $proc & '"'
    Local $colItems, $objItem, $objWMIService = ObjGet("winmgmts:\\.\root\CIMV2")
    If IsNumber ($proc) And $proc>0 Then $strProc = "IDProcess=" & $proc
    ; Считываем необходимые характеристики процесса - попытка №1
    $colItems = $objWMIService.ExecQuery ("SELECT IDProcess,PercentProcessorTime,Timestamp_Sys100NS FROM Win32_PerfRawData_PerfProc_Process WHERE " & $strProc, "WQL", 0x30)
    For $objItem In $colItems
        $aCount[0]=$objItem.IDProcess
        $aCount[1]=$objItem.PercentProcessorTime
        $aCount[2]=$objItem.Timestamp_Sys100NS
        ExitLoop
    Next
    If $aCount[0] Then
        ; Накапливаем статистику...
        Sleep ($ticks)
        ; Считываем необходимые характеристики процесса - попытка №2
        $colItems = $objWMIService.ExecQuery ("SELECT PercentProcessorTime,Timestamp_Sys100NS FROM Win32_PerfRawData_PerfProc_Process WHERE IDProcess=" & $aCount[0], "WQL", 0x30)
        For $objItem In $colItems
            Return Round (100*($objItem.PercentProcessorTime - $aCount[1])/($objItem.Timestamp_Sys100NS - $aCount[2]))
        Next
    EndIf
    Return ""
EndFunc


Creat0R 03-03-2007 15:40

amel27
Цитата:

что-то типа такого:
Не работает :( до цикла дело не доходит...

Вернее доходит (это я с полным именем проверял, включая расширение), но возвращается всегда ноль :(

amel27 05-03-2007 03:36

Creat0R
попробуй запустить архивацию каталога и проверить процесс "winrar",
FYI: эта функция показывает мгновенное значение загрузки CPU

Izh 05-03-2007 12:57

люди подскажите пожалуйста
недавно аозникла проблема доведения инсталяции софта до уровня автомата...
почти сразу столкнулся с проблемой - не могу заставить скрипт определить сидюк. если прописываешь жестко с какого диска стартовать софтину, то все прекрасно, но когда надо чтоб он сам запуске скрипта определял под каким диском идет сидюк, возникают проблемы, команда неверна и тому подобное....
заранее благодарен

Creat0R 05-03-2007 17:44

amel27
Цитата:

попробуй запустить архивацию каталога и проверить процесс "winrar",
FYI: эта функция показывает мгновенное значение загрузки CPU
Да, для архивации показывает (хотя и не совсем мгновенно), но я пробовал на таком примере, и странно что не работает:

Код:

#include <GuiConstants.au3>
GUICreate("CPU Usage Test", 200, 200)

$ProcessName = "AutoIt3"
$StatusBar = GUICtrlCreateLabel("CPU Usage: ", 0, 185, 200, 15, BitOr($SS_SIMPLE,$SS_SUNKEN))

GUISetState()

AdlibEnable("SetStatus", 20)

While GUIGetMsg() <> -3
WEnd

Func SetStatus()
    GUICtrlSetData($StatusBar, "CPU Usage: " & _GetCPUUsage($ProcessName))
EndFunc

Ведь по идее сам процесс скрипта (AutoIt3.exe) занимает около 10-20-ти процентов загрузкий ЦП (в данном примере), но возвращается всегда ноль. Я пробовал и на других процессах, но результат тот же :(

И ещё, а для чего по умолчанию стоит процесс idle, как я понял это типа “Бездействие системы”? но если оставлять по умолчанию, то возвращается тоже ноль, хотя в Диспетчере задач если ничего не грузит процессор то это значение становиться 99.

P.S
Что такое FYI?


Izh
Цитата:

заставить скрипт определить сидюк
Из спраки немного изменил пример (поиск по команде DriveGetDrive):

Код:

$var = DriveGetDrive( "CDROM" )
If NOT @error Then
    MsgBox(4096,"", "Found " & $var[0] & " drives")
    For $i = 1 to $var[0]
        MsgBox(4096,"Drive " & $i, $var[$i])
    Next
EndIf


amel27 06-03-2007 06:51

Как определить период бездействия пользователя (пример):
Код:

#include <Date.au3>
Opt("TrayIconHide", 1)

$IdleMinimum = 1000 ; Количество допустимых секунд неактивности
$LogFileName = StringTrimRight (@ScriptFullPath, 4) & ".log" ; Имя файла журнала

While 1
    ; Ожидание неактивности достаточной длительности
    $iIdle = _IdleWaitCommit ($IdleMinimum)
    ; Запись этого события в лог
    Local $sHours = '', $sMins = '', $sSecs = ''
    $iHours = Int ($iIdle/3600)
    If $iHours Then $sHours = $iHours & ' часов '
    $iMins = Int (Mod ($iIdle, 3600)/60)
    If $iMins Then $sMins = $iMins & ' минут '
    $iSecs = Round (Mod (Mod ($iIdle, 3600), 60))
    If $iSecs Then $sSecs = $iSecs & ' секунд'
    FileWriteLine ($LogFileName, _Now () & ' ' & @UserName & ' неактивен ' & $sHours & $sMins & $sSecs & @CRLF)
Wend

; Функция: ожидание неактивности пользователя.
; Возвращает: время неактивности в секундах.
; $idlesec - минимальная длительность ожидаемой неактивности в сек.
Func _IdleWaitCommit ($idlesec)
    $idlesec = $idlesec * 1000
    Local $iSave, $LastInputInfo = DllStructCreate ("uint;dword")
    DllStructSetData ($LastInputInfo, 1, DllStructGetSize ($LastInputInfo))
    DllCall ("user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr ($LastInputInfo))
    Do
        $iSave = DllStructGetData ($LastInputInfo, 2)
        Sleep(500)
        DllCall ("user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr ($LastInputInfo))
    Until (DllStructGetData ($LastInputInfo, 2)-$iSave) > $idlesec
    Return Round ((DllStructGetData ($LastInputInfo, 2)-$iSave)/1000)
EndFunc


amel27 06-03-2007 08:33

Creat0R
Ну... значит процесс не может определить загрузку самого себя, т.к. эти операции выполняются синхронно - пока WMI вычисляет загрузку сам процесс (AutoIt3) ожидает ответа, т.е. действительно простаивает... потому я и сказал о мгновенном значении.

по поводу Idle - там скорей всего общая загрузка CPU

P.S. FYI - For Yur Information :)

xstranger 06-03-2007 08:58

Цитата:

люди подскажите пожалуйста
недавно аозникла проблема доведения инсталяции софта до уровня автомата...
почти сразу столкнулся с проблемой - не могу заставить скрипт определить сидюк. если прописываешь жестко с какого диска стартовать софтину, то все прекрасно, но когда надо чтоб он сам запуске скрипта определял под каким диском идет сидюк, возникают проблемы, команда неверна и тому подобное....
заранее благодарен
я сделал немного по другому

$source = RegRead("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup", "SourcePath")

runwait($source & 'Software\prog.exe')


это хорошо работает на этапе GuiRunOnce, при автоустановке софта. но может и дальше использоваться если конфигурация носителей не меняется

Creat0R 06-03-2007 13:58

amel27
Цитата:

значит процесс не может определить загрузку самого себя
Но ведь...

Цитата:

Я пробовал и на других процессах, но результат тот же :(
Цитата:

пока WMI вычисляет загрузку сам процесс (AutoIt3) ожидает ответа, т.е. действительно простаивает
Да, но, в Диспетчере задач явно видно что процесс вовсе не простаивает, а именно грузит ЦП.

Цитата:

по поводу Idle - там скорей всего общая загрузка CPU
Тогда почему тоже всегда ноль? :)

Цитата:

P.S. FYI - For Yur Information
Спасибо, буду знать (и наверное юзать ;) )

amel27 07-03-2007 10:37

Creat0R
исправил скрипт - добавил усреднение по заданному интервалу (в "тиках"), кроме того процесс может теперь передаваться как по имени, так и по PID.

Creat0R 08-03-2007 06:51

amel27
Цитата:

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

Хотя мне пока не удаётся подобрать оптимальный интервал использования этой функции (между каждым её вызовом и установкой тикания ;) ).

Цитата:

процесс может теперь передаваться как по имени, так и по PID
По PID вроде не работает, а по имени опять же, нужно без расширения.... но это думаю не страшно (хотя иногда существуют процессы не только с расширением *.exe... тогда придётся делать перебор по всем процессам на существование с подобным именем)...

Мне вообще то всё это нужно для одного моего небольшого проэктика, я пытаюсь написать утилитку менеджер процессов - Получилось ВСЁ что хотел, кроме (теперь корректного, т.е в реальном времени) слежения за загрузкой ЦП (каждого процесса в отдельности и общего использования), и использования памяти каждым процессом.

Мне удалось адаптировать многие функции из офф. форума, естественно кучу твоих функции, и пару собственных.
Утилита позволяет просматривать подробную информацию о процессе, имеет почти все те же функции что и у встроенного taskmgr.exe в Windows (включая собственный диалог запуска приложении - FileRun), и даже чуть чуть больше :) .

Добавлено:



amel27
Цитата:

Как определить период бездействия пользователя
Бездействия в каком смысле? что юзер (не) должен делать для бездействия? я запустил этот пример, ничего не делал пару секунд, потом что то начал делать :), но лог не пишется.

Creat0R 08-03-2007 23:52

Diamond
Ты как то спрашивал про то, как заставить гуи НЕ отображать системны стиль, так вот я нашел на офф. форуме решение этой задачки...

Это простой скачивальщик (не знаю на сколько он полезен), при его запуске задаётся стиль как в старых/без стильных виндоус.
Вот ссылка, я немного переделал, так как там не совсем весь гуи был таким стилем, я даже удивился, как окно от FileSelectFolder() приняло старый (не)стиль :) - видимо и всё остальное что будет использованно в гуи будет иметь подобный стиль.
Я не разбирался как оно работает, но видимо там упорно используются Dll'овские штучки :)

Creat0R 09-03-2007 00:12

amel27
Тоже на офф. форуме нашел функцию для слежения за бездельем юзера :biggrin: (немного переделал для примера) :

Код:

Dim $i_LastActive = _LastActive()

$TimeInit = TimerInit()
While 1
    If $i_LastActive <> _LastActive() Then ExitLoop
    Sleep(100)
WEnd

MsgBox(64, "Activity Test", "You was not active <" & Round(TimerDiff($TimeInit)/1000, 1) & "> second(s)")

 Func _LastActive($v_User32Dll = 'user32.dll')
    Local $str_LastInput = DllStructCreate('uint;dword')
    DllStructSetData($str_LastInput, 1, DllStructGetSize($str_LastInput))
    DllCall($v_User32Dll, 'int', 'GetLastInputInfo', 'ptr', DllStructGetPtr($str_LastInput))
    Return DllStructGetData($str_LastInput, 2)
EndFunc

Я давно искал подобное, мне нужно было проверить, была ли нажата какая либо клавиша, или кнопка мышки, и это идеально подходит!

amel27 09-03-2007 04:06

Creat0R
Цитата:

По PID вроде не работает
да не, вроде работает если PID передавать не строкой, а числом
Цитата:

я пытаюсь написать утилитку менеджер процессов
в таком случае эффективней выполнять запрос не по отдельным процессам, а сразу по всему списку, вот вариант ProcessList, который кроме PID и Name выводит дополнительно инфу по загрузке CPU:
Код:

$a = _ProcessList ('')
If IsArray ($a) Then
    For $i=0 To $a[0][0]
        ConsoleWrite (StringFormat('%4i', $a[$i][0]) & ' : ' & StringFormat('%02i', $a[$i][2]) & ' : ' & $a[$i][1] & @CRLF)
    Next
EndIf

Func _ProcessList ($name = '', $ticks = 1000)
    Local $arrWork[1][3] = [[0,0,0]], $arrMain[1][3] = [[0,'_Summary',0]]
    Local $i, $colItems, $objItem, $objWMIService = ObjGet("winmgmts:\\.\root\CIMV2"), $where = 'WHERE IDProcess>0'
    If $name <> '' Then $where &= ' AND Name=' & '"' & $name & '"'
    ; Считываем необходимые характеристики процессов - попытка №1
    $colItems = $objWMIService.ExecQuery ("SELECT IDProcess,PercentProcessorTime,Timestamp_Sys100NS FROM Win32_PerfRawData_PerfProc_Process " & $where, "WQL", 0x30)
    For $objItem In $colItems
        $arrWork[0][0]+=1
        ReDim $arrWork[$arrWork[0][0]+1][3]
        $arrWork[$arrWork[0][0]][0]=$objItem.IDProcess
        $arrWork[$arrWork[0][0]][1]=$objItem.PercentProcessorTime
        $arrWork[$arrWork[0][0]][2]=$objItem.Timestamp_Sys100NS
    Next
    If $arrWork[0][0]=0 Then Return ''
    ; Накапливаем статистику...
    Sleep ($ticks)
    ; Считываем необходимые характеристики процессов - попытка №2
    $colItems = $objWMIService.ExecQuery ("SELECT IDProcess,PercentProcessorTime,Timestamp_Sys100NS FROM Win32_PerfRawData_PerfProc_Process " & $where, "WQL", 0x30)
    For $objItem In $colItems
        For $i=1 To $arrWork[0][0]
            If $arrWork[$i][0]=$objItem.IDProcess Then
                $arrMain[0][0]+=1
                ReDim $arrMain[$arrMain[0][0]+1][3]
                $arrMain[$arrMain[0][0]][0]=$objItem.IDProcess
                $arrMain[$arrMain[0][0]][1]=$objItem.Name
                $arrMain[$arrMain[0][0]][2]=Round(100*($arrWork[$i][1]-$objItem.PercentProcessorTime)/($arrWork[$i][2]-$objItem.Timestamp_Sys100NS))
                $arrMain[0][2]+=$arrMain[$arrMain[0][0]][2]
            EndIf
        Next
    Next
    If $arrMain[0][2]>100 Then $arrMain[0][2]=100
    Return $arrMain
EndFunc


amel27 09-03-2007 04:25

Creat0R
Цитата:

на офф. форуме нашел функцию для слежения за бездельем юзера
мне свой вариант нравится больше, т.к. позволяет отслеживать не только начало, но и конец бездействия.... кстати можно использовать для хранителей экрана :)
Код:

#include <Date.au3>

$IdleMinimum = 5000 ; допустимый период неактивности в миллисекундах

While 1
    $iIdle = _IdleWaitStart ($IdleMinimum)
    ConsoleWrite (_Now () & ' ' & @UserName & ' неактивен уже ' & _TickToTimeString ($iIdle) & @CRLF)
    $iIdle = _IdleWaitCommit($IdleMinimum)
    ConsoleWrite (_Now () & ' ' & @UserName & ' был неактивен ' & _TickToTimeString ($iIdle) & @CRLF)
Wend

; Ожидание начала бездействия пользователя.
; Возвращает время неактивности (в тиках)
; $idlesec - минимальная длительность ожидаемой неактивности (в тиках)
Func _IdleWaitStart ($idlesec)
    Local $aRet, $iSave, $iTick, $LastInputInfo = DllStructCreate ("uint;dword")
    DllStructSetData ($LastInputInfo, 1, DllStructGetSize ($LastInputInfo))
    DllCall ("user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr ($LastInputInfo))
    Do
        Sleep(200)
        $iSave= DllStructGetData ($LastInputInfo, 2)
        DllCall ("user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr ($LastInputInfo))
        $aRet = DllCall ("kernel32.dll", "long", "GetTickCount")
    Until ($aRet[0] - DllStructGetData ($LastInputInfo, 2))> $idlesec
    Return $aRet[0] - DllStructGetData ($LastInputInfo, 2)
EndFunc

; Ожидание окончания бездействия пользователя.
; Возвращает время неактивности в (тиках)
; $idlesec - минимальная длительность ожидаемой неактивности в (тиках)
Func _IdleWaitCommit ($idlesec)
    Local $iSave, $LastInputInfo = DllStructCreate ("uint;dword")
    DllStructSetData ($LastInputInfo, 1, DllStructGetSize ($LastInputInfo))
    DllCall ("user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr ($LastInputInfo))
    Do
        $iSave = DllStructGetData ($LastInputInfo, 2)
        Sleep(200)
        DllCall ("user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr ($LastInputInfo))
    Until (DllStructGetData ($LastInputInfo, 2)-$iSave) > $idlesec
    Return DllStructGetData ($LastInputInfo, 2)-$iSave
EndFunc

Func _TickToTimeString ($iTicks)
    Local $iHours, $iMins, $iSecs, $sText = ''
    _TicksToTime  ($iTicks, $iHours, $iMins, $iSecs)
    If $iHours Then $sText = $iHours & ' часов '
    If $iMins  Then $sText = $sText & $iMins & ' минут '
    If $iSecs  Then $sText = $sText & $iSecs & ' секунд'
    If $sText = '' Then $sText = 'меньше секунды'
    Return $sText
EndFunc


Creat0R 09-03-2007 22:17

amel27
Цитата:

работает если PID передавать не строкой, а числом
Строкой в смысле String'ом ? я из переменной передаю, но переменная содержит непосредственно цифри (это PID берётся из списка прцессов в ListView)... но как выяснилось, берутся не только цифры(?), я подставил Number($Pid) и всё нормально определяется... мистика... :)

Цитата:

в таком случае эффективней выполнять запрос не по отдельным процессам, а сразу по всему списку
100% согласен, но у меня с этим проблема - у меня уже считывается список в ListView, и при обновлении этого списка, нужно обновлять только колонку с загрузкой ЦП, т.к весь список обновлять слишком долго (для обновления списка в случае отсутствия/добавления процесса, идёт отдельная проверка, где сравнивается список существующих процессов и список процессов в ListView, если найдены различия, то обновляется всё).

Цитата:

мне свой вариант нравится больше
Мне тоже (твой) :) - интересно, можно на его основе, сделать запись статистики? т.е к примеру, указать промежуток слежения за юзером (можно из InputBox() или ещё лучше, GUI нарисовать с отображением графика даты и времени), допустим в течении 24-ёх часов, и накапливать в переменную (а лучше в массив) данные, А) о том сколько юзер был не активен (в течении этого времени, т.е 24-ёх часов), и Б) сколько юзер был активен - данные чтобы возвращались в поноценном формате времени (по необходимости и даты)... я попробовал что-то подбное сделать, но безуспешно... могу выложить мои безнадёжные попытки если нужно (там уже гуик нарисован) :)

amel27 11-03-2007 08:20

Creat0R
Цитата:

PID берётся из списка прцессов в ListView
значит нужно передавать значение переменной, обработанное ф-цией Number()

Цитата:

100% согласен, но у меня с этим проблема - у меня уже считывается список в ListView
Имхо лучше ввести пару рабочих массивов со списками процессов, которые бы поочередно (целиком) обновлялись WMI-запросами, и на основании сравнения этих массивов определять какие GUI-элементы необходимо обновить...

Цитата:

интересно, можно на его основе, сделать запись статистики?
не вижу препятствий, например можно вести два массива - с информаций об активности и о бездействии: начало, конец и длительность временного периода... останется только решить в каком виде представлять содержимое массивов
Код:

#include <Date.au3>

$IdleMinimum = 5000 ; Minimum inactivity in seconds

Dim $arrUserActive[1][3]=[[0,0,0]]
Dim $arrUserInactive[1][3]=[[0,0,0]]
While 1
    $arrUserActive[0][0]+=1
    ReDim $arrUserActive[$arrUserActive[0][0]+1][3]
    $arrUserActive[$arrUserActive[0][0]][0]=_Now ()
    $iIdle = _IdleWaitStart ($IdleMinimum)
    $arrUserActive[$arrUserActive[0][0]][1]=_Now ()
    $arrUserActive[$arrUserActive[0][0]][2]=_TickToTimeString($iIdle)
    ConsoleWrite ("Записей активности: " & $arrUserActive[0][0] & @TAB & "Записей нективности: " & $arrUserInactive[0][0] & @CRLF)

        $arrUserInactive[0][0]+=1
    ReDim $arrUserInactive[$arrUserInactive[0][0]+1][3]
    $arrUserInactive[$arrUserInactive[0][0]][0]=_Now ()
    $iIdle = _IdleWaitCommit($IdleMinimum)
    $arrUserInactive[$arrUserInactive[0][0]][1]=_Now ()
    $arrUserInactive[$arrUserInactive[0][0]][2]=_TickToTimeString($iIdle)
    ConsoleWrite ("Записей активности: " & $arrUserActive[0][0] & @TAB & "Записей нективности: " & $arrUserInactive[0][0] & @CRLF)
Wend

З.Ы.это только пример - для графического представления потребуется числовое представление интервалов а не текст

Creat0R 11-03-2007 08:56

amel27
Цитата:

значит нужно передавать значение переменной, обработанное ф-цией Number()
Я так и делаю (уже)...
Цитата:

я подставил Number($Pid) и всё нормально определяется
Цитата:

Имхо лучше ввести пару рабочих массивов со списками процессов, которые бы поочередно (целиком) обновлялись WMI-запросами, и на основании сравнения этих массивов определять какие GUI-элементы необходимо обновить...
Не так то всё просто, ещё нужно сравнивать какой именно элемент в списке соответствует элементу массива, а иногда в списке могут быть (и будут) одинаковые имена процессов, что может вызвать конфиликты... естественно можно сравнивать по PID, но всё же всё это для меня пока ещё смутно... нужно немного поламать голову ;)

Цитата:

не вижу препятствий
Знаю, а вот я вижу... присмотревшись к твоему примеру, у меня началась голова кружится... я понимаю (с трудом) двумерный массив, а трёхмерный массив у меня вызывает желание закрыть побыстрее SciTE :biggrin:

Я пока остановлюсь на простеньком... я сделал типа юмористичесукую напоминалку для бездельника :) - вот код:

Код:

HotKeySet("^e", "Quit")
TraySetIcon("shell32.dll", 111)
TraySetToolTip("Laziness Detecter (!)")

$Idle = 0
$MinLaziness = 10
$MaxLaziness = 60
$LazyLimit = Random($MinLaziness, $MaxLaziness, 1)
$TimeStamp = TimerInit()
AdlibEnable("CheckLaziness", 10)

While 1
    $Idle = _IdleWaitCommit(0)
    TrayTip("", "", 0)
    $TimeStamp = TimerInit()
    $Idle = 0
WEnd

Func CheckLaziness()
    $TimeDiff = Round(TimerDiff($TimeStamp)/1000)
    If $TimeDiff > $LazyLimit And $Idle = 0 Then
        TrayTip("You are lazy", "You are been lazy for a long time (" & _SecsToTime($TimeDiff, ":") & ")", 5, 1)
        $TimeStamp = TimerInit()
        $LazyLimit = Random($MinLaziness, $MaxLaziness, 1)
    EndIf
    If $TimeDiff >= ($LazyLimit/2) Then TrayTip("", "", 0)
EndFunc

Func _SecsToTime($iTicks, $Delim)
    If Number($iTicks) >= 0 Then
        $iHours = Int($iTicks / 3600)
        $iTicks = Mod($iTicks, 3600)
        $iMins = Int($iTicks / 60)
        $iSecs = Round(Mod($iTicks, 60))
        If StringLen($iHours) = 1 Then $iHours = "0" & $iHours
        If StringLen($iMins) = 1 Then $iMins = "0" & $iMins
        If StringLen($iSecs) = 1 Then $iSecs = "0" & $iSecs
        $Time = $iHours & $Delim & $iMins & $Delim & $iSecs
        Return $Time
    Else
        SetError(1)
        Return 0
    EndIf
EndFunc

Func _IdleWaitCommit($idlesec)
    Local $iSave, $LastInputInfo = DllStructCreate ("uint;dword")
    DllStructSetData ($LastInputInfo, 1, DllStructGetSize ($LastInputInfo))
    DllCall ("user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr ($LastInputInfo))
    Do
        $iSave = DllStructGetData ($LastInputInfo, 2)
        Sleep(200)
        DllCall ("user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr ($LastInputInfo))
    Until (DllStructGetData ($LastInputInfo, 2)-$iSave) > $idlesec
    Return DllStructGetData ($LastInputInfo, 2)-$iSave
EndFunc

Func Quit()
    Exit
EndFunc

Можно задать минимум и максимум ($MinLaziness = 10 и $MaxLaziness = 60 - в секундах) время в течении которого будет считаться что юзер бкездельник :biggrin:
Будет перебираться случайный промежуток времени, и выскакивать треевская подсказака с напоминанием о том сколько времени пользователь ничего не делал.

amel27 11-03-2007 11:53

Creat0R
Цитата:

трёхмерный массив у меня вызывает желание закрыть побыстрее SciTE
тут кажись только двумерные... ;)
Цитата:

Не так то всё просто, ещё нужно сравнивать какой именно элемент в списке соответствует элементу массива, а иногда в списке могут быть (и будут) одинаковые имена процессов, что может вызвать конфиликты... естественно можно сравнивать по PID, но всё же всё это для меня пока ещё смутно... нужно немного поламать голову
может этот пример поможет:
Код:

#include <array.au3>

$b = _ProcessList ()
While 1
    Sleep (1000)
    Dim $a = $b
    $b = _ProcessList ()
    _CompProcList ($a, $b)
Wend

Func _CompProcList (ByRef $a, ByRef $b)
    Local $i
    Local $a1[$a[0][0]+1], $a2[$a[0][0]+1], $b1[$b[0][0]+1], $b2[$b[0][0]+1]
    If $a[0][0] Then
        ; индексируем массив $a
        For $i=1 To $a[0][0]
            $a1[$i]=$a[$i][0] & $a[$i][1] ; PID и имя процесса
            $a2[$i]=$a[$i][0] & $a[$i][1] & $a[$i][2] ; PID, имя процесса и ЦП
        Next
        ; индексируем массив $b
        For $i=1 To $b[0][0]
            $b1[$i]=$b[$i][0] & $b[$i][1] ; PID и имя процесса
            $b2[$i]=$b[$i][0] & $b[$i][1] & $b[$i][2] ; PID, имя процесса и ЦП
        Next
        ; Сравниваем новый массив ($b) со старым ($a)
        For $i=1 To $b[0][0]
            $f1 = _ArraySearch($a1, $b1[$i], 1)
            $f2 = _ArraySearch($a2, $b2[$i], 1)
            If $f1<0 Then
                ConsoleWrite('Новый процесс: ' & StringFormat ('%4.0i',$b[$i][0]) & ' : ' & $b[$i][1] & @CRLF)
            ElseIf $f1>0 And $f2<0 Then
                ConsoleWrite('Изменилась загрузка ЦП: ' & StringFormat ('%4.0i',$b[$i][0]) & ' : ' & StringFormat ('%02i',$a[$f1][2]) & ' > ' & StringFormat ('%02i',$b[$i][2]) & ' : ' & $b[$i][1] & @CRLF)
            EndIf
        Next
        ; Сравниваем старый массив ($a) с новым ($b)
        For $i=1 To $a[0][0]
            $f1 = _ArraySearch($b1, $a1[$i], 1)
            If $f1<0 Then
                ConsoleWrite('Исчез процесс: ' & StringFormat ('%4.0i',$a[$i][0]) & ' : ' & $a[$i][1] & @CRLF)
            EndIf
        Next
    EndIf
EndFunc

Цитата:

сделал типа юмористичесукую напоминалку для бездельника
забавно, хотя Random имхо лишний... по крайней мере для бездельника :)

Creat0R 11-03-2007 13:33

amel27
Цитата:

тут кажись только двумерные
Упс.. точно... но тоже путает (особенно подстановка самого массива в элемент этого же массива в каждом месте :wacko: ).

Цитата:

может этот пример поможет:
О! это точно поможет, попробую его адаптировать в утилитку. Спасибо!

Цитата:

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

Кстати, я вот ещё что придумал... заносим в массив (можно из файла) разные сообщения (с разной характеристикой и контекстом), и тоже случайным перебором выводим в TrayTip'е, а также можно занести в массив все файлы из папки мелодии Windows - C:\windows\media (можно даже свою папку с мелодиями указать), и тоже в момент вывода сообщения случайно (в смысле в случайном порядке :) ) их проигрывать...

Creat0R 11-03-2007 18:28

Ура!!! я это сделал, немного помучался, но всё же сделал!

Вместо использования звуков системы, я использовал её персонажа - старый добрый волшебник “Merlin” :)...

Если в системе не найден персонаж, то выводится TrayTip. А и ещё, чтобы персонаж ещё и говорил, в системе должен быть установлен голосовой движёк.

При простое более 5-ти секунд, иконка трея меняется на неактивного юзера, при активности иконка обратно меняется на что-то вроде юзера в движении (не смог в системе найти более походящей иконки).

Также при простое в переменную $TotalTime накапливается общее время простоя (секунды), а при активности эта переменная сбрасывается на ноль (0)...
Также удалось заносить в массив отдельные заготовки сообщении, если есть файл сообщении (LazyMessages.dat), то с него считываются строки, если его нет, то в скрипте уже заготовлены 10 сообщении (на английском)...
Для выхода из скрипта в любое время, нужно нажать Ctrl E (при английской раскладке).

В общем, на мой взгляд получилось довольно неплохо... правда есть пару моментов, например, как можно проверить закончил ли персонаж читать текст, и соответственно убить его? :) ... вот скрипт:

Код:

HotKeySet("^e", "Quit")
TraySetIcon("shell32.dll", 160)
TraySetToolTip("Laziness Detecter (!)")

Dim $MessagesArr[11]
$MessagesArr[0] = 10
$MessagesArr[1] = "You are been lazy for a long time <%n>"
$MessagesArr[2] = "This is enough, start doing something >:( - you are lazy to much (%n)"
$MessagesArr[3] = "Hello!? Any one is home? why you are so lazy so long time? <%n> do somthing!"
$MessagesArr[4] = "Hi! Don't you fill like cow? Laziness is reason number 1 of why people die"
$MessagesArr[5] = "It's been over a <%n> time sense you touch your computer, touch it now!"
$MessagesArr[6] = "I can not wait for you so long (%n), I am going to shutdown myself.... beep.. beeep.. beeeeeep"
$MessagesArr[7] = "Hey man, are you forgot about me? Fine! I want to divorced"
$MessagesArr[8] = "You have no check your email for <%n> time, maybe there something intersteing?"
$MessagesArr[9] = "There is a virus on your computer! (it exists there for a long time <%n>) perform virus checking immediately!"
$MessagesArr[10] = "Hi! What's up dog? Don't pay attention; I am just stupid character that doesn't need attention! >:("

$MessagesFile = "LazyMessages.dat"
If FileExists($MessagesFile) And FileRead($MessagesFile) <> "" Then $MessagesArr = StringSplit(FileRead($MessagesFile), @LF)

$Idle = 0
$TotalTime = 0
$MinLaziness = 10
$MaxLaziness = 60
$LazyLimit = Random($MinLaziness, $MaxLaziness, 1)
$TimeStamp = TimerInit()

AdlibEnable("CheckLaziness", 10)

While 1
        $Idle = _IdleWaitCommit(0)
        TraySetIcon("shell32.dll", 160)
        TrayTip("", "", 0)
        $TimeStamp = TimerInit()
        $Idle = 0
        $TotalTime = 0
WEnd

Func CheckLaziness()
        $TimeDiff = Round(TimerDiff($TimeStamp)/1000)
        If $TimeDiff > $LazyLimit And $Idle = 0 Then
                TraySetIcon("shell32.dll", 111)
                $TotalTime += $TimeDiff
                $LazyTime = _SecsToTime($TotalTime, ":")
                $TextToSay = StringReplace($MessagesArr[Random(1, $MessagesArr[0], 1)], "%n", $LazyTime)
                $SleepTime = Round((StringLen($TextToSay)/7)*1000)
                If StringLen($TextToSay) < 7 Then $SleepTime = 5000
                CharacterMsg($TextToSay, Random(100, @DesktopWidth-100, 1), Random(10, @DesktopHeight-150, 1), $SleepTime)
                If @error Then TrayTip("You are lazy", $TextToSay, 5, 1)
                $LazyLimit = Random($MinLaziness, $MaxLaziness, 1)
                $TimeStamp = TimerInit()
        EndIf
        If $TimeDiff >= ($LazyLimit/2) Then TrayTip("", "", 0)
        If $TimeDiff >= 5 And $LazyLimit > 5 Then TraySetIcon("shell32.dll", 111)
EndFunc

Func _SecsToTime($iTicks, $Delim)
        If Number($iTicks) >= 0 Then
                $iHours = Int($iTicks / 3600)
                $iTicks = Mod($iTicks, 3600)
                $iMins = Int($iTicks / 60)
                $iSecs = Round(Mod($iTicks, 60))
                If StringLen($iHours) = 1 Then $iHours = "0" & $iHours
                If StringLen($iMins) = 1 Then $iMins = "0" & $iMins
                If StringLen($iSecs) = 1 Then $iSecs = "0" & $iSecs
                $Time = $iHours & $Delim & $iMins & $Delim & $iSecs
                Return $Time
        Else
                SetError(1)
                Return 0
        EndIf
EndFunc

Func _IdleWaitCommit($idlesec)
    Local $iSave, $LastInputInfo = DllStructCreate ("uint;dword")
    DllStructSetData ($LastInputInfo, 1, DllStructGetSize ($LastInputInfo))
    DllCall ("user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr ($LastInputInfo))
    Do
        $iSave = DllStructGetData ($LastInputInfo, 2)
        Sleep(200)
        DllCall ("user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr ($LastInputInfo))
    Until (DllStructGetData ($LastInputInfo, 2)-$iSave) > $idlesec
    Return DllStructGetData ($LastInputInfo, 2)-$iSave
EndFunc

Func CharacterMsg($TextToSay, $MovexX=200, $MoveY=200, $Sleep=5000)
        $figure = "merlin"
        If $TextToSay = "" Then $TextToSay = "Oops! there was an Error!"
        $Path = @WindowsDir & "\MSAGENT\CHARS\merlin.acs"
        If Not FileExists($Path) Then Return SetError(1)
        $AgentControl = ObjCreate("Agent.Control.1")
        $SinkObject=ObjEvent($AgentControl, "event_")
        If Isobj($AgentControl) Then $AgentControl.Connected = True
        $AgentControl.Characters.Load($figure, $Path)
        $A = $AgentControl.Characters($figure)
        $A.MoveTo($MovexX, $MoveY, 0)
        $A.Show
        $A.Speak($TextToSay)
        $A.Play("Greet")
        $A.Play("RestPose")
        Sleep($Sleep)
        $A.Hide
        $A.StopAll
        $AgentControl.Characters.Unload($figure)
EndFunc

Func Quit()
        Exit
EndFunc

P.S
Скрипт чёрно-белый потому как в разукрашенном виде он занимает более 40-ка тысяч строк.

Sanja Alone 12-03-2007 18:16

Я тоже игрался с msagent-ом. Мои наблюдения:
  1. Поскольку у различных персонажей разные действия, для обработки этой ситуации мне пришлось влепить Switch. А как бы вызывать действия случайным образом (ес-но имеющиеся у конкретного персонажа).
  2. Даже после Unload-а персонажа, в памяти продолжает висеть процесс AgentSvr.exe, к-рый занимает порядка 25-30Мб ОЗУ - это неприкольно, а убить процесс как-то некрасиво...
  3. Если агент был запущен из бесконечного цикла, то, пока он не будет Unload-ен, основной цикл стоит на паузе. В связи с этим возник вопрос о возможности реализации многопоточных задач посредстом AutoIt в целом.
Код:

#include <File.au3>
#include <Misc.au3>

$Path=@WindowsDir&"\MSAGENT\CHARS\"
$figures=_FileListToArray($Path,"*.acs",1)

;демонстрация
_msagent("Привет! Это просто тест")

Func _msagent($msg)
        If IsArray($figures) Then
                $P = $Path & $figures[Random(1,$figures[0],1)]
                $fig = StringMid($P,StringInStr($P,'\',0,-1)+1)
                $fig = StringLeft($fig,StringInStr($fig,".acs",0,-1)-1)

                If FileExists($P) Then
                        $AgentControl = ObjCreate("Agent.Control.1")
                        $SinkObject = ObjEvent($AgentControl, "event_")
                        If Isobj($AgentControl) Then
                                $AgentControl.Connected = True
                                $AgentControl.Characters.Load($fig, $P)
                                With $AgentControl.Characters($fig)
                                        .Show
                                        Switch StringLower($fig)
                                                Case 'offcat'
                                                        .Play("Greeting")
                                                        .Play("RestPose")
                                                Case 'dot'
                                                        .Play("Greeting")
                                                        .Play("RestPose")
                                                Case 'f1'
                                                        .Play("Greeting")
                                                        .Play("RestPose")
                                                Case 'logo'
                                                        .Play("Greeting")
                                                        .Play("RestPose")
                                                Case 'rocky'
                                                        .Play("Greeting")
                                                        .Play("RestPose")
                                                Case 'clippit'
                                                        .Play("Congratulate")
                                                        .Play("RestPose")
                                                Case 'mnature'
                                                        .Play("Congratulate")
                                                        .Play("RestPose")
                                                Case 'qmark'
                                                        .Play("Welcome")
                                                        .Play("RestPose")
                                                Case 'angel'
                                                        .Play("Halo")
                                                        .Play("Glow")
                                                        .Play("Glowoff")
                                                Case 'blonde fem a'
                                                        .Play("Blink")
                                                        .Play("Wink")
                                                        .Play("RestPose")
                                                Case 'candy'
                                                        .Play("Blink")
                                                        .Play("RestPose")
                                                Case 'max'
                                                        .Play("Blink")
                                                        .Play("RestPose")
                                                Case 'paige'
                                                        .Play("Pointleftreturn")
                                                Case 'reaper'
                                                        .Play("Smile")
                                                        .Play("RestPose")
                                                Case 'scientist'
                                                        .Play("Blackboard")
                                                        .Play("Entropy")
                                                        .Play("RestPose")
                                                Case 'sharky'
                                                        ;
                                                Case Else
                                                        .Play("Greet")
                                                        .Play("RestPose")
                                        EndSwitch
                                        While _KeyPressed()=0
                                                .MoveTo(Random(180,@DesktopWidth-180,1), Random(260,@DesktopHeight-260,1))
                                                .Speak($msg)
                                        WEnd
                                        .Hide
                                        .StopAll
                                Endwith
                                $AgentControl.Characters.Unload($fig)
                        EndIf
                EndIf
        EndIf
EndFunc

Func _KeyPressed()
        Local $j
        Local $dll = DllOpen("user32.dll")
        For $j = 01 to 20
                If _IsPressed($j, $dll) Then
                        DllClose($dll)
                        Return 1
                EndIf
        Next
        DllClose($dll)
        Return 0
EndFunc


Creat0R 12-03-2007 23:53

Sanja Alone
Цитата:

Поскольку у различных персонажей разные действия, для обработки этой ситуации мне пришлось влепить Switch. А как бы вызывать действия случайным образом (ес-но имеющиеся у конкретного персонажа).
Можно занести эти действия в массив, и перебирать его по Random (я также в примере сократил немного Switch ;) ) :

Код:

                                With $AgentControl.Characters($fig)
                                        .Show
                                        Switch StringLower($fig)
                                                Case 'offcat', 'dot', 'logo', 'rocky'
                                                        $PlayArr = StringSplit("Greeting|RestPose", "|")
                                                        .Play($PlayArr[Random(1, $PlayArr[0], 1)])
                                                Case 'clippit', 'mnature'
                                                        $PlayArr = StringSplit("Congratulate|RestPose", "|")
                                                        .Play($PlayArr[Random(1, $PlayArr[0], 1)])
                                                Case 'qmark'
                                                        $PlayArr = StringSplit("Welcome|RestPose", "|")
                                                        .Play($PlayArr[Random(1, $PlayArr[0], 1)])
                                                Case 'angel'
                                                        $PlayArr = StringSplit("Halo|Glow|Glowoff", "|")
                                                        .Play($PlayArr[Random(1, $PlayArr[0], 1)])
                                                Case 'blonde fem a'
                                                        $PlayArr = StringSplit("Blink|Wink|RestPose", "|")
                                                        .Play($PlayArr[Random(1, $PlayArr[0], 1)])
                                                Case 'candy', 'max'
                                                        $PlayArr = StringSplit("Blink|RestPose", "|")
                                                        .Play($PlayArr[Random(1, $PlayArr[0], 1)])
                                                Case 'paige'
                                                        .Play("Pointleftreturn")
                                                Case 'reaper'
                                                        $PlayArr = StringSplit("Smile|RestPose", "|")
                                                        .Play($PlayArr[Random(1, $PlayArr[0], 1)])
                                                Case 'scientist'
                                                        $PlayArr = StringSplit("Blackboard|Entropy|RestPose", "|")
                                                        .Play($PlayArr[Random(1, $PlayArr[0], 1)])
                                                Case 'sharky'
                                                        ;
                                                Case Else
                                                        $PlayArr = StringSplit("Greet|RestPose", "|")
                                                        .Play($PlayArr[Random(1, $PlayArr[0], 1)])
                                        EndSwitch
                                        While _KeyPressed()=0
                                                .MoveTo(Random(180,@DesktopWidth-180,1), Random(260,@DesktopHeight-260,1))
                                                .Speak($msg)
                                        WEnd
                                        .Hide
                                        .StopAll
                                Endwith

И ещё, цикл который удерживает персонажа, вызывает большую загрузку ЦП, я поставил паузу в 10 мc, и загрузки нет :)
-А что, при использовании Switch учитывается регистр букв? (я про StringLower).

Цитата:

Даже после Unload-а персонажа, в памяти продолжает висеть процесс AgentSvr.exe
Странно, у меня он (процесс) выгружается спустя пару секунд после Unload'а.

Цитата:

Если агент был запущен из бесконечного цикла, то, пока он не будет Unload-ен, основной цикл стоит на паузе.
Тоже заметил, поэтому я использовал AdlibEnable() до вызова функции с загрузкой персонажа.


Кстати, в системе есть более одного персонажа, благодаря этой статье, я значительно улучшил скрипт - Я написал функцию которая собирает в массив пути к этим персонажам (если они найдены) - _FiguresListToArray(), и затем на основе этих путей, методом случайного перебора (Random естественно), вызывается персонаж...

А также удалось осуществить “убийство” персонажа при любой активности пользователя (это я реализовал на основе наводок твоего примера - спасибо).


У меня такие вопросы:
1. Где можно узнать список действий определённого персонажа? (желательно средствами AutoIt'а выявить список действии для указанного персонажа).
2. Как можно, и можно ли вообще, регулировать скорость произношения речи? (или хотябы скорость печатания букв).




Вот новый скрипт - Детектер лени - Я пока не знаю какой из существующих персонажей что умеет делать, поэтому присвоил им всем одинаковые действия (ошибку вроде не выдаёт) - можно было ещё перебирать оффисные персонажи (как и в статье указанно), но я посчитал это лишнее, хватит пока и 4-ёх :).

Код:

HotKeySet("^e", "Quit")
TraySetIcon("shell32.dll", 160)
TraySetToolTip("Laziness Detecter (!)")

Dim $MessagesArr[11]
$MessagesArr[0] = 10
$MessagesArr[1] = "You are been lazy for a long time <%n>"
$MessagesArr[2] = "This is enough, start doing something >:( - you are lazy to much (%n)"
$MessagesArr[3] = "Hello!? Any one is home? why you are so lazy so long time? <%n> do somthing!"
$MessagesArr[4] = "Hi! Don't you fill like cow? Laziness is reason number 1 of why people die"
$MessagesArr[5] = "It's been over a <%n> time sense you touch your computer, touch it now!"
$MessagesArr[6] = "I can not wait for you so long (%n), I am going to shutdown myself.... beep.. beeep.. beeeeeep"
$MessagesArr[7] = "Hey man, are you forgot about me? Fine! I want to divorced"
$MessagesArr[8] = "You have no check your email for <%n> time, maybe there something intersteing?"
$MessagesArr[9] = "There is a virus on your computer! (it exists there for a long time <%n>) perform virus checking immediately!"
$MessagesArr[10] = "Hi! What's up dog? Don't pay attention; I am just stupid character that doesn't need attention! >:("

$MessagesFile = "LazyMessages.dat"
If FileExists($MessagesFile) And FileRead($MessagesFile) <> "" Then $MessagesArr = StringSplit(FileRead($MessagesFile), @LF)

$Idle = 0
$TotalTime = 0
$MinLaziness = 10
$MaxLaziness = 60
$LazyLimit = Random($MinLaziness, $MaxLaziness, 1)
$TimeStamp = TimerInit()

AdlibEnable("CheckLaziness", 10)

While 1
        $Idle = _IdleWaitCommit(0)
        TraySetIcon("shell32.dll", 160)
        TrayTip("", "", 0)
        $TimeStamp = TimerInit()
        $Idle = 0
        $TotalTime = 0
WEnd

Func CheckLaziness()
        $TimeDiff = Round(TimerDiff($TimeStamp)/1000)
        If $TimeDiff > $LazyLimit And $Idle = 0 Then
                TraySetIcon("shell32.dll", 111)
                $TotalTime += $TimeDiff
                $LazyTime = _SecsToTime($TotalTime, ":")
                $TextToSay = StringReplace($MessagesArr[Random(1, $MessagesArr[0], 1)], "%n", $LazyTime)
                $SleepTime = Round((StringLen($TextToSay)/7)*1000)
                If StringLen($TextToSay) < 7 Then $SleepTime = 5000
                CharacterMsg($TextToSay, Random(100, @DesktopWidth-100, 1), Random(10, @DesktopHeight-150, 1), $SleepTime)
                If @error Then TrayTip("You are lazy", $TextToSay, 5, 1)
                $LazyLimit = Random($MinLaziness, $MaxLaziness, 1)
                $TimeStamp = TimerInit()
        EndIf
        If $TimeDiff >= ($LazyLimit/2) Then TrayTip("", "", 0)
        If $TimeDiff >= 5 And $LazyLimit > 5 Then TraySetIcon("shell32.dll", 111)
EndFunc

Func _SecsToTime($iTicks, $Delim)
        If Number($iTicks) >= 0 Then
                $iHours = Int($iTicks / 3600)
                $iTicks = Mod($iTicks, 3600)
                $iMins = Int($iTicks / 60)
                $iSecs = Round(Mod($iTicks, 60))
                If StringLen($iHours) = 1 Then $iHours = "0" & $iHours
                If StringLen($iMins) = 1 Then $iMins = "0" & $iMins
                If StringLen($iSecs) = 1 Then $iSecs = "0" & $iSecs
                $Time = $iHours & $Delim & $iMins & $Delim & $iSecs
                Return $Time
        Else
                SetError(1)
                Return 0
        EndIf
EndFunc

Func _IdleWaitCommit($idlesec, $TimeInit=0, $SleepTime=0)
    Local $iSave, $LastInputInfo = DllStructCreate ("uint;dword")
    DllStructSetData ($LastInputInfo, 1, DllStructGetSize ($LastInputInfo))
    DllCall ("user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr ($LastInputInfo))
    Do
        $iSave = DllStructGetData ($LastInputInfo, 2)
        Sleep(100)
        DllCall ("user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr ($LastInputInfo))
                If $SleepTime <> 0 And TimerDiff($TimeInit) >= $SleepTime Then ExitLoop
    Until (DllStructGetData ($LastInputInfo, 2)-$iSave) > $idlesec
    Return DllStructGetData ($LastInputInfo, 2)-$iSave
EndFunc

Func CharacterMsg($TextToSay, $MovexX=200, $MoveY=200, $Sleep=5000)
        If $TextToSay = "" Then $TextToSay = "Oops! there was an Error!"
        $FiguresArr = _FiguresListToArray()
        If Not IsArray($FiguresArr) Then Return SetError(1)
        $RandomFigure = Random(1, $FiguresArr[0], 1)
        $FigurePath = $FiguresArr[$RandomFigure]
        $FigureName = StringTrimRight(StringRegExpReplace($FigurePath, '^.*\\', ''), 4)
        If Not FileExists($FigurePath) Then Return SetError(2)
        $AgentControl = ObjCreate("Agent.Control.1")
        $SinkObject = ObjEvent($AgentControl, "event_")
        If Not Isobj($AgentControl) Then Return SetError(3)
        $AgentControl.Connected = True
        $AgentControl.Characters.Load($FigureName, $FigurePath)
        $hCharacter = $AgentControl.Characters($FigureName)
        With $hCharacter
                .MoveTo($MovexX, $MoveY, 0)
                .Show
                .Speak($TextToSay)
                .Play("Greet")
                .Play("RestPose")
                $SleepInit = TimerInit()
                While TimerDiff($SleepInit) < $Sleep
                        If _IdleWaitCommit(0, $SleepInit, $Sleep) <> 0 Then ExitLoop
                WEnd
                .Hide
                .StopAll
        EndWith
        $AgentControl.Characters.Unload($FigureName)
EndFunc

Func _FiguresListToArray()
        $FiguresPath1 = @WindowsDir & "\MSAGENT\CHARS\"
        $FiguresPath2 = @WindowsDir & "\srchasst\chars\"
        If Not FileExists($FiguresPath1) And Not FileExists($FiguresPath2) Then Return SetError(1)
        Local $FiguresArr[1]
        ;If FileExists($FiguresPath1 & "*.acs") Then
                Local $FigureFind1 = FileFindFirstFile($FiguresPath1 & "*.acs")
                If $FigureFind1 <> -1 Then
                        While 1
                                $CurrentFigure = FileFindNextFile($FigureFind1)
                                If @error Then ExitLoop
                                ReDim $FiguresArr[UBound($FiguresArr)+1]
                                $FiguresArr[0] += 1
                                $FiguresArr[UBound($FiguresArr)-1] = $FiguresPath1 & $CurrentFigure
                        WEnd
                EndIf
                FileClose($FigureFind1)
        ;EndIf
        ;If FileExists($FiguresPath2 & "*.acs") Then
                Local $FigureFind2 = FileFindFirstFile($FiguresPath2 & "*.acs")
                If $FigureFind2 <> -1 Then
                        While 1
                                $CurrentFigure = FileFindNextFile($FigureFind2)
                                If @error Then ExitLoop
                                ReDim $FiguresArr[UBound($FiguresArr)+1]
                                $FiguresArr[0] += 1
                                $FiguresArr[UBound($FiguresArr)-1] = $FiguresPath2 & $CurrentFigure
                        WEnd
                EndIf
                FileClose($FigureFind2)
        ;EndIf
        Return $FiguresArr
EndFunc

Func Quit()
        Exit
EndFunc

Напомню, что в данном примере (где $MinLaziness = 10, а $MaxLaziness = 60), нужно ничего не делать как минимум от 10-ти до 60-ти секунд чтобы увидеть результат этого скрипта ;) .

Sanja Alone 14-03-2007 17:47

Creat0R
Цитата:

Можно занести эти действия в массив, и перебирать его по Random
Это не прикольно, гораздо практичнее получать список действий персонажа программно. Вот в чем вопрос... "желательно средствами AutoIt'а выявить список действии для указанного персонажа" :)

Цитата:

А что, при использовании Switch учитывается регистр букв?
Только что проверил - не учитывается. Можно StringLower убрать.

Цитата:

Я написал функцию которая собирает в массив пути к этим персонажам
У меня так тоже сделано, причем с учетом персонажей в директориях Офиса, но это уже явный перебор :)

Цитата:

Как можно, и можно ли вообще, регулировать скорость произношения речи?
Код:

[HKEY_CURRENT_USER\Software\Microsoft\Speech\Voices]
;низкая
"DefaultTTSRate"=dword:FFFFFFF6
;средняя
"DefaultTTSRate"=dword:00000000
;высокая
"DefaultTTSRate"=dword:0000000a

Ну, и промежуточные значения есть, ес-но. Посмотри regshot-ом.

Sancho111 14-03-2007 18:29

привет, в общем такая проблемка, нужно чтобы в этом скрипте перед Send ( 'Иванов' )
раскладка менялась на русскую
а перед Send ( 'Ivanov@f57.nalog.ru' ) на англискую
заранее спасибо
Код:

;  Автоматическое заполнение квитанции
;  ========================================


Run ( 'fap2006.exe' )
WinWaitActive ( 'Редактор актов приёма ПО' )
WinWaitActive ( 'Открыть' )
WinWaitActive ( 'Редактор актов приёма ПО', 'Акт приёма' )
Send ( '{Tab}' )
Send ( '9977' )
AutoItSetOption ( "SendKeyDelay", 20 )

Send ( '{Tab}' )
Send ( '{Tab}' )
Send ( '{Tab}' )
Send ( '{Tab}' )
Send ( '{Tab}' )
Send ( 'Иванов' )
AutoItSetOption ( "SendKeyDelay", 20 )
Send ( '{Tab}' )
Send ( 'Александр' )
AutoItSetOption ( "SendKeyDelay", 20 )
Send ( '{Tab}' )
Send ( 'Сергеевич' )
AutoItSetOption ( "SendKeyDelay", 20 )
Send ( '{Tab}' )
Send ( '913-08-24' )
AutoItSetOption ( "SendKeyDelay", 20 )
Send ( '{Tab}' )
Send ( 'Ivanov@f57.nalog.ru' )
AutoItSetOption ( "SendKeyDelay", 20 )

Exit


Sanja Alone 14-03-2007 20:01

Sancho111
FAQ -> Как с помощью AutoIt сменить раскладку клавиатуры -> WinAPI-метод

Creat0R 15-03-2007 01:14

Sanja Alone
Ты не поверишь, но я на офф. сайте нашел библиотеку для управления персонажами MSAgent!

Там есть функция которая возвращает массив всех действии для заданного персонажа, и даже больше, там есть функции позволяющие добавлять/удалять действия в контекстное меню персонажа (по правой кнопке мышки на нём).

В общем я в эйфории! :yahoo:

Цитата:

Ну, и промежуточные значения есть, ес-но. Посмотри regshot-ом.
Спасибо за направление, а что это за regshot? не слышал о нём, и как посмотреть? т.е как получить промежуточные значения? (жалко что нельзя просто цифрами задавать :( )



А функция для получения списка действии персонажа вот (довольно проста оказалась) :

Код:

Func _MAListCharAnimations( ByRef $oCharacter )
    Local $RetVal[1]
    $RetVal[0] = 0
    If IsObj( $oCharacter ) Then
        For $AnimName in $oCharacter.AnimationNames
            Redim $RetVal[ Ubound( $RetVal ) + 1 ]
            $RetVal[0] = Ubound( $RetVal ) - 1
            $RetVal[$RetVal[0]] = $AnimName
        Next
    EndIf
    Return $RetVal
EndFunc

$oCharacter естественно должен передаваться как объект загрузки персонажа.

Sanja Alone 15-03-2007 12:25

Creat0R
Цитата:

что это за regshot?
RegShot (редакция ParaGlider-а)

Цитата:

жалко что нельзя просто цифрами задавать
Можно. Представь себе координатную ось с 21 координатой (10 отрицательных, ноль и 10 положительных):
Код:

FFFFFFF6 - минимальное значение
FFFFFFF7
...
FFFFFFFF
00000000 - 0 (начало координат)
00000001
...
00000009
0000000a - максимальное значение


Sancho111 15-03-2007 15:40

Код:

;  Автоматическое заполнение квитанции
;  ========================================

;клавиши (разрешенные клавиши: 1,2,3,4,5,6,7,8,9,0,~,Ё - знак ударения)
$vrtkey='1,2'
;модификаторы клавиш (разрешены: '05' - Ctrl;)
$keymod='05,05'
;коды языков (можете посмотреть в разделе "Appendix" руководства по AutoIt или в вышеприведенном примере)
$lang='0409,0419'

;включаем возможность раздельного переключения языков (англ. - Ctrl+Shift+1; рус. - Ctrl+Shift+2;)
_EnableLangSwitching($vrtkey,$keymod,$lang)




Run ( 'fap2006.exe' )



WinWaitActive ( 'Редактор актов приёма ПО' )
WinWaitActive ( 'Открыть' )
WinWaitActive ( 'Редактор актов приёма ПО', 'Акт приёма' )
Sleep(500)
;переключение на рус.
Send('^+2')
Send ( '{Tab}' )
Send ( '9977' )
AutoItSetOption ( "SendKeyDelay", 20 )

Send ( '{Tab}' )
Send ( '{Tab}' )
Send ( '{Tab}' )
Send ( '{Tab}' )
Send ( '{Tab}' )
Send ( 'Иванов' )
AutoItSetOption ( "SendKeyDelay", 20 )
Send ( '{Tab}' )
Send ( 'Александр' )
AutoItSetOption ( "SendKeyDelay", 20 )
Send ( '{Tab}' )
Send ( 'Сергеевич' )
AutoItSetOption ( "SendKeyDelay", 20 )
Send ( '{Tab}' )
Send ( '913-08-24' )
AutoItSetOption ( "SendKeyDelay", 20 )
Send ( '{Tab}' )
;переключение на англ.
Send('^+1')
Send ( 'Ivanov@f58.nalog.ru' )
AutoItSetOption ( "SendKeyDelay", 20 )

;отключение возможности раздельного переключения языков (удаление из реестра внесенных туда веток)
;в кач-ве аргумента укажите к-во языков, заданное выше в переменной $lang (для данного примера. - 3)
_DisableLangSwitching(3)

Func _EnableLangSwitching($key,$mod,$lng)
$constpart="HKEY_CURRENT_USER\Control Panel\Input Method\Hot Keys\000001"
$akey=StringSplit($key,',',1)
$amod=StringSplit($mod,',',1)
$alng=StringSplit($lng,',',1)
If UBound($akey,1)=UBound($amod,1) and UBound($akey,1)=UBound($alng,1) Then
        For $i=1 To UBound($alng,1)-1
                RunWait('REG ADD "' & $constpart & StringFormat('%02s"',$i-1) & ' /v "Virtual Key" /t REG_BINARY /d ' & Hex(Asc($akey[$i]),2) & '000000 /f','',@SW_HIDE)
                RunWait('REG ADD "' & $constpart & StringFormat('%02s"',$i-1) & ' /v "Key Modifiers" /t REG_BINARY /d ' & $amod[$i] & 'c00000 /f','',@SW_HIDE)
                RunWait('REG ADD "' & $constpart & StringFormat('%02s"',$i-1) & ' /v "Target IME" /t REG_BINARY /d ' & StringRight($alng[$i],2)&StringLeft($alng[$i],2)&StringRight($alng[$i],2)&StringLeft($alng[$i],2) & ' /f','',@SW_HIDE)
        Next
        SetError(0)
        Return(1)
Else
        SetError(1)
        Return(0)
EndIf
EndFunc

Func _DisableLangSwitching($count)
$constpart="HKEY_CURRENT_USER\Control Panel\Input Method\Hot Keys\000001"
For $i=0 To $count-1
        RunWait('REG DELETE "' & $constpart & StringFormat('%02s"',$i) & ' /f','',@SW_HIDE)
Next
EndFunc

Exit

выдает ошибку
$akey=StringSplit($key,',',1)
$akey=^ERROR
Error: Incorect number of parametrs in function call

Sanja Alone 16-03-2007 00:15

Sancho111
Я же говорил о методе "WinAPI"
Код:

Run ( 'fap2006.exe' )
AutoItSetOption ( "SendKeyDelay", 20 )
WinWaitActive ( 'Редактор актов приёма ПО' )
WinWaitActive ( 'Открыть' )
WinWaitActive ( 'Редактор актов приёма ПО', 'Акт приёма' )
$hWnd = WinGetHandle ( 'Редактор актов приёма ПО', 'Акт приёма' )
Send ( '{Tab}' )
Send ( '9977' )
Send ( '{Tab}' )
Send ( '{Tab}' )
Send ( '{Tab}' )
Send ( '{Tab}' )
Send ( '{Tab}' )
_SetKeyboardLayout("00000419", $hWnd)
Send ( 'Иванов' )
Send ( '{Tab}' )
Send ( 'Александр' )
Send ( '{Tab}' )
Send ( 'Сергеевич' )
Send ( '{Tab}' )
Send ( '913-08-24' )
Send ( '{Tab}' )
_SetKeyboardLayout("00000409", $hWnd)
Send ( 'Ivanov@f57.nalog.ru' )

Func _SetKeyboardLayout($sLayoutID, $hWnd)
Local $WM_INPUTLANGCHANGEREQUEST = 0x50
Local $ret = DllCall("user32.dll", "long", "LoadKeyboardLayout", "str", $sLayoutID, "int", 0)
DllCall("user32.dll", "ptr", "SendMessage", "hwnd", $hWnd, "int", $WM_INPUTLANGCHANGEREQUEST, "int", 1, "int", $ret[0])
EndFunc


Sancho111 16-03-2007 11:05

Спасибо за код, но возникла следущая ошибочка

Local $ret = DllCall("user32.dll", "long", "LoadKeyboardLayout", "str", $sLayoutID, "int", 0)
Local $ret =^ERROR

Error Uknown Function name

Creat0R 16-03-2007 12:08

Sancho111
Цитата:

Error Uknown Function name
Какая у тебя версия AutoIt? и на сколько я помню, должна быть поддержка AutoIt3x...

Установи последнюю версию.

Creat0R 16-03-2007 13:40

Sanja Alone
Цитата:

Можно. Представь себе координатную ось с 21 координатой (10 отрицательных, ноль и 10 положительных)
О, спасибо (как это я пропустил твой пост)...

Сделал функцию для установки скорости произношения речи, но не уверен что это правильно:

Код:

Func _SetSpeachSpeed($Speed)
    If $Speed < 1 Or $Speed > 21 Then Return SetError(1)
    Local $SetRate
    Switch $Speed
        Case 1 To 11
            $SetRate = 4294967280 + ($Speed+5)
            If $Speed = 11 Then $SetRate = 0
        Case 12 To 21
            $SetRate = $Speed-11
    EndSwitch
    Return RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Speech\Voices", "DefaultTTSRate", "REG_DWORD", $SetRate)
EndFunc

P.S
Что то никак не соображу как использовать Regshot.

VelDmi 16-03-2007 14:12

Creat0R
Цитата:

Что то никак не соображу как использовать Regshot.
Жмакаешь кнопку 1 снимок, потом делаешь изменения в системе (например ставишь галочку в или двигаешь ползунок), затем жмакаешь 2 снимок, затем сравнить.
Он сравнит состояния реестра до и после и выдаст изменения.

Creat0R 16-03-2007 14:39

VelDmi
Цитата:

Жмакаешь кнопку 1 снимок, потом делаешь изменения в системе (например ставишь галочку в или двигаешь ползунок), затем жмакаешь 2 снимок, затем сравнить.
Он сравнит состояния реестра до и после и выдаст изменения.
Ну я как бы прочитал Readme, но спасибо всё ровно... просто я не совсем понял как мне это поможет узнать промежуточные значения для скорости произношения речи.

У меня вроде нечем так особо задать скорость, до, и после, а потом проверить... т.е нету способной на это программы, сами персонажи вроде не задают скорость, да и в функциях которые я нашел (с офф. форума) нету ничего подобного.

Sanja Alone 16-03-2007 16:23

Creat0R
Цитата:

как мне это поможет узнать промежуточные значения для скорости произношения речи
Пуск -> Панель управления -> Речь -> Скорость голоса. Двигаем ползунок и смотрим regshot-ом. Хотя я тебе и так уже все возможные значения выдал интуитивным методом :)

Creat0R 16-03-2007 16:38

Sanja Alone
Цитата:

Пуск -> Панель управления -> Речь -> Скорость голоса.
Ах вот оно где находится...

Цитата:

Хотя я тебе и так уже все возможные значения выдал интуитивным методом
Да, спасибо, а я видимо подобно интуитивным методом подобрал для этого функцию ;)

P.S
Кстати на её (функции) основе, можно также в своих скриптах строить подобный ползунок :).

Dirk Diggler 19-03-2007 09:02

написал скрипт, который сперва пишет огромный файл, а потом его же считывает, и проверяет, считалось то же, что записалось или нет?
работает, но медленно, видимо, за счет сравнения строк. Как бы ускорить? что писать в файл, значения абсолютно не имеет.

Код:

$filename = "now" & @MIN & @SEC & "temp"

$fil = FileOpen( $filename, 2)
$kb = ""

For $i = 1 to 1024 Step 1
        $kb &= "1"
Next

$Mb = ""

For $i = 1 to 1024 Step 1
        $Mb &= $kb & @CRLF
Next

#region --- GuiBuilder code Start ---
; Script generated by AutoBuilder 0.6 Prototype

#include <GuiConstants.au3>

GuiCreate("MyGUI", 147, 45,-1, -1 , BitOR($WS_OVERLAPPEDWINDOW, $WS_CLIPSIBLINGS))
$btStop = GuiCtrlCreateButton("Stop writing!", 10, 10, 130, 30)
GuiSetState()

$volume = 0
Do
    $msg = GuiGetMsg()
        Select
                Case ($msg = $GUI_EVENT_CLOSE) or ($msg = $btStop)
                        ExitLoop
                Case Else
                ;;;
        EndSelect
        $err= FileWriteLine( $fil, $Mb)
        $volume += 1
Until ($err <> 1)
FileClose($fil)

GUIDelete()

GuiCreate("MyGUI", 147, 45,-1, -1 , BitOR($WS_OVERLAPPEDWINDOW, $WS_CLIPSIBLINGS))
$btStop = GuiCtrlCreateButton("verifyin'...", 10, 10, 130, 30)
GuiSetState()
$fil = FileOpen( $filename,0 )

$verifyfailed = 0
$verified = 0
While 1
        $msg = GuiGetMsg()
        if  ($msg = $GUI_EVENT_CLOSE) or ($msg = $btStop) Then ExitLoop
        for $k = 1 to 1024
                $line = FileReadLine($fil)
                If @error = -1 Then ExitLoop
                if $line <> $kb then
                        $verifyfailed = 1
                        SetError(1)
                EndIf
               
        Next
        If @error = -1 Then ExitLoop
        $verified += 1       
       
Wend

GUIDelete()
MsgBox(0,"Verify result", "Volume: " & ($volume) & "Mb" & @CRLF & "Verified:" & $verified & "Mb" & @CRLF  & "Verify failed: " & ($verifyfailed = 1))
       
FileClose($fil)
FileDelete($filename)


Creat0R 19-03-2007 11:09

Dirk Diggler
Цитата:

Как бы ускорить?
Ну во-первых, желательно убрать из второго цикла для гуи $msg = GuiGetMsg() - т.к в GuiGetMsg() встроена задержка в 10 мс.

И нет необходимости строить новый гуи и удалять старый, можно использовать и тот же. А для проверки нажатия кнопки, можно использовать метод реагирования на событие (On Event Mode)...

И ещё, зачем SetError(1)? это нигде не используется, или я что-то упустил? Просто быстрее делать:
If .. Then ...

чем:

If ... Then
...
EndIf


Вот немного переделал пример:

Код:

$filename = "now" & @MIN & @SEC & "temp"

$fil = FileOpen( $filename, 2)
$kb = ""

For $i = 1 to 1024 Step 1
    $kb &= "1"
Next

$Mb = ""

For $i = 1 to 1024 Step 1
    $Mb &= $kb & @CRLF
Next

#include <GuiConstants.au3>
GuiCreate("MyGUI", 147, 45,-1, -1 , BitOR($WS_OVERLAPPEDWINDOW, $WS_CLIPSIBLINGS))
$btStop = GuiCtrlCreateButton("Stop writing!", 10, 10, 130, 30)
GuiSetState()

$volume = 0
Do
    $msg = GuiGetMsg()
    Select
        Case $msg = $GUI_EVENT_CLOSE Or $msg = $btStop
            Opt("GuiOnEventMode", 1)
            FileClose($fil)
            $fil = FileOpen( $filename, 0)
            $verifyfailed = 0
            $verified = 0
            $ExitLoop = 0
            GUICtrlSetData($btStop, "Verifyin'...")
            GUICtrlSetOnEvent($btStop, "Verifyin")
            While 1
                If $ExitLoop = 1 Then ExitLoop
                For $k = 1 To 1024
                    $line = FileReadLine($fil)
                    If @error = -1 Then ExitLoop
                    If $line <> $kb Then $verifyfailed = 1
                Next
                If @error = -1 Then ExitLoop
                $verified += 1
            Wend
            ExitLoop
    EndSelect
    $err = FileWriteLine($fil, $Mb)
    $volume += 1
Until ($err <> 1)

 GUIDelete()

MsgBox(0,"Verify result", "Volume: " & ($volume) & "Mb" & @CRLF & "Verified: " & $verified & "Mb" & @CRLF  & "Verify failed: " & ($verifyfailed = 1))

    FileClose($fil)
FileDelete($filename)

Func Verifyin()
    $ExitLoop = 1
EndFunc

Хотя кажется не очень то заметно увеличение в скорости :shuffle:

Dirk Diggler 19-03-2007 17:34

ды вот. эти все потери несущественны по сравнению с теми, что происходят на проверке равенства строк. Вот как бы придумать алгоритм
какой-нть хитрый, ну типа сделать AND по каждому отдельному символу считанной строки и сравнить результат с одим символом?


Цитата:

И ещё, зачем SetError(1)?
забыл после него ExitLoop

Creat0R 19-03-2007 17:51

Dirk Diggler
Цитата:

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

Я если честно не вникаю в затею, почему бы не записать временный массив при создании файла, и потом перечитать весь файл в другой массив, и заием сравнивать оба массива по одному элементу за раз? но опять же, я не вижу смысл всего этого, поэтому немного трудно помочь найти решение :( .

Цитата:

забыл после него ExitLoop
Вот я в начале и хотел в исправленный пример его добавить, но не был уверен что нужно прирываь цикл при первом различии строк.

Dirk Diggler 19-03-2007 18:43

справился. чтение большими блоками устранило проблему.

Цитата:

Так это же будет намного медленнее(?)...
когда-то давно битовые логические операции были куда быстрей сравнения

amel27 20-03-2007 04:57

Dirk Diggler
Цитата:

чтение большими блоками устранило проблему
проблема не только в размере блока, но и в функциях FileReadLine/FileWriteLine, которые более интеллектуальные по сравнению с обычными FileRead/FileWrite в части поиска/обработки символов конца строк, а значит и более медленные.
Цитата:

когда-то давно битовые логические операции были куда быстрей сравнения
В AutoIT кроме обычных строк есть бинарные, сравнение которых по идее должно проходить быстрей, но к сожалению все операции чтения файлов возвращают только стандартную символьную строку (даже если читать в RAW-mode), а смена типа строковой переменной может свести на нет это преимущество.... хотя, конечно, нужно пробовать

ADD: предположение не подтвердилось - бинарные строки сравниваются медленней обычных ~ на 10%, видимо оператор сравнения не оптимизирован для таких строк.

mel_kos 23-03-2007 13:28

как добраться до свойств диска?нужно включить квотирование.

Creat0R 26-03-2007 23:39

amel27

Возможно ли как то адаптировать твою API-функцию _FileSelectFolder() чтобы деактивировалась (disabled) кнопка ОК пр выбранных папках которые немогут содержать (для “нормальной” записи) данные (такие как “Мой компьютер”, “Корзина”, “Сетевое окружение”, “Панель управления” и т.п)? это реально?
И конечно очень хотелось бы всё таки иметь возможность указываь заранее исходный каталог (Init Dir).

Я тут уже почти доделал подобную функцию на обычном ГУИ, но у меня ушло более 5-сот строк кода и кучу времени на то чтобы построить этот недо-механизм... в общем получается но кривовато, и кажется очень не надёжно :( .

magnetikus 29-03-2007 20:16

Народ! Киньте ссылку или подскажите
1) Как нажать клавиши стрелочек, клавиши windows shift contol и т.д.
2) Как получить значение текста из поля ввода какой либо програмы
3)Есть ли где русскоязычный сайт посвящённый AutoIt?
P.S. Пишу скрипт переключения на другой SQL сервер через DSN

Creat0R 30-03-2007 18:33

magnetikus
Цитата:

Как нажать клавиши стрелочек
Код:

Send("{Down}")
Send("{Up}")

См. в справке (в шапке есть ссылки на русскую) команду Send.

Цитата:

Как получить значение текста из поля ввода какой либо програмы
Какой либо наврядли получится, а вот если это поле имеет идентификатор (ControlID) то можно попробовать (узнав его и заголовок программы из утилиты Au3Info.exe - в дистрибутиве с AutoIt'ом прилагается).

Цитата:

Есть ли где русскоязычный сайт посвящённый AutoIt?
Нет кажется (пока ;) ), есть эта тема (мне лично безмерно помагали тут, и продолжают помагать :) ).
Входя в мир программирования, английский желательно основной знать, и тогда есть офф. форум ;) - Там целый клад для начинающего программиста на AutoIt'е.

GTeam 08-04-2007 06:38

как правельно скачать и установить файл?
 
Здравствуйте!

кто может сказать это правельный скрипт?
Код:

;качаем файл
InetGet("http://site.com/setup.exe", "setup.exe", 1, 1)
;ждём 30 секунд до запуска файла
$begin = TimerInit()
sleep(30000)
$dif = TimerDiff($begin)
;установка в тихом режиме
Global $file3='setup.exe'
RunWait ( $file3 & ' /S' )

;ждём 3 секунды что бы скачать класс Process.au3
$begin = TimerInit()
sleep(3000)
$dif = TimerDiff($begin)
;качаем класс Process.au3
InetGet("http://www.site.com/Process.au3", "Process.au3", 1, 1)

;ждём 10 секунд для выполнение RunDos комманды
$begin = TimerInit()
sleep(10000)
$dif = TimerDiff($begin)
;выполняем RunDos комманду
#include <Process.au3>
$rc = _RunDos("start http://site.com/autoit/stats.php?v=1&ip=1.0.0.1&file=autoit3.exe")

есть еще пару вопросов...
1. насколько и как максимально уменьшить размер создоваемого exe файла?
2. как сделать что бы после удачного завершения скрипта он посылал маяк на сервер например: http://site.com/autoit/stats.php?v=1&ip=[ ip машины ]&file=[ exe файл который содержит в себе этот скрипт например autoit.exe файл который установился ]
как можно это реализовать? нужно это сделать в скрытом режими через RunDos не получиться !

twincode 09-04-2007 09:29

Подскажите есть ли возможность прочитать файл с разделителями при помощи Autoit.
Команда for /F с этим справляется отлично,но хочется через autoit.
Подскажите.Спасибо.

Creat0R 09-04-2007 13:31

GTeam
Цитата:

это правельный скрипт?
Не совсем, TimerInit/Diff там лишние (это нужно для засикания промежутка времени от одной точки во времени к другой), команда Sleep() замечательно сама справляется с задержкой ;)

Код:

;качаем файл
InetGet("http://site.com/setup.exe", "setup.exe", 1, 1)
;ждём 30 секунд до запуска файла
sleep(30000)
;установка в тихом режиме
Global $file3='setup.exe'
RunWait ( $file3 & ' /S' )

;ждём 3 секунды что бы скачать класс Process.au3
sleep(3000)
;качаем класс Process.au3
InetGet("http://www.site.com/Process.au3", "Process.au3", 1, 1)

;ждём 10 секунд для выполнение RunDos комманды
sleep(10000)
;выполняем RunDos комманду
$rc = _RunDos("start http://site.com/autoit/stats.php?v=1&ip=1.0.0.1&file=autoit3.exe")

А также там лишний #Include - после этого должно быть что то указанно (файл вложения).

Цитата:

насколько и как максимально уменьшить размер создоваемого exe файла?
Чем меньше кода, меньша устанавливаемых файлов, ну и ещё от версии Аутоита зависит.

twincode
Цитата:

есть ли возможность прочитать файл с разделителями при помощи Autoit
Как понять с разделителями? через delims=xxx? тут немного другая ситуация, какую конкретно задачу нужно выполнить? на аутоите работа с файлами намного продвинутее чем в ком. строке ;) .

GTeam 09-04-2007 14:15

Цитата:

А также там лишний #Include - после этого должно быть что то указанно (файл вложения).
но если убрать инклуд то rundos не будет работать..

Creat0R 09-04-2007 15:14

GTeam
Цитата:

но если убрать инклуд то rundos не будет работать..
В твоём примере оно и так не будет работать, нужно после #Include поставить имя файла с которого будет браться функция _RunDos() (Process.au3)...

Но в данном случае можно и без этой функции обойтиться:

Код:

ShellExecute("http://site.com/autoit/stats.php?v=1&ip=1.0.0.1&file=autoit3.exe")
Ну или так:

Код:

Run(@ComSpec & " /c start http://site.com/autoit/stats.php?v=1&ip=1.0.0.1&file=autoit3.exe")

AxelM 09-04-2007 15:40

Подскажите пожалуйста, как получить Product version файла. Я нашел только способ получения File version.

Creat0R 09-04-2007 16:52

AxelM
Цитата:

как получить Product version файла.
Из справки:

Цитата:

filename Filename to check.
stringname [optional] name of the field to be retried from the header version file info.

stringname can be the basic one as :
Comments, InternalName, ProductName, CompanyName, LegalCopyright, ProductVersion,
FileDescription, LegalTrademarks, PrivateBuild, FileVersion, OriginalFilename, SpecialBuild

Код:

$ProductVersion = FileGetVersion($FileName, "ProductVersion")
;)

twincode 10-04-2007 08:49

Creat0R
Цитата:

Как понять с разделителями? через delims=xxx? тут немного другая ситуация, какую конкретно задачу нужно выполнить? на аутоите работа с файлами намного продвинутее чем в ком. строке
Задача такая нужно вывести net use в файл. Потом пропарсить его на предмет подцепленных дисков и если присутствует меп на определенный серве перемепить его на другой.
Написал батник но он на 98 работать не будет из-за расширенных функций [ SetLocal enabledelayedexpansion ].Хотел переделать под au3,только вот как net use парсить не представляю.
вот батник
Код:

@echo off
IF "%1" == "" GOTO :ERR
IF "%2" == "" GOTO :ERR
IF %OS%==Windows_NT set key=/persistent:yes
IF exist c:\windows\ГЛАВНО~1\ПРОГРА~1\АВТОЗА~1\null set bat=c:\windows\ГЛАВНО~1\ПРОГРА~1\АВТОЗА~1
IF exist d:\windows\ГЛАВНО~1\ПРОГРА~1\АВТОЗА~1\null set bat=d:\windows\ГЛАВНО~1\ПРОГРА~1\АВТОЗА~1
IF exist e:\windows\ГЛАВНО~1\ПРОГРА~1\АВТОЗА~1\null set bat=e:\windows\ГЛАВНО~1\ПРОГРА~1\АВТОЗА~1
IF %OS%==Windows_NT set bat=%windir%\system32
set newshare=%bat%\newshare.bat
set source=%bat%\list_share.txt
net use >%source%

set oldserver=%1
set newserver=%2

setlocal
echo ::%oldserver%>%newshare%
for %%a in (%newshare%) do set "size=%%~za"
set /a "size=size-4"
set /a "size2=size+3"
echo ::%size% >%newshare%


echo ::Переменные заданы %oldserver% %newserver% >> %newshare%

 SetLocal enabledelayedexpansion
for /F "eol=T tokens=1,2,3 skip=6 delims= " %%a in (%source%) DO (
set status=%%a
set status1=!status!
set letter=%%b
set letter1=!letter!
set server=%%c
set server1=!server:~2,%size%!
echo ::"!letter!","%oldserver%","!server1:~0,%size%!","\\%newserver%\!server:~%size2%,10!">>%newshare%

IF /i "%oldserver%" EQU "!server1:~0,%size%!" echo net use !letter! /del /y >>%newshare%
IF /i "%oldserver%" EQU "!server1:~0,%size%!"  echo net use !letter! "\\%newserver%\!server:~%size2%,100!" %key% >>%newshare%
                                        )   
endlocal

call %newshare%
::IF %OS%==Windows_NT del %newshare%

@echo ***********************************************************
@echo *                                                        *
@echo *        Программа завершила все операции!!              *
@echo * Проверьте правильность переключения ресурсов с сервера: *
@echo *          %oldserver% на новый сервер %newserver%         
@echo *  При появлении ошибок обратитесь к администраторам    *
@echo *                                                        *
@echo ***********************************************************
pause
goto END

:ERR
@echo **********************************************************
@echo *                                                        *
@echo *        Не передан параметр в программу!!!            *
@echo * Парамеры запуска newmap [старый сервер] [новый сервер] *
@echo *          Пример:newmap server1 server2                *
@echo *                                                        *
@echo **********************************************************
pause
:END


mariolast 12-04-2007 12:30

Нету ли скрипта для установки программы Mobil Edit? С ключами тихая устанока не работает.

http://forum.ru-board.com/topic.cgi?...7&start=780#lt

amel27 16-04-2007 07:04

twincode
Цитата:

если присутствует меп на определенный серве перемепить его на другой
Может без NET USE устроит?
Код:

$ABC = "cdefghijklmnopqrstuvwxyz"
$oldShare = "\\server1\share1"
$newShare = "\\server2\share2"

For $i=1 To StringLen ($ABC)
    $drive = StringMid ($ABC, $i, 1) & ':'
    $share = DriveMapGet ($drive)
    If $share = $oldShare Then
        DriveMapDel ($drive)
        DriveMapAdd ($drive, $newShare)
    EndIf
Next


amel27 16-04-2007 09:01

Creat0R
Цитата:

Возможно ли как то адаптировать твою API-функцию _FileSelectFolder() чтобы деактивировалась (disabled) кнопка ОК пр выбранных папках которые немогут содержать (для “нормальной” записи) данные (такие как “Мой компьютер”, “Корзина”, “Сетевое окружение”, “Панель управления” и т.п)? это реально?
угу - нужно добавить флаг BIF_RETURNUNLYFSDIRS = 0x1
Код:

    ;...
    Local $ulf = BitOR (BitShift(BitAnd ($flags,1),-9), _
        BitShift(BitAnd ($flags,2),-5), _
        BitShift(BitAnd ($flags,4),-2), 1)
    ;...

Цитата:

И конечно очень хотелось бы всё таки иметь возможность указываь заранее исходный каталог (Init Dir).
понимаю, но к сожалению пока не вижу вариантов... :search:
Цитата:

Я тут уже почти доделал подобную функцию на обычном ГУИ, но у меня ушло более 5-сот строк кода и кучу времени на то чтобы построить этот недо-механизм... в общем получается но кривовато, и кажется очень не надёжно.
Количество строк пожалуй меньше не получится, но надежность можно повысить выделив в UDF специфические задачи хранения структуры каталогов в массиве, общее решение есть в любом учебнике по структурам данных, осталось только реализовать на AutoIT ;).

Creat0R 16-04-2007 16:04

amel27
Цитата:

нужно добавить флаг BIF_RETURNUNLYFSDIRS = 0x1
Работает! Спасибо!
Правда теперь можно использовать только $flags=1, иначе оно не работает :(

Цитата:

осталось только реализовать на AutoIT
Пытаюсь, пытаюсь... (уже получилось код сократить до 150-ти строк :) ).

sattva 16-04-2007 17:53

Подскажите как в AutoIT создать ярлык с зарание выбранной иконкой типа как в VB (Shortcut.IconLocation = WshShell.ExpandEnvironmentStrings("%SystemRoot%\system32\SHELL32.dll, 92"))

twincode 16-04-2007 19:57

amel27
Цитата:

Может без NET USE устроит?
Решение интересное.Спасибо.Задача правда немного другая.Бум считать что неизвестно на какую букву и на какой ресурс подмеплены пользователи.Нужно именно перемепить.

amel27 17-04-2007 05:46

Creat0R
Цитата:

Правда теперь можно использовать только $flags=1, иначе оно не работает
хм... действительно, по ходу этот флаг работает только со старым стилем окна

ADD: на форуме сабжа нашел DLL-ку, позволяющую реализовать CallBack-функциив AutoIT... Если устроит такой вариант можно попробовать для случая стартового каталога в самопальном _FileSelectFolder().

sattva
Смотри в справке функцию FileCreateShortcut(), 6-й и 8-й параметры задают файл и номер иконки в файле.

twincode
если имя шары не меняется, то можно и так:
Код:

$ABC = "cdefghijklmnopqrstuvwxyz"
$oldServer = "server1"
$newServer = "server2"

For $i=1 To StringLen ($ABC)
    $drive = StringMid ($ABC, $i, 1) & ':'
    $share = DriveMapGet ($drive)
    If $share <> "" Then
        $border = StringInStr ($share, '\' ,0 ,3)
        $server = StringMid ($share, 3, $border-3)
        $folder = StringMid ($share, $border)
        If $server = $oldServer Then
            DriveMapDel ($drive)
            DriveMapAdd ($drive, '\\' & $newServer & $folder)
        EndIf
    EndIf
Next


Creat0R 18-04-2007 03:41

amel27
Цитата:

Если устроит такой вариант можно попробовать для случая стартового каталога в самопальном _FileSelectFolder()
Устроит, почему бы и нет :), я хотя и не очень разбираюсь в Dll'ках, но мне кажется их использование довольно надёжно (или ошибаюсь?).

amel27 18-04-2007 06:27

Creat0R
Ну... при использовании штатных библиотек (поставляемых с операционной системой) придется сначала внимательно прочитать MSDN, так как варианты вызова обычно зависят от множества факторов типа версии Windows и пр. Если все требования соблюдены, то теоретически проблем не должно быть. Касаемо самопальных библиотек (типа той с форума) - тут все на совести их разработчика :) .

kreol 18-04-2007 14:27

я новичек в autoit
пытаюсь написать скрипт установки программы. дошел до окна, где нужно выбрать несколько чекбоксов и нажать "далее". Если все это делать с функциеей Send, и выставить побольше AutoItSetOption("SendKeyDelay", 150), товсе идет, а вот с функциеей ControlClick нет.
Флажки не ставятся, а сразу "Далее" (это если Send("!Д")) если Send("{ENTER}") или той же ControlClick просто стоит. До нажатия "далее" все работает. Я думал, что скрип выполняеться построчно ....Помогите разобраться

magnetikus 18-04-2007 20:17

Флажки можно поставить пробелом. Перескакивать между элементами - ТАВ
Кстати кто нибудь знает как при компиляции в скрипт загнать свои собственные файлы и папки - пишу собственный инсталлятор

Creat0R 18-04-2007 21:25

magnetikus
Цитата:

как при компиляции в скрипт загнать свои собственные файлы
См. в справке FileInstall() - на счёт папок не получится, нужно будет устанавливать файлы, и в процессе создавать папки (если в результате нужно чтобы файлы помещались в определённую папку).

kreol 19-04-2007 16:35

Цитата:

Флажки можно поставить пробелом. Перескакивать между элементами - ТАВ
Я так и делал
Send("{DOWN}")
Send("{DOWN}")
Send("{SPACE}")
Send("{DOWN}")
Send("{DOWN}")
Send("{ENTER}")
Send("{DOWN}")
Send("{DOWN}")
Send("{DOWN}")
Send("{DOWN}")
Send("{SPACE}")
Send("{DOWN}")
Send("{DOWN}")
Send("{ENTER}")
Send("{ENTER}")
Меня интересуе, почему при использовании ControlClick начинает исполняться Send("{ENTER}"), а предшевствующие ей ControlClick прорускаються?!

Dirk Diggler 23-04-2007 18:48

Как с пом. Autoit узнать список установленных обновлений ОС[и их версий] ?

amel27 24-04-2007 10:44

Dirk Diggler
например, из реестра... не понял насчет версий, как вариант - найти соотв. CAT-файл и восстановить его дату
Код:

#include <Array.au3>

$file = "C:\HotFixes.txt"
$aList = _GetHotFixes ()

$f = FileOpen ($file, 2)
For $i=1 To $aList[0][0]
    FileWrite ($file, $aList[$i][0] & @CRLF & $aList[$i][1] & @CRLF & $aList[$i][2] & @CRLF & @CRLF)
Next
FileClose ($f)

Func _GetHotFixes ()
    Local $i, $j, $k, $iKey, $jKey, $kKey
    Local Const $root1 = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\HotFix"
    Local Const $root2 = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Updates"
    Local $arrList[1] = [0], $arrHFix[1][3] = [[0,0,0]]
    $i=1
    While True
        $iKey = RegEnumKey ($root1, $i)
        If @error Then  ExitLoop
        $arrList[0]+=1
        ReDim $arrList[$arrList[0]+1]
        $arrList[$arrList[0]] = $iKey
        $i+=1
    Wend
    $i=1
    While True
        $iKey = RegEnumKey ($root2, $i)
        If @error Then  ExitLoop
        $j=1
        While True
            $jKey = RegEnumKey ($root2 & '\' & $iKey, $j)
            If @error Then  ExitLoop
            If _ArraySearch ($arrList, $jKey, 1) > 0 Then
                $arrHFix[0][0] +=1
                ReDim $arrHFix[$arrHFix[0][0]+1][3]
                $arrHFix[$arrHFix[0][0]][0]=$jKey
                $arrHFix[$arrHFix[0][0]][1]=$iKey
                $arrHFix[$arrHFix[0][0]][2]=RegRead ($root2 & '\' & $iKey & '\' & $jKey, 'Description')
                If @error Then $arrHFix[$arrHFix[0][0]][2]=RegRead ($root2 & '\' & $iKey & '\' & $jKey, 'PackageName')
            ElseIf StringRegExp ($jKey, '^SP[1-9]$') Then
                $k=1
                While True
                    $kKey = RegEnumKey ($root2 & '\' & $iKey & '\' & $jKey, $k)
                    If @error Then  ExitLoop
                    If _ArraySearch ($arrList, $kKey, 1) > 0 Then
                        $arrHFix[0][0] +=1
                        ReDim $arrHFix[$arrHFix[0][0]+1][3]
                        $arrHFix[$arrHFix[0][0]][0]=$kKey
                        $arrHFix[$arrHFix[0][0]][1]=$iKey
                        $arrHFix[$arrHFix[0][0]][2]=RegRead ($root2 & '\' & $iKey & '\' & $jKey & '\' & $kKey, 'Description')
                        If @error Then $arrHFix[$arrHFix[0][0]][2]=RegRead ($root2 & '\' & $iKey & '\' & $jKey, 'PackageName')
                    EndIf
                    $k+=1
                Wend
            EndIf
            $j+=1
        Wend
        $i+=1
    Wend
    Return $arrHFix
EndFunc


mrak1990 25-04-2007 20:53

Сделал недавно скрипт, в котором на одной из стадий заменяются три файла (именно в таком порядке):

c:\windows\system32\dllcache\Notepad.exe
c:\windows\system32\Notepad.exe
c:\windows\Notepad.exe

У меня на компе при этом выскакивает сообщение о том, что системные файлы были изменины. Ну я засунул в конец скрипта следующий код:

WinWaitActive ( "Защита файлов Windows", "Файлы, нужные для правильной работы Windows" )
ControlClick ( "Защита файлов Windows", "Файлы, нужные для правильной работы Windows", 2 )
WinWaitActive ( "Защита файлов Windows", "Вы отказались от восстановления исходных версий файлов." )
ControlClick ( "Защита файлов Windows", "Вы отказались от восстановления исходных версий файлов.", 6 )

На моём компе всё ставится отлично. А на компе одного из знакомых сообщение не выскакивает. Только происходит замена моего файла на стандартный. Не знаю, что и делать. Единственное отличие между компами: на моём нет никаких заплаток, тогда как у знакомо есть выделенка и стоит куча обновлений.

Creat0R 25-04-2007 21:26

mrak1990
Цитата:

на компе одного из знакомых сообщение не выскакивает
Так а в чём проблема? файлы ведь заменяются? зачем нужно это сообщение? :)

mrak1990 25-04-2007 22:43

Цитата:

mrak1990

Цитата:
на компе одного из знакомых сообщение не выскакивает


Так а в чём проблема? файлы ведь заменяются? зачем нужно это сообщение?
Я имел в виду следующее. Скрипт заменяет оригинальный файл Notepad.exe на мой. Но через некоторое время срабатывает защита от подмены файлов и Windows возвращает старый, оригинальный файл Notepad.exe.

Creat0R 25-04-2007 22:54

mrak1990
Цитата:

через некоторое время срабатывает защита от подмены файлов и Windows возвращает старый, оригинальный файл Notepad.exe.
А откуда она его берёт? наскольео я помню именно с c:\windows\system32\dllcache\Notepad.exe, может изменить последовательность замеы:

c:\windows\system32\dllcache\Notepad.exe
c:\windows\Notepad.exe
c:\windows\system32\Notepad.exe

mrak1990 25-04-2007 23:03

Из дистрибутива к Notepad++. Точнее, из аддона к этой проге, который заменяет блокнот на Notepad++.

mrak1990 26-04-2007 16:48

Появился вопрос насчёт работы AutoIt с SysTreeView321. А именно я бы хотел заставить работать с окном: Свойства папки. Но подходящих операторов что-то не нашёл. Только в папке Include есть файл с нужными функциями:


; _GUICtrlTreeViewDeleteItem
; _GUICtrlTreeViewExpand
; _GUICtrlTreeViewGetBkColor
; _GUICtrlTreeViewGetCount
; _GUICtrlTreeViewGetIndent
; _GUICtrlTreeViewGetLineColor
; _GUICtrlTreeViewGetParentHandle
; _GUICtrlTreeViewGetParentID
; _GUICtrlTreeViewGetState
; _GUICtrlTreeViewGetText
; _GUICtrlTreeViewGetTextColor
; _GUICtrlTreeViewGetTree
; _GUICtrlTreeViewInsertItem
; _GUICtrlTreeViewSelectItem
; _GUICtrlTreeViewSetBkColor
; _GUICtrlTreeViewSetIcon
; _GUICtrlTreeViewSetIndent
; _GUICtrlTreeViewSetLineColor
; _GUICtrlTreeViewSetState
; _GUICtrlTreeViewSetText
; _GUICtrlTreeViewSetTextColor
; _GUICtrlTreeViewSort


Но у меня такое ощущение, что они работают только с создаными GUI.

Creat0R 26-04-2007 17:39

mrak1990
Цитата:

Но у меня такое ощущение, что они работают только с создаными GUI.
Угу, эти функции предназначены только для работы с AutoIt'овским GUI.

Для управления внешними элементами, нужно пробовать ControlClick(), ControlCommand(), и им подобные.
Но именно со случаем Свойства папки будет сложновато, я как то пытался управлять элементами, но там идентификатор управляющих (Control ID) почти не распознаётся (программой Au3Info).

mrak1990 26-04-2007 18:01

Цитата:

mrak1990

Цитата:
Но у меня такое ощущение, что они работают только с создаными GUI.


Угу, эти функции предназначены только для работы с AutoIt'овским GUI.

Для управления внешними элементами, нужно пробовать ControlClick(), ControlCommand(), и им подобные.
Но именно со случаем Свойства папки будет сложновато, я как то пытался управлять элементами, но там идентификатор управляющих (Control ID) почти не распознаётся (программой Au3Info).
А ты какой Control ID имеешь ввиду? Всего дерева или отдельных пунктов? У всего дерева я знаю какой код: 30120
Сейчас попробовал повозиться с прогой Winspector. В конце концов нашёл команду, которая ставит или убирает галочку: TVM_SETITEMW

И плюс к этому прога выдаёт ещё какую-то инфу:

Item: 0*00094d88
Mask: TVIF_HANDLE | TVIF_IMAGE | TVIF_PARAM | TVIF_SELECTEDIMAGE | TVIF_TEXT
IParam: 0*000ee458
Text: Отображать "Панель управления" в папке "Мой компьютер"



Это вообще может как-то пригодиться?

Creat0R 26-04-2007 18:34

mrak1990
Цитата:

В конце концов нашёл команду, которая ставит или убирает галочку: TVM_SETITEMW
Как то так может:

Код:

Opt("WinTitleMatchMode", 4)
$hWnd = WinGetHandle("Свойства папки")

DllCall("user32.dll", "long", "SendMessage", "hwnd", $hWnd, "int", "TVM_SETITEMW", "int", "0*00094d88", "int", 0)

Это неверно, но направление кажется верное :)...

Все эти опции можно редактировать из реестра - HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced

mrak1990 26-04-2007 19:47

Цитата:

Как то так может:


Код:
Opt("WinTitleMatchMode", 4)
$hWnd = WinGetHandle("Свойства папки")

DllCall("user32.dll", "long", "SendMessage", "hwnd", $hWnd, "int", "TVM_SETITEMW", "int", "0*00094d88", "int", 0)

Это неверно, но направление кажется верное ...

А можно где-нибудь поподробнее узнать о синтаксисе?



Цитата:

Все эти опции можно редактировать из реестра - HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced
Просто уменя не пашет через реестр одна из опций: Скрывать защищённые системные файлы.

mrak1990 26-04-2007 20:37

В общем раскопал справочник по WinAPI. Но мне от него толку маловато:


Код:

Функция SendMessage

    Описание:
 function SendMessage(Wnd: HWnd; Msg, wParam: Word; lParam: Longint): Longint;

    Посылает сообщение оконной функции указанного окна. Возвpат из функции осуществляется только после обpаботки сообщения.

    Паpаметpы:
    Wnd: Окно, пpинимающее сообщение или $FFFF для посылки всем всплывающим окнам в системе.
    Msg: Тип сообщения.
    wParam: Дополнительная инфоpмация о сообщении.
    lParam: Дополнительная инфоpмация о сообщении.

    Возвpащаемое значение:
    Значение, возвpащенное пpинимающей оконной функцией.

 функция находится в файле user32.dll

Ну а это, я думаю все разобрались что такое:

Код:

DllCall ( "dll", "return type", "function" [, "type1", param1 [, "type n", param n]] )

В общем, кто хоть что-то в этом деле смыслит помогите разобраться.


Creat0R 26-04-2007 22:12

mrak1990
Цитата:

Просто уменя не пашет через реестр одна из опций: Скрывать защищённые системные файлы.
Всё очень просто:

Код:

RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced", "ShowSuperHidden", "REG_DWORD", 1) ;если 0, тогда файлы будут показываться.
Если нужно обновить программно все папки и даже рабочий стол, см. мою утилитку для отката расширении файлов и скрытых папок тут (исходники естественно в архиве прилагаются ;) ).

Цитата:

раскопал справочник по WinAPI
На русском? можно ссылку на источник?

qeraser 27-04-2007 11:11

Задача - запуск и работа 1с с конкретной конфигурацией с флэш-диска на любом компьютере.
Платформа + база находятся на флэш.
Т.е подключив флэшку и запустив 1с с нее же, загружалась нужная конфигурация.
Чтобы 1с видел базы пути к ним должны быть прописаны пути в реестре.

Я могу написать bat, au3 файл который вносил бы соотв. записи в реестр, но в путях к базам нужно указать букву диска. Проблема в том, что компьютеры разные, соответственно флэш-диск будет иметь разные буквы в системе.

Как можно поэлегантнее реализовать?

amel27 27-04-2007 12:12

qeraser

для BAT подстановка %~d0 возвращает букву диска, откуда запущен скрипт
для AU3 выражение StringLeft (@ScriptDir, 2) работает аналогично

qeraser 27-04-2007 12:49

amel27
Спасибо, разобрался :)

TERMINAL 27-04-2007 14:47

Как определить - есть ли на диске свободных 1 гиг, если есть то вывести сообщений №1, если нет-вывести сообщение №2?!

amel27
А возможно чтобы обновления записывальсь в текстовый файл?
где изменения сделать?

mrak1990 27-04-2007 15:51

Цитата:

На русском? можно ссылку на источник?
Без проблем:

http://foxpopuli.narod.ru/books/api_help.zip

mrak1990 27-04-2007 16:49

Creat0R
Код:

Func UpdateExplorer()
        Local $WinExpListArr = _ExplWinGetList()
        Local $OldOpt = Opt("WinTitleMatchMode", 4)
        Local $GetWinState, $Hwnd
        If IsArray($WinExpListArr) Then
                For $iWin = 1 To $WinExpListArr[0]
                        $GetWinState = WinGetState($WinExpListArr[$iWin])
                        $Hwnd = WinGetHandle($WinExpListArr[$iWin])
                        DllCall("user32.dll", "long", "SendMessage", "hwnd", $hWnd, "int", 0x111, "int", 28931, "int", 0)
                Next
        EndIf
       
        $Hwnd = WinGetHandle("classname=Progman")
        DllCall("user32.dll", "long", "SendMessage", "hwnd", $hWnd, "int", 0x111, "int", 28931, "int", 0)
        Opt("WinTitleMatchMode", $OldOpt)
EndFunc

Func _ExplWinGetList()
        Local $OldOpt = Opt("WinTitleMatchMode", 4)
        Local $WinList = WinList("classname=CabinetWClass")
        Opt("WinTitleMatchMode", $OldOpt)
        If IsArray($WinList) Then
                Local $WinListArr[$WinList[0][0]+1]
                For $iW = 1 To $WinList[0][0]
                        $WinListArr[$iW] = $WinList[$iW][0]
                Next
                $WinListArr[0] = $WinList[0][0]
                Return $WinListArr
        Else
                Return ""
        EndIf
EndFunc

У меня вопрос вот по этому коду. Можешь просто описать в общих чертах, как он работает?

Creat0R 27-04-2007 18:49

TERMINAL
Цитата:

Как определить - есть ли на диске свободных 1 гиг, если есть то вывести сообщений №1, если нет-вывести сообщение №2?!
Код:

$CD = "C:\"
$FreeSpace = DriveSpaceFree($CD)
If $FreeSpace >= 1024 Then
    MsgBox(64, "", "Ok, есть на диске <" & $CD & "> " & $FreeSpace & " мб свободного места.")
Else
  MsgBox(48, "", "На диске <" & $CD & "> не хватает свободного места (" & $FreeSpace & " мб).")
EndIf

mrak1990

Цитата:

Без проблем:
Спасибо!

Цитата:

Можешь просто описать в общих чертах, как он работает?
Конечно...

Первая функция ( UpdateExplorer() ), в начале использует вторую ( _ExplWinGetList() ), чтобы получить список заголовок всех окон которые являются папками (мы же не хотим обновлять к примеру Internet Explorer :) ).
Затем для каждого найденого окна (из полученного списка в массиве), происходит обновление (это делает вызов Dll), всё это в принципе для одной цели - обновить программно все открытые эксплореровские окна (в том числе и рабочий стол), не активируя их и не используя никаких посылании клавишь типа F5 :) , а просто прямой вызов функции (для конкретного окна) обновления окна (та же функция которая выполняется Windows после нажатия F5).

mrak1990 27-04-2007 18:53

Creat0R
Остался один вопрос. Для чего ты вызываешь два раза функцию DllCall? Один раз для папок, а другой для рабочего стола?

Creat0R 27-04-2007 19:10

mrak1990
Цитата:

Для чего ты вызываешь два раза функцию DllCall? Один раз для папок, а другой для рабочего стола?
Да, для рабочего стола класс заголовка окнка немного другой, поэтому получить его из списка одновременно не получается... хотя можно было конечно во второй функции добавить последний элемент в массив который содержал бы заголовок окна для рабочего стола, но так тоже нормально работает :)

И ещё, $GetWinState = WinGetState($WinExpListArr[$iWin]) там уже лишнее, это раньше у меня не получалось напрямую обновлять окна, поэтому приходилось активировать их, посылать им обновление, и затем возвращать окно в исходное положение (свёрнутое/развёрнутое, активное/не активное).

Вот обновил функции, теперь список всех окон возвращается средствами функции _ExplWinGetList(), а также убрал лишние строчки:

Код:

Func UpdateExplorer()
    Local $OldOpt = Opt("WinTitleMatchMode", 4)
    Local $WinExpListArr = _ExplWinGetList()
    Local $Hwnd
    If IsArray($WinExpListArr) Then
        For $iWin = 1 To $WinExpListArr[0]
            $Hwnd = WinGetHandle($WinExpListArr[$iWin])
            DllCall("user32.dll", "long", "SendMessage", "hwnd", $hWnd, "int", 0x111, "int", 28931, "int", 0)
        Next
    EndIf
    Opt("WinTitleMatchMode", $OldOpt)
EndFunc

Func _ExplWinGetList()
    Local $WinList = WinList("classname=CabinetWClass")
    If IsArray($WinList) Then
        Local $WinListArr[$WinList[0][0]+2]
        For $iW = 1 To $WinList[0][0]
            $WinListArr[$iW] = $WinList[$iW][0]
        Next
        $WinListArr[0] = $WinList[0][0]+1
        $WinListArr[$WinListArr[0]] = "classname=Progman"
        Return $WinListArr
    Else
        Return ""
    EndIf
EndFunc


mrak1990 28-04-2007 00:20

Creat0R
Разобрался наконец с твоим скриптом. Но остался один маленький вопросик:
Код:

Local $WinListArr[$WinList[0][0]+2]
В скриптах AutoIT нужно при объявлении массива указывать в квадратных скобках число элементов? Если так, то почему ты приписываешь "+2", а не "+1"?

Creat0R 28-04-2007 00:49

mrak1990
Цитата:

почему ты приписываешь "+2", а не "+1"?
Функция WinList возвращает массив заголовок окон, но в этом массиве нет заголовка для рабочего стола, поэтому при объявлении массива требуется увеличить его на один элемент, в момент обработки массива он остаётся пустым, но в конце функции я задаю этому пустому элементу значение ровняющееся заголовку рабочего стола ($WinListArr[$WinListArr[0]] = "classname=Progman"), чтобы в родительской функции ( UpdateExplorer() ) небыло необходимости в определении заголовка для рабочего стола, он будет браться их возвращённого массива (последний элемент).

mrak1990 28-04-2007 00:57

Creat0R
Я всё это понял. Просто для чего два дополнительных элемента?

Creat0R 28-04-2007 02:36

mrak1990
Цитата:

для чего два дополнительных элемента?
Когда объявляем массив, нужно добавлять ещё один элемент, который будет содержать общее число элементов, в данном случае, нужно два (т.е тоже число элемнтов как и у массива возвращённого от WinList, плюс один элемент (WinList[0][0] содержит общее число элементов этого массива)), а дополнительный для того чтобы поместить в него ещё один заголовок окна (рабочего стола)...

Можно конечно и обойтиться +2, вот так:

Код:

Func _ExplWinGetList()
    Local $WinList = WinList("classname=CabinetWClass")
    If IsArray($WinList) Then
        Local $WinListArr[UBound($WinList)+1]
        For $iW = 1 To $WinList[0][0]
            $WinListArr[$iW] = $WinList[$iW][0]
        Next
        $WinListArr[0] = $WinList[0][0]+1
        $WinListArr[$WinListArr[0]] = "classname=Progman"
        Return $WinListArr
    Else
        Return ""
    EndIf
EndFunc

В этом случае Ubound($WinList) ровняется WinList[0][0]+1 (нуливой элемент содержащий общее количество элементов, и все остальные элементы), поэтому мы добавляем только +1.

amel27 28-04-2007 12:42

TERMINAL
Цитата:

А возможно чтобы обновления записывальсь в текстовый файл?
где изменения сделать?
подправил скрипт для случая файла и исправил один недочет в скрипте...

З.Ы. имхо скрипт не очень практичен, но не если есть интерес принимаются любые предложения по доработке... заодно можно придать более внятный вид - по аналогии с энумераторами RegEnum* с индексом... типа HotFixEnum

Diamond 28-04-2007 15:25

Защита от повторного запуска
P.S. Просьба, не тестировать этот скрипт из редактора.
Код:

$objService=ObjGet("winmgmts:{impersonationLevel=impersonate}!\\.\root\CIMV2")
$colProc=$objService.ExecQuery("SELECT * FROM Win32_Process WHERE CommandLine LIKE '%" & @ScriptName & "%'")
If $colProc.Count > 1 Then
    Msgbox(0+48,"Совпадений: " & $colProc.Count,"Скрипт уже запущен")
    Exit(1)
EndIf
;~ --== Здесь должен быть код Вашего скрипта ==--

Отслеживание вновь запущенных процессов:
Код:

$strComputer = "."
$objWMIService = ObjGet("winmgmts:" & _
"{impersonationLevel=impersonate}!\\" & $strComputer & "\root\cimv2")
$colMonitoredProcesses=$objWMIService.ExecNotificationQuery("select * from __instancecreationevent " & _ 
" within 1 where TargetInstance isa 'Win32_Process'")
While 1
$objLatestProcess = $colMonitoredProcesses.NextEvent
MsgBox(0,"Обнаружен запуск",$objLatestProcess.TargetInstance.Name)
WEnd

Отслеживание завершающихся процессов:
Код:

$strComputer = "."
$objWMIService = ObjGet("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & $strComputer & "\root\cimv2")
$colMonitoredProcesses = $objWMIService.ExecNotificationQuery("select * from __instancedeletionevent " _ 
& "within 1 where TargetInstance isa 'Win32_Process'")
While 1
$objLatestProcess = $colMonitoredProcesses.NextEvent
MsgBox(0,"Обнаружено завершение",$objLatestProcess.TargetInstance.Name)
WEnd

Отследить запуск определённого процесса:
Код:

$process='notepad.exe'
$strComputer = "."
$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
$objEvents = $objWMIService.ExecNotificationQuery _
("SELECT * FROM Win32_ProcessStartTrace WHERE ProcessName = '" & $process & "'")
MsgBox(0,"","Ожидание событий ...")
While 1
    $objReceivedEvent = $objEvents.NextEvent
    MsgBox(0,"",$process & " запущен")
WEnd

Отследить завершение определённого процесса:
Код:

$process='notepad.exe'
$strComputer = "."
$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
$objEvents = $objWMIService.ExecNotificationQuery _
("SELECT * FROM Win32_ProcessStopTrace WHERE ProcessName = '" & $process & "'")
MsgBox(0,"","Ожидание событий ...")
While 1
    $objReceivedEvent = $objEvents.NextEvent
    MsgBox(0,"",$process & " завершён")
WEnd

А этот скрипт я как-то писал для отслеживания вируса по его PID (долгая история...)
С его помощью можно определить, какие программы запускали на компьютере в ваше отсутствие,
остаётся только перенаправить информацию в текстовой файл...
Код:

#Include <date.au3>
$strComputer = "."
$objWMIService = ObjGet("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & $strComputer & "\root\cimv2")
$colMonitoredProcesses = $objWMIService.ExecNotificationQuery("select * from __instancedeletionevent " _ 
& "within 1 where TargetInstance isa 'Win32_Process'")
While 1
$objLatestProcess = $colMonitoredProcesses.NextEvent
$pdel = _Now()
MsgBox(0,"", "Имя: " & $objLatestProcess.TargetInstance.Name  & @CRLF & _
"Расположение: " & $objLatestProcess.TargetInstance.ExecutablePath & @CRLF & _
"Командная строка: " & $objLatestProcess.TargetInstance.CommandLine & @CRLF & _
"PID: " & $objLatestProcess.TargetInstance.ProcessId & @CRLF & _
"Приоритет: " & $objLatestProcess.TargetInstance.Priority & @CRLF & _
"Время запуска:        " & WMIDateStringToDate($objLatestProcess.TargetInstance.CreationDate) & @CRLF & _
"Время завершения: " & $pdel & @CRLF & _
"____________________________________")
WEnd

;###########################################
Func WMIDateStringToDate($str)
Local $WMIDateStringToDate
If not $str = "" Then
        $WMIDateStringToDate=StringMid($str,7,2) & '.' & StringMid($str,5,2) & '.' & _
        StringLeft($str,4) & chr(32) & StringMid($str,9,2) & ':' & _
        StringMid($str,11,2) & ':' & StringMid($str,13,2)
EndIf
Return $WMIDateStringToDate
EndFunc

З.Ы.
Не мешало бы скрыть присутствие скрипта в списке процессов.
Слышал, что это можно сделать через WinApi, но я не знаю как...

Creat0R 28-04-2007 16:34

Diamond
Хорошие функции!

Правда с первой что-то не получается :(
При первом запуске выдаёт два совпадения и что скрипт уже запущен, хотя это не так.

P.S
Это только если имя скрипта test.au3, в других случаях вроде всё нормально.

Кстати, а можно ли как то получить список скрытых процессов?

mrak1990 28-04-2007 18:33

Creat0R
Я тут переписал твой скрипт в таком виде, в каком, как мне кажется проще его понять начинающим. Плюс добавил комментарии. Вот что из этого получилось.
Код:

#cs
;~ Toogle Hidden folders and files program - This is AutoIt source code (AutoIt vesrion 3.2.2.0).
;~ Author: G.Sandler a.k.a CreatoR - http://creator-lab.ucoz.ru
;~ ICQ: 5607655
#ce

#NoTrayIcon

$RegKey = "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
If RegRead($RegKey, "Hidden") = 1 Then
        RegWrite($RegKey, "Hidden", "REG_DWORD", 2)
Else
        RegWrite($RegKey, "Hidden", "REG_DWORD", 1)
EndIf

UpdateExplorer()

Func UpdateExplorer()
    Local $OldOpt = Opt("WinTitleMatchMode", 4) ;Устанавливаем параметр AutoIT, отвечающий за идендификацию окон
    Local $WinExpListArr = _ExplWinGetList() ;Получаем массив, возвратённый функцией "_ExplWinGetList"
    Local $Hwnd
    If IsArray($WinExpListArr) Then
        For $iWin = 1 To $WinExpListArr[0]
            $Hwnd = WinGetHandle($WinExpListArr[$iWin])
            DllCall("user32.dll", "long", "SendMessage", "hwnd", $hWnd, "int", 0x111, "int", 28931, "int", 0) ;Посылаем команду на обновление всех папок и Рабочего стола
        Next
    EndIf
    Opt("WinTitleMatchMode", $OldOpt) ;Устанавливаем старое значение параметра AutoIT, отвечающего за идендификацию окон
EndFunc

Func _ExplWinGetList()
    Local $WinList = WinList("classname=CabinetWClass")  ;Получаем массив, содержащий список открытых папок и их HWND
    If IsArray($WinList) Then
        Local $WinListArr[UBound($WinList)+1] ;Создаём новый массив, который будет содержать ТОЛЬКО ИМЕНА папок, CLASSNAME Рабочего стола и кол-во элементов в массиве
                $WinListArr[0] = $WinList[0][0]+1 ;Присваеваем нулевому элементу массива число, содержащее кол-во элементов в массиве
        $WinListArr[$WinListArr[0]-1] = "classname=Progman" ;Присваиваем последнему элементу массива "Classname" Рабочего стола
        For $iW = 1 To $WinListArr[0]-2 ;Вычесть двойку нужно из-за того, что первый и последний элемент массива не содержат имен папок
            $WinListArr[$iW] = $WinList[$iW][0] ;Присваиваем первому и всем последующим элементам массива названия открытых окон
        Next
        Return $WinListArr ;Возвращаем массив, содержащий список всех окон, "Classname" Рабочего стола и кол-во элементов в массиве
    Else
        Return ""
    EndIf
EndFunc


Creat0R 28-04-2007 21:33

mrak1990
Цитата:

Я тут переписал твой скрипт в таком виде, в каком, как мне кажется проще его понять начинающим. Плюс добавил комментарии.
Спасибо.

Правда комментарии немного не точные, так будет правильнее (также немного изменил функции, раньше если небыло найдено окон, то рабочий стол тоже не обновлялся, а также во второй функции сразу помещаются в массив уникальные идентификаторы (hWnd), чтобы не нужно было их определять в первой функции - они ведь возвращаются от WinList() ):

Код:

Func _UpdateExplorer()
    ;Устанавливаем параметр, отвечающий за метод распознвания заголовок окон (4 - самый чувствительный),
    ;и помещаем в переменную $OldOpt исходное значение этого параетра.
    Local $OldOpt = Opt("WinTitleMatchMode", 4)
    ;Получаем массив содержащий заголовки окон проводника Windows вкдючая Рабочего стола (по средствам функции _ExplWinGetList).
    Local $WinExpListArr = _ExplWinGetList()
    ;Если возвратился массив (а значит найдены заголовки окон),
    ;то перебираем весь массив, с целью обновления каждого окна (по его заголовку из элементов массива).
    If IsArray($WinExpListArr) Then
        For $iWin = 1 To $WinExpListArr[0]
            ;Вызов функции для обновления текущего окна
            ;(по уникальному идентификатору который содержится в текущем элементе массива).
            DllCall("user32.dll", "long", "SendMessage", "hwnd", $WinExpListArr[$iWin], "int", 0x111, "int", 28931, "int", 0)
        Next
    Else
        ;Если не вернулся массив (значит небыли найдены окна проводника), тогда обновляем только Рабочий стол
        ;(переменная $WinExpListArr теперь содержит только один уникальный идентификатор Рабочего стола).
        DllCall("user32.dll", "long", "SendMessage", "hwnd", $WinExpListArr, "int", 0x111, "int", 28931, "int", 0)
    EndIf
    ;Устанавливаем исходное значение (заданное значение при входе в функцию) параметра,
    ;отвечающего за метод распознвания заголовок окон.
    Opt("WinTitleMatchMode", $OldOpt)
EndFunc

Func _ExplWinGetList()
    ;Получаем массив, содержащий список существующих заголовок окон проводника Windows (Explorer),
    ;и их уникальный идентификатор (hWnd).
    Local $WinList = WinList("classname=CabinetWClass")
    ;Если вернулся массив (а значит найдено одно или более окон), тогда делаем перебор по массиву,
    ;в целях отсеивания только уникальных идентификаторов существующих окон (проводника Windows).
    If IsArray($WinList) Then
        ;Объявляем массив, который будет собдержать список уникальных идентификаторов существующих окон.
        Local $WinListArr[UBound($WinList)+1]
        ;Перебираем полученный массив $WinList, и отсеиваем в новый массив $WinListArr
        ;только уникальные идентификаторы окон Explorer.
        For $iW = 1 To $WinList[0][0]
            $WinListArr[$iW] = $WinList[$iW][1]
        Next
        ;Присваеваем нулевому элементу нового массива ($WinListArr), значение ровняющееся общему количеству элементов в этом массиве.
        $WinListArr[0] = UBound($WinListArr)-1
        ;Присваиваем последнему элементу этого же массива, уникальный идентификатор (основываясь на "Classname") Рабочего стола.
        $WinListArr[$WinListArr[0]] = WinGetHandle("classname=Progman")
        ;Возвращаем массив, содержащий список идентификаторов всех существующих окон проводника (вкючая Рабочего стола).
        Return $WinListArr
    Else
        ;Если функция WinList() не "вернула" массив (а значит небыло найдено окон проводника),
        ;тогда возвращаем только один уникальный идентификатор Рабочего стола.
        Return WinGetHandle("classname=Progman")
    EndIf
EndFunc


amel27 29-04-2007 10:08

Diamond
Цитата:

Не мешало бы скрыть присутствие скрипта в списке процессов.
Слышал, что это можно сделать через WinApi, но я не знаю как...
вот вариант на основе скрипта с оффсайта, к сожалению он полезен только в учебных целях...
с другой стороны, все остальные способы будут оффтопом для этой ветки. ;)
Код:

$process = "script.exe"

While 1
    WinWait ("Диспетчер задач Windows")
    $index = ControlListView ("Диспетчер задач Windows", "", 1009, "FindItem", $process)
    If $index = -1 Then
        Sleep(5)
    Else
        $hwnd = ControlGetHandle ("Диспетчер задач Windows", "", 1009)
        DllCall("user32.dll", "int", "SendMessage", "hwnd", $hwnd, "int", 0x1008, "int", $index, "int", 0)
    EndIf
Wend


Diamond 29-04-2007 12:39

Creat0R
Цитата:

При первом запуске выдаёт два совпадения и что скрипт уже запущен, хотя это не так.
У меня всё нормально, хотя если запускать его из редактора то обнаруживается лишнее "совпадение".
Цитата:

Кстати, а можно ли как то получить список скрытых процессов?
Думаю, что процесс будет скрыт только от "Диспетчера задач Windows" и подобных ему, т.е. от WMI он не скроется.

amel27
Цитата:

к сожалению он полезен только в учебных целях...
Действительно к сожалению...
Наверное что-то вроде этого я и искал, но не ожидал что это будет работать именно так...
В любом случае, Спасибо!
Цитата:

все остальные способы будут оффтопом для этой ветки.
Любой способ который можно использовать в AutoIT, или который имеет прямое отношение к скрипту AutoIT, разве это оффтоп? Хотя...

Скажем, я хочу знать какие программы запускали на моём компьютере в моё отсутствие.
Проблема в том, что более опытный юзер может легко обнаружить и завершить мой "шпионский" процесс.
У меня возникла идея не скрывать, а просто сделать невозможным его завершение, т.е. скомпилировать скрипт и назвать его к примеру lsass.exe.
Хотя и примитивно - зато надёжно. ;)


Diamond 29-04-2007 14:40

Creat0R
Я понял почему обнаруживается совпадение. Если открыть скрипт в редакторе (даже незапускать) то командная строка редактора будет содержать путь к скрипту, а это уже одно "совпадение".
Попробуй закрыть редактор и запустить скрипт снова. ;)

Creat0R 29-04-2007 16:25

Diamond
Цитата:

если запускать его из редактора то обнаруживается лишнее "совпадение"
Я запускал сам скрипт, редактор вовсе не открывал (с браузера сразу скрипт пишется на рабочий стол ;) - кстати если интересно, могу выложить тут небольшой код). Но как я упоминул, скрипт именуется как test.au3, при другом имени всё вроде ок, даже и не знаю почему так (может у меня уже запущен подобный скрипт, и он не виден в диспетчере задач :idontnow: ).




Есть у меня один вопрос - как можно проверить определённое окно, на наличие ControlID, но способ нужен надёжный, я написиал вот такую функцию (см. далее), но она не везде срабатывает, к примеру в браузере Opera, возвращаются не все ControlID, хотя в Au3Info.exe нужные (мне, для проверки) ControlID видны:

Код:

Func _ControlIDIsExists($hWnd, $ControlID)
    If Not IsHWnd($hWnd) Then $hWnd = WinGetHandle($hWnd)
    If Not WinExists($hWnd) Then Return SetError(1, 0, 0)
    Local $ClassesArr = StringSplit(WinGetClassList($hWnd), @LF)
    If IsArray($ClassesArr) Then
        For $i = 1 To UBound($ClassesArr)-1
            If $ClassesArr[$i] = $ControlID Then Return True
        Next
    EndIf
    Return False
EndFunc


amel27 29-04-2007 19:06

Diamond
Цитата:

Скажем, я хочу знать какие программы запускали на моём компьютере в моё отсутствие.
Проблема в том, что более опытный юзер может легко обнаружить и завершить мой "шпионский" процесс.
У меня возникла идея не скрывать, а просто сделать невозможным его завершение, т.е. скомпилировать скрипт и назвать его к примеру lsass.exe.
угу, типичное поведение трояна... Проблема в том, что "мимикрия", хуки и прочие фокусы могут конфликтовать с настройками безопасности системы, а также перехватываться антивирусами и файерволами. На самом деле задача регистрации запускаемых файлов решается штатными средствами администрирования, без привлечения программ-шпионов и прочих ухищрений - прежде всего это средства аудита файловой системы, кроме того можно оформить подписку на любые системные WMI-события... никаких "левых" процессов при этом не создается, т.к. все выполняется средствами системы. Именно это я и имел ввиду говоря про оффтоп...

Creat0R
Цитата:

Есть у меня один вопрос - как можно проверить определённое окно, на наличие ControlID
ControlGetHandle() не устраивает? Кстати, почему именно ControlID?.. а если скажем ClassName?

Creat0R 29-04-2007 23:18

amel27
Цитата:

ControlGetHandle() не устраивает?
Я не уверен что понял... ControlGetHandle() вернёт hWnd, а мне нужно проверить наличие Control.

Цитата:

почему именно ControlID?.. а если скажем ClassName?
Мне не важно, мне нужно проверить существование Control...
Дело в том, что в разных версиях определённой программы (в этом случае браузер Opera), меняются постоянно(?) ClassNameNN/ControlID, вот мне нужно как то проверить, существует ли в текущей версии определённый Control, если нет, то я буду перебирать их последовательность (обычно меняется только цифра).
К примеру вот такой класс - "OperaWindowClass14" - нужно проверить, есть ли он в программе (в окне), не смистился ли.

amel27 30-04-2007 05:52

Creat0R
Цитата:

Я не уверен что понял... ControlGetHandle() вернёт hWnd, а мне нужно проверить наличие Control.
…ну, в смысле если контрола нет, то и не вернет hwid... Зачем тянуть весь список, если нужно проверить только один?

Цитата:

Мне не важно, мне нужно проверить существование Control...
есть такой фокус, когда для поиска контролов используется функция поиска окон... так как контрол по сути то же окно, только дочернее. К сожалению штатный "AutoIt Window Info" не показывает информацию о "хозяине" для дочерних окон, я использовал HwndSpy... жаль он шароварный. :(
Код:

; Поиск Control по его классу (аналогично можно сделать и по заголовку)
; штатными средствами и через API, на примере CsiTE4

$WinClass = "SciTEWindow"          ; Класс головного окна
$CtrlClass1 = "SciTEWindowContent" ; Класс дочернего окна 1-го уровня
$CtrlClass2 = "Scintilla"          ; Класс дочернего окна 2-го уровня

; Поиск средствами API
$hAPI0 = DLLCall ("user32.dll", "hwnd", "FindWindow", _
    "str", $WinClass, _
    "int", 0 )
$hAPI1 = DllCall ("user32.dll", "hwnd", "FindWindowEx", _
    "hwnd", $hAPI0 [0], _
    "int", 0 , _
    "str", $CtrlClass1, _
    "int", 0 )
$hAPI2 = DllCall ("user32.dll", "hwnd", "FindWindowEx", _
    "hwnd", $hAPI1 [0], _
    "int", 0 , _
    "str", $CtrlClass2, _
    "int", 0 )

; Поиск штатными средствами AutoIT через поиск контрола
$BakWTM = Opt ("WinTitleMatchMode", 4) ; Включаем поиск по классам
$hCtrl = ControlGetHandle("classname=" & $WinClass, '', 350)

; Поиск штатными средствами AutoIT через поиск окна
$BakWSC = Opt ("WinSearchChildren", 1) ; Включаем поиск по вложенным окнам
$hWind = WinGetHandle ("classname=" & $CtrlClass2)

; Вывод результата:
MsgBox (0, 'Test',  'WinAPI:' & @TAB & 'ClassName' & @TAB & $hAPI2 [0] & @CRLF & _
                    'AutoIT:' & @TAB & 'ControlID ' & @TAB & $hCtrl & @CRLF & _
                    'AutoIT:' & @TAB & 'ClassName'  & @TAB & $hWind & @CRLF )
; Возвращаем настройки
Opt ("WinTitleMatchMode", $BakWTM)
Opt ("WinSearchChildren", $BakWSC)


Creat0R 30-04-2007 07:28

amel27
Цитата:

…ну, в смысле если контрола нет, то и не вернет hwid... Зачем тянуть весь список, если нужно проверить только один?
Хм, а я как то не подумал в эту сторону (видимо нужно раньше ложиться спать :biggrin: ), спасибо!

Цитата:

есть такой фокус, когда для поиска контролов используется функция поиска окон... так как контрол по сути то же окно, только дочернее.
Вот за эту инфу тоже спасибо, не знал что контроли могут распознваться используя функции поиска окон, и также не знал (из самой функции) что можно подбирать ControlID через classname=....

Цитата:

я использовал HwndSpy... жаль он шароварный.
Есть WinSpy... бесплатный вроде, но не уверен что он отдаёт нужную инфу.

Спасибо ещё раз большое за пример/инфу, буду пробовать это использовать :) .

Diamond 30-04-2007 08:48

Creat0R
Процесс в котором обнаруживается совпадение, скорее всего виден в Диспетчере задач.
Попробуй индифицировать его по параметрам командной строки:
Код:

$CommandString='Test.au3'

;~ Соединяемся с WMI
$objService = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\.\root\CIMV2")
;~ Задаём параметры объекта
$colProc = $objService.ExecQuery("SELECT * FROM Win32_Process WHERE CommandLine LIKE '%" & $CommandString & "%'")
;~ Цикл по элементам объекта-коллекции
For $Proc In $colProc
Msgbox(0+48,"Обнаружен процесс: " & $Proc.name,"Командная строка запуска:" & @CR & $Proc.CommandLine)
Next


amel27 30-04-2007 18:44

Creat0R

Краткий (промежуточный) отчет о самопальных _FileSelectFolder и подобных функций… На время их активности действительно прерывается любая работа AutoIT-скрипта, причем отключаются все механизмы диспетчеризации вызовов, включая AdLib и GUIRegisterMsg. Впрочем, это вполне логично, так как управление полностью передается системной функции. Отсюда становится понятно, почему разработчики не внесли функциональность HWID в свои функции выбора… просто они не стали заморачиваться разработкой своих функций, а взяли те же системные API-функции (aka wrapper).

Особенность _FileSelectFolder (и аналогичных) в том, что ее поведение управляется набором специальных сообщений SendMessage, которые:
- функция может инициализировать себе сама через вызов специальной (CallBack) функции,
- окно выбора может получить извне.

Первый случай не реализуем средствами AutoIT по причине отсутствия поддержки указателей на функцию. Это ограничение можно обойти подключением внешних DLL, содержащих требуемые функции и способных возвращать их указатели. Одна из таких реализаций предложена на форуме оффсайта, к сожалению, она не подходит для нашего случая по указанным ранее причинам, так как опирается на механизм GUIRegisterMsg… Поэтому потребуется писать свою специфическую DLL, либо расширить функциональность предложенной – в любом случае это придется делать на чем-то другом, отличном от AutoIT - способном компилировать DLL, дружить с GUI и обязательно фриварном.

Второй случай в принципе можно реализовать на AutoIT, но потребуется дополнительный скрипт, управляющий поведением основного на время выполнения системных функций выбора… при этом придется решить ряд вопросов по синхронизации этих процессов. Кроме того, этот вариант очень ограничен по функциональности, так как управляющий скрипт не будет получать информации о состоянии окна главного скрипта (оперативные сообщения). Например, можно попытаться задать начальную папку или текст статусной строки, но управлять кнопкой «Ok» или реагировать на ошибки ввода не получится.

mrak1990 30-04-2007 20:59

Creat0R
Взял на себя смелость собрать дистрибутив этой проги (выглядит он точно так же), чтобы ты его у себя на сайте обновил. В коде ничего не мнеял. Только опечатки убрал:
Код:

#cs
;~ Toogle Hidden folders and files program - This is AutoIt source code (AutoIt vesrion 3.2.2.0).
;~ Author: G.Sandler a.k.a CreatoR - http://creator-lab.ucoz.ru
;~ ICQ: 5607655
#ce

#NoTrayIcon

$RegKey = "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
If RegRead($RegKey, "Hidden") = 1 Then
        RegWrite($RegKey, "Hidden", "REG_DWORD", 2)
Else
        RegWrite($RegKey, "Hidden", "REG_DWORD", 1)
EndIf

UpdateExplorer()

Func _UpdateExplorer()
    ;Устанавливаем параметр, отвечающий за метод распознавания заголовок окон (4 - самый чувствительный),
    ;и помещаем в переменную $OldOpt исходное значение этого параметра.
    Local $OldOpt = Opt("WinTitleMatchMode", 4)
    ;Получаем массив, содержащий заголовки окон проводника Windows (включая Рабочего стола), по средствам функции _ExplWinGetList.
    Local $WinExpListArr = _ExplWinGetList()
    ;Если возвратился массив (а значит найдены заголовки окон),
    ;то перебираем весь массив, с целью обновления каждого окна (по его hWnd из элементов массива).
    If IsArray($WinExpListArr) Then
        For $iWin = 1 To $WinExpListArr[0]
            ;Вызов функции для обновления текущего окна
            ;(по уникальному идентификатору, который содержится в текущем элементе массива).
            DllCall("user32.dll", "long", "SendMessage", "hwnd", $WinExpListArr[$iWin], "int", 0x111, "int", 28931, "int", 0)
        Next
    Else
        ;Если не вернулся массив (значит не были найдены окна проводника), тогда обновляем только Рабочий стол
        ;(переменная $WinExpListArr теперь содержит только один уникальный идентификатор Рабочего стола).
        DllCall("user32.dll", "long", "SendMessage", "hwnd", $WinExpListArr, "int", 0x111, "int", 28931, "int", 0)
    EndIf
    ;Устанавливаем исходное значение (заданное значение при входе в функцию) параметра,
    ;отвечающего за метод распознавания заголовок окон.
    Opt("WinTitleMatchMode", $OldOpt)
EndFunc

Func _ExplWinGetList()
    ;Получаем массив, содержащий список существующих заголовок окон проводника Windows (Explorer),
    ;и их уникальный идентификатор (hWnd).
    Local $WinList = WinList("classname=CabinetWClass")
    ;Если вернулся массив (а значит найдено одно или более окон), тогда делаем перебор по массиву,
    ;в целях отсеивания только уникальных идентификаторов существующих окон (проводника Windows).
    If IsArray($WinList) Then
        ;Объявляем массив, который будет содержать список уникальных идентификаторов существующих окон.
        Local $WinListArr[UBound($WinList)+1]
        ;Перебираем полученный массив $WinList, и отсеиваем в новый массив $WinListArr
        ;только уникальные идентификаторы окон Explorer.
        For $iW = 1 To $WinList[0][0]
            $WinListArr[$iW] = $WinList[$iW][1]
        Next
        ;Присваиваем нулевому элементу нового массива ($WinListArr), значение ровняющееся общему количеству элементов в этом массиве.
        $WinListArr[0] = UBound($WinListArr)-1
        ;Присваиваем последнему элементу этого же массива, уникальный идентификатор (основываясь на "Classname") Рабочего стола.
        $WinListArr[$WinListArr[0]] = WinGetHandle("classname=Progman")
        ;Возвращаем массив, содержащий список идентификаторов всех существующих окон проводника (включая Рабочего стола) и
        ;общее кол-во элементов в этом массиве
        Return $WinListArr
    Else
        ;Если функция WinList() не "вернула" массив (а значит не было найдено окон проводника),
        ;тогда возвращаем только один уникальный идентификатор Рабочего стола.
        Return WinGetHandle("classname=Progman")
    EndIf
EndFunc

Вот ссылка: http://ifolder.ru/1856047

P.S. Единственное, что я не смог изменить, это информацию о файле (вкладка "Версия"). Одна программа при изменении коверкает, другая не хочет сохранять.

Creat0R 30-04-2007 23:39

Diamond
Цитата:

Процесс в котором обнаруживается совпадение, скорее всего виден в Диспетчере задач.
Неа, не видно :)

Цитата:

Попробуй индифицировать его по параметрам командной строки:
Тоже нету :idontnow:
Я не уверен что это корректный способ проверять вторичный запуск скрипта, ведь подобных процессов может быть запущено несколько, и тогда проверка провалится (выдаст что уже запущен процесс)... вроде _Singleton() хорошо справляется с этой задачей.


amel27
Цитата:

Второй случай в принципе можно реализовать на AutoIT, но потребуется дополнительный скрипт, управляющий поведением основного на время выполнения системных функций выбора
Можно использовать тот же скрпт, но запускать его (до/в процессе вызова функции) с параметрами ком. строки, в которых кстати можно и передавать разного рода информацию нужную для идентификации запускаемого окна. А в начале скрипта поставить распознавание этой самой ком. строки - один минус, будет запущено два процесса одного скрипта.

Цитата:

можно попытаться задать начальную папку или текст статусной строки
Смутно себе представляю как можно извне задать начальную папку (речь ведь идёт о функции _FileSelectFolder() ?), я ещё не встречал функции которые способны раскрывать дерево папок во внешних приложениях (окон) основываясь на обычных данных (имя папки в данном случае), не на основе идентификаторов (типа ControlID).

mrak1990
Цитата:

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

mrak1990 01-05-2007 00:17

Creat0R
Цитата:

Там установщик для каких целей? помещает ярлыки? хотелось бы реализовать помещение пункта в контекстное меню проводника, тогда это было бы весьма полезно.
Если честно, то я просто сделал архив подобный тому, что висит у тебя на сайте... Но идея, предложенная тобой кажется мне очень удачной. Сегодня же возьмусь за её реализацию.


P.S. Так что пока можешь не скачивать выложенный мною архив.

amel27 01-05-2007 06:29

Creat0R
Цитата:

Смутно себе представляю как можно извне задать начальную папку (речь ведь идёт о функции _FileSelectFolder() ?), я ещё не встречал функции которые способны раскрывать дерево папок во внешних приложениях (окон) основываясь на обычных данных (имя папки в данном случае), не на основе идентификаторов (типа ControlID)
все гораздо проще... :) API-функция SHBrowseForFolder сама на многое способна, нужно только отправить ей нужное сообщение, полный список поддерживаемых сообщений смотри в "Remarks" к Callback-функции: http://msdn2.microsoft.com/en-us/library/ms649522.aspx

Creat0R 01-05-2007 07:27

amel27
Цитата:

API-функция SHBrowseForFolder сама на многое способна, нужно только отправить ей нужное сообщение
Ох... еслиб я ещё знал как теперь всё это реализовать :sorry: ... как вообще изначально вызвать эту функцию? (я уже не говорю/спрашиваю о том как ей что то передать).

amel27 01-05-2007 10:19

Creat0R

К сожалению, CallBack-функция ничем не сможет помочь, зато в мануале к ней перечислены все сообщения, которые она может отправлять... В первом приближении все достаточно просто - запускаем _FileSelectFolder, открывается окно выбора каталога, уравляющий (фоновый) скрипт распознает это окно и отправляет ему сообщение (SendMessage или PostMessage) о переходе в нужное место дерева каталогов

mrak1990 01-05-2007 18:52

У меня такой вопрос. Как можно по средствам AutoIT удалить ветку реестра? Стандартными командами, как я понял нельзя.

Creat0R
Кстати помещение пункта в контекстное меню проводника у меня получилось.

amel27 01-05-2007 19:22

mrak1990
Цитата:

У меня такой вопрос. Как можно по средствам AutoIT удалить ветку реестра? Стандартными командами, как я понял нельзя.
цитата из справки:
Цитата:

RegDelete
--------------------------------------------------------------------------------

Deletes a key or value from the registry.
FYI: key - ветка, value - параметр

mrak1990 01-05-2007 19:38

Цитата:

цитата из справки:
Цитата:
RegDelete
--------------------------------------------------------------------------------

Deletes a key or value from the registry.

FYI: key - ветка, value - параметр
Это я всё знаю. Но как я понял, с её помощью можно удалять только ключи. Пробовал удалять с её помощью разделы. Никак не получается.
Допустим, мне нужно удалить следующий раздел рестра: "HKEY_CLASSES_ROOT\*\shell\Toogle Hidden Files&Folders\command" Как будет выглядеть команда в этом случае?

mrak1990 01-05-2007 19:52

Пробовал вводить команду: REG DELETE "HKCR\*\shell\Toogle Hidden Files&Folders" Но что-то не очень помогает.

amel27 01-05-2007 21:22

mrak1990
все удаляет - и через AutoIT, и через CMD... какие сообщения?

mrak1990 01-05-2007 22:46

Цитата:

mrak1990
все удаляет - и через AutoIT, и через CMD... какие сообщения?
Как оказалось, у меня были временные заскоки в реестром. Может быть из-за того, что я просматривал его через RegWorks. Хотя сейчас всё нормально.

amel27
Можешь всё таки написать, как удалить раздел реестра, только через RegDelete?

Creat0R 01-05-2007 23:46

amel27
Цитата:

запускаем _FileSelectFolder, открывается окно выбора каталога, уравляющий (фоновый) скрипт распознает это окно и отправляет ему сообщение (SendMessage или PostMessage)
а вот как его послать? полагаю нужно вызвать как то Dll (User32.dll?), но как, с какими именно параметрами... для меня эта сфера пока ещё тёмный лес... даже боюсь туда зайти :not-me:

mrak1990
Цитата:

помещение пункта в контекстное меню проводника у меня получилось.
Если не трудно, раскажи в чём секрет? :) (в ПМ наверно, а то как то оффтоп получается).

Цитата:

как удалить раздел реестра, только через RegDelete?
Код:

RegDelete("HKCR\*\shell\Toogle Hidden Files&Folders")

mrak1990 02-05-2007 18:51

Цитата:

Цитата:
как удалить раздел реестра, только через RegDelete?




Код:
RegDelete("HKCR\*\shell\Toogle Hidden Files&Folders")
Извиниясь за этот тупой вопрос. Я же до этого сам написал, что проблема была в заскоках моей Винды.



Creat0R
Закончил я с обещанным скриптом. Я думаю ты и сам разберёшься как он работает. Запускай только СКОМПИЛИРОВАННЫЙ скрипт.
Вот ссылка на скачку: http://ifolder.ru/1876076



P.S. Описание в самом начале скрипта я немного изменил (авторские права)... :mellow:

Creat0R 02-05-2007 20:55

mrak1990
Цитата:

Закончил я с обещанным скриптом
Спасибо.

Но пару примечании...

Не совсем верно переименовывать файл скриптом из самого себя :) - это иногда может и не сработать. Лучше сначала прописать в реестре данные, а потом перед самым выходом скрипта послать командную строку с ожиданим в одну секунду, и переименовыванием скрипта... примерно так:

Код:

Run(@ComSpec & ' /c ping -n 1 localhost > nul & Ren "' & @ScriptFullPath & '" "' & @ScriptDir & '\Выключить Fast Toogle Hidden Files&Folders.exe"', '', @SW_HIDE)
Exit

И ещё, это не совсем то что я имел в виду, мне нужен способ поместить пункт не в контекстное меню файлов и папок (кстати с этим методом в меню папок пункт так и не помещается), а в меню которое появляется при нажатии правой кнопкой мышки в пустом месте проводника (даже на рабочем столе) или нажатием Ctrl Shift F10 - См. мой пост тут - Пока что никто так и не знает как это сделать :(.

mrak1990 02-05-2007 21:05

Цитата:

Не совсем верно переименовывать файл скриптом из самого себя - это иногда может и не сработать. Лучше сначала прописать в реестре данные, а потом перед самым выходом скрипта послать командную строку с ожиданим в одну секунду, и переименовыванием скрипта... примерно так:
А с чем это связано? Как я понял, при запуске скрипа он первым делом обрабатывается интерпретатором и висит в памяти. И он уже не обращается к файлу. Возможно, что я и не прав. У кого есть мысли по этому поводу - пишите.

mrak1990 03-05-2007 00:07

Creat0R
Цитата:

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

amel27 03-05-2007 17:11

Creat0R
Цитата:

полагаю нужно вызвать как то Dll (User32.dll?), но как, с какими именно параметрами... для меня эта сфера пока ещё тёмный лес...
вот пример, проверил - вроде работает:
Код:

$hwnd = WinGetHandle ("Обзор папок")

$ret = DllCall ("user32.dll", "int", "SendMessage", _
    "hwnd", $hwnd, _
    "int", 0x400 + 101, _ ; код сообщения BFFM_SETOKTEXT
    "int", 0, _
    "int", 0 ) ; 0/1 - выключить/включить кнопку "OK"


Creat0R 04-05-2007 05:45

amel27
Цитата:

вот пример
Спасибо, но вроде в функции уже есть возможность автоотключения кнопки ОК в нужный момент (если использовать $flag=1), но вот как быть с Init Dir? какой код у параметра BFFM_SETEXPANDED (или может нужен BFFM_SETSELECTION?)?

Creat0R 04-05-2007 14:34

Такой вопрос:
Как можно средставми RegExp осуществлять массовую замену в переменной?

Т.е к примеру, имеем такое значение - $Var = "Test%20My/Test" - тут нужно одним махом заменить %20 на пробел, а / (перевёрнуты слэш) на \ (прямой слэш)....

Пробую так:

Код:

$NewVar = StringRegExpReplace($Var, "%20|/", " |\\")
Но замена осуществляется всех вхождении (из набора разделённого через |) на вот это - |\
Как такую замену можно произвести? или это не предусмотрено?

TERMINAL 04-05-2007 19:15

Вопрос !
Кто-то может помочь?

Например винт разбит на С, D, E, F - CD-ROM, нужно скриптом определить эти диски и отформатить D,E без всяких визуальных эфектов (тихий режим).

Creat0R 05-05-2007 01: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 09:53

Creat0R
Цитата:

вроде в функции уже есть возможность автоотключения кнопки ОК в нужный момент (если использовать $flag=1)
это в качестве примера использования SendMessage... кстати, с помощью этого сообщения можно ограничить возможность выбора файлов по определенному признаку - имени, типу, etc. Но для этого придется наладить "диалог" с окном выбора, а без CallBack-функций этого не осуществить.
Цитата:

какой код у параметра
На оффсайте есть очень полезная тулза, возвращающая коды по всем (или почти всем) GUI-сообщениям:
http://www.autoitscript.com/forum/in...howtopic=32691
Цитата:

BFFM_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 10:15

Creat0R
Цитата:

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

Creat0R 05-05-2007 12: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 13: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 10:02

Creat0R
Цитата:

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

Не получается нормально определить заголовок окна выбора каталога (Обзор папок)
ну да, проблематично определить HWID окна, которое еще не создано :) ... тем более, что класс у него вполне стандартный, как вариант - использовать для идентификации кроме заголовка - текст окна, переданный первым параметром функции.

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

amel27 07-05-2007 12:30

Creat0R

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

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

mrak1990 07-05-2007 17: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 14: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 15:45

amel27
Цитата:

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

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

Diamond 11-05-2007 04: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 05:34

mrak1990
Цитата:

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

mrak1990 11-05-2007 21:56

Diamond
Цитата:

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

VelDmi 13-05-2007 13: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 17:31

VelDmi
Цитата:

Как привильно запустить команду?
А в чём проявляется проблема с данным примером?

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

Код:

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

VelDmi 13-05-2007 18:45

не работает > fsum.err, то есть при вызове из автоит не пишет в файл fsum.err

amel27 14-05-2007 07:20

VelDmi
проверил - с @COMSPEC все работает, попробуй вместо /c поставить /k и отследить сообщения

VelDmi 14-05-2007 10:39

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

amel27 14-05-2007 13: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 07:06

Вышла новая версия - AutoIt v3.2.4.1...

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

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

Справка на русском для AutoIt v3.2.4.0.

storm2005 15-05-2007 17:11

Интересует взлом скомпилированного AutoIt .exe. Можно или нет это сделать, если при компиляции был выставлен пароль или убрана галка позволяющая декомпилировать?

Creat0R 15-05-2007 18:25

storm2005
Цитата:

Можно или нет это сделать, если при компиляции был выставлен пароль или убрана галка позволяющая декомпилировать?
Если был выставлен пароль, то естественно при его наличии это возможно, а вот если была убрана галка позволяющая декомпилировать, то нет.

storm2005 16-05-2007 11:02

Цитата:

Если был выставлен пароль, то естественно при его наличии это возможно, а вот если была убрана галка позволяющая декомпилировать, то нет.
если есть пароль но он неизвестен. можно ли декомпилировать?

интересует этот вопрос т. к. хочу устанавливать некоторый софт через логонный скрипт юзера. но проблема в том, что под юзером большинство софта не ставится т. к. юзер не обладает административными правами. в AutoIt нашел замечательную функцию RunAsSet в которой можно передать пароль в отличие от команды runas. но хотелось быть уверенным, что скомпилировав скрипт под паролем его никто не декомпилирует.

amel27 16-05-2007 18:12

storm2005
Цитата:

если есть пароль но он неизвестен. можно ли декомпилировать?
Можно, причем это ответ не мой, а разработчиков... Говорят есть хакнутый aut2exe, декомпилирующий такие скрипты, хотя сам я его не видел... впрочем и не искал.
Цитата:

проблема в том, что под юзером большинство софта не ставится т. к. юзер не обладает административными правами
такие задачи обычно решаются клиент-серверным методом, когда один модуль работает с правами системы/админа и заточен на выполнение конкретных задач (например, установки софта), а второй - под обычным юзером и дает ему "команды"... Для этого можно использовать технологии COM, WMI или обычный скрипт, запущенный в качестве службы.

NikLok 16-05-2007 23:22

storm2005
Цитата:

но хотелось быть уверенным, что скомпилировав скрипт под паролем его никто не декомпилирует.
Очень хочется примеры таких скриптов узнать! В смысле какую такую инфу ты защищаешь от пользователя.?!
ALL
Последнее время при адаптации скриптов под новые версии программ наталкиваюсь на странное поведение AutoIT.

А именно при выполнении команды ControlClick как бы не происходит отработки нажатия кнопки.
Например это началось в Wintools Net Pro начиная с версии после 8.1.1
Есть такой же проблемный кусок и в установке OutPost (вернее он всегда там был)
Код:

        WinWaitActive("Configuration Wizard","")
        $text = WinGetText("Configuration Wizard","")
        If StringRegExp($text,"Some applications that can cause system stability issues") Then
                If Not WinActive("Configuration Wizard","Some applications that can cause system stability issues") Then WinActivate("Configuration Wizard","Some applications that can cause system stability issues")
                WinWaitActive("Configuration Wizard","Some applications that can cause system stability issues")
                Send("{TAB}{ENTER}")
        EndIF

        If StringRegExp($text,"Advanced security") Then
                If Not WinActive("Configuration Wizard","Advanced security") Then WinActivate("Configuration Wizard","Advanced security")
                WinWaitActive("Configuration Wizard","Advanced security")
                Sleep(30)
                ControlClick("Configuration Wizard","Advanced security","Button3")
                Sleep(30)
                Send("{ENTER}")
        EndIF

Не получается выбрать "Advanced security" и пройти далее.

Может кто-то уже решал такую проблему?!
Может как-то можно задавать длительность нажатия кнопки?!

Angel_19 17-05-2007 21:17

В обсуждаемом продукте вроде есть запись макросов - как это можно осуществить и можно ли?

VelDmi 17-05-2007 21:48

Имеется каталог CutDir. в нем куча файлов. Есть файл (file.txt) содержащий строки вида:
C:\Compare\CutDir\Bin\SD0405.dll
C:\Compare\CutDir\Bin\LOA\SD0434.dll
C:\Compare\CutDir\WEZ\BIGz\erwg.dll

Как правильнее удалить из каталога все файлы, не содержащиеся в списках?
Пробовал

$line = FileReadLine($file)
FileMove ($CutDir & $line2, $DestDir & $line2, 0)
Работает, только для файлов в корне каталога CutDir, т.е. он не создает автоматически вложенные каталоги при копировании. А мне нужно оставить только файлы, перечисленные в списке, причем и во всех вложенных каталогах тоже.

Creat0R 17-05-2007 22:46

VelDmi
amel27 как то написал функцию возвращающую массив дерева каталогов включая подкаталоги, с её помощью эту задачу реализовать довольно просто:

Код:

#include <Array.au3>
#include <File.au3>

;Создаём нужные переменные и массив для содержания списка файлов которые удалять не нужно
$Dir = "CutDir"
$ExcludeListFile = "file.txt"
Dim $ExcludeListArr[1]

;Получаем массив структуры каталогов в папке "CutDir" (из переменной $Dir)
$DirsArray =  _DirListToArray($Dir)

;Получаем массив со списком файлов которые не нужно удалять (из файл от переменной $ExcludeListFile)..
_FileReadToArray($ExcludeListFile, $ExcludeListArr)

;Проходим по массиву структуры каталогов, получаем массив со списком файлов в каждом каталоге, и удаляем файлы не находящиеся в списке.
For $i = 1 To UBound($DirsArray)-1
    ;Получаем массив со списком файлов текущего каталога...
    $InDirFilesArr = _FileListToArray($DirsArray[$i], "*.*", 1)

        ;Если в текущем каталоге найдены файлы, то проходимся по массиву и ищем текущий элемент в массиве списка исключенных файлов.
    If IsArray($InDirFilesArr) Then
        For $iF = 1 To UBound($InDirFilesArr)-1
            ;Поиск элемента (текущего файла включая полный путь)...
            $SearchInArr = _ArraySearch($ExcludeListArr, $DirsArray[$i] & "\" & $InDirFilesArr[$iF])
            ;Если не найден, то удаляем файл...
            If $SearchInArr = -1 Then FileDelete($DirsArray[$i] & "\" & $InDirFilesArr[$iF])
        Next
    EndIf
Next

;Функция возвращает массив структуры подкаталогов
Func _DirListToArray ($sPath)
    Local $i, $j, $rlist[1]=[0], $blist, $alist=_FileListToArray ($sPath, '*', 2)
    If IsArray ($alist) Then
        For $i=1 To $alist [0]
            _ArrayAdd ($rlist, $sPath & "\" & $alist [$i])
            $blist = _DirListToArray ($sPath & "\" & $alist [$i])
            If $blist[0]>0 Then
                For $j=1 To $blist [0]
                    _ArrayAdd ($rlist, $blist [$j])
                Next
            EndIf
        Next
    EndIf
    $rlist [0] = UBound ($rlist) - 1
    Return $rlist
EndFunc

P.S
Я не тестировал скрипт, написал на скорую руку.

VelDmi 17-05-2007 23:30

Creat0R
Уфф, мне не дано такое понять...
Написал сам через попу, но работает вроде:
Код:

RunWait (@COMSPEC & ' /c fsum.exe -r -d".\CutDir" *.* > sums.md5', @ScriptDir, @SW_HIDE)
;через эту прогу создается список файлов
$filesums = FileOpen(@ScriptDir& '\sums.md5', 0)
If $filesums = -1 Then
    MsgBox(0, "Ошибка.", "Не могу открыть файл sums.md5")
    Exit
 EndIf
$filesums2 = FileOpen(@ScriptDir& '\sums2.md5', 0)
If $filesums2 = -1 Then
    MsgBox(0, "Ошибка.", "Не могу открыть файл sums2.md5")
    Exit
 EndIf

While 1
        $i = FileReadLine($filesums2)
        If @error = -1 Then ExitLoop
        $Count2 = $Count2 + 1
WEnd
FileClose($filesums2)

While 1
    $line = FileReadLine($filesums)
        If @error = -1 Then ExitLoop
    If StringLeft ($line, 1) = ';' Then ContinueLoop
                $filesums2 = FileOpen(@ScriptDir& '\sums2.md5', 0)
                $Del = 1
                For $i = 1 To $Count2
                        If $line = FileReadLine($filesums2) Then
                                $Del = 0
                                ExitLoop
                        EndIf
                Next
                If $Del = 1 Then FileDelete ($CutDir & StringTrimLeft( $line, 34 ))
                FileClose($filesums2)
WEnd
FileClose($filesums)

теперь попробую твой способ.

Creat0R 18-05-2007 00:41

VelDmi
Цитата:

Уфф, мне не дано такое понять...
Время покажет, я так тоже раньше думал, если бы мне, где то пол года назад показали подобный код, я бы точно также отреагировал ;)

Вот превратил всё это дело в функцию, теперь проверил работоспособность, вроде работает :)

Переменная $ExcludeList также может иметь сразу список файлов для исключения, вот пример - $ExcludeList = "C:\CutDir\test.txt|C:\CutDir\test2.txt" - файлы C:\CutDir\test.txt и C:\CutDir\test2.txt не будут тронуты функцией. Также можно передать во второй параметр функции _DeleteFilesWithExcludes() массив содержащий список файлов для исключения, ну и как показанно в примере, поддерживается и обычный путь к файлу, с которого будет браться список исключении.

При успешной операции, возвращает @extended, макрос будет содержать число файлов которые были удалены (именно удалены, не просто количество файлов в соответствии со списком исключении).

Код:

#include <Array.au3>
#include <File.au3>

$Dir = @ScriptDir & "\CutDir"

;Эта переменная может быть массивом, полным списком файлов исключении (разделённый через |),
;а так-же это можт быть путь к файлу содержащий список файлов которые будут исключены при удалении.
$ExcludeList = @ScriptDir & "\file.txt" ;Пример переменной - "c:\CutDir\test.txt|c:\CutDir\test2.txt" ... и т.д

_DeleteFilesWithExcludes($Dir, $ExcludeList)

If Not @error Then MsgBox(262144+64, "Finish", "Было удалено <" & @extended & "> файлов")

;Функция для удаления файлов из всех подкаталогов заданного каталога, в соответствии со списком исключении.
Func _DeleteFilesWithExcludes($sPath, $ExcludeList)
    Local $ExcludeListArr[1], $Extended = 0
    ;Если не существует каталога (в котором следует производить удаление) или переменная $sPath не является каталогом,
    ;возвращаем ошибку №1.
    If Not StringInStr(FileGetAttrib($sPath), "D") Then Return SetError(1, 0, 0)
    ;Получаем массив структуры каталогов в папке "CutDir" (из переменной $Dir)
    Local $DirsArray =  _DirListToArray($sPath)

        If Not IsArray($ExcludeList) And FileExists($ExcludeList) Then
        ;Получаем массив со списком файлов которые не нужно удалять (из файл от переменной $ExcludeList)..
        _FileReadToArray($ExcludeList, $ExcludeListArr)
    ElseIf IsString($ExcludeList) And StringInStr($ExcludeList, "|") Then
        ;Превращаем переменную в массив (разделяя этим символом |)
        $ExcludeListArr = StringSplit($ExcludeList, "|")
    ElseIf IsArray($ExcludeList) Then
        ;Присваиваем внутреннему массиву (ранее созданному) то же значение что и у массива $ExcludeList
        $ExcludeListArr = $ExcludeList
    Else
        ;Не предвиденная ошибка, передана пустая переменная или неверный формат массива/переменной - возвращаем ошибку №2.
        Return SetError(2, 0, 0)
    EndIf

        ;Получаем массив со списком файлов корневого каталога ($sPath)...
    $RootFilesArr = _FileListToArray($sPath, "*.*", 1)
    If IsArray($RootFilesArr) Then
        For $iR = 1 To UBound($RootFilesArr)-1
            ;Поиск элемента (текущего файла включая полный путь)...
            $SearchInArr = _ArraySearch($ExcludeListArr, $sPath & "\" & $RootFilesArr[$iR])
            ;Если не найден, то удаляем файл...
            If $SearchInArr = -1 Then $Extended += FileDelete($sPath & "\" & $RootFilesArr[$iR])
        Next
    EndIf

        ;Проходим по массиву структуры каталогов, получаем массив со списком файлов в каждом каталоге,
    ;и удаляем файлы не находящиеся в списке.
    For $i = 1 To UBound($DirsArray)-1
        ;Получаем массив со списком файлов текущего каталога...
        $InDirFilesArr = _FileListToArray($DirsArray[$i], "*.*", 1)

                ;Если в текущем каталоге найдены файлы, то проходимся по массиву и ищем текущий элемент в массиве списка исключенных файлов.
        If IsArray($InDirFilesArr) Then
            For $iF = 1 To UBound($InDirFilesArr)-1
                ;Поиск элемента (текущего файла включая полный путь)...
                $SearchInArr = _ArraySearch($ExcludeListArr, $DirsArray[$i] & "\" & $InDirFilesArr[$iF])
                ;Если не найден, то удаляем файл...
                If $SearchInArr = -1 Then $Extended += FileDelete($DirsArray[$i] & "\" & $InDirFilesArr[$iF])
            Next
        EndIf
    Next
    Return SetError(0, $Extended, 1)
EndFunc

;Функция возвращает массив структуры подкаталогов
Func _DirListToArray ($sPath)
    Local $i, $j, $rlist[1]=[0], $blist, $alist=_FileListToArray ($sPath, '*', 2)
    If IsArray ($alist) Then
        For $i=1 To $alist [0]
            _ArrayAdd ($rlist, $sPath & "\" & $alist [$i])
            $blist = _DirListToArray ($sPath & "\" & $alist [$i])
            If $blist[0]>0 Then
                For $j=1 To $blist [0]
                    _ArrayAdd ($rlist, $blist [$j])
                Next
            EndIf
        Next
    EndIf
    $rlist [0] = UBound ($rlist) - 1
    Return $rlist
EndFunc


Creat0R 19-05-2007 07:42

Я как то сообщил на офф. форуме о серъёзном баге, наверняка многие из вас его заметили, его трудно не заметить...

Разработчики приписали моему репорту NOBUG (не бага), хотя я не согласен :).

Баг заключается в следующем - 1) В момент перетаскивания окна ГУИ скрипта по его заголовку, 2) в момент изменения размера ГУИ окна, 3) при зажатии одной из кнопок закрытия/Сворачивания/Разворачивания окна, 4) а также и при открытии любых меню гуи (как главных так и контекстных), и в добавок, 5) при открытии меню из иконки в левом верхнем углу (значок программы) - Скрпит полностью останавливается на время указанных действии.

Мне кажется что это не должно происходить, разработчики свернули вину на Windows, мол это баг самой ОС, хотя не смотря на это, некоторые программы (и кстати, написанные тоже на C++) умудряются "не останавливать" свою работу на момент перетаскивания их окна или любой другой указанной ранее “дейтяльности” со стороны юзера.

Вобщем я решил эту задачку (надеюсь временно, желательно увидеть решение этой проблеме со стороны разработчиков) вот таким образом:

Код:

#include <GuiDragable.au3>
#include <Guiconstants.au3>

Dim $LeftPos

$GuihWnd = _GuiDragableCreate("Drag GUI Demo", 300, 150, -1, -1)
GUISetBkColor(0xffffff)

$ExampleLabel = GUICtrlCreateLabel("Drag Me (but not by controls) ;)", 0, 60, 250, 20)
GUICtrlSetFont(-1, 12, 600, 0, "Tahoma")
GUICtrlSetColor(-1, 0xDD0000)

AdlibEnable("Example", 50)

DllCall("User32.dll", "long", "AnimateWindow", "hwnd", $GuihWnd, "long", 300, "long", 0x10)
GUISetState()

While 1
    Sleep(10)
WEnd

Func Example()
    $LeftPos += 3
    GUICtrlSetPos($ExampleLabel, $LeftPos, 60)
    If $LeftPos >= 300 Then $LeftPos = -250
EndFunc

Нужно в папке со скриптом иметь этот файл - http://www.autoitscript.com/forum/in...=post&id=14661

При перетаскивании окна (при зажатии мышки в любом места окна за исключением контролов, ведь мы же хотим иметь возможность нажимать на кнопки и т.п.), бегущая строка по прежнему "продолжает бежать" :) - это свидетильствует о том что скрипт не остановлен.

Creat0R 21-05-2007 22:00

Метод позволяющий запускать код VBS не создавая временных файлов:


Код:

$ProcessName = "AutoIt3.exe"

$RetArr = _ProcessExistsVbs($ProcessName)

If IsArray($RetArr) Then MsgBox(64, "", "Process <" & $RetArr[1] & "> exists." & @LF & @LF & _
    "The returned PID is: " & $RetArr[2] & @LF & @LF & _
    "Returned Executable Path is: " & @LF & $RetArr[3] & @LF & @LF & _
    "Command Line of executed process is: " & @LF & $RetArr[4])

;Функция возвращает массив содержащий имя процесса, его уникальный идентификатор (PID), путь запуска, и коммандную строку запуска.
;В случае если указанный процесс не существует, возвращается 0.
Func _ProcessExistsVbs($ProcName)
    Local $Code = ""
    $Code &= 'Function ProcessExists(ProcessName)' & @LF
    $Code &= '  Set Processes = GetObject("winmgmts://localhost")' & @LF
    $Code &= '  Set myProcEnum = Processes.ExecQuery("select * from Win32_Process")' & @LF
    $Code &= '  For Each Proc In myProcEnum' & @LF
    $Code &= '      If StrComp(Proc.Name, ProcessName, 1) = 0 Or StrComp(Proc.ProcessID, ProcessName, 1) = 0 Then' & @LF
    $Code &= '          Dim RetArr' & @LF
    $Code &= '          RetArr = Array(4, Proc.Name, Proc.ProcessID, Proc.ExecutablePath, Proc.CommandLine)' & @LF
    $Code &= '          ProcessExists = RetArr' & @LF
    $Code &= '          Exit Function' & @LF
    $Code &= '      End If' & @LF
    $Code &= '  Next' & @LF
    $Code &= '  ProcessExists = 0' & @LF
    $Code &= 'End Function'

    Local $VbsObj = ObjCreate("ScriptControl")
    If @error Then Return SetError(1, 0, -1)

    $VbsObj.Language = "vbscript"
    $VbsObj.AddCode($Code)
    Local $RetArr = $VbsObj.Run("ProcessExists", $ProcName)
    If $RetArr = 0 Then Return SetError(0, 0, 0)
    Return $RetArr
EndFunc


amel27 22-05-2007 13:44

Creat0R
Цитата:

как то сообщил на офф. форуме о серъёзном баге
Думаю проблема в AdLib, так как это чисто AutoIT-овский планировщик и он отключается на время передачи управления системному коду (через DLLCall), поэтому ИМХО нужно либо избегать таких вызовов, либо использовать модель GUIRegisterMsg, которая поддерживается самой системой... правда в этом случае прорисовку придется выполнять в основном цикле, а обработку нажатий наоборот в процедуре.

Цитата:

Метод позволяющий запускать код VBS не создавая временных файлов:
Весьма забавный трюк, только какая в нем польза, если возможности AutoIT на порядок шире VBS?.. Шутка. ;)

Diamond 22-05-2007 15:31

Creat0R
Отлично! Очень интересный способ! :UP:
Даже не подозревал что существует такой объект...
Я выяснил что "MSScriptControl.ScriptControl" предназначен также и для JavaScript'ов. VbScript'ы у меня запускаются а вот с JavaScript'ами почему-то ничего не выходит.
Привожу два упрощённых примера для сравнения:
vbscript:
Код:

;~ Доступ к контекстному меню папок:
Dim $Code
$Code = 'Set objShellApp = CreateObject ("Shell.Application")' & @LF & _
 'Set objFolderItem = objShellApp.NameSpace("C:\").Self' & @LF & _
 'Set objFIVs = objFolderItem.Verbs' & @LF & _
 'MsgBox objFIVs.Count,0,"Кол-во элементов:"' & @LF & _
 'For Each ThisCheck in objFIVs' & @LF & _
 '        If ThisCheck.Name = "&Найти..." Then' & @LF & _
 '                ThisCheck.DoIt' & @LF & _
 '        End If' & @LF & _
 'MsgBox ThisCheck.Name' & @LF & _
 'Next'

$VbsObj = ObjCreate("MSScriptControl.ScriptControl")
$VbsObj.Language = "VbScript"
$VbsObj.AddCode($Code)

javascript:
Код:

;~ Диалог открытия файлов:
Dim $Code
$Code = 'var WshShell = WScript.CreateObject ("WScript.Shell");' & @LF & _
 'var objDialog = new ActiveXObject("UserAccounts.CommonDialog");' & @LF & _
 'objDialog.Filter = "All Files|*.*";' & @LF & _
 'objDialog.InitialDir = "C:\\";' & @LF & _
 'intResult = objDialog.ShowOpen();' & @LF & _
 'if (intResult) WshShell.PopUp(objDialog.FileName);'

$VbsObj = ObjCreate("MSScriptControl.ScriptControl")
$VbsObj.Language = "JScript"
$VbsObj.AddCode($Code)

Может я что-то делаю не так? :dont-know

Creat0R 22-05-2007 22:54

amel27
Цитата:

Думаю проблема в AdLib
Я в этом не уверен, это не только связанно с этой процедурой, она чисто для демонстрации бага(?). Мне кажется останавливается весь скрипт целиком, и вот вроде этому доказательство...

Код:

Opt("GuiOnEventMode", 1)

GUICreate("Test")
GUISetOnEvent(-3, "Quit")

GUICtrlCreateMenu("Test Menu")

GUISetState()

While 1
    Sleep(10)
    ConsoleWrite("! test")
WEnd

Func Quit()
    Exit
EndFunc

Тащим ГУИ, или просто нажимаем на, вроде полусозданное меню, и в консоль ничего не пишется....

Цитата:

нужно либо избегать таких вызовов, либо использовать модель GUIRegisterMsg, которая поддерживается самой системой
А возможно ли таким методом запустить выполнение определённх операции по заданному интервалу? (аналогично Adlib). Хотя сомневаюсь что это поможет, скрипт всё ровно будет останавливаться (полагаю).

Цитата:

Весьма забавный трюк, только какая в нем польза, если возможности AutoIT на порядок шире VBS?
Динамический код однако ;) - Можно таким образом создавать функции в обычном файле, чтобы даже закомпилированный скрипт мог их обрабатывать - ну это как опция вообще то, а замысел в том, что иногда функция на VBS сработает куда быстрее чем AutoIt'овская (в некоторых случаях), основная идея не моя, это я "украл" на офф. форуме, там для сортировки ListView (при чём очень быстрой) используется именно такой метод. А я всего лишь по такому же методу сделал набросок для функции ProcessExists() (которую недавно написал на VBS), и в качестве демонстрации использовал её в коде :).

Creat0R 22-05-2007 23:07

Diamond
Цитата:

VbScript'ы у меня запускаются а вот с JavaScript'ами почему-то ничего не выходит.
Я если честно с JavaScript никогда не работал, скорее всего нужен либо другой объект, либо другой синтаксис для этого объекта, у меня подобные ошибки выводились когда писал неверный синтаксис в коде VBS, видимо для обработки кода нужен точный синтаксис, иначе действие для объекта не релевантное.

amel27 23-05-2007 05:27

Creat0R
Цитата:

Мне кажется останавливается весь скрипт целиком
а я и не оспаривал, только предложил обходной путь :)
Цитата:

А возможно ли таким методом запустить выполнение определённх операции по заданному интервалу?
из самого скрипта нет, ты веть сам это показал выше ;) ... только извне
Цитата:

сомневаюсь что это поможет, скрипт всё ровно будет останавливаться
не будет, так как вызовы функций выполняет система а не скрипт - проверено!

VelDmi 23-05-2007 05:57

Цитата:

Мне кажется останавливается весь скрипт целиком, и вот вроде этому доказательство...
Если создать в autoit прогресс бар и нажать на него мышкой, то он остановится.
Если во время архивации WINRAR нажать на окно мышкой архивация остановится! Мне кажется тут дело в системе, а не в Autoit.

Creat0R 23-05-2007 06:52

amel27
Цитата:

не будет, так как вызовы функций выполняет система а не скрипт - проверено!
Ок, а как это реализовать? :shuffle: (хотябы набросок того как оно будет запускать к примеру каждые 100 мс определённую функцию).

VelDmi
Цитата:

Если создать в autoit прогресс бар и нажать на него мышкой, то он остановится.
Нажать мышкой на сам прогресс? у меня не останавлвиается :idontnow: .

Цитата:

Если во время архивации WINRAR нажать на окно мышкой архивация остановится!
Это да, видимо когда писали Winrar это не предусмотрели :).

Цитата:

Мне кажется тут дело в системе, а не в Autoit.
Как раз то нет, я об этом и твердил...

Цитата:

разработчики свернули вину на Windows, мол это баг самой ОС, хотя не смотря на это, некоторые программы (и кстати, написанные тоже на C++) умудряются "не останавливать" свою работу на момент перетаскивания их окна или любой другой указанной ранее “дейтяльности” со стороны юзера.
Добавлено:
Т.е получается, что это ответственность программиста предусматривать подобные вещи, а не системы...

TERMINAL 23-05-2007 17:24

Хотел написать автоустановку разных антивирусов-написал, но проблема вот такая- каждый антивирус заканчивает свою установку по разному и у меня проблема с теми которые начинают сразу после установки сканить диски. Паузу ставить безсмыслено, а вот с процессами поработать можно было было. Какой скрипт лучше написать, если при сканировании антивир процесс грузит примерно до 40 процентов, а когда закончен равен нулю =0 (я так думаю) !? Или может кто-то с этим сталкивался? Свои мысли может изложить...

Diamond 24-05-2007 07:35

Creat0R
VelDmi
Мне трудно представить что кто-то, с затёкшим от напряжения пальцем, упорно удерживает панель заголовка, во время работы приложения. :laugh:
Цитата:

Т.е получается, что это ответственность программиста предусматривать подобные вещи, а не системы...
Полностью согласен, но при этом возникает интересный парадокс. :)
Мы требуем от разработчиков исправления бага, но в тоже время забываем что сами являемся в определённой степени разработчиками приложений на AutoIT.
А что нам в свою очередь, мешает исправить этот баг в собственных AutoIT сценариях. Тем более, как уже было сказано amel27 такая возможность есть:
Цитата:

Думаю проблема в AdLib, так как это чисто AutoIT-овский планировщик и он отключается на время передачи управления системному коду (через DLLCall), поэтому ИМХО нужно либо избегать таких вызовов, либо использовать модель GUIRegisterMsg, которая поддерживается самой системой... правда в этом случае прорисовку придется выполнять в основном цикле, а обработку нажатий наоборот в процедуре.
Что... для нас это сложно и не удобно? А уж что говорить о разработчиках AutoIT. Учитывая тот факт что AutoIT бесплатен, сомневаюсь что они захотят что-то глобально поменять.
Получается разработчики AutoIT, свернули вину на разработчиков Windows, а мы в свою очередь свернули вину на разработчиков AutoIT. Но никто из всех трёх (включая и нас), не хочет изменять что-либо в коде. :no:

VelDmi 24-05-2007 08:12

Diamond
Цитата:

Но никто из всех трёх (включая и нас), не хочет изменять что-либо в коде.
Оно, я думаю, не очень то и надо.
Учитывая
Цитата:

Мне трудно представить что кто-то, с затёкшим от напряжения пальцем, упорно удерживает панель заголовка, во время работы приложения.

Creat0R 24-05-2007 08:30

Diamond
Цитата:

Мне трудно представить что кто-то, с затёкшим от напряжения пальцем, упорно удерживает панель заголовка, во время работы приложения
Тут дело не в этом, просто иногда “скрипт вынужден” использовать внешние ресурсы, и для корректного слежения за работой этих ресурсов (что не маловажно), или даже для вывода информации возвращяемой от этих ресурсов, требуется упорное наблюдение (не упуская из виду как говорится). А когда юзеру вдруг приспичет подвигать то или иное окошко (кстати, я на оф. форуме приводил пример, что если на деактивированном меню нажать мышкой, то также весь скрипт останавливается, и юзеру нет необходимости затёкшими пальцами удерживать что либо :) ), то слежка будет нарушена, что может привести к неправильной работе родительского скрипта (я с этим не раз сталкивался, поэтому и начал эту тему).

Цитата:

Мы требуем от разработчиков исправления бага, но в тоже время забываем что сами являемся в определённой степени разработчиками приложений на AutoIT.
Да, но в отличие от остальных полноценных языков программирования, AutoIt обладает многими ограничениями, я не жалуюсь, этот инструмент для меня стал серъёзным шагом в понимании основ программирования, просто иногда хочется подвигать горизонты :) (что вполне могут сделать разработчики, не прикладывая столько усилии сколько уйдёт у нас, у “простых смертных”).

Цитата:

Что... для нас это сложно и не удобно? А уж что говорить о разработчиках AutoIT.
Ну им наверняка проще...


Цитата:

Получается разработчики AutoIT, свернули вину на разработчиков Windows, а мы в свою очередь свернули вину на разработчиков AutoIT.
Я бы так не сказал, я лично не сворачивал на них вину, просто заметил эту проблему, тем самым намекнул на то что желательно бы это поправить :)

Цитата:

Но никто из всех трёх (включая и нас), не хочет изменять что-либо в коде.
Эх, мне бы знания разработчиков AutoIt, при этом оставить свою амбицию и стремление, и о желании речи никакой не будет, оно есть... ну и чуток времени бы свободного ;)

amel27 24-05-2007 09:54

Creat0R
Цитата:

Ок, а как это реализовать?
только двумя процессами:
Код:

#include <GUIConstants.au3>
; Ветвление на "генератор" по параметру командной строки: <time> <hwnd>  TimeDisp_1
If ""&$CmdLine[$CmdLine[0]]='TimeDisp_1' Then TimeDisp_1 ($CmdLine[2], $CmdLine[1])
; Регистрируем свое событие и функцию
GUIRegisterMsg ($WM_USER+1, "TimeProc_1")
$Time_1 = 100 ; период повторения
; Твой ГУИ (без изменений)
Opt("GuiOnEventMode", 1)
$hWndMain=GUICreate("Test")
GUISetOnEvent(-3, "Quit")
GUICtrlCreateMenu("Test Menu")
GUISetState()
; Запускаем генератор событий
ShellExecute (@AutoItExe, '"'& @ScriptFullPath &'" '& $Time_1 &' '& $hWndMain &' TimeDisp_1')
; Пустой цикл
While 1
    Sleep (1000)
Wend
; Код "генератора событий"
Func TimeDisp_1($hWnd, $tWait = 500)
    $hWnd = HWnd($hWnd)
    While WinExists($hWnd)
        Sleep ($tWait)
        $ret = DllCall ("user32.dll", "int", "SendMessage", "hwnd", $hWnd, "int", $WM_USER+1, "int", 0, "ptr", 0 )
    Wend
    Exit
EndFunc
; Функция обработки события
Func TimeProc_1($hWnd, $Msg, $wParam, $lParam)
    ConsoleWrite('*')
EndFunc
; Кусок ГУИ
Func Quit()
    Exit
EndFunc

Цитата:

в отличие от остальных полноценных языков программирования, AutoIt обладает многими ограничениями
все-таки это скриптовый язык, а в своей категории он имхо лучший

NikLok 24-05-2007 18:19

amel27
А как ты код при вставке цветныс делаешь?

Creat0R 24-05-2007 19:29

amel27
Цитата:

только двумя процессами:
Хм.. я думал это будет что-то вроде установки задачи для Windows чтобы она собственными средствами “вызывала” подобное сообщение в моём Гуи (т.е без надобности постоянного вызова вторичного скрипта).

Но оно работает, а значит это решаемо проще чем я думал, спасибо большое!

NikLok
Цитата:

А как ты код при вставке цветныс делаешь?
Вопрос не ко мне, но я всё же отвечу...

Я как то тоже поинтересовался этим вопросом, ответ от amel27 ;).

P.S
Кстати, я немного изменил метод (для себя), в принципе нет особой необходимости сохранять в файл результаты, поэтому при первом открытии Гуи галка для ввода исходного кода вручную сразу устанавлвивается, а также есть возможность после вывода результатов одной кнопкой скопировать результат в буфер обмена и закрыть Гуи.
Скоро выложу обновлённую версию.

amel27 25-05-2007 05:48

Creat0R
Цитата:

я думал это будет что-то вроде установки задачи для Windows чтобы она собственными средствами “вызывала” подобное сообщение
собственными средствами можно только "зашедулить" вызов скрипта/программы, т.е. опять же процесса
Цитата:

без надобности постоянного вызова вторичного скрипта
по аналогии с CallBack можно сваять простенькую DLL-ку и отправлять сообщения из специального потока в том же процессе... если есть интерес могу попробовать на выходных... кстати, с подачи Piccaso (с оффсайта) Dll-ки собираю теперь на FreeBasic

Цитата:

Скоро выложу обновлённую версию
ADD: скрипты выкладывай в форум, интернет-качалками (типа Dounload Master) аттачи нормально берутся

Creat0R 25-05-2007 06:24

amel27
Цитата:

если есть интерес могу попробовать на выходных
Есть :), спасибо.

Цитата:

крипты выкладывай в форум
Ок.

Diamond 25-05-2007 07:22

VelDmi
Ну да, скорее всего так.
У многих приложений наблюдается подобное поведение. Думаю, если это можно назвать "багом", то условно.
Creat0R
Цитата:

Тут дело не в этом, просто иногда “скрипт вынужден” использовать внешние ресурсы, и для корректного слежения за работой этих ресурсов
Если речь идёт об автоматизации управляющих элементов и окон, то да. Случалось и у меня... С другой стороны, можно использовать BlockInput(), ограничится предупреждением пользователя, либо отказаться от использования GUI, ну и в конце концов запустить другой процесс(скрипт), который выполнит необходимые действия и передаст информацию GUI. Думаю, выход можно найти почти из любой ситуации.
Цитата:

Ну им наверняка проще...
Это похоже на сложившийся у многих стереотип, типа: "хорошо там, где нас нет". :)
Цитата:

Я бы так не сказал, я лично не сворачивал на них вину, просто заметил эту проблему, тем самым намекнул на то что желательно бы это поправить :)
Ведь я выразился фигурально, а под словом "мы" подразумевал если не всех, то большинство пользователей AutoIT (включая и меня). Все хотят улучшений и расширений возможностей AutoIT, а в случае обнаружения багов сетуют на разработчиков(было бы странно, если бы всё было наоборот). Но ведь если есть возможность обойти проблему другим путём, то почему бы и не попробовать.
Ну и конечно всегда остаётся второй вариант: "дождаться пока проблему решат разработчики", что кстати вполне возможно, ведь AutoIT от версии к версии набирает силу, и надеюсь что появится больше нововведений которые если даже и не исправят, то по крайней мере с большей вероятностью позволят обойти тот или иной баг.
Цитата:

Эх, мне бы знания разработчиков AutoIt, при этом оставить свою амбицию и стремление, и о желании речи никакой не будет, оно есть... ну и чуток времени бы свободного
Любое программирование требует времени и усилий, и чем больше затрачено усилий на решение поставленной задачи, тем больше радость от победы, разве нет? При этом вопрос нехватки времени уже сам по себе переходит на второй план, ведь здесь важна самоцель и я верю что у тебя она есть. А знания при таком подходе обязательно придут.

Creat0R 25-05-2007 10:41

1 вложений
Diamond
Цитата:

можно использовать BlockInput(), ограничится предупреждением пользователя, либо отказаться от использования GUI
Ну это уже крайности, тогда нет смысла что либо говорить о ГУИ, ведь проблема замечена именно с ним ;) - Можно не прибегать к подобным крайностям, и просто деактивировать гуи, но это то самое ограничение, о которм я писал.

Цитата:

выход можно найти почти из любой ситуации.
100% согласен, но думаю в результате важен именно “выход”, и как он будет выполнен :)

Цитата:

если есть возможность обойти проблему другим путём, то почему бы и не попробовать.
От безвыходости именно это мы и делаем, но как оказывается в конце концов, эти “пробы” заканчиваются ещё большими ограничениями и подхрамываниями в работе скрипта чем те о которых я писал.

Цитата:

всегда остаётся второй вариант: "дождаться пока проблему решат разработчики", что кстати вполне возможно, ведь AutoIT от версии к версии набирает силу, и надеюсь что появится больше нововведений которые если даже и не исправят, то по крайней мере с большей вероятностью позволят обойти тот или иной баг.
“Надежда умирает последней” © - Вот поэтому я и пишу баг репорты, потому что знаю что есть шанс на фиксы, кстати, пару моих репортов (1, 2, 3, 4, 5) всё таки пофиксили ;).

Цитата:

чем больше затрачено усилий на решение поставленной задачи, тем больше радость от победы, разве нет?
Конечно да. Просто иногда после “длительных усилии” уже не хватает сил на радости :biggrin:

amel27, NikLok и ВСЕ:

Прикрепил к посту новую версию ГУИ для обработки скрпитов в “цветной вид” (для вставки на форумах).
Теперь в нём все настройки сохраняются, и добавлены многие проверки на ошибочность.

amel27
Чуть не забыл, если пропустить на обработку сам скрипт (иронично получается :) ), то находятся неопознаные стили, я что-то так и не понял, как распознавать и соответственно добавлять неопознанные стили?

amel27 25-05-2007 11:07

Creat0R
Цитата:

что-то так и не понял, как распознавать и соответственно добавлять неопознанные стили
ты разве не понял принцип работы скрипта?.. Если в тексте после всех замен остались XML-теги, то считается что есть неопознанные стили... соответственно, сам себя он не сможет обработать, так как не сможет отличить XML-тег от строки сравнения.

Creat0R 25-05-2007 11:40

amel27
Цитата:

соответственно, сам себя он не сможет обработать, так как не сможет отличить XML-тег от строки сравнения.
Теперь всё ясно, большое спасибо, парадокс однако получается :)

NikLok 25-05-2007 13:06

Creat0R Спасибо!

VadikanМожет этот скрипт прямо к форуму прикурутить. Вставил код и он принулительно разукрасился!?

amel27 25-05-2007 16:57

1 вложений
Creat0R
Цитата:

если есть интерес могу попробовать на выходных

Есть , спасибо
как ни странно получилось, и выглядит многообещающе... :)
Код:

#include <GUIConstants.au3>
; ГУИ
Opt("GuiOnEventMode", 1)
$hWndMain=GUICreate("Test")
GUISetOnEvent(-3, "Quit")
GUICtrlCreateMenu("Test Menu")
GUISetState()
; Регистрируем сообщение
GUIRegisterMsg($WM_USER+1, "Tick")
; Открываем DLL и возвращаем указатель на функцию
$hDll = DllOpen("ticker.dll")
$hProc = DllCall($hDll,"int","TickerPtr")
; Структура для параметров "генератора сообщений"
$parms = DllStructCreate ("hwnd;int;long;long" )
  ; Установка требуемых параметров
DllStructSetData ($parms, 1, $hWndMain) ; хэндл главного окна
DllStructSetData ($parms, 2, $WM_USER+1) ; ID сообщения
DllStructSetData ($parms, 3, 300) ; таймаут между сообщениями
DllStructSetData ($parms, 4, 0) ; сколько раз отправить сообщение
; Запускаем поток
$res = DllCall("kernel32.dll","int","CreateThread","int",0,"int",0,"ptr",$hProc[0],"int",DllStructGetPtr($parms),"int",0,"int_ptr",0)
; Пустой цикл
While 1
    Sleep (1000)
Wend
; Функция обработки события
Func Tick ($hWnd, $iMsg, $WParam, $LParam)
    ConsoleWrite (Number($WParam) & @CRLF)
EndFunc
; Снова ГУИ
Func Quit()
    Exit
EndFunc


Creat0R 26-05-2007 01:10

amel27
Цитата:

как ни странно получилось
Я не сомневался :)

Старая проблема со скачакой атачментов всплыла, файл не скачивается :( - Пробовал DMaster'ом, пробовал через IE качалку, через “Сохранить по ссылке как”, но архив скачивается повреждённый (или вовсе не архив а php файл).

amel27 26-05-2007 07:06

Creat0R
Цитата:

Старая проблема со скачакой атачментов всплыла, файл не скачивается
странно, на работе через прокси в IE качает, дома через диалап только DMastrer'ом... так что надежда есть, попробуй FlashGet'ом

линк: http://www.sendspace.com/file/iaq1xh

Creat0R 27-05-2007 00:36

amel27
Спасибо, работает!

Правда при нажатии на кнопку закрытия/сворачивания и её удерживания (на месте, если удерживая и двигать мышку то нормально), то счётчик останавливается :( - но это не критично, а так работает... я так понял это вызваная Dll'ка посылает постоянно зарегистрированное сообщения в окно ГУИ, и этим самым “провоцируя” запуск нужной функции (зарегистрированной), так?
Хорошо что сама Dll'ка не большая, обычно они бывают большими :)

amel27 27-05-2007 04:37

Creat0R
Цитата:

я так понял это вызваная Dll'ка посылает постоянно зарегистрированное сообщения в окно ГУИ, и этим самым “провоцируя” запуск нужной функции (зарегистрированной), так?
угу, самопальный AdLib :) ... имхо в исходнике и без комментов все прозрачно
Цитата:

Хорошо что сама Dll'ка не большая, обычно они бывают большими
FreeBasic рулит! ;)

Diamond 28-05-2007 11:58

Системные цвета
Код:

Const $COLOR_SCROLLBAR = 0 ; - цвет полосы прокрутки
Const $COLOR_BACKGROUND = 1 ; - цвет фона окна
Const $COLOR_ACTIVECAPTION = 2 ; - цвет заголовка активного окна
Const $COLOR_INACTIVECAPTION = 3 ; - цвет заголовка неактивного окна
Const $COLOR_MENU = 4 ; - цвет меню
Const $COLOR_WINDOW = 5 ; - цвет окна
Const $COLOR_WINDOWFRAME = 6 ; - цвет обрамления окна
Const $COLOR_MENUTEXT = 7 ; - цвет текста меню
Const $COLOR_WINDOWTEXT = 8 ; - цвет текста окна
Const $COLOR_CAPTIONTEXT = 9 ; - цвет текста в заголовке окна

Const $COLOR_ACTIVEBORDER = 10 ; - цвет активной границы окна
Const $COLOR_INACTIVEBORDER = 11 ; - цвет неактивной границы окна
Const $COLOR_APPWORKSPACE = 12 ; - цвет рабочего места окна
Const $COLOR_HIGHLIGHT = 13 ; - цвет подсветки
Const $COLOR_HIGHLIGHTTEXT = 14 ; - цвет подсвеченного текста
Const $COLOR_BTNFACE = 15 ; - цвет лицевой части кнопки
Const $COLOR_BTNSHADOW = 16 ; - цвет тени кнопки
Const $COLOR_GRAYTEXT = 17 ; - цвет "серого" текста
Const $COLOR_BTNTEXT = 18 ; - цвет текста в кнопке
Const $COLOR_INACTIVECAPTIONTEXT = 19 ; - цвет текста в заголовке неактивного окна

Const $COLOR_BTNHIGHLIGHT = 20 ; - цвет текущей кнопки

;~ Получаем цвет лицевой части кнопки на текущий момент:
$OldColor = _GetSysColor($COLOR_BTNFACE)
;~ Задаём красный цвет для лицевой части кнопки:
_SetSysColor($COLOR_BTNFACE, 0xFF0000)
;~ тайм-аут 5 секунд
Sleep(5000)
;~ Восстанавливаем полученный ранее цвет
_SetSysColor($COLOR_BTNFACE, $OldColor)

############# -= ФУНКЦИИ =- #############

;~ Позволяет получать системные цвета, определённые текущими параметрами оформления
Func _GetSysColor($nIndex)
        $BGRColor = DllCall("user32.dll", "long", "GetSysColor", "long", $nIndex)
        $BGR = Hex ($BGRColor[0],6 )
        $RGB = "0x" & StringRight($BGR,2) & StringMid($BGR,3,2) & StringLeft($BGR,2)
        Return $RGB
EndFunc
 
;~ Позволяет установить новый цвет для указанного элемента оформления
Func _SetSysColor($nIndex, $nRGBColor)
        $RGB = Hex($nRGBColor,6 )
        $BGR = "0x" & StringRight($RGB,2) & StringMid($RGB,3,2) & StringLeft($RGB,2)
        Local $structColor = DllStructCreate("udword")
        Local $structIndex = DllStructCreate("udword")
        DllStructSetData($structIndex, 1, $nIndex)
        DllStructSetData($structColor, 1, $BGR)
        DllCall("user32.dll", "long", "SetSysColors", "long", 1, "ptr", DllStructGetPtr($structIndex), "ptr", DllStructGetPtr($structColor))
EndFunc


Creat0R 28-05-2007 14:50

Diamond
Спасибо, давно искал что-то подобное :)

Diamond 28-05-2007 15:13

Creat0R
Рад, что пригодилось. Собирал информацию как говориться с мира по нитке. :)
Вот только мне не нравиться что эти функции цвета переворачивают с RGB на GBR, надо будет потом поправить...

Diamond 29-05-2007 10:18

Creat0R
Поправил. :) Теперь только RGB.

V0van3 29-05-2007 16:06

Я написал AutoIt скрипт который автоматически закрывает рекламное окно в visicom 2003:

;Отслеживает и закрывает рекламное окно
;скрыть в системной панели индикатор AutoIt
;AutoItSetOption("TrayIconHide", 1)
;Отображать текущую строку сценария с помощью индикатора системной панели в режиме отладки.
AutoItSetOption("TrayIconDebug", 1)
AutoItSetOption("SendKeyDelay", 15)
;Переходим в папку с visicom
;FileChangeDir('%1%')
FileChangeDir('c:\temp\Visicom')
Run('Vcmurbas.exe')
WinWaitActive('','')
ControlClick('','Вход','Button1')
;MsgBox(4096, "", ProcessExists("mmc.exe"))
;включить режим поиска в окнах-потомках
Opt("WinSearchChildren", 1)
While ProcessExists("ntvdm.exe")<>0
;дожидаемся активности окна с рекламой
WinWait('Внимание!','Подробнее...')
WinClose('Внимание!','Подробнее...')
Sleep(200)
WEnd

запускаю %path_cmdutils%\Autoit3.exe Visicom.au3 %visicom_path% (переменные объявлены и заданы верно)
Работает (рекламные окна закрывает), но не отслеживает закрытия visicom и скрипт продолжает зацикливаться.

Прикол в том что vcmurbas.exe запущен через NTVDM и в явном виде его ProcessExists не видет :(

система Win2kSP4en, что посоветуете? Как это можно обойти?



amel27 30-05-2007 04:25

V0van3
Цитата:

vcmurbas.exe запущен через NTVDM и в явном виде его ProcessExists не видет
так вроде работает:
Код:

$pid = Run("Vcmurbas.exe")

While ProcessExists($pid)
  Sleep(200)
WEnd


mariolast 30-05-2007 10:32

Клевая прога для работы с телефонной книгой, картинками, мелодиями и т.п. для целой кучи 357 видов мобил
Скачать http://download.mobiledit.com/mobiledit!/MOBILedit!.exe
Русик http://msilab.net/show.php?rus=1033
Наброски AutoIt скрипта http://forum.oszone.net/showthread.p...697#post592697
:moderator
Цитата:

Цитата из Шапки темы
Данная тема предназначена для общих вопросов по AutoIt. Вопросы по установке приложений при помощи AutoIt следует задавать в соответствии с правилами форума "Автоматическая установка приложений"


voler 31-05-2007 09:06

Вот написал скрипт для установки Adobe Acrobat 7.0.0 Professional но видимо где то проблема с нажатием кнопки, так как вылетает сообщение уверены что хотите отменить установку Adobe Acrobat 7.0.0 Professional, и скрипт авто отвечает нет и установка идет далее. Проверял все кнопки все, вроде указано верно в чем может быть проблема?

HTML код:

#cs
----------------------
Приложение: Adobe Acrobat
На какой(их) версии(ях) тестировалось: 7.0.0 Professional

Автор скрипта: Voler
----------------------
#ce
;предотвращение возможности множественного запуска скрипта
If WinExists(@ScriptName) Then Exit
AutoItWinSetTitle(@ScriptName)
;Отображать текущую строку сценария с помощью индикатора системной панели в режиме отладки.
AutoItSetOption("TrayIconDebug", 1)

; Установка переменных
Global $file='setup.exe', $key='keygen.exe', $AvtCode, $ACStr

Run ( $file )

;Splash
WinWaitActive ( 'Adobe Acrobat 7.0 Professional -  Setup' )
ControlClick ( 'Adobe Acrobat 7.0 Professional -  Setup', '', 'Button1' )

;Welcome to the Adobe Acrobat 7.0 Professional Setup
WinWaitActive ( 'Adobe Acrobat 7.0 Professional - Setup' )
Sleep ( 500 )
ControlClick ( 'Adobe Acrobat 7.0 Professional - Setup', '', 'Button1' )

;Click Next to view the End User License agreement.
WinWaitActive ( 'Adobe Acrobat 7.0 Professional - Setup' )
ControlClick ( 'Adobe Acrobat 7.0 Professional - Setup', '', 'Button1' )

;End User License agreement.
WinWaitActive ( 'Adobe Acrobat 7.0 Professional - Setup' )
ControlClick ( 'Adobe Acrobat 7.0 Professional - Setup', '', 'Button2' )

;Customer Information.
WinWaitActive ( 'Adobe Acrobat 7.0 Professional - Setup' )
ControlClick ( 'Adobe Acrobat 7.0 Professional - Setup', '', 'Button1' )

;Cache the Installer Files.
WinWaitActive ( 'Adobe Acrobat 7.0 Professional - Setup' )
ControlClick ( 'Adobe Acrobat 7.0 Professional - Setup', '', 'Button1' )

;PDFMaker Installation and Integration Information.
WinWaitActive ( 'Adobe Acrobat 7.0 Professional - Setup' )
ControlClick ( 'Adobe Acrobat 7.0 Professional - Setup', '', 'Button1' )

;Please select a setup type.
WinWaitActive ( 'Adobe Acrobat 7.0 Professional - Setup' )
ControlClick ( 'Adobe Acrobat 7.0 Professional - Setup', '', 'Button5' )

;Destination Folder.
WinWaitActive ( 'Adobe Acrobat 7.0 Professional - Setup' )
ControlClick ( 'Adobe Acrobat 7.0 Professional - Setup', '', 'Button1' )

; рапорт инсталятора о готовности к установки
WinWait ( 'Adobe Acrobat 7.0 Professional','Ready to Install the Program' )
WinWaitActive ( 'Adobe Acrobat 7.0 Professional','Ready to Install the Program' )
ControlClick ( 'Adobe Acrobat 7.0 Professional', 'Ready to Install the Program', 'Button1' )

; активация - начало
WinWait  ( 'Adobe Acrobat Installer','Activation Options' )

;это окно иногда появляется, а иногда нет. Закономерность появления не найдена.
If WinExists ( 'Adobe Acrobat Installer', 'Activate Using the Internet' ) Then
      WinActivate (  'Adobe Acrobat Installer', 'Activate Using the Internet' )
      WinWaitActive (  'Adobe Acrobat Installer', 'Activate Using the Internet' )
      ControlClick ( 'Adobe Acrobat Installer', 'Activate Using the Internet', 'Button3' )
EndIf

; продолжение активации - выбираем активировать по телефону
WinWaitActive ( 'Adobe Acrobat Installer','Activation Options' )
Sleep ( 500 )
ControlClick ( 'Adobe Acrobat Installer','Activation Options', 'Button2' )
Sleep ( 500 )
ControlClick ( 'Adobe Acrobat Installer','Activation Options', 'Button7' )

exit


amel27 31-05-2007 12:39

voler
Цитата:

в чем может быть проблема?
проблема очевидна - при появлении окна отрабатывают сразу все 9 ControlClick'ов, т.е. для Button1, Button2, Button5, так как эти окна ничем не отличаются - используйте для идентификации текст окна. Кроме того:

- "предотвращение возможности множественного запуска скрипта" работать не будет, используйте функцию ProcessList();
- если окно может не появиться используйте WinWait() / WinWaitActive() с таймаутом ожидания.
- автоматизацию keygen'а лучше с форума убрать, задавайте вопросы по существу.

_Flame_ 31-05-2007 16:29

Сейчас объясню. У меня есть программа в папке, где такое дерево каталогов.

\
\Files

Мне надо, чтобы открывался txt файл, который лежит в папке \Files


Как мне такое сделать.. (Или как вообще txt открыть...)

voler 31-05-2007 17:00

Цитата:

проблема очевидна - при появлении окна отрабатывают сразу все 9 ControlClick'ов, т.е. для Button1, Button2, Button5, так как эти окна ничем не отличаются - используйте для идентификации текст окна. Кроме того:
Скажи ты имеешь ввиду вставлять текст в

WinWaitActive ( 'Adobe Acrobat 7.0 Professional - Setup' )
ControlClick ( 'Adobe Acrobat 7.0 Professional - Setup', 'Вот Сюда?', 'Button1' ) И какой текст вводить?

HTML код:

&Next >
&Cancel
< &Back
The Wizard will install Adobe Acrobat 7.0 Professional on your computer. To continue, click Next.
WARNING: This program is protected by copyright law and international treaties.
BmpDlgImage
InstallShield
InstallShield
Welcome to the Adobe Acrobat 7.0 Professional Setup


DenchikK 31-05-2007 17:08

Не могу понять, как осуществить задуманное.
Идея такая:
Надо в программе заполнять 3 поля: ссылка, логин, пароль.
Список ссылок, логинов и паролей находится в файлах links.txt, logins.txt, pass.txt
Для одной ссылки, пароля и логина я знаю как это делается:

Код:

#include <GUIConstants.au3>

If WinExists(@ScriptName) Then Exit
AutoItWinSetTitle(@ScriptName)
AutoItSetOption("TrayIconDebug", 1)
AutoItSetOption("SendKeyDelay", 60)
AutoItSetOption("MouseCoordMode", 0)

Global $file, $line_logins, $line_pass, $line_links

; Чтение Файла С Логинами

$file = FileOpen("logins.txt", 0)

If $file = -1 Then
    MsgBox(0, "Error", "Unable to open file.")
    Exit
EndIf

$line_logins = FileReadLine($file)

FileClose($file)

; Чтение Файла С Паролями

$file = FileOpen("pass.txt", 0)

If $file = -1 Then
    MsgBox(0, "Error", "Unable to open file.")
    Exit
EndIf

$line_pass = FileReadLine($file)

FileClose($file)

; Чтение Файла С Линками

$file = FileOpen("links.txt", 0)

If $file = -1 Then
    MsgBox(0, "Error", "Unable to open file.")
    Exit
EndIf

$line_links = FileReadLine($file)

FileClose($file)

; Запуск программы

Run ('avaload.exe')

; Построение GUI

GUICreate("Автозаполнение", 330, 300)

$checkCN1 = GUICtrlCreateCheckbox ($line_logins, 10, 10, 180, 20)
$checkCN2 = GUICtrlCreateCheckbox ("CHECKBOX 2", 10, 30, 180, 20)
$checkCN3 = GUICtrlCreateCheckbox ("CHECKBOX 3", 10, 50, 180, 20)

$Start = GUICtrlCreateButton("Заполнить", 200, 10, 120, 20)
$Close = GUICtrlCreateButton("Выход", 200, 30, 120, 20)

GUISetState ()

; Основная Работа Скрипта

While 1
$msg = GUIGetMsg()
If $msg = $GUI_EVENT_CLOSE  Or $msg = $Close Then
        Exit

ElseIf $msg = $Start Then

      If GUICtrlRead($checkCN1) = 1 Then
                    WinActivate ("AvaRemoteLoad")
                    ControlSetText ( 'AvaRemoteLoad', '', 'Edit1', $line_links )
                    ControlSetText ( 'AvaRemoteLoad', '', 'Edit2', $line_logins)
                    ControlSetText ( 'AvaRemoteLoad', '', 'Edit3', $line_pass )
        EndIf

        If GUICtrlRead($checkCN2) = 1 Then
                    MsgBox(0,"Установка","Чекбокс 2",1)
        EndIf

        If GUICtrlRead($checkCN3) = 1 Then
                    MsgBox(0,"Установка","Чекбокс 3",1)
        EndIf

EndIf
WEnd

а вот как переделать это под список - чтоб чекбоксов появлялось столько, сколько записей.

И ещё наверное, либо есть способ чтоб выделялся только один чекбокс, либо надо будет переделать под radiobutton.

Заранее благодарен за любую помощь.

Creat0R 31-05-2007 20:20

_Flame_
Цитата:

Мне надо, чтобы открывался txt файл, который лежит в папке \Files
Открывался в редакторе по умолчанию? тогда так:

Код:

$FilePath = "Files\textfile.txt"
ShellExecute($FilePath)

DenchikK
Цитата:

как переделать это под список - чтоб чекбоксов появлялось столько, сколько записей.
Примерно так - это отдельный набросок для создания чекбоксов в зависимости от числа записей, которые предварительно нужно поместить в массив (см. функцию _FileReadToArray() ) :

Код:

;---это в начало файла---
#include <File.au3>
;------------------------

; Построение GUI
GUICreate("Автозаполнение", 330, 300)

Global $Links_Array
_FileReadToArray("links.txt", $Links_Array)

If IsArray($Links_Array) Then
    $Top = 10
    For $i = 1 To $Links_Array[0]
        GUICtrlCreateCheckbox($Links_Array[$i], 10, $Top, 180, 20)
        $Top += 20
    Next
EndIf

$Start = GUICtrlCreateButton("Заполнить", 200, 10, 120, 20)
$Close = GUICtrlCreateButton("Выход", 200, 30, 120, 20)

GUISetState()

Если записей (каждая запись это отдельная строка в файле) больше чем чекбоксы помещаются в ГУИ, то также как я проделал с переменной $Top, нужно проделать и с левым выравниванием чекбоксов ($Left = 10 и потом прибавлять в цикле, скажем по 80).

DenchikK 01-06-2007 02:47

Creat0R
Спасибо большое! Построение GUI идет как надо, но вот только теперь я не понимаю, как обрабатывать эти чекбоксы... Не понимаю, как это:

Код:

If GUICtrlRead($checkCN1) = 1 Then
                    WinActivate ("AvaRemoteLoad")
            ControlSetText ( 'AvaRemoteLoad', '', 'Edit1', $Links_Array[1] )
                    ControlSetText ( 'AvaRemoteLoad', '', 'Edit2', $Logins_Array[1])
                    ControlSetText ( 'AvaRemoteLoad', '', 'Edit3', $Pass_Array[1])
        EndIf

заставить работать с построением GUI...

Тупо заделал так, но теряется возможность определять, сколько чекбоксов надо сделать для содержимого файла логов:

Код:

#include <GUIConstants.au3>
#include <File.au3>

If WinExists(@ScriptName) Then Exit
AutoItWinSetTitle(@ScriptName)
AutoItSetOption("TrayIconDebug", 1)
AutoItSetOption("SendKeyDelay", 60)
AutoItSetOption("MouseCoordMode", 0)

; Запуск программы

Run ('avaload.exe')

; Построение GUI

GUICreate("Автозаполнение", 330, 300)

Global $Links_Array, $Logins_Array, $Pass_Array

_FileReadToArray("logins.txt", $Logins_Array)
_FileReadToArray("pass.txt", $Pass_Array)
_FileReadToArray("links.txt", $Links_Array)

$checkCN1 = GUICtrlCreateCheckbox ($Logins_Array[1], 10, 10, 180, 20)
$checkCN2 = GUICtrlCreateCheckbox ($Logins_Array[2], 10, 30, 180, 20)
$checkCN3 = GUICtrlCreateCheckbox ($Logins_Array[3], 10, 50, 180, 20)
$checkCN4 = GUICtrlCreateCheckbox ($Logins_Array[4], 10, 70, 180, 20)
$checkCN5 = GUICtrlCreateCheckbox ($Logins_Array[5], 10, 90, 180, 20)
$checkCN6 = GUICtrlCreateCheckbox ($Logins_Array[6], 10, 110, 180, 20)
$checkCN7 = GUICtrlCreateCheckbox ($Logins_Array[7], 10, 130, 180, 20)
$checkCN8 = GUICtrlCreateCheckbox ($Logins_Array[8], 10, 150, 180, 20)
$checkCN9 = GUICtrlCreateCheckbox ($Logins_Array[9], 10, 170, 180, 20)
$checkCN10 = GUICtrlCreateCheckbox ($Logins_Array[9], 10, 190, 180, 20)

$Start = GUICtrlCreateButton("Заполнить", 200, 10, 120, 20)
$Close = GUICtrlCreateButton("Выход", 200, 30, 120, 20)

GUISetState ()

; Основная Работа Скрипта

While 1
$msg = GUIGetMsg()
If $msg = $GUI_EVENT_CLOSE  Or $msg = $Close Then
        Exit

ElseIf $msg = $Start Then

 If GUICtrlRead($checkCN1) = 1 Then
                    WinActivate ("AvaRemoteLoad")
                ControlSetText ( 'AvaRemoteLoad', '', 'Edit1', $Links_Array[1])
                    ControlSetText ( 'AvaRemoteLoad', '', 'Edit2', $Logins_Array[1])
                    ControlSetText ( 'AvaRemoteLoad', '', 'Edit3', $Pass_Array[1])
        EndIf

        If GUICtrlRead($checkCN2) = 1 Then
                    WinActivate ("AvaRemoteLoad")
                ControlSetText ( 'AvaRemoteLoad', '', 'Edit1', $Links_Array[2])
                    ControlSetText ( 'AvaRemoteLoad', '', 'Edit2', $Logins_Array[2])
                    ControlSetText ( 'AvaRemoteLoad', '', 'Edit3', $Pass_Array[2])
        EndIf

        If GUICtrlRead($checkCN3) = 1 Then
                    WinActivate ("AvaRemoteLoad")
                ControlSetText ( 'AvaRemoteLoad', '', 'Edit1', $Links_Array[3])
                    ControlSetText ( 'AvaRemoteLoad', '', 'Edit2', $Logins_Array[3])
                    ControlSetText ( 'AvaRemoteLoad', '', 'Edit3', $Pass_Array[3])
        EndIf

        If GUICtrlRead($checkCN4) = 1 Then
                    WinActivate ("AvaRemoteLoad")
                ControlSetText ( 'AvaRemoteLoad', '', 'Edit1', $Links_Array[4])
                    ControlSetText ( 'AvaRemoteLoad', '', 'Edit2', $Logins_Array[4])
                    ControlSetText ( 'AvaRemoteLoad', '', 'Edit3', $Pass_Array[4])
        EndIf

        If GUICtrlRead($checkCN5) = 1 Then
                    WinActivate ("AvaRemoteLoad")
                ControlSetText ( 'AvaRemoteLoad', '', 'Edit1', $Links_Array[5])
                    ControlSetText ( 'AvaRemoteLoad', '', 'Edit2', $Logins_Array[5])
                    ControlSetText ( 'AvaRemoteLoad', '', 'Edit3', $Pass_Array[5])
        EndIf

        If GUICtrlRead($checkCN6) = 1 Then
                    WinActivate ("AvaRemoteLoad")
                ControlSetText ( 'AvaRemoteLoad', '', 'Edit1', $Links_Array[5])
                    ControlSetText ( 'AvaRemoteLoad', '', 'Edit2', $Logins_Array[5])
                    ControlSetText ( 'AvaRemoteLoad', '', 'Edit3', $Pass_Array[5])
        EndIf

        If GUICtrlRead($checkCN7) = 1 Then
                    WinActivate ("AvaRemoteLoad")
                ControlSetText ( 'AvaRemoteLoad', '', 'Edit1', $Links_Array[7])
                    ControlSetText ( 'AvaRemoteLoad', '', 'Edit2', $Logins_Array[7])
                    ControlSetText ( 'AvaRemoteLoad', '', 'Edit3', $Pass_Array[7])
        EndIf

        If GUICtrlRead($checkCN8) = 1 Then
                    WinActivate ("AvaRemoteLoad")
                ControlSetText ( 'AvaRemoteLoad', '', 'Edit1', $Links_Array[8])
                    ControlSetText ( 'AvaRemoteLoad', '', 'Edit2', $Logins_Array[8])
                    ControlSetText ( 'AvaRemoteLoad', '', 'Edit3', $Pass_Array[8])
        EndIf

        If GUICtrlRead($checkCN9) = 1 Then
                    WinActivate ("AvaRemoteLoad")
                ControlSetText ( 'AvaRemoteLoad', '', 'Edit1', $Links_Array[9])
                    ControlSetText ( 'AvaRemoteLoad', '', 'Edit2', $Logins_Array[9])
                    ControlSetText ( 'AvaRemoteLoad', '', 'Edit3', $Pass_Array[9])
        EndIf

        If GUICtrlRead($checkCN10) = 1 Then
                    WinActivate ("AvaRemoteLoad")
                ControlSetText ( 'AvaRemoteLoad', '', 'Edit1', $Links_Array[10])
                    ControlSetText ( 'AvaRemoteLoad', '', 'Edit2', $Logins_Array[10])
                    ControlSetText ( 'AvaRemoteLoad', '', 'Edit3', $Pass_Array[10])
        EndIf


EndIf
WEnd

Попробовал по изощряться для компактности с $i - не вышло...

Creat0R 01-06-2007 04:45

DenchikK
Цитата:

как обрабатывать эти чекбоксы
По идее можно создавать динамический массив который будет содержать в себе все управляющие идентификаторы (ControlID) от созданных чекбоксов, и отслеживать каждый раз нужный проверяя элементы массива..

Лучше (надёжнее) проверять все чекбоксы, а нужный текст брать из самого названия чекбокса, ведь каждый зажатый чекбокс (который мы и будем проверять), имеет то название, которое и требуется для записи...

Я бы если честно предложил использовать события (Events), правда придётся немного переделать структуру всего GUI (не сильно :) ), для этого в начале скрипта нужно установить опции для срабатывания событии - Opt("GuiOnEventMode", 1), и потом всем (нужным для обработки) контролам присваивать функцию которая будет срабатывать на событие, так в дальнейшем легче обрабатывать элементы (имхо):

Код:

#include <GUIConstants.au3>
#include <File.au3>

If WinExists(@ScriptName) Then Exit
AutoItWinSetTitle(@ScriptName)
Opt("TrayIconDebug", 1)
Opt("SendKeyDelay", 60)
Opt("MouseCoordMode", 0)
Opt("GuiOnEventMode", 1)

Global $Array_logins, $Array_pass, $Array_links, $CheckBoxIDArray[1]

; Чтение Файла С Логинами
_FileReadToArray("logins.txt", $Array_logins)
If @error Then
    MsgBox(0, "Error", "Unable to open file.")
    Exit
EndIf

; Чтение Файла С Паролями
_FileReadToArray("pass.txt", $Array_pass)
If @error Then
    MsgBox(0, "Error", "Unable to open file.")
    Exit
EndIf

; Чтение Файла С Линками
_FileReadToArray("links.txt", $Array_links)
If @error Then
    MsgBox(0, "Error", "Unable to open file.")
    Exit
EndIf

; Запуск программы

Run ('avaload.exe')

; Построение GUI

GUICreate("Автозаполнение", 330, 300)
GUISetOnEvent(-3, "Quit")

$Top = 10
$Left = 10

;Чекбоксы для логинов
If IsArray($Array_logins) Then
    For $i = 1 To $Array_logins[0]
        ReDim $CheckBoxIDArray[UBound($CheckBoxIDArray)+1]
        $CheckBoxIDArray[UBound($CheckBoxIDArray)-1] = GUICtrlCreateCheckbox($Array_logins[$i], $Left, $Top, 180, 20)
        $Top += 20

                If $Top >= 200 Then
            $Top = 10
            $Left += 90
        EndIf
    Next
EndIf

;Чекбоксы для паролей
If IsArray($Array_pass) Then
    For $i = 1 To $Array_pass[0]
        ReDim $CheckBoxIDArray[UBound($CheckBoxIDArray)+1]
        $CheckBoxIDArray[UBound($CheckBoxIDArray)-1] = GUICtrlCreateCheckbox($Array_pass[$i], $Left, $Top, 180, 20)
        $Top += 20
        If $Top >= 160 Then
            $Top = 10
            $Left += 90
        EndIf
    Next
EndIf

;Чекбоксы для линков
If IsArray($Array_links) Then
    For $i = 1 To $Array_links[0]
        ReDim $CheckBoxIDArray[UBound($CheckBoxIDArray)+1]
        $CheckBoxIDArray[UBound($CheckBoxIDArray)-1] = GUICtrlCreateCheckbox($Array_links[$i], $Left, $Top, 180, 20)
        $Top += 20
        If $Top >= 160 Then
            $Top = 10
            $Left += 90
        EndIf
    Next
EndIf

$Start = GUICtrlCreateButton("Заполнить", 200, 10, 120, 20)
GUICtrlSetOnEvent($Start, "Start")

$Close = GUICtrlCreateButton("Выход", 200, 30, 120, 20)
GUICtrlSetOnEvent($Close, "Quit")

GUISetState()

While 1
    Sleep(10)
WEnd

; Основная Работа Скрипта - функция для обработки чекбоксов
Func Start()
    For $i = 1 To UBound($CheckBoxIDArray)-1
        If GUICtrlRead($CheckBoxIDArray[$i]) = 1 Then
            WinActivate("AvaRemoteLoad")
            $CurrentText = GUICtrlRead($CheckBoxIDArray[$i], 1)
            ControlSetText('AvaRemoteLoad', '', 'Edit1', $CurrentText)
            ControlSetText('AvaRemoteLoad', '', 'Edit2', $CurrentText)
            ControlSetText('AvaRemoteLoad', '', 'Edit3', $CurrentText)
        EndIf
    Next
EndFunc

Func Quit()
    Exit
EndFunc

P.S
Кстати, (кажется в последних версиях AutoIt) не обязательно активировать окно для ControlSetText() ;).

DenchikK 01-06-2007 05:31

Creat0R
Ещё раз огромное спасибо!
Но я что то пока так и не смог разобраться, как же всё это работает...

Эти строки я убрал, так они не нужны и мешают (идея какая - если выбран 3 логин, то выбираются вместе с ним 3 пасс и 3 линк):

Код:

;Чекбоксы для паролей

If IsArray($Array_pass) Then
    For $i = 1 To $Array_pass[0]
        ReDim $CheckBoxIDArray[UBound($CheckBoxIDArray)+1]
        $CheckBoxIDArray[UBound($CheckBoxIDArray)-1] = GUICtrlCreateCheckbox($Array_pass[$i], $Left, $Top, 180, 20)
        $Top += 20
        If $Top >= 160 Then
            $Top = 10
            $Left += 90
        EndIf
    Next
EndIf

;Чекбоксы для линков
If IsArray($Array_links) Then
    For $i = 1 To $Array_links[0]
        ReDim $CheckBoxIDArray[UBound($CheckBoxIDArray)+1]
        $CheckBoxIDArray[UBound($CheckBoxIDArray)-1] = GUICtrlCreateCheckbox($Array_links[$i], $Left, $Top, 180, 20)
        $Top += 20
        If $Top >= 160 Then
            $Top = 10
            $Left += 90
        EndIf
    Next
EndIf

и видать из за этого результат этого один и тот же для всех полей:
Код:

; Основная Работа Скрипта - функция для обработки чекбоксов
Func Start()
    For $i = 1 To UBound($CheckBoxIDArray)-1
        If GUICtrlRead($CheckBoxIDArray[$i]) = 1 Then
            WinActivate("AvaRemoteLoad")
            $CurrentText = GUICtrlRead($CheckBoxIDArray[$i], 1)
            ControlSetText('AvaRemoteLoad', '', 'Edit1', $CurrentText)
            ControlSetText('AvaRemoteLoad', '', 'Edit2', $CurrentText)
            ControlSetText('AvaRemoteLoad', '', 'Edit3', $CurrentText)
        EndIf
    Next
EndFunc

То бишь у меня получается в поля Линк, Логин, Пароль - пихается Логин... Сижу, пытаюсь понять, как, не выходит...

И скорее всего придётся отказаться от чекбоксов в пользу радиобуттонов, но структура case мне пока не даётся...

amel27 01-06-2007 05:58

voler
Код:

WinWait ( 'Adobe Acrobat 7.0 Professional - Setup', 'Сюда вставить тект окна, отличающий его от остальных')
ControlClick ( 'Adobe Acrobat 7.0 Professional - Setup', 'Сюда тот же текст, что и в предыдущей функции', 'Button1' )

Текст окна можно посмотреть в штатной "AutoIt Window Info".

Creat0R 01-06-2007 06:30

DenchikK
Цитата:

идея какая - если выбран 3 логин, то выбираются вместе с ним 3 пасс и 3 линк
Я если честно теперь ещё больше запутался в отношении самой идеи...

Если можешь, поясни пошагово (не программно, а как бы со стороны юзера) - Что должно произойти, какие чекбоксы будут созданы (их структура и цель назначения), что должно происходить при зажатом чекбоксе (после нажатия кнопки Start) и т.д.

А я попробую построить соответственно гуи и описать процесс... должно быть не сложно, но цель немного смутновата - когда есть чётко поставленная цель, остальное это время, и усидчивость! (+ немного знании ;)).

ChVL 01-06-2007 11:34

В одной папке находятся скрипт .au3 и .exe исходного приложения. При запуске скрипта всё устанавливается правильно, до самого конца.
Через контекстное меню компилирую. При этом скомпилированный .exe "съедает" исходный .exe и имеет иконку такую же, как и скрипт. При запуске скомпилированного .exe ничего не происходит.
AutoIt версия 3.2.4.9.
Что делаю не так?

amel27 01-06-2007 11:43

ChVL
Цитата:

скомпилированный .exe "съедает" исходный .exe и имеет иконку такую же, как и скрипт.
так ты выбери для скрипта другое имя, к примеру: Setup.exe - приложение, Setup_AU.au3 - скрипт, тогда никакого наложения имен при компиляции не будет

ChVL 01-06-2007 12:04

amel27
Цитата:

выбери для скрипта другое имя
Действительно, всё работает! Спасибо!
Странно, что нигде ни в одном мануале о необходимости переименования скрипта нет ни слова. Это же не очевидно. Ну, съедает... А может так и надо?

V0van3 01-06-2007 13:36

уважаемый amel27
к сожалению в данном случае не всё так просто. видимо вы не проверяли.
я добавил сразу после запуска Visicom
MsgBox(4096, "otladka", $pid) и оказалось что Visicom.exe имеет Pid=0 т.е. не отлавливает
т.к. Visicom запускается как дочерний процесс NTVDM.exe, последний продолжает оставаться в памяти при закрытии Visiciom то PID NTVDM'а как условие не годится.
В случае например с Notepad.exe или ещё с каким-нибуть другим приложением, которое висит в памяти как самостоятельный процесс проблем нет.
Естессно ваш код более правильный т.к. позволяет отловить именно тот процесс который запустил скрипт (если есть другой процесс с таким же именем), но в данном случае не в этом проблема.

DenchikK 01-06-2007 14:09

Creat0R
Суть работы скрипта такова:
Заливка файлов по списку ссылок в аккаунты, доступ к которым задается логином и паролем.
То есть со стороны юзеа это выглядит так: он подготоавливает список ссылок на файлы, которые хочет скачать, и список пустых аккаунтов, в которые эти ссылки будут помещены. 1 линк = 1 аккаунт. При запуске скрипта юзер выбирает, в какой именно аккаунт будет заливаться любой по списку файл по линку (radibutton подходит лучше, но я что то до сих пор с опреатором case из примера не разобрался):
http://img154.imageshack.us/img154/3923/1autowa8.jpg

И вот когда выбран нужный аккаунт, поле самой программы заполняется:
http://img154.imageshack.us/img154/8333/2autoyc1.jpg

В поле линк - идет ссылка, тут наверное даже не принципиально её положение в файле, пускай будет самая первая в списке (ещё б сделать в этом случае её удаление из списка, после заполнения поля)
В поле Логин - тот Логин, что выбран, в поле Пароль - соответствующий ему пароль . Например 6 логин сверху соответствует 6 сверху паролю (то же былоб интереснее, чтоб после заполнения они бы стирались).

Вообщем как то так...

Спасибо Вам что Вы со мною возитесь! :-)

voler 01-06-2007 15:55

Проблема, при отработке скрипта. Ставлю прогу , кто может объясните почему нажатие кнопок не срабатывает. В предыдущем посте мне объяснили в чем проблема. Но не помогает.

HTML код:

#cs
----------------------

----------------------
#ce
;предотвращение возможности множественного запуска скрипта
If WinExists(@ScriptName) Then Exit
AutoItWinSetTitle(@ScriptName)
;Отображать текущую строку сценария с помощью индикатора системной панели в режиме отладки.
AutoItSetOption("TrayIconDebug", 1)

; Установка переменных
Global $file='hddinsp.exe', $ACStr

Run ( $file )

WinWaitActive ( 'Installer Language', 'Please select a language.' )
ControlClick ( 'Installer Language', 'Please select a language.', 'Button1' )

WinWaitActive ( 'Установка Hard Drive Inspector Professional', 'Мастер установки Hard Drive Inspector Professional' )
ControlClick ( 'Установка Hard Drive Inspector Professional', 'Мастер установки Hard Drive Inspector Professional', 'Button2' )

WinWaitActive ( 'Установка Hard Drive Inspector Professional', 'Лицензионное соглашение' )
ControlClick ( 'Установка Hard Drive Inspector Professional', 'Лицензионное соглашение', 'Button4' )

WinWaitActive ( 'Установка Hard Drive Inspector Professional', 'Лицензионное соглашение' )
ControlClick ( 'Установка Hard Drive Inspector Professional', 'Лицензионное соглашение', 'Button2' )

WinWaitActive ( 'Установка Hard Drive Inspector Professional', 'Выбор папки установки' )
ControlClick ( 'Установка Hard Drive Inspector Professional', 'Выбор папки установки', 'Button2' )

WinWaitActive ( 'Установка Hard Drive Inspector Professional', 'Папка в меню "Пуск"' )
ControlClick ( 'Установка Hard Drive Inspector Professional', 'Папка в меню "Пуск"', 'Button2' )

WinWaitActive ( 'Установка Hard Drive Inspector Professional', 'Установка завершена' )
ControlClick ( 'Установка Hard Drive Inspector Professional', 'Установка завершена', 'Button2' )

WinWaitActive ( 'Установка Hard Drive Inspector Professional', 'Завершение работы мастера установки' )
ControlClick ( 'Установка Hard Drive Inspector Professional', 'Завершение работы мастера установки', 'Button4' )

WinWaitActive ( 'Установка Hard Drive Inspector Professional', 'Завершение работы мастера установки' )
ControlClick ( 'Установка Hard Drive Inspector Professional', 'Завершение работы мастера установки', 'Button2' )

exit


ChVL 01-06-2007 16:28

Сразу недосмотрел. Скомпилированный exe работает, но только тогда, когда рядом присутствует исходный exe, т.е. ничем не отличается от работы со скриптом au3. Самостоятельно НЕ запускается - сразу же требует исходный exe. Декомпилировал его с помощью Exe2Aut и увидел, что в него один к одному переписан скрипт и больше ничего нет, хотя объём около 200 KB.
Интересный момент: видимое содержимое декомпилированного exe с одинаковыми именами (который вообще не запускается) абсолютно аналогично описанному выше (это просто текст скрипта), и объёмы у них одинаковы.
Где ещё копать?

Diamond 01-06-2007 20:29

voler
Цитата:

Ставлю прогу , кто может объясните почему нажатие кнопок не срабатывает.
Проверил несколько кнопок - работает, но только тогда, когда окно активно...
Я бы заменил WinWaitActive на WinWait(), поскольку ControlClick() умеет работать даже с неактивными окнами, и вполне достаточно просто дождаться появления окна.

Creat0R 02-06-2007 04:19

DenchikK
Попробую переформулировать (для проверки, правильно ли я понял):

Запускаем скрипт, создаются столько чекбоксов, сколько есть записей в файле линков (и только для этих записей создаём чекбоксы)...

а точнее (как я понял), создаём radio button ;)

Далее после нажатия на Старт, в каждое поле вписывается соответственно - Ссылка, логин, и пароль.

Вот только есть одна проблема - какое должно быть название у чекбоксов? можно совместить что то вроде этого:

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

Такой вопрос:
А списки обязательно держать в трёх разных файлах? может можно записывать в один ini файл (к примеру AvaRemote.ini), чтобы имя секции ровнялось ссылке, а под секцией записи пароля и логина, что то типа такого:

Код:

[http://mail.ru]
loging1=DenchikK
pass1=12345

login2=DenchikK
pass2=54321

и т.д

Так будет намного эргономичнее и удобнее обрабатывать данные.

Работать с Radio button совсем не сложно, почти также как и с обычными чекбоксами, разница только в том что может быть выбран один пункт в определённой группе (при наличии таковой).

Вот пример:

Код:

GUICreate("test")

$Radio1 = GUICtrlCreateRadio("Radio1", 10, 40)

$Radio2 = GUICtrlCreateRadio("Radio2", 10, 70)

$Radio3 = GUICtrlCreateRadio("Radio3", 10, 100)

$ShowSelectedButton = GUICtrlCreateButton("Show checked button", 150, 200)

GUISetState()

While 1
    Switch GUIGetMsg()
        Case -3
            Exit
        Case $ShowSelectedButton
            Select
                Case GUICtrlRead($Radio1) = 1
                    MsgBox(0, "", "This radio button checked: " & GUICtrlRead($Radio1, 1))
                Case GUICtrlRead($Radio2) = 1
                    MsgBox(0, "", "This radio button checked: " & GUICtrlRead($Radio2, 1))
                Case GUICtrlRead($Radio3) = 1
                    MsgBox(0, "", "This radio button checked: " & GUICtrlRead($Radio3, 1))
            EndSelect
    EndSwitch
WEnd


ChVL
Цитата:

Скомпилированный exe работает, но только тогда, когда рядом присутствует исходный exe
Это напряму зависит от того, какой состав скрипта, возможно в скрипте используются данные читаемые при выполнении из самого скрипта :) - чтобы сказать более точно, необходимо видеть исходный код.

DenchikK 02-06-2007 13:02

Creat0R
Цитата:

Запускаем скрипт, создаются столько чекбоксов, сколько есть записей в файле линков (и только для этих записей создаём чекбоксы)...
Почти так - только не линков, а логинов. :-)

Цитата:

Вот только есть одна проблема - какое должно быть название у чекбоксов?
Названия - как у логинов.

Цитата:

А списки обязательно держать в трёх разных файлах? может можно записывать в один ini файл (к примеру AvaRemote.ini)
Это было б вообще прекрасно! Я и не знал о такой возможности!

Цитата:

Работать с Radio button совсем не сложно, почти также как и с обычными чекбоксами
Спасибочки! Сейчас буду пробовать работать с Radio Button

Добавлено ещё раз :-)
C radiobutton кое как разобрался. С ini файлом вроде то же (спасибо огромное за подсказку его использовать! так стало гораздо удобнее ). Вот немного уменьшил скрипт, как смог:
Код:

#include <GUIConstants.au3>
#include <File.au3>

If WinExists(@ScriptName) Then Exit
AutoItWinSetTitle(@ScriptName)
AutoItSetOption("TrayIconDebug", 1)
AutoItSetOption("SendKeyDelay", 60)
AutoItSetOption("MouseCoordMode", 0)

Global $i, $file, $group_1, $group_2, $group_3, $Links_Array, $Logins_Array, $Pass_Array, $Servers_Array, $Secrets_Array

; Запуск программы

Run ('avaload.exe')

; Считывание Данных

$Logins_Array = IniReadSection("ava.ini", "logins")
$Pass_Array = IniReadSection("ava.ini", "pass")
$Links_Array = IniReadSection("ava.ini", "links")
$Servers_Array = IniReadSection("ava.ini", "servers")
$Secrets_Array = IniReadSection("ava.ini", "secrets")

; Построение GUI

GUICreate("Автозаполнение", 340, 350)

;If IsArray($Links_Array) Then
;    $Top = 20
;    For $i = 1 To Logins_Array[0][0]
;    GUICtrlCreateRadio($Logins_Array[$i][1], 10, $Top)
;    $Top += 20
;    Next
;EndIf

$Radio1 = GUICtrlCreateRadio($Logins_Array[1][1], 10, 20)
$Radio2 = GUICtrlCreateRadio($Logins_Array[2][1], 10, 40)
$Radio3 = GUICtrlCreateRadio($Logins_Array[3][1], 10, 60)
$Radio4 = GUICtrlCreateRadio($Logins_Array[4][1], 10, 80)
$Radio5 = GUICtrlCreateRadio($Logins_Array[5][1], 10, 100)
$Radio6 = GUICtrlCreateRadio($Logins_Array[6][1], 10, 120)
$Radio7 = GUICtrlCreateRadio($Logins_Array[7][1], 10, 140)
$Radio8 = GUICtrlCreateRadio($Logins_Array[8][1], 10, 160)
$Radio9 = GUICtrlCreateRadio($Logins_Array[9][1], 10, 180)
$Radio10 = GUICtrlCreateRadio($Logins_Array[10][1], 10, 200)
$Radio11 = GUICtrlCreateRadio($Logins_Array[11][1], 10, 220)
$Radio12 = GUICtrlCreateRadio($Logins_Array[12][1], 10, 240)
$Radio13 = GUICtrlCreateRadio($Logins_Array[13][1], 10, 260)
$Radio14 = GUICtrlCreateRadio($Logins_Array[14][1], 10, 280)
$Radio15 = GUICtrlCreateRadio($Logins_Array[15][1], 10, 300)
$Radio16 = GUICtrlCreateRadio($Logins_Array[16][1], 10, 320)

$Start = GUICtrlCreateButton("Заполнить", 210, 20, 120, 20)
$Close = GUICtrlCreateButton("Выход", 210, 40, 120, 20)
$Server1  = GUICtrlCreateButton("Сервер 1", 210, 60, 120, 20)
$Server2  = GUICtrlCreateButton("Сервер 2", 210, 80, 120, 20)

$group_1 = GUICtrlCreateGroup ("Выбор Аккаунта", 5, 5, 190, 340)
$group_2 = GUICtrlCreateGroup ("Кнопочки", 205, 5, 130, 100)
$group_3 = GUICtrlCreateGroup ("Описание", 205, 105, 130, 240)

$Label1 = GUICtrlCreateLabel("    Описание Работы", 210, 120)
$Label2 = GUICtrlCreateLabel("1. Впишите в ava.ini", 210, 140)
$Label3 = GUICtrlCreateLabel("линки,логины,пароли,", 210, 155)
$Label4 = GUICtrlCreateLabel("параметры серверов.", 210, 170)
$Label5 = GUICtrlCreateLabel("2. Выберите Сервер", 210, 185)
$Label6 = GUICtrlCreateLabel("3. Выберите пустой ", 210, 200)
$Label7 = GUICtrlCreateLabel("аккаунт для заливки. ", 210, 215)
$Label8 = GUICtrlCreateLabel("    Принцип работы: ", 210, 235)
$Label9 = GUICtrlCreateLabel("Например, выбираем", 210, 250)
$Label10 = GUICtrlCreateLabel("первый логин,в него", 210, 265)
$Label11 = GUICtrlCreateLabel("будет заливаться ", 210, 280)
$Label12 = GUICtrlCreateLabel("первый линк. и.т.д", 210, 295)
$Label13 = GUICtrlCreateLabel("            Удачи! ", 210, 315)

GUISetState ()

; Основная Работа Скрипта

GUISetState()  ; display the GUI

While 1
    Switch GUIGetMsg()
        Case -3
            Exit
 
        Case $Close
            Exit

        Case $Server1

                WinActivate ("AvaRemoteLoad")
                ControlClick ( 'AvaRemoteLoad', '', "Button4")

                WinWaitActive ('Настройки')
                ControlSetText ( 'Настройки', '', 'Edit1', $Servers_Array[1][1])
                ControlSetText ( 'Настройки', '', 'Edit2', $Secrets_Array[1][1])

                ControlClick ( 'Настройки', '', "Button2")

        Case $Server2
                WinActivate ("AvaRemoteLoad")
                ControlClick ( 'AvaRemoteLoad', '', "Button4")

                WinWaitActive ('Настройки')
                ControlSetText ( 'Настройки', '', 'Edit1', $Servers_Array[2][1])
                ControlSetText ( 'Настройки', '', 'Edit2', $Secrets_Array[2][1])

                ControlClick ( 'Настройки', '', "Button2")

        Case $Start

        Select

        Case GUICtrlRead($Radio1) = 1
                $i = 1
        Case GUICtrlRead($Radio2) = 1
                $i = 2
        Case GUICtrlRead($Radio3) = 1
                $i = 3
        Case GUICtrlRead($Radio4) = 1
                $i = 4
        Case GUICtrlRead($Radio5) = 1
                $i = 5
        Case GUICtrlRead($Radio6) = 1
                $i = 6
        Case GUICtrlRead($Radio7) = 1
                $i = 7
        Case GUICtrlRead($Radio8) = 1
                $i = 8
        Case GUICtrlRead($Radio9) = 1
                $i = 9
        Case GUICtrlRead($Radio10) = 1
                $i = 10
        Case GUICtrlRead($Radio11) = 1
                $i = 11
        Case GUICtrlRead($Radio12) = 1
                $i = 12
        Case GUICtrlRead($Radio13) = 1
                $i = 13
        Case GUICtrlRead($Radio14) = 1
                $i = 14
        Case GUICtrlRead($Radio15) = 1
                $i = 15
        Case GUICtrlRead($Radio16) = 1
                $i = 16
            EndSelect

                    WinActivate ("AvaRemoteLoad")
            ControlSetText ( 'AvaRemoteLoad', '', 'Edit1', $Links_Array[$i][1])
                    ControlSetText ( 'AvaRemoteLoad', '', 'Edit2', $Logins_Array[$i][1])
                    ControlSetText ( 'AvaRemoteLoad', '', 'Edit3', $Pass_Array[$i][1])

EndSwitch
WEnd

И вот тут у меня появляется такая затыка:

Для последующей обработки выбора radiobutton
Код:

Case GUICtrlRead($Radio1) = 1
                $i = 1

пытался впихнуть строчку
Код:

If IsArray($Logins_Array) Then
    $Top = 20
    For $i = 1 To Logins_Array[0][0]
    GUICtrlCreateRadio($Logins_Array[$i][1], 10, $Top)
  $Radio[$i] = GUICtrlCreateRadio($Logins_Array[$i][1], 10, $Top)
    $Top += 20
    Next
EndIf

но не получилось, вываливается ошибка. Как сопоставить теперь автоматическое рисование нужного количества радиобутаннов и их работу - ума не приложу...

amel27 03-06-2007 06:20

Diamond
Цитата:

Я бы заменил WinWaitActive на WinWait()
+1
Почему-то был уверен, что поставил WinWait(), уже исправил...

V0van3
Цитата:

к сожалению в данном случае не всё так просто. видимо вы не проверяли
+1 :)
конечно не проверял, нынче найти 16-битное приложение не так просто... вот навскидку два варианта:

Простой и надежный способ ценой лишнего CMD-процесса:
Код:

$exe = 'Vcmurbas.exe' ; Имя 16-битного приложения
$dir = 'C:\Program Files\Vcmurbas' ; Путь к каталогу программы
$pid = Run(@COMSPEC & ' /C START /WAIT /SEPARATE ' & $exe, $dir, @SW_HIDE)

While ProcessExists($pid)
  Sleep(200)
WEnd

Более "навороченный", но без дополнительных процессов:
Код:

$exe = 'Vcmurbas.exe' ; Имя 16-битного приложения
$dir = 'C:\Program Files\Vcmurbas' ; Путь к каталогу программы

$PDL = ProcessList ('ntvdm.exe')
Run (@COMSPEC & ' /C START /SEPARATE ' & $exe, $dir, @SW_HIDE)
$PID = _ProcessListWait($PDL, 'ntvdm.exe')

While ProcessExists($pid)
  Sleep(200)
WEnd

; Функция, которая сравнивает списки процессов до появления различий
; и возвращает PID нового процесса.
Func _ProcessListWait (ByRef $arrPLOld, $strPName = '')
    Local $i, $arrPLNew, $strPLOld='', $newPID=0
    For $i=1 To $arrPLOld[0][0]
        $strPLOld &= $arrPLOld[$i][1] &';'
    Next
    Do
        Sleep (100)
        If @NUMPARAMS=1 Then $arrPLNew = ProcessList()
        If @NUMPARAMS=2 Then $arrPLNew = ProcessList($strPName)
        For $i=1 To $arrPLNew[0][0]
            If StringInStr($strPLOld, $arrPLNew[$i][1]&';')=0 Then $newPID=$arrPLNew[$i][1]
        Next
    Until $newPID
    Return $newPID
EndFunc

З.Ы. Во 2-м случае можно обойтись без @COMSPEC если настроить систему на запуск каждого 16-битного приложения в отдельном NTVDM-процессе: ключ реестра HKLM\SYSTEM\CurrentControlSet\Control\WOW, параметр DefaultSeparateVDM = "yes"

ChVL 03-06-2007 20:55

Creat0R
Цитата:

Цитата:

Скомпилированный exe работает, но только тогда, когда рядом присутствует исходный exe
Это напряму зависит от того, какой состав скрипта, возможно в скрипте используются данные читаемые при выполнении из самого скрипта - чтобы сказать более точно, необходимо видеть исходный код.
Использовал разные au3, в том числе и от Sanja Alone. Во всех случаях скомпилированный exe имеет объём чуть больше 200 КВ, не зависит от объёма исходного exe и от того, какая прога устанавливается.

Diamond 03-06-2007 23:15

amel27
Цитата:

Почему-то был уверен, что поставил WinWait(), уже исправил...
А я был уверен что идея принадлежит voler ... :blush:
Это и не ошибка вовсе, а всего лишь другой способ. :sorry:

amel27 04-06-2007 03:37

Diamond
Цитата:

Это и не ошибка вовсе, а всего лишь другой способ
ИМХО при автоматизации установки имеют смысл только два варианта:

- WinWait()+ControlClick()/ControlCommand()
- WinWait()+WinActivate()+Send().

Creat0R 04-06-2007 03:48

DenchikK
Цитата:

в соответствии с ini файлом, как я понял, переделал так:
Не совсем верно, дело в том, что функция IniReadSection() возвращяет двумерный массив, нулевой элемент ([0]), как и в других обычных массивах, содержит общее число элементов массива.
Построение цикла, должно быть так:

Код:

For $i = 1 To NN

Next

Тут For $i = 1, означает что для переменной $i, в теле цикла, будет присваиваться возрастающее значение от 1 и до NN (вместо NN нам и нужно подставить общее число элементов нашего массива, в данном случае, это $Logins_Array[0][0], иногда, обычно самодельные массивы, могут быть построены неверно, поэтому надёжнее проверять общее число массива, используя функцию Ubound, но при этом нужно отнять 1, чтобы нулевой элемент не учитывался:

Код:

For $i = 1 To Ubound($Logins_Array) - 1
   
Next

Или используем нулевой элемент для выявления общего числа элементов массива (не самый надёжный метод):

Код:

For $i = 1 To $Logins_Array[0][0]
   
Next

В справке написано, что функция IniReadSection(), возвращает двумерный массив, теперь его элементы присваиваются так:

Logins_Array[N][0] = Ключь в Ini-Файле
Logins_Array[N][1] = Значение этого же ключа (ключ это то что идёт перед знаком ровно в Ini-файле).

Цитата:

пытался впихнуть строчку
Тут тоже ошибка, ведь в начале идёт проверка переменной, является ли она массивом - If IsArray($Links_Array) Then...

Но в теле условия (If ... Then ... EndIf), массив обрабатывается совсем другой...

GUICtrlCreateRadio($Logins_Array[$i][1], 10, $Top)...

Вот отсюда и может быть вызвана ошибка.


Попытка №2 :) :

(Добавил также немного проверок на ошибочность).

Код:

#include <GUIConstants.au3>

If WinExists(@ScriptName) Then Exit
AutoItWinSetTitle(@ScriptName)
AutoItSetOption("TrayIconDebug", 1)
AutoItSetOption("SendKeyDelay", 60)
AutoItSetOption("MouseCoordMode", 0)

Global $group_1, $group_2, $group_3, $RadioArr[1], $Links_Array, $Logins_Array, $Pass_Array, $Servers_Array, $Secrets_Array

; Запуск программы

Run ('avaload.exe')

; Считывание Данных

$Logins_Array = IniReadSection("ava.ini", "logins")
$Pass_Array = IniReadSection("ava.ini", "pass")
$Links_Array = IniReadSection("ava.ini", "links")
$Servers_Array = IniReadSection("ava.ini", "servers")
$Secrets_Array = IniReadSection("ava.ini", "secrets")

; Построение GUI

GUICreate("Автозаполнение", 340, 350)

If IsArray($Logins_Array) Then
        ReDim $RadioArr[UBound($Logins_Array)]
        $Top = 20
    For $i = 1 To UBound($Logins_Array)-1
                $RadioArr[$i] = GUICtrlCreateRadio($Logins_Array[$i][1], 10, $Top)
                $Top += 20
    Next
EndIf

$Start = GUICtrlCreateButton("Заполнить", 210, 20, 120, 20)
$Close = GUICtrlCreateButton("Выход", 210, 40, 120, 20)
$Server1  = GUICtrlCreateButton("Сервер 1", 210, 60, 120, 20)
$Server2  = GUICtrlCreateButton("Сервер 2", 210, 80, 120, 20)

$group_1 = GUICtrlCreateGroup ("Выбор Аккаунта", 5, 5, 190, 340)
$group_2 = GUICtrlCreateGroup ("Кнопочки", 205, 5, 130, 100)
$group_3 = GUICtrlCreateGroup ("Описание", 205, 105, 130, 240)

$Label1 = GUICtrlCreateLabel("    Описание Работы", 210, 120)
$Label2 = GUICtrlCreateLabel("1. Впишите в ava.ini", 210, 140)
$Label3 = GUICtrlCreateLabel("линки,логины,пароли,", 210, 155)
$Label4 = GUICtrlCreateLabel("параметры серверов.", 210, 170)
$Label5 = GUICtrlCreateLabel("2. Выберите Сервер", 210, 185)
$Label6 = GUICtrlCreateLabel("3. Выберите пустой ", 210, 200)
$Label7 = GUICtrlCreateLabel("аккаунт для заливки. ", 210, 215)
$Label8 = GUICtrlCreateLabel("    Принцип работы: ", 210, 235)
$Label9 = GUICtrlCreateLabel("Например, выбираем", 210, 250)
$Label10 = GUICtrlCreateLabel("первый логин,в него", 210, 265)
$Label11 = GUICtrlCreateLabel("будет заливаться ", 210, 280)
$Label12 = GUICtrlCreateLabel("первый линк. и.т.д", 210, 295)
$Label13 = GUICtrlCreateLabel("            Удачи! ", 210, 315)

GUISetState ()

; Основная Работа Скрипта

GUISetState()  ; display the GUI

While 1
    Switch GUIGetMsg()
        Case -3, $Close
            Exit
                Case $Server1
                       
                        If UBound($Servers_Array) < 2 Or UBound($Secrets_Array) < 2 Then
                                MsgBox(48, "Ошибка", "Извените, невозможно продолжить, видимо не были найдены данные серверов")
                                ContinueLoop
                        EndIf
                       
                        WinActivate ("AvaRemoteLoad")
                        ControlClick ( 'AvaRemoteLoad', '', "Button4")

                        WinWaitActive ('Настройки')
                        ControlSetText ( 'Настройки', '', 'Edit1', $Servers_Array[1][1])
                        ControlSetText ( 'Настройки', '', 'Edit2', $Secrets_Array[1][1])

                        ControlClick ( 'Настройки', '', "Button2")

                Case $Server2
                       
                        If UBound($Servers_Array) < 3 Or UBound($Secrets_Array) < 3 Then
                                MsgBox(48, "Ошибка", "Извените, невозможно продолжить, видимо не были найдены данные серверов")
                                ContinueLoop
                        EndIf
                       
                        WinActivate ("AvaRemoteLoad")
                        ControlClick ( 'AvaRemoteLoad', '', "Button4")

                        WinWaitActive ('Настройки')
                        ControlSetText ( 'Настройки', '', 'Edit1', $Servers_Array[2][1])
                        ControlSetText ( 'Настройки', '', 'Edit2', $Secrets_Array[2][1])

                        ControlClick ( 'Настройки', '', "Button2")

                Case $Start
                       
                        Local $iSet = 0
                        For $i = 1 To UBound($Logins_Array)-1
                                If GUICtrlRead($RadioArr[$i]) = 1 Then
                                        $iSet = $i
                                        ExitLoop
                                EndIf
                        Next
                       
                        If $iSet = 0 Then
                                MsgBox(48, "Ошибка", "Выберите пожалуйста один из логинов")
                                ContinueLoop
                        EndIf
                       
                        If $iSet > UBound($Links_Array)-1 Or $iSet > UBound($Logins_Array)-1 Or $iSet > UBound($Pass_Array)-1 Then
                                MsgBox(48, "Ошибка", "Извените, невозможно продолжить, видимо не были найдены данные линков/логинов/паролей")
                                ContinueLoop
                        EndIf
                       
                        WinActivate ("AvaRemoteLoad")
                        ControlSetText ( 'AvaRemoteLoad', '', 'Edit1', $Links_Array[$iSet][1])
                        ControlSetText ( 'AvaRemoteLoad', '', 'Edit2', $Logins_Array[$iSet][1])
                        ControlSetText ( 'AvaRemoteLoad', '', 'Edit3', $Pass_Array[$iSet][1])

        EndSwitch
WEnd

ChVL
Цитата:

Во всех случаях скомпилированный exe имеет объём чуть больше 200 КВ, не зависит от объёма исходного exe и от того, какая прога устанавливается.
Не вижу связи с поставленной проблемой...

Цитата:

Скомпилированный exe работает, но только тогда, когда рядом присутствует исходный exe
:idontnow:

...И с тем что я написал :)

ChVL 04-06-2007 06:27

Creat0R
Ещё конкретнее.
Беру autoit-winamp.au3 (7.43 KB) от Sanja Alone и winamp533_pro.exe (6.33 MB). Компилирую. Теперь autoit-winamp.exe имеет объём 205 КВ. Это правильно? Этот autoit-winamp.exe работает только тогда, когда рядом находится winamp533_pro.exe.

Creat0R 04-06-2007 07:01

ChVL
Цитата:

Этот autoit-winamp.exe работает только тогда, когда рядом находится winamp533_pro.exe.
Значит в самом скрипте путь к winamp533_pro.exe указан тот же в котором находится сам скрипт, либо вовсе не указан (в таком случае, путь обычно проверяется в соответствии с рабочим каталогом).

Но я всё же не понимаю связи с этим:

Цитата:

Скомпилированный exe работает, но только тогда, когда рядом присутствует исходный exe
Либо тут неправильная подстановка термина “исходный exe”, либо я чего то недопонимаю... в моём понимании “исходный exe”, это не скомпилированный скрипт :) - именно на основе этого понимания я и ответил:

Цитата:

Это напряму зависит от того, какой состав скрипта, возможно в скрипте используются данные читаемые при выполнении из самого скрипта - чтобы сказать более точно, необходимо видеть исходный код.
А в чём собственно проблема?

amel27 04-06-2007 07:33

Creat0R
Цитата:

Или используем нулевой элемент для выявления общего числа элементов массива (не самый надёжный метод):
Хм... Почему "ненадежный"?.. Не вижу смысла подсчитывать количество элементов если это уже сделала за нас функция... двойная работа получается. Откуда такое недоверие к разработчикам? ;)

Creat0R 04-06-2007 07:43

amel27
Цитата:

Откуда такое недоверие к разработчикам?
Я это на всякий случай пишу, потому что лучше перестраховаться, при наличии больших скриптов, можно “не вспомнить” кто создавал массив, встроенная функция, или построенный нами цикл (или просто “рукописный массив”) :)

Я вовсе не утверждал что нужно не доверять встроенным функциям, я им очень даже доверяю (но проверяю ;) ), ведь если бы не доверял, то и небыло бы для меня повода использовать ту же встроенную функцию Ubound() ;)

VelDmi 04-06-2007 07:44

ChVL
Цитата:

Теперь autoit-winamp.exe имеет объём 205 КВ. Это правильно?
Да, правильно.
Цитата:

Этот autoit-winamp.exe работает только тогда, когда рядом находится winamp533_pro.exe.
Естественно, ведь он запускает winamp533_pro.exe, а затем производит над его окном определенные действия. Если же ты хотел, чтобы получился всего один файл, то прочитай справку по fileinstall (). Тогда winamp533_pro.exe будет помещен внутрь скрипта и получится один exe большого размера.

DenchikK 04-06-2007 14:01

Creat0R
Огромное Вам спасибо! Буду разбираться.

ChVL 04-06-2007 18:04

VelDmi
Спасибо!
C помощью FileInstall поместил дистрибутив в скомпилированный скрипт (по размеру скрипта всё сходится). Как теперь сделать так, чтобы скрипт при запуске использовал именно этот exe, а не требовал его снаружи?

Второй вопрос. Как сделать так, чтобы не мелькали окна приложения в процессе установки?

Creat0R 04-06-2007 19:49

ChVL
Цитата:

Как теперь сделать так, чтобы скрипт при запуске использовал именно этот exe, а не требовал его снаружи?
FileInstall() позволяет помещать файлы в скомпилированный скрипт, чтобы потом они распаковывались в указанное место, вот перед всеми основными действиями скрипта, нужно прописать установку нужного файла, можно распаковывать с любым указанным именем, в данном случае, можно взять имя самого скрипта, и прибавить к нему приставку _Setup:

Код:

$WinampPath = StringTrimRight(@ScriptFullPath, 4) & "_Setup.exe"
FileInstall("winamp533_pro.exe", $WinampPath, 1)
Run($WinampPath)

Цитата:

Как сделать так, чтобы не мелькали окна приложения в процессе установки?
Либо запустить приложение в скрытом режиме ( Run($WinampPath, "", @SW_HIDE) ), либо прятать окна в процессе (см. WinSetState("Title", "Text", @SW_HIDE) )

ChVL 04-06-2007 22:07

Creat0R
Спасибо!
C FileInstall() разобрался, работает. Не сразу, правда, понял, что AutoIt принципиально не переваривает кириллицу в директории (безуспешно пытался использовать Рабочий стол).

Со скрытым режимом не получается.
Запуск ( Run($WinampPath, "", @SW_HIDE) ) на окна, выскакивающие в процессе установки, не влияет (не скрывает).
Функция WinSetState оказалась несовместимой с WinWaitActive. Если WinSetState ставить перед WinWaitActive, то последняя не работает. Если после - нет смысла, т.к. окно уже промелькнуло.
Эти варианты пробовал и раньше, а другие не нашёл.

Creat0R 04-06-2007 22:43

ChVL
Цитата:

AutoIt принципиально не переваривает кириллицу в директории
Ну почему, в случае с FileInstall очень даже переваривает, возможно неверно указаны параметры функции? первый параметр не должен содержать переменных и/или макросов, только чистый текст.

Цитата:

Функция WinSetState оказалась несовместимой с WinWaitActive
Если нам нужно скрыть окна, то WinWaitActive ни к чему, окно никогда не будет активным :) - но вот WinWait может помочь, оно позволит ожидать окно, т.е ожидать его появление, а не активность...

Код:

WinWait("Title", "", 5)
WinSetState("Title", "", @SW_HIDE)


Creat0R 06-06-2007 03:40

Функции (и пример использования) для отображения стильного диалога “О Программе”

Код:

#include <GUIConstants.au3>

$Title = "About Info"

$MainLabel = "My program Name"
$CopyRLabel = "Copyright © " & @YEAR & " Company/Author. All rights reserved."

$NameURL1 = "App Web Page"
$URL1 = "http://www.autoitscript.com"
$NameURL2 = "Email"
$URL2 = "mailto:my_email@mail.com"
$NameURL3 = "Some additional link"
$URL3 = "http://personalwebpafe.com"
$LinkColor = 0x0000FF
$BkColor = 0xFFFFFF

$ParentGui = GUICreate('Parent For "About Program" Demo')

$Menu = GUICtrlCreateMenu("Help")
$AboutItem = GUICtrlCreateMenuitem("About...", $Menu)

GUISetState()

While 1
        Switch GUIGetMsg()
                Case -3
                        Exit
                Case $AboutItem
                        _About($Title, $MainLabel, $CopyRLabel, "v1.0", $NameURL1, $URL1, $NameURL2, $URL2, $NameURL3, $URL3, @AutoItExe, $LinkColor, $BkColor, -1, -1, -1, -1, $ParentGui)
        EndSwitch
WEnd


Func _About($Title, $MainLabel, $CopyRLabel, $VerLabel, $NameURL1, $URL1, $NameURL2, $URL2, $NameURL3, $URL3, $IconFile="", $LinkColor=0x0000FF, $BkColor=0xFFFFFF, $Left=-1, $Top=-1, $Style=-1, $ExStyle=-1, $Parent=0)
        Local $OldEventOpt = Opt("GUIOnEventMode", 0)
        Local $OldRunErrOpt = Opt("RunErrorsFatal", 0)
        Local $GUI, $LinkTop=120, $Msg, $CurInfo
        Local $CurIsOnCtrlArr[1]
       
        Local $LinkVisitedColor[4] = [3, $LinkColor, $LinkColor, $LinkColor]
        Local $LinkLabel[4]
       
        WinSetState($Parent, "", @SW_DISABLE)
       
        If $ExStyle = -1 Then $ExStyle = ""
        $GUI = GUICreate($Title, 320, 240, $Left, $Top, $Style, 0x00000080+$ExStyle, $Parent)
        GUISetBkColor($BkColor)

        GUICtrlCreateLabel($MainLabel, 40, 20, 280, 25, 1)
        GUICtrlSetFont(-1, 16)

        GUICtrlCreateIcon($IconFile, 0, 10, 20)

        GUICtrlCreateGraphic(5, 75, 310, 3, $SS_ETCHEDFRAME)
       
        For $i = 1 To 3
                $LinkLabel[$i] = GUICtrlCreateLabel(Eval("NameURL" & $i), 150, $LinkTop, 145, 15, 1)
                GUICtrlSetCursor(-1, 0)
                GUICtrlSetColor(-1, $LinkColor)
                GUICtrlSetFont(-1, 9, 400, 0)
                GUICtrlSetTip(-1, Eval("URL" & $i))
                $LinkTop += 30
        Next

        GUICtrlCreateLabel("Program version: " & @LF & $VerLabel, 10, 130, 150, 35, 1)
        GUICtrlSetFont(-1, 10, 600, 0, "Tahoma")
       
        GUICtrlCreateLabel($CopyRLabel, 0, 220, 320, -1, 1)

        GUISetState(@SW_SHOW, $GUI)

        While 1
                $Msg = GUIGetMsg()
                If $Msg = -3 Then ExitLoop
                For $i = 1 To 3
                        If $Msg = $LinkLabel[$i] Then
                                While 1
                                        GUISetCursor(0, 1, $GUI)
                                        If GUIGetMsg() = $GUI_EVENT_PRIMARYUP Then
                                                $CurInfo = GUIGetCursorInfo($GUI)
                                                If $CurInfo[4] = $LinkLabel[$i] Then
                                                        GUISetCursor(-1, 0, $GUI)
                                                        $LinkVisitedColor[$i] = 0xAC00A9
                                                        GUICtrlSetColor($LinkLabel[$i], $LinkVisitedColor[$i])
                                                        ShellExecute(Eval("URL" & $i))
                                                EndIf
                                                ExitLoop
                                        EndIf
                                WEnd
                                GUISetCursor(-1, 0, $GUI)
                        EndIf
                Next
                If WinActive($GUI) Then
                        For $i = 1 To 3
                                ControlHover($GUI, $LinkLabel[$i], $i, $CurIsOnCtrlArr, 0xFF0000, $LinkVisitedColor[$i])
                        Next
                EndIf
        WEnd
        WinSetState($Parent, "", @SW_ENABLE)
        GUIDelete($GUI)
        Opt("GUIOnEventMode", $OldEventOpt)
        Opt("RunErrorsFatal", $OldRunErrOpt)
EndFunc

Func ControlHover($hWnd, $CtrlID, $CtrlNum, ByRef $CurIsOnCtrlArr, $HoverColor=0xFF0000, $LinkColor=0x0000FF)
        Local $CursorCtrl = GUIGetCursorInfo($hWnd)
        ReDim $CurIsOnCtrlArr[UBound($CurIsOnCtrlArr)+1]
        If $CursorCtrl[4] = $CtrlID And $CurIsOnCtrlArr[$CtrlNum] = 1 Then
                GUICtrlSetFont($CtrlID, 9, 400, 6)
                GUICtrlSetColor($CtrlID, $HoverColor)
                $CurIsOnCtrlArr[$CtrlNum] = 0
        ElseIf $CursorCtrl[4] <> $CtrlID And $CurIsOnCtrlArr[$CtrlNum] = 0 Then
                GUICtrlSetFont($CtrlID, 9, 400, 0)
                GUICtrlSetColor($CtrlID, $LinkColor)
                $CurIsOnCtrlArr[$CtrlNum] = 1
        EndIf
EndFunc


Diamond 06-06-2007 19:52

Пример Gui-оболочки для консольных конверторов
У меня накопилось с десяток консольных программ типа: архиваторы, конверторы звуковых и графических файлов и т.п. и я подумал, что неплохо было бы для них написать Gui.
Цели, которые я поставил при написании:
1. Список для добавляемых файлов должен быть ListView, при чем с поддержкой перетаскивания файлов (Drag&Drop)
2. Каждый новый Файл должен добавляться в конец списка, а как следствие - сортировка ListView запрещена.
3. В списке не должно быть дубликатов файловых путей.

Это только стартовый интерфейс, но надеюсь он кому-то сэкономит время в написании подобных программ. :)
Код:

#include <GUIConstants.au3>
#include <GuiListView.au3>
Opt("GUIOnEventMode",1)
Opt("TrayIconHide",1)
Global Const $WM_DROPFILES = 0x233
Global $StringCount=0
Global $Dict=ObjCreate("Scripting.Dictionary") ; <- Словарь
$hGUI=GUICreate("Конвертор ;)",600,500,-1,-1,-1,$WS_EX_ACCEPTFILES)
        GUISetOnEvent($GUI_EVENT_CLOSE,"Quit")
$listview=GUICtrlCreateListView  ("Файл|Путь",5,5,590,450,BitOR($LVS_NOSORTHEADER,$LVS_SHOWSELALWAYS))
$ButtonDelete=GUICtrlCreateButton("Удалить",250,465,80,24)
        GUICtrlSetOnEvent(-1,"StrDelete")
$ButtonAdd=GUICtrlCreateButton("Добавить",120,465,80,24)
        GUICtrlSetOnEvent(-1,"AddOpenFiles")
GUISetState(@SW_SHOWNORMAL)

;~ Регистрируем событие Drag&Drop
GUIRegisterMsg ($WM_DROPFILES, "DropFiles")

While 1
        Sleep(1000)
WEnd

;~ Выход из приложения
Func Quit()
        Exit(0)
EndFunc

;~ Этот функция была взята с официального форума или... точно не помню ;)
;~ Создаёт массив $gaDropFiles, из файлов полученный при перетаскивании
;~ Вызывается событием, прописанным в GUIRegisterMsg()
Func DropFiles($hWnd, $msgID, $wParam, $lParam)
    Local $nSize, $pFileName, $gaDropFiles[1]
    Local $nAmt = DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", 0xFFFFFFFF, "ptr", 0, "int", 255)
    For $i = 0 To $nAmt[0] - 1
        $nSize = DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", $i, "ptr", 0, "int", 0)
        $nSize = $nSize[0] + 1
        $pFileName = DllStructCreate("char[" & $nSize & "]")
        DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", $i, "ptr", DllStructGetPtr($pFileName), "int", $nSize)
        ReDim $gaDropFiles[$i+1]
        $gaDropFiles[$i] = DllStructGetData($pFileName, 1)
        $pFileName = 0
    Next
        Call ("AddDropedFiles", $gaDropFiles)
EndFunc

;~ Добавляет в ListViev файлы, полученные с помощью перетаскивания (Drag&Drop)
;~ Является продолжением функции DropFiles()
Func AddDropedFiles($gaDropFiles)
        Call ("DictionaryAdd")
        Local $Count=$StringCount
        For $o In $gaDropFiles
                If Not $Dict.Exists($o) Then
                        _GUICtrlListViewInsertItem($listview, $Count, GetFileName($o) & '|' & $o)
                        Call ("AutoSize")
                        $Count=$Count+1
                EndIf
        Next
        $Dict.RemoveAll
EndFunc

;~ Добавляет файлы в ListViev с помощью FileOpenDialog()
;~ Вызывается кнопкой
Func AddOpenFiles()
        $FilePath = FileOpenDialog("Открыть","","Wave файлы (*.wav) | Все файлы (*.*)",4+1)
        If @error <> 1 Then
                Local $array = StringSplit($FilePath, "|")
                Local $Count = $StringCount
                If $array[0]>1 Then
                        $path=$array[1]
                        Call ("DictionaryAdd")
                        For $i=2 To $array[0]
                                $FullPath=$path & "\" & $array[$i]
                                If Not $Dict.Exists($FullPath) Then
                                        _GUICtrlListViewInsertItem($listview, $Count, $array[$i] & '|' & $FullPath)
                                        Call ("AutoSize")
                                        $Count=$Count+1
                                EndIf
                        Next
                ElseIf $array[0]=1 Then
                        Call ("DictionaryAdd")
                        If Not $Dict.Exists($array[1]) Then
                                _GUICtrlListViewInsertItem($listview, $StringCount, GetFileName($array[1]) & '|' & $array[1])
                                Call ("AutoSize")
                        Endif
                EndIf
                $Dict.RemoveAll
        EndIf
EndFunc

;~ Удаляет выбранные элементы в ListViev
;~ Вызывается кнопкой
Func StrDelete()
        _GUICtrlListViewDeleteItemsSelected($listview)
        If _GUICtrlListViewGetItemCount($listview) Then AutoSize()
EndFunc

;~ ========================
;~ Вспомогательные функции:
;~ ========================

; Возвращает имя файла или папки из пути
;~ Вызывается некоторыми функциями
Func GetFileName($FilePath)
        If StringRight($FilePath,1)="\" Then
                $FilePath=StringTrimRight($FilePath,1)
        EndIf
        Return StringTrimLeft($FilePath,StringInStr($FilePath,"\",0,-1))
EndFunc

;~ Изменяет размеры колонок в ListViev
;~ Вызывается некоторыми функциями
Func AutoSize()
_GUICtrlListViewSetColumnWidth($listview,1,$LVSCW_AUTOSIZE)
_GUICtrlListViewSetColumnWidth($listview,0,$LVSCW_AUTOSIZE)
EndFunc

;~ Добавляет в словарь все элементы второй колонки ListViev (Пути к файлам)
;~ З.Ы. Поиск дубликатов по словарю, значительно быстрее чем перебор-сравнение в массиве!
Func DictionaryAdd()
        $StringCount=_GUICtrlListViewGetItemCount($listview)
        For $i=0 To $StringCount
                $Item = _GUICtrlListViewGetItemTextArray ($listview, $i)
                If IsArray($Item) Then
                        $Dict.Add($Item[2],"")
                EndIf
        Next
EndFunc

;~ ---------------------------------------------
;~ Позволят получить файловое расширение из пути или имени файла.
;~ Это единственная функция которая нигде не используется!
Func FileGetExtension($name)
        Local $Count=StringInStr($name,".",0,-1)
        If $Count=0 Then
                Return 0
        Else
                Return StringTrimLeft($name,$Count)
        EndIf
EndFunc


Creat0R 06-06-2007 23:17

Diamond
Цитата:

Этот функция была взята с официального форума или... точно не помню ;)
Да да, иименно от туда, я и сам ей пользуюсь с удовольствием :), взял тоже именно с оф. форума (её наисал кажется gafrost).

У меня почему то при вызове $dict.Exists скрипт выпадает с ошибкой:

Цитата:

The requested action with this object has failed.
Вобщем я немного изменил скрипт, надеюсь что в лучшую сторону, изменения таковы:

-Функцию _FileOpenDialog() добавил самдельную (от amel27) - позволяет открыть диалог для выбора файла как дочерний диалог ГУИ.

-Добавил функцию для поиска в самом ListView, имхо, так надёжнее, и не так уж намного медленнее ;)

-Во всех функциях где добавляются новые айтемы (файлы), вызывается AutoSize на каждый добавляемый файл, хотя логичнее бдет вызвать один раз эту функцию по оканчанию добавления всех файлов.

-Теперь при добавлении файлов используя перетаскивание, существующие в списке файлы будут подсвечиваться (выделяться) - так думаю более удобно :).

-Функцию GetFileName() немного укоротил ;)

-Добавил отображение иконок для добавляемых файлов, иконки определяются используя функцию _FileGetIcon() (тоже где то на оф. форуме нашел, правда немного изменил).

-Чтобы можно было присваивать иконки айтемам, пришлось вместо вставки айтемов, создавать их встроенными средствами, т.к требуется ControlID.

Вот что получилось:

Код:

#include <GUIConstants.au3>
#include <GuiListView.au3>
Opt("GUIOnEventMode",1)
Opt("TrayIconHide",1)
Global Const $WM_DROPFILES = 0x233
Global $StringCount=0
Global $Dict=ObjCreate("Scripting.Dictionary") ; <- Словарь
$hGUI=GUICreate("Конвертор ;)",600,500,-1,-1,-1,$WS_EX_ACCEPTFILES)
        GUISetOnEvent($GUI_EVENT_CLOSE,"Quit")
$listview=GUICtrlCreateListView  ("Файл|Путь",5,5,590,450,BitOR($LVS_NOSORTHEADER,$LVS_SHOWSELALWAYS))
$ButtonDelete=GUICtrlCreateButton("Удалить",250,465,80,24)
        GUICtrlSetOnEvent(-1,"StrDelete")
$ButtonAdd=GUICtrlCreateButton("Добавить",120,465,80,24)
        GUICtrlSetOnEvent(-1,"AddOpenFiles")
GUISetState(@SW_SHOWNORMAL)

;~ Регистрируем событие Drag&Drop
GUIRegisterMsg ($WM_DROPFILES, "DropFiles")

While 1
        Sleep(1000)
WEnd

;~ Выход из приложения
Func Quit()
        Exit(0)
EndFunc

;~ Этот функция была взята с официального форума или... точно не помню ;)
;~ Создаёт массив $gaDropFiles, из файлов полученный при перетаскивании
;~ Вызывается событием, прописанным в GUIRegisterMsg()
Func DropFiles($hWnd, $msgID, $wParam, $lParam)
    Local $nSize, $pFileName, $gaDropFiles[1]
    Local $nAmt = DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", 0xFFFFFFFF, "ptr", 0, "int", 255)
    For $i = 0 To $nAmt[0] - 1
        $nSize = DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", $i, "ptr", 0, "int", 0)
        $nSize = $nSize[0] + 1
        $pFileName = DllStructCreate("char[" & $nSize & "]")
        DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", $i, "ptr", DllStructGetPtr($pFileName), "int", $nSize)
        ReDim $gaDropFiles[$i+1]
        $gaDropFiles[$i] = DllStructGetData($pFileName, 1)
        $pFileName = 0
    Next
        Call ("AddDropedFiles", $gaDropFiles)
EndFunc

;~ Добавляет в ListViev файлы, полученные с помощью перетаскивания (Drag&Drop)
;~ Является продолжением функции DropFiles()
Func AddDropedFiles($gaDropFiles)
        Local $SelCount = 1, $LVIID, $IconFile, $IconID
        For $o In $gaDropFiles
                $FindPathInLV = _FindInListView($listview, 1, $o)
                If $FindPathInLV = -1 Then
                        $LVIID = GUICtrlCreateListViewItem(GetFileName($o) & '|' & $o, $listview)
                        _FileGetIcon($IconFile, $IconID, $o)
                        GUICtrlSetImage($LVIID, $IconFile, $IconID)
                Else
                        If $SelCount = 1 Then ControlListView($hGUI, "", $listview, "SelectClear")
                        _GUICtrlListViewSetItemSelState($listview, $FindPathInLV)
                        $SelCount = -1
                EndIf
        Next
        If $SelCount = -1 Then ControlFocus($hGUI, "", $listview)
        Call ("AutoSize")
EndFunc

;~ Добавляет файлы в ListViev с помощью FileOpenDialog()
;~ Вызывается кнопкой
Func AddOpenFiles()
        $FilePath = _FileOpenDialog("Открыть","","Wave файлы (*.wav) | Все файлы (*.*)",4+1, "", "", $hGUI)
        If Not @error Then
                $FilePath = StringStripCR($FilePath)
                Local $array = StringSplit($FilePath, "|")
                Local $LVIID, $IconFile, $IconID
                If $array[0]>1 Then
                        $path=$array[1]
                        For $i=2 To $array[0]
                                $FullPath=$path & "\" & $array[$i]
                                If _FindInListView($ListView, 1, $FullPath) = -1 Then
                                        $LVIID = GUICtrlCreateListViewItem($array[$i] & '|' & $FullPath, $listview)
                                        _FileGetIcon($IconFile, $IconID, $FullPath)
                                        GUICtrlSetImage($LVIID, $IconFile, $IconID)
                                EndIf
                        Next
                ElseIf $array[0]=1 Then
                        If _FindInListView($ListView, 1, $array[1]) = -1 Then
                                $LVIID = GUICtrlCreateListViewItem(GetFileName($array[1]) & '|' & $array[1], $listview)
                                _FileGetIcon($IconFile, $IconID, $array[1])
                                GUICtrlSetImage($LVIID, $IconFile, $IconID)
                        EndIf
                EndIf
                Call ("AutoSize")
        EndIf
EndFunc

;~ Удаляет выбранные элементы в ListViev
;~ Вызывается кнопкой
Func StrDelete()
        _GUICtrlListViewDeleteItemsSelected($listview)
        If _GUICtrlListViewGetItemCount($listview) Then AutoSize()
EndFunc

;~ ========================
;~ Вспомогательные функции:
;~ ========================

; Возвращает имя файла или папки из пути
;~ Вызывается некоторыми функциями
Func GetFileName($FilePath)
        Return StringRegExpReplace($FilePath, "^.*\\", "")
EndFunc

;~ Изменяет размеры колонок в ListViev
;~ Вызывается некоторыми функциями
Func AutoSize()
_GUICtrlListViewSetColumnWidth($listview,1,$LVSCW_AUTOSIZE)
_GUICtrlListViewSetColumnWidth($listview,0,$LVSCW_AUTOSIZE)
EndFunc

;~ Добавляет в словарь все элементы второй колонки ListViev (Пути к файлам)
;~ З.Ы. Поиск дубликатов по словарю, значительно быстрее чем перебор-сравнение в массиве!
Func DictionaryAdd()
        $StringCount=_GUICtrlListViewGetItemCount($listview)
        For $i=0 To $StringCount
                $Item = _GUICtrlListViewGetItemTextArray ($listview, $i)
                If IsArray($Item) Then
                        $Dict.Add($Item[2],"")
                EndIf
        Next
EndFunc

;~ Функция производит поиск в списке List View, в случае удачи, возвращает индекс найденного айтема в списке,
;в противном случае возвращает -1
Func _FindInListView($ListViewID, $SubItem, $WhatToFind, $SubItem2=-1, $WhatToFind2="")
        Local $TotalItemsArr = _GUICtrlListViewGetItemCount($ListViewID)
        Local $CurrentText, $CurrentText2
        If $TotalItemsArr > 0 Then
                For $i = 0 To $TotalItemsArr - 1
                        $CurrentText = _GUICtrlListViewGetItemText($ListViewID, $i, $SubItem)
                        If $SubItem2 <> -1 Then
                                $CurrentText2 = _GUICtrlListViewGetItemText($ListViewID, $i, $SubItem2)
                                If $CurrentText = $WhatToFind And $CurrentText2 = $WhatToFind2 Then Return $i
                        Else
                                If $CurrentText = $WhatToFind Then Return $i
                        EndIf
                Next
        EndIf
        Return -1
EndFunc

;~ Самодельная функци FileOpenDialog() - позволяет открыть диалог для выбора файла как дочерний диалог ГУИ.
Func _FileOpenDialog($sTitle, $sInitDir, $sFilter = 'All (*.*)', $iOpt = 0, $sDefaultFile = "", $sDefaultExt = "", $mainGUI = 0)
    Local $iFileLen = 65536 ; Max chars in returned string
    ; API flags prepare
    Local $iFlag = BitOR ( _
        BitShift (BitAND ($iOpt, 1),-12), BitShift (BitAND ($iOpt, 2),-10), BitShift (BitAND ($iOpt, 4),-7 ), _
        BitShift (BitAND ($iOpt, 8),-10), BitShift (BitAND ($iOpt, 4),-17) )
    ; Filter string to array convertion
    Local $asFLines = StringSplit ( $sFilter, '|'), $asFilter [$asFLines [0] *2+1]
    Local $i, $iStart, $iFinal, $suFilter = ''
    $asFilter [0] = $asFLines [0] *2
    For $i=1 To $asFLines [0]
        $iStart = StringInStr ($asFLines [$i], '(', 0, 1)
        $iFinal = StringInStr ($asFLines [$i], ')', 0,-1)
        $asFilter [$i*2-1] = StringStripWS (StringLeft ($asFLines [$i], $iStart-1), 3)
        $asFilter [$i*2] = StringStripWS (StringTrimRight (StringTrimLeft ($asFLines [$i], $iStart), StringLen ($asFLines [$i]) -$iFinal+1), 3)
        $suFilter = $suFilter & 'byte[' & StringLen ($asFilter [$i*2-1])+1 & '];byte[' & StringLen ($asFilter [$i*2])+1 & '];'
    Next
    ; Create API structures
    Local $uOFN = DllStructCreate ('dword;int;int;ptr;ptr;dword;dword;ptr;dword' & _
        ';ptr;int;ptr;ptr;dword;short;short;ptr;ptr;ptr;ptr;ptr;dword;dword' )
    Local $usTitle  = DllStructCreate ('byte[' & StringLen ($sTitle) +1 & ']')
    Local $usInitDir= DllStructCreate ('byte[' & StringLen ($sInitDir) +1 & ']')
    Local $usFilter = DllStructCreate ($suFilter & 'byte')
    Local $usFile  = DllStructCreate ('byte[' & $iFileLen & ']')
    Local $usExtn  = DllStructCreate ('byte[' & StringLen ($sDefaultExt) +1 & ']')
    For $i=1 To $asFilter [0]
        DllStructSetData ($usFilter, $i, $asFilter [$i])
    Next
    ; Set Data of API structures
    DllStructSetData ($usTitle, 1, $sTitle)
    DllStructSetData ($usInitDir, 1, $sInitDir)
    DllStructSetData ($usFile, 1, $sDefaultFile)
    DllStructSetData ($usExtn, 1, $sDefaultExt)
    DllStructSetData ($uOFN,  1, DllStructGetSize($uOFN))
    DllStructSetData ($uOFN,  2, $mainGUI)
    DllStructSetData ($uOFN,  4, DllStructGetPtr ($usFilter))
    DllStructSetData ($uOFN,  7, 1)
    DllStructSetData ($uOFN,  8, DllStructGetPtr ($usFile))
    DllStructSetData ($uOFN,  9, $iFileLen)
    DllStructSetData ($uOFN, 12, DllStructGetPtr ($usInitDir))
    DllStructSetData ($uOFN, 13, DllStructGetPtr ($usTitle))
    DllStructSetData ($uOFN, 14, $iFlag)
    DllStructSetData ($uOFN, 17, DllStructGetPtr ($usExtn))
    DllStructSetData ($uOFN, 23, BitShift (BitAND ($iOpt, 32), 5))
    ; Call API function
    $ret = DllCall ('comdlg32.dll', 'int', 'GetOpenFileName', _
            'ptr', DllStructGetPtr ($uOFN) )
    If $ret [0] Then
        If BitAND ($iOpt, 4) Then
            $i = 1
            While 1
                If DllStructGetData ($usFile, 1, $i) =0 Then
                    If DllStructGetData ($usFile, 1, $i+1) Then
                        DllStructSetData ($usFile, 1, 124, $i)
                    Else
                        ExitLoop
                    EndIf
                EndIf
                $i += 1
            Wend
        EndIf
        Return DllStructGetData ($usFile, 1)
    Else
        SetError (1)
        Return ""
    EndIf
EndFunc

;~ Функция задаёт значения для переменных $szIconFile и $nIcon путь к файлу и идентификатор иконки в файле
; (для определения иконки по заданному пути к файлу).
Func _FileGetIcon(ByRef $szIconFile, ByRef $nIcon, $szFile)
        Local $OldEES = Opt("ExpandEnvStrings", 1)
        Local $szRegDefault = "", $szDefIcon = "", $szExt
        $nIcon = 0
        If _IsDir($szFile) Then
                $szRegDefault = RegRead("HKCR\Folder", "")
                If $szRegDefault <> "" Then $szDefIcon = RegRead("HKCR\Folder\DefaultIcon", "")
        Else
                $szExt = StringRegExpReplace($szFile, '^.*\.', '.')
                If $szExt = $szFile Then
                        $szExt = FileFindFirstFile($szFile & ".*")
                        $szExt = StringRegExpReplace(FileFindNextFile($szExt), '^.*\.', '.')
                        $szFile = $szFile & $szExt
                EndIf
                $szRegDefault = RegRead("HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\" & $szExt, "ProgID")
                If $szRegDefault = "" Then $szRegDefault = RegRead("HKCR\" & $szExt, "")
                If $szRegDefault <> "" Then $szDefIcon = RegRead("HKCR\" & $szRegDefault & "\DefaultIcon", "")
        EndIf
        If $szDefIcon = "" Then
                $szIconFile = "shell32.dll"
        ElseIf $szDefIcon <> "%1" Then
                If StringRegExpReplace($szFile, "^.*\\", "") = "shell32.dll" Then
                        $szIconFile = $szFile
                        $nIcon = 0
                Else
                        $arSplit = StringSplit($szDefIcon, ",")
                        If IsArray($arSplit) Then
                                $szIconFile = $arSplit[1]
                                If $arSplit[0] > 1 Then $nIcon = $arSplit[2]
                        Else
                                Opt("ExpandEnvStrings", $OldEES)
                                Return 0
                        EndIf
                EndIf
        ElseIf $szDefIcon = "%1" Then
                $szIconFile = $szFile
                $nIcon = 0
        EndIf
        Opt("ExpandEnvStrings", $OldEES)
        Return 1
EndFunc

;~ Функция предназначена для проверки, является ли заданый путь каталогом.
Func _IsDir($Path)
        Return StringInStr(FileGetAttrib($Path), "D")
EndFunc

;~ ---------------------------------------------
;~ Позволят получить файловое расширение из пути или имени файла.
;~ Это единственная функция которая нигде не используется!
Func FileGetExtension($name)
        Local $Count=StringInStr($name,".",0,-1)
        If $Count=0 Then
                Return 0
        Else
                Return StringTrimLeft($name,$Count)
        EndIf
EndFunc


Creat0R 07-06-2007 03:13

Есть такой вопрос:

Утилита OpenedFilesView, “умеет просматривать” файлы которые заняты разными приложениями...
Среди прочих возможностей программы, она имеет весьма удобную функцию - закрывать файлы (их Handle), чтобы к примеру, можно было удалить/переместить/переименовать файл без проблем, или изменить в нём данные.

Также программа отображает полный путь к приложению которое “держит” эти файлы...

Вопрос в том, возможно ли и на AutoIt получить доступ к подобной информации, а также иметь возможность закрывать Handles файлов, или временно их неитрализовывать (чего в самой программе нет :) )?

Полагаю тут надо копать в сторону DllCall, но я даже и не знаю какой “тип лопаты” выбрать :biggrin:

P.S
На оф. форуме поднимался подобный вопрос, но до сих пор так ни кто и не нашёл решения, надеюсь среди наших, найдутся знатоки и умеющие хорошо копать люди :)

gregaz 07-06-2007 13:22

Просьба помочь "чайнику" AutoItа
Надоело вариться в собственном соку

Как правильно организовать скрипт с использованием GUI ?
Хотел обратиться раньше,но решил сначала немного самому пощупать(и не без пользы .оказывается)
Просьба показать на примере,содержащем следующее :

1.Создается окно GUI

2.В нем создаются :
- пара текстовых строк (наверное Label 1 - Label 2)
- пара кнопок ( скажем button 1-Button 2)

3.При нажатии кнопки button 1:
- предыдущая инфа стирается
- создается :
- пара новых текстовых строк
- пара элементов Input ( с каким то текстом )
- пара новых кнопок ( скажем Read-Save)
- при нажатии новой кнопки Read :
- выводится инфа до редактирования текста в окнах Input(Слева в окне GUI)
- при нажатии новой кнопки Save :
- выводится инфа после редактирования текста в окнах Input (Справа в окне GUI)

4.При нажатии кнопки button 2:
- Все окно очищается
- Выводится любая обобщающая информация

Из примера хотелось бы понять :

1.Как правильно вводить текст и очищать окно
2.Как правильно организовать опрос элементов GUI при наличии вновь появляющихся
элементов (кнопок Read-Save,элементов Input и т.п. )
3.Как правильно осуществлять поиск по данной теме форума
Заранее благодарен

Creat0R 07-06-2007 15:59

gregaz
Цитата:

Просьба показать на примере,содержащем следующее
Вот пример:

Код:

Global $Input1, $Input2, $ReadButton=-1, $SaveButton=-1

$Gui = GUICreate("Demo GUI", 400, 300)

$Label1 = GUICtrlCreateLabel("Строка 1", 20, 50, 300)
$Label2 = GUICtrlCreateLabel("Строка 2", 20, 100, 300)

$Button1 = GUICtrlCreateButton("Button1", 100, 260, 70)
$Button2 = GUICtrlCreateButton("Button2", 250, 260, 70)

GUISetState()

While 1
    Switch GUIGetMsg()
        Case -3
            Exit
        Case $Button1 ;нажата кнопка "Button1"
            ;Нажата кнопка "Button1", а значит стираем инфу и вместо неё пишем другую
            ;(можно конечно удалять контроли и создавать новые, но не вижу в этом смысла ;) )...
            GUICtrlSetData($Label1, "Новая строка 1")
            GUICtrlSetData($Label2, "Новая строка 2")

                        ;Создаём поля ввода
            $Input1 = GUICtrlCreateInput("Поле ввода 1", 20, 140, 300)
            $Input2 = GUICtrlCreateInput("Поле ввода 2", 20, 180, 300)

                        ;Создаём кнопки Read-Save
            $ReadButton = GUICtrlCreateButton("Read", 100, 220, 70)
            $SaveButton = GUICtrlCreateButton("Save", 250, 220, 70)
        Case $Button2 ;нажата кнопка "Button2"
            ;Удаляем всё кроме кнопок "Button1" и "Button2"
            GUICtrlDelete($Label1)
            GUICtrlDelete($Label2)
            GUICtrlDelete($Input1)
            GUICtrlDelete($Input2)
            GUICtrlDelete($ReadButton)
            GUICtrlDelete($SaveButton)
        Case $ReadButton ;нажата кнопка "Read"
            ;Выводим тот текст что создали (я так понял это нужно?)
            MsgBox(64, "Info", "Поле ввода 1" & @LF & "Поле ввода 2")
        Case $SaveButton ;нажата кнопка "Save"
            ;Выводим то что в полях ввода
            $ReadInput1 = GUICtrlRead($Input1)
            $ReadInput2 = GUICtrlRead($Input2)
            MsgBox(64, "Info", $ReadInput1 & @LF & $ReadInput2)
    EndSwitch
WEnd

Цитата:

Как правильно вводить текст и очищать окно
Это очень сильно зависит от конкретного случая... можно удалить все созданные контроли, но можно и просто очистить данные (GuiCtrlSetData($ControlID, ""), но это также зависит от типа контроля (поле ввода, чекбокс, и т.д).

Цитата:

Как правильно организовать опрос элементов GUI при наличии вновь появляющихся
В каком смысле опрос элементов? чтобы иметь к ним доступ? я это привёл в примере, те контроли, что создаются позже в цикле, нужно заранее обьявить, и желательно со значениями не ровняющимися нулю (0) - типичное поведение переменных обьявленых без значения.

Цитата:

Как правильно осуществлять поиск по данной теме форума
Лучше всего переключить в режим печати (ВСЕ), и искать на странице (Ctrl F :)).

Diamond 07-06-2007 17:33

Creat0R
Рукописная функция _FileOpenDialog у меня возвращает цифры 0x433A5C446F63756D... и т.п. и очень много нулей. :idontnow:
Цитата:

У меня почему то при вызове $dict.Exists скрипт выпадает с ошибкой
А в отдельном скрипте сам объект не пробовал тестировать?
Цитата:

-Добавил функцию для поиска в самом ListView, имхо, так надёжнее, и не так уж намного медленнее
Разница в скорости станет очевидной при обработке больших объёмов информации. ИМХО "Scripting.Dictionary" очень даже надёжен и я принципиально не хочу:lo: от него отказываться. ;)
Цитата:

иконки определяются используя функцию _FileGetIcon()
Я уже начал писать нечто подобное, вот только не знал как получить иконку для папки. Спасибо.
Цитата:

вызывается AutoSize на каждый добавляемый файл, хотя логичнее бдет вызвать один раз эту функцию по оканчанию добавления всех файлов.
... уже думал об этом, но потом решил что это не сильно отразиться на скорости добавления - возможно я и не прав... :dont-know
Цитата:

-Чтобы можно было присваивать иконки айтемам, пришлось вместо вставки айтемов, создавать их встроенными средствами, т.к требуется ControlID.
Спасибо, буду разбираться. :)

Diamond 07-06-2007 18:43

Creat0R
Цитата:

Полагаю тут надо копать в сторону DllCall, но я даже и не знаю какой “тип лопаты” выбрать
По поводу лопаты... Думаю, нужно копать в сторону файловых дескрипторов.
Скорее всего, программе удаётся это сделать за счёт подмены или переназначения блокирующего дескриптора, для своего собственного процесса.
К сожалению, больше ничем помочь не смогу... :dont-know

gregaz 07-06-2007 19:22

Creat0R !
Спасибо за помощь !
Многое стало понятнее .

Естественно сразу возникли вопросы :

1. Почему даный пример работает даже без обьявления #include <GUIConstants.au3> ?

2. Правильно ли я понял ,что обявление Global переменных нужно только лишь для Обьявления
начальных значений еще не созданных элементов ( можно наверное и так : $Input1 ="" и т.д.) ?

3. Цикл Switch-Case-EndSwitch полностью аналогичен циклу Select-Case-EndSelect или есть отличия ?
Можно ли здесь поменять их ?

4. Что означает Case -3 (GUIGetMsg()= -3 ) ? Когда появится это значение ?

5. Правильно ли я понял ,что независимо от появляющихся впоследствии элементов GUI , опрос
об их состояниях (значениях) производится ВСЕГДА в одном общем цикле While-Wend ?
Я пытался после создания новых элементов создавать еще внутренний цикл While-Wend ,поскольку иначе они
почему то получались статическими.

6. Можно ли вместо вывода информации в окне MsgBox осуществлять вывод в том же окне GUI ?

7.Можно ли для очиски окна использовать GUICtrlDelete($ControlID) или GuiCtrlSetData($ControlID, "") - что правильнее ?

8. Как праильно осуществлять поиск ранее обсуждавшихся вопросов на форуме ( не на странице) ?

Извините что напрягаю.

Creat0R 08-06-2007 01:51

Diamond

Цитата:

Рукописная функция _FileOpenDialog у меня возвращает цифры 0x433A5C446F63756D... и т.п. и очень много нулей.
Странно, amel27, что скажешь, от чего это может быть вызвано?

Цитата:

А в отдельном скрипте сам объект не пробовал тестировать?
Не пробовал, но как выяснилось, это вызвано тем, что самопальная функция возвращает символы перевода строки на конце переменной выбранных файлов. При передаче подобной переменной в проверку словаря, действие проваливается.

gregaz
Цитата:

Почему даный пример работает даже без обьявления #include <GUIConstants.au3> ?
Паотому что нет констант из этого вложения используемых примером :)

Цитата:

Правильно ли я понял ,что обявление Global переменных нужно только лишь для Обьявления
начальных значений еще не созданных элементов ( можно наверное и так : $Input1 ="" и т.д.) ?
Совершенно правильно. Если переменные создавать вне функции/циклов (в начале скрипта), то особой необходимости в глобальном обьявлении переменных нет (в данном случае), но всё же это не помешает.

Цитата:

Цикл Switch-Case-EndSwitch полностью аналогичен циклу Select-Case-EndSelect или есть отличия ?
Отличия в том, что при Select подстанавливается полное условие - Case 1 = 1, а при Switch можно один раз указать с чем следует использовать (сравнивать) условия - Switch $Test.... Case 1 - этот случай будет выполнен если переменная $Test будет ровна 1.

Цитата:

Правильно ли я понял ,что независимо от появляющихся впоследствии элементов GUI , опрос
об их состояниях (значениях) производится ВСЕГДА в одном общем цикле While-Wend ?
Не всегда, при желании (необходимости) можно создавать несколько циклов.

Цитата:

Можно ли вместо вывода информации в окне MsgBox осуществлять вывод в том же окне GUI ?
Можно, нужно строить также новый ГУИ ;)

Цитата:

Можно ли для очиски окна использовать GUICtrlDelete($ControlID) или GuiCtrlSetData($ControlID, "") - что правильнее ?
если нужно поменять значение у текстовой строки (Label), то лучше использовать GuiCtrlSetData($ControlID, ""), для полного удаления контроля из ГУИ, нужно использовать GUICtrlDelete($ControlID).

Цитата:

Как праильно осуществлять поиск ранее обсуждавшихся вопросов на форуме
Есть на этом форуме раздел поиска, там вводишь нужный запрос с нужными параметрами (есть помощь там же по поиску), и осуществляется поиск :)

amel27 08-06-2007 07:17

Creat0R
Цитата:

Странно, amel27, что скажешь, от чего это может быть вызвано?
чего-то не пойму что там разработчики намутили с юникодом, кто нибудь может объяснить поведение скрипта?.. у меня значения не совпадают в 2 раза +2
Код:

$u = DllStructCreate ('byte[10]')
ConsoleWrite ("Размер байтового массива: "& DllStructGetSize ($u) &@CRLF)
ConsoleWrite ("Размер данных в массиве: "& StringLen (DllStructGetData ($u,1)) &@CRLF)


amel27 08-06-2007 08:16

Creat0R
Цитата:

Вопрос в том, возможно ли и на AutoIt получить доступ к подобной информации
ИМХО не тот случай, чтобы внешним утилитам предпочесть DLLCall... Надежней будет сваять GUI-интерфейс над подходящей CMD-утилитой, благо возможностей в AutoIT предостаточно... :) Дополнительные линки по теме:

http://www.thefreecountry.com/utilit...kedfiles.shtml
http://www.microsoft.com/technet/sys...on/Handle.mspx

З.Ы. Поясню свою позицию. Дело в том, что в Windows нет документированных API-функций по перечислению открытых хэндлов, все подобные утилиты используют недокументированные вызовы функций ядра что не есть хорошо для обычного приложения, в частности могут возникать утечки памяти... При вызове внешних приложений таких проблем не возникает, так как при закрытии процесса система подчищает за ним все "хвосты". Лопата здесь лежит: http://forum.sysinternals.com/forum_...ID=3577&a%20mp. ;)

amel27 08-06-2007 09:21

Creat0R
Помнится, мы мучали функцию _PathSplitByRegExp()... Так вот оказалось, что RegExp-аналог оригинальной функции _PathSplit() занимает всего одну строчку... :)
Код:

#include <array.au3>

$path = 'C:\Program Files\AutoIT3\test.au3'
$p = StringRegExp ($path, '(?i)^\s*([A-Z]:|\\\\[^\\]*)(\\.*\\)(.*?)(\.?[^\.]*)\s*$', 3)

_ArrayDisplay ($p, $path)


gregaz 08-06-2007 18:46

Creat0R !
Спасибо за пример и разьяснения !
Все встает на свои места.

Еще пару вопросов,если можно :

1.На вопрос: Можно ли вместо вывода информации в окне MsgBox осуществлять вывод в том же окне GUI ?
был дан ответ : Можно, нужно строить также новый ГУИ .

А разве нельзя в этом же GUI вот так(тот же пример) : ? Вроде работает.

Код:

Global $Input1, $Input2, $ReadButton=-1, $SaveButton=-1

$Gui = GUICreate("Demo GUI", 400, 300)

$Label1 = GUICtrlCreateLabel("Строка 1", 20, 50, 300,40)
$Label2 = GUICtrlCreateLabel("Строка 2", 20, 100, 300,40)

$Button1 = GUICtrlCreateButton("Button1", 100, 260, 70)
$Button2 = GUICtrlCreateButton("Button2", 250, 260, 70)

GUISetState()

While 1
    Switch GUIGetMsg()
        Case -3
            Exit
        Case $Button1 ;нажата кнопка "Button1"
            ;Нажата кнопка "Button1", а значит стираем инфу и вместо неё пишем другую
            ;(можно конечно удалять контроли и создавать новые, но не вижу в этом смысла ;) )...
            GUICtrlSetData($Label1, "Новая строка 1")
            GUICtrlSetData($Label2, "Новая строка 2")

                        ;Создаём поля ввода
            $Input1 = GUICtrlCreateInput("Поле ввода 1", 20, 140, 300)
            $Input2 = GUICtrlCreateInput("Поле ввода 2", 20, 180, 300)

                        ;Создаём кнопки Read-Save
            $ReadButton = GUICtrlCreateButton("Read", 100, 220, 70)
            $SaveButton = GUICtrlCreateButton("Save", 250, 220, 70)
        Case $Button2 ;нажата кнопка "Button2"
            ;Удаляем всё кроме кнопок "Button1" и "Button2"
            GUICtrlDelete($Label1)
            GUICtrlDelete($Label2)
            GUICtrlDelete($Input1)
            GUICtrlDelete($Input2)
            GUICtrlDelete($ReadButton)
            GUICtrlDelete($SaveButton)
        Case $ReadButton ;нажата кнопка "Read"
            ;Выводим тот текст что создали (я так понял это нужно?)
                        GUICtrlSetData($Label1, "Поле ввода 1" & @LF & "Поле ввода 2")
;                        MsgBox(64, "Info", "Поле ввода 1" & @LF & "Поле ввода 2")
        Case $SaveButton ;нажата кнопка "Save"
            ;Выводим то что в полях ввода
            $ReadInput1 = GUICtrlRead($Input1)
            $ReadInput2 = GUICtrlRead($Input2)
                        GUICtrlSetData($Label2, $ReadInput1 & @LF & $ReadInput2)
;                        MsgBox(64, "Info", $ReadInput1 & @LF & $ReadInput2)
    EndSwitch
WEnd

Может быть такая кострукция в чем то неверна и это скажется в других случаях ?

2. Просьба привести любой простой пример выполнения опросов состояний элементов GUI в разных циклах
Может быть даже в том же примере провести опрос состояний кнопок "Read" и "Save"в отдельном цикле ?
3. Что означает Case -3 (GUIGetMsg()= -3 )? Какой-то идентификатор завершения процессов ???

Diamond 08-06-2007 21:12

Creat0R
Цитата:

как выяснилось, это вызвано тем, что самопальная функция возвращает символы перевода строки на конце переменной выбранных файлов. При передаче подобной переменной в проверку словаря, действие проваливается.
OK, тестирую...
Код:

$Dict=ObjCreate("Scripting.Dictionary")
Dim $var[4]
$var[0]="test1 -->" & @CRLF & "<-- возврат каретки и перенос строки"
$var[1]="test2" & @CRLF
$var[2]=@CRLF & "test3" & @CRLF
$var[3]=@CRLF & @CRLF & @LF & @LF & @CR & @CR

;~ Добавление ключей:
For $o In $var
        $Dict.Add($o,"")
Next

;~ Проверка добавленных ключей:
For $o In $var
        If $Dict.Exists($o) Then
;~        OK!
        Else
;~        ...
        EndIf
Next
;~ У меня не вылетает

;~ Проверка несуществующего ключа
MsgBox(0,"Должен быть: 0",$Dict.Exists("test5"))

;~ Проверка массива:
$arrayKey=$Dict.Keys
For $i=0 To $Dict.Count-1
        MsgBox(0,"Перебор массива...",$arrayKey[$i])
Next
;~ Всё на своём месте.

Наверное дело в чём то другом...
Похожая ошибка возникает при попытке добавить в словарь ключ (Кеу) который там уже существует. (Словарь - изначально не поддерживает дубликаты)


Creat0R 09-06-2007 00:06

amel27
Цитата:

Лопата здесь лежит:
Спасибо, немного покапал, правда не очень глубоко...

Утилита из того топика, вызвращает хэндлы TCP/UDP (правда не совсем понимаю что это), для обычных файлов информации нет :(.

Взял утилиту из второго линка, она возвращает то что нужно, но 400 с лишним кб, это тяжко, даже очень тяжко :sorry: .


Creat0R 09-06-2007 01:03

amel27
Цитата:

оказалось, что RegExp-аналог оригинальной функции _PathSplit() занимает всего одну строчку...
Оригинально, прадва расширение не возвращается...
Но вообще то, я делал функцию _PathSplitByRegExp() не как аналог функции _PathSplit(), а как что то более юзабельное и функциональнее, можно сказать что это как бы “мод” той функции :).


gregaz
Цитата:

А разве нельзя в этом же GUI вот так(тот же пример)
Можно, но лучше отдельно построить ГУИ для вывода информации, и поместить его в функцию, чтобы при каждом вызове небыло необходимости строить занового гуи:

Код:

#include <GuiConstants.au3>

$Gui = GUICreate("Demo GUI", 400, 300)

$Button1 = GUICtrlCreateButton("Button1", 100, 260, 70)

GUISetState()

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Button1 ;нажата кнопка "Button1"
            $Ret = _GuiMsgBox($WS_EX_TOPMOST, 2, "Info", "Текст 1" & @LF & "Текст 2", 330, 120, _
                "Больше не показывать", "OK", "Отмена", $Gui)
            MsgBox(0, "", "Вернувшееся значение: " & $Ret)
    EndSwitch
WEnd

;Функция для показа самодельного окна MsgBox
Func _GuiMsgBox($Type, $ButtonsNumber, $Title, $Text, $Left, $Top, $CheckBoxText, $FirstButtonText="OK", $SecondButtonText="Cancel", $hWnd=0)
    Local $Yes, $No, $OK, $CheckBox=-1, $Gui, $Msg, $ReturnVal = 0

        If $hWnd <> 0 Then WinSetState($hWnd, "", @SW_DISABLE)

        $Gui = GuiCreate($Title, $Left, $Top, -1, -1, -1, $Type, $hWnd)

    GUICtrlCreateLabel($Text, ($Left-($Left-($Left/2/2)))/2, (($Top/2)/2)-10, $Left-($Left/2/2), 40, $SS_CENTER)

    Select
        Case $ButtonsNumber = 2
            $Yes = GUICtrlCreateButton($FirstButtonText, ($Left/2)-90, ($Top/2), 70, 20)
            $No = GUICtrlCreateButton($SecondButtonText, ($Left/2)+20, ($Top/2), 70, 20)
        Case $ButtonsNumber > 2 Or $ButtonsNumber <= 1
            $OK = GUICtrlCreateButton($FirstButtonText, ($Left-70)/2, $Top/2, 70, 20)
    EndSelect

    If $CheckBoxText <> "" Then $CheckBox = GUICtrlCreateCheckbox($CheckBoxText, 15, $Top-30)
    GuiSetState(@SW_SHOW, $Gui)

    While 1
        $Msg = GUIGetMsg()
        Select
            Case $ButtonsNumber = 2 And $Msg = $Yes
                If GUICtrlRead($CheckBox) = 1 Then
                    $ReturnVal = 6+8
                Else
                    $ReturnVal = 6
                EndIf
                ExitLoop
            Case $ButtonsNumber = 2 And $Msg = $No
                If GUICtrlRead($CheckBox) = 1 Then
                    $ReturnVal = 7+8
                Else
                    $ReturnVal = 7
                EndIf
                ExitLoop
            Case ($ButtonsNumber = 1 Or $ButtonsNumber <> 2) And $Msg = $OK
                If GUICtrlRead($CheckBox) = 1 Then
                    $ReturnVal = 1+8
                Else
                    $ReturnVal = 1
                EndIf

                            Case $Msg = -3
                ExitLoop
        EndSelect
    Wend
    If $hWnd <> 0 Then WinSetState($hWnd, "", @SW_ENABLE)
    GUIDelete($Gui)
    Return $ReturnVal
EndFunc

Цитата:

Просьба привести любой простой пример выполнения опросов состояний элементов GUI в разных циклах
Не уверен что понимаю просьбу, что значить в разных циклах? цикл не важен, важно действие, что именно требуеся опрашивать, если нужно проверить текст поля ввода, тогда GuiCtrlGetData, если нужно проверить зажат ли той или инной чекбокс (птичка), тогда GuiCtrlRead() - если 1, тогда зажата, в противном случе вернётся 4, и т.д.

Цитата:

Что означает Case -3 (GUIGetMsg()= -3 )? Какой-то идентификатор завершения процессов ???
-3 это тоже самое что и $GUI_EVENT_CLOSE, я просто изначально значение многих констант выучил наизусть, поэтому по привычке использую их как есть, это иногда удобно, и позволяет не использовать вложения библиотеки, типа #Include <GuiConstants.au3>. $GUI_EVENT_CLOSE это константа, функция GuiGetMsg() возвращает её значение (-3) если послана команда закрыть окно ГУИ (пользователь нажал крестик закрытия программы).

Diamond
Цитата:

Наверное дело в чём то другом...
Возможно...

Цитата:

Похожая ошибка возникает при попытке добавить в словарь ключ (Кеу) который там уже существует.
Но у меня выводилась ошибка именно на строке с проверкой $Dict.Exists... :idontnow:

P.S
Но я всё же больше доверяю массивам :tongue: (возможно боязень чего то нового).

amel27 09-06-2007 07:28

Creat0R
Цитата:

правда расширение не возвращается
енто частности, уже исправил. :)

Кстати, насчет твоего старого вопроса о массовой замене и функции _StringRexExpReplaceEx… зачем там RegExp? Имхо вариант с обычным StringReplace справится лучше, плюсы очевидны:

- работает быстрее;
- нет проблем с форматными символами (речь о "|");
- если элементу из массива $Pattern нет соответствия в $Replace автоматически предполагается пустая строка.
Код:

$String = 'file://localhost/%22c:/my%20test/test.zip%22'
Dim $Pattern [4] = ['/','%20','%22','file:\\localhost\']
Dim $Replace[3] = ['\',' ','"']

Func _StringReplaceEx ($String, $Pattern, $Replace)
    Local $i
    ReDim $Replace[UBound($Pattern)]
    For $i=0 To UBound($Pattern)-1
        ConsoleWrite ($Pattern[$i]&':'&$Replace[$i]&@CRLF)
        $String = StringReplace ($String, $Pattern[$i], $Replace[$i])
    Next
    Return $String
EndFunc

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


gregaz 09-06-2007 10:26

Creat0R
функция _GuiMsgBox достаточно громоздкая видимо из-за своей универсальности(на все случаи жизни)
Попробую разобраться в ней.
А пока 1 вопрос :
При закрытии дочернего окна GUI у меня обычно закрывается и родительсое окно.
У тебя же в примере этого не происходит .
Чем это достигнуто ?

Creat0R 09-06-2007 10:37

amel27
Цитата:

зачем там RegExp?
Я тоже в начале не хотел это использовать, но дело в том, что в отличие от приведённого мной примера, иногда есть необходимость для каждой замены задавать Patern (кстати, как оно по русский? :) ), чтобы по нему делать замену.

Вобщем спасибо, идея с созданием массива вне функции мне понравилась, это позволяет более удобно задавать Patern и соответственно замену.
А также...

Цитата:

- нет проблем с форматными символами (речь о "|");
:)

Вот немного переделал, добавил проверку ошибочности и возврат общего числа сделанных замен (@Extended):

Код:

$String = 'file://localhost/%22c:/my%20test/test.zip%22'
Dim $Pattern[4] = ['/', '%20', '%22', 'file:\\localhost\']
Dim $Replace[4] = ['\', ' ', '"', '']

$String = _StringMultiReplace($String, $Pattern, $Replace)

MsgBox (64, "Results", $String  & @LF & "Число замен: " & @extended)
;На выходе имеем это:
;"c:\my test\test.zip"
;Число замен: 9

Func _StringMultiReplace($String, $Pattern, $Replace)
    If Not IsArray($Pattern) Or Not IsArray($Replace) Then Return SetError(1, 0, $String)
    Local $Extended = 0
    ReDim $Replace[UBound($Pattern)]
    For $i = 0 To UBound($Pattern)-1
        $String = StringReplace($String, $Pattern[$i], $Replace[$i])
        $Extended += @extended
    Next
    Return SetError(0, $Extended, $String)
EndFunc

gregaz
Цитата:

При закрытии дочернего окна GUI у меня обычно закрывается и родительсое окно.
Это зависит от того как оно закрывается...

Цитата:

Чем это достигнуто ?
Функция GuiDelete() имеет один опциональный параметр, это должен быть уникальный идентификатор, который возвращается функцией GuiCreate().

Соответственно, если имеем 2 ГУИ:

$Gui_1 = GuiCreate("Первый ГУИ")

$Gui_2 = GuiCreate("Второй ГУИ")


То для закрытия второго (предполагается что они оба уже видны), задаём как первый параметр команды GuiDelete() его идентификатор:

GuiDelete($Gui_2)

Также можно и спрятать окно:

GuiSetState(@SW_HIDE, $Gui_2)

Для показа обратно:

GuiSetState(@SW_SHOW, $Gui_2)

gregaz 09-06-2007 11:01

Цитата:

gregaz
Цитата:При закрытии дочернего окна GUI у меня обычно закрывается и родительсое окно.

Creat0R
Это зависит от того как оно закрывается...
Спасибо это тоже полезно,ноя имел ввиду закрытие системным крестиком (в правом верхнем углу ).

amel27 09-06-2007 11:33

Creat0R
По поводу _FileOpenDialog() - замени по тексту в определении структур "byte" на "char"... Так вроде работает, но логику изменений в работе структурных функций AutoIT-а пока не просек... нелогично это, когда бинарные данные (не текст!) по умолчанию преобразуются в юникод... на выходе получается чёрти-чё...

Creat0R 09-06-2007 12:27

gregaz
Цитата:

я имел ввиду закрытие системным крестиком
Но если в главном цикле не задать действие для этого крестика, а именно это:

If GuiGetMsg = -3 Then
GuiDelete($Gui_2)
EndIf

то ничего происходить не будет.

Поэтому я и написал, что это зависит от ситуации и метода закрытия.

amel27
Цитата:

замени по тексту в определении структур "byte" на "char"
Ок, спасибо, но у меня пока этой проблемы нет, я ещё не ставил новую версию AutoIt (юзаю 3.2.2.0), но когда поставлю, полагаю мне это пригодится :)

Часовой пояс GMT +4. Сейчас 02:58.


Часовой пояс GMT -5. Сейчас 17:21.
© OSzone.net 2001-2004