Что нового

Запуск скомпилированного AutoIt-скрипта

Yura1970

Новичок
Сообщения
5
Репутация
0
Есть вопрос.

Написал скрипт, скомпилировал в EXE.

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

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

Fever

Скриптер
Сообщения
308
Репутация
112
у себя подобных проблем не замечал :-\

выложите код исходника
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Yura1970
Абсолютно согласен с Fever. Скорей всего проблема в Вашем скрипте. Компиляция "превращает" скрипт в независимый исполняемый файл и ему уже "по барабану", установлен AutoIt или нет. На самый крайний случай, если в скрипте проблем нет, то , если Вы используете при компиляции UPX, некоторые "сильно продвинутые" антивирусы могут не давать отрабатывать скомпилированному скрипту.
 
Автор
Y

Yura1970

Новичок
Сообщения
5
Репутация
0
Да легко.

Но сначала объясню суть - есть досовская утилита для анализа файла, необходимо запусть ее на выполнение и обработать сообщение выдаваемое на экран и в зависимости от того что там написано - выполнить операции с файлом, например, переместить его в определенную папку. Понимаю, что для вызова досовской утилиты использовать CMD-файл - извращение, но по другому не удалось, так как если просто писать досовскую команду без кавычек в команде RUN, то почему то съедалось значение ключа. То есть получалось так:
1. Из командной строки в FAR-е
CheckFile.exe /n NameFile
Результат: outbox
2. Из команды RUN запуск той же самой команды на выходе получаем: "неверное число параметров"

Ну а вот и сам листинг программы.

Код:
#include <Constants.au3> 

;~ Проверяем наличие INI-файла и при отсутствии данного создаем автоматически со следующими параметрами 
;~ Название 1-ой секции [InBox] - в данной секции прописывается путь к каталогу в котором хранятся проверяемые файлы 
;~ Название переменной                 -        Path 
;~ Значение по умолчанию        -        C:\Box\In 
;~ Название 2-ой секции [OutBox] - в данной секции прописывается путь к каталогу в котором будут хранятся проверенные файлы содержащие 2 ЭЦП 
;~ Название переменной                 -        Path 
;~ Значение по умолчанию        -        C:\Box\Out 
If Not FileExists(@ScriptDir & "\Test.ini") Then 
   $fileINI = FileOpen(@ScriptDir & "\Test.ini", 2) 
   FileWriteLine($fileINI, "[InBox]") 
   FileWriteLine($fileINI, "Path=C:\Box\In") 
   FileWriteLine($fileINI, "[OutBox]") 
   FileWriteLine($fileINI, "Path=C:\Box\Out") 
   FileClose($fileINI) 
EndIf 

;~ Считываем из INI-файла значение переменной Path находящейся в секции [InBox] - путь к каталогу в котором хранятся проверяемые файлы 
;~ (Значение по умолчанию - C:\Box\In) 
$PathInBox=IniRead ( @ScriptDir & "\Test.ini", "InBox", "Path", "C:\Box\In" ) 
;~ Считываем из INI-файла значение переменной Path находящейся в секции [OutBox] - путь к каталогу в котором будут хранятся проверенные файлы
;~ (Значение по умолчанию - C:\Box\Out) 
$PathOutBox=IniRead ( @ScriptDir & "\Test.ini", "OutBox", "Path", "C:\Box\Out" ) 

;~ Проверяем наличие файлов в каталоге с проверяемыми файлами 
$SearchFile = FileFindFirstFile($PathInBox & "\*.*")   
If $SearchFile = -1 Then 
;~         В случае отсутствия файлов в данном каталоге выдаем сообщение о том что нет ни одного файла для проверки и закрываем программу 
    MsgBox(0, "Ошибка", "В указанном каталоге " & $PathInBox & " нет ни одного файла для проверки.") 
    Exit 
EndIf 

;~ В цикле проходим по всем файлам содержащимся в каталоге проверяемых файлов 
While 1 
        ;~         Получаем имя файла 
    $FileFind = FileFindNextFile($SearchFile) 
        ;~         Если мы не можем получить новое имя файла, то завершаем выполнение цикла 
    If @error Then ExitLoop 
        ;~         Имя проверяемого файла получено, поэтому для каждого проверяемого файла создаем специальный CMD-файл с командной строкой проверки файла 
        $FileCMD = FileOpen(@ScriptDir & "\test.cmd", 2) 
        FileWriteLine($FileCMD, '"C:\Program Files\CheckFile\CheckFile.exe" /n "' & $PathInBox & '\' & $FileFind & '"') 
        FileClose($FileCMD) 
        ;~ Запускаем созданный CMD-файл на выполнение 
        $foo=Run(@ScriptDir & "\test.cmd", $PathInBox , @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD) 
        ;~ Выводим в переменную $WorkCMD результаты проверки файла 
        $WorkCMD="" 
        While 1 
                $line = StdoutRead($foo) 
                If @error Then ExitLoop 
                IF NOT StringIsSpace($line) Then 
                        $WorkCMD=$WorkCMD & $line 
                EndIf 
        Wend 
        ;~ Переводим значение переменной $WorkCMD из DOS-кодировки в Windows-кодировку 
        $WorkCMD=OemToAnsi($WorkCMD) 
        ;~ Считываем из переменной $WorkCMD построчно данные и в зависимости от находящейся в них 
        ;~ информации обрабатываем файл 
        $LineWorkCMD = StringSplit($WorkCMD, @CR) 
        For $i=1 to $LineWorkCMD[0] 
                ;~ Проверяем строку, необходимо чтобы в ней содержалось указание на то куда перемещать 
                ;~ файл 
                If StringInStr($LineWorkCMD[$i],"outbox")>0 Then 
                        FileMove($PathInBox & '\' & $FileFind , $PathOutBox & '\' & @MON & '_' & @MDAY & '\' & $FileFind,8) 
                        $i=$LineWorkCMD[0] 
                Else 
                        MsgBox(4096, "Результаты проверки файла: " & $FileFind , "В данном файле осутствуют указания для сортировки - повторите процедуру отправки файлов заново! ") 
                EndIf 
        Next 
WEnd 

FileClose($SearchFile) 

Exit 

func OemToAnsi ($inline) 
Local $stString  = DLLStructCreate("char[" & StringLen($inline)+2 & "]") 
        DllStructSetData($stString,1,$inline) 
        DllStructSetData($stString,1,chr(0),StringLen($inline)+2) 
        DllCall("user32.dll", "long", "OemToChar", "ptr", DllStructGetPtr($stString), "ptr",DllStructGetPtr($stString) ) 
Return DllStructGetData($stString,1) 
EndFunc 

func AnsiToOem ($inline) 
Local $stString  = DLLStructCreate("char[" & StringLen($inline)+2 & "]") 
        DllStructSetData($stString,1,$inline) 
        DllStructSetData($stString,1,chr(0),StringLen($inline)+2) 
        DllCall("user32.dll", "long", "CharToOem", "ptr", DllStructGetPtr($stString), "ptr",DllStructGetPtr($stString) ) 
Return DllStructGetData($stString,1) 
EndFunc
 
Автор
Y

Yura1970

Новичок
Сообщения
5
Репутация
0
madmasles сказал(а):
Yura1970
Абсолютно согласен с Fever. Скорей всего проблема в Вашем скрипте. Компиляция "превращает" скрипт в независимый исполняемый файл и ему уже "по барабану", установлен AutoIt или нет. На самый крайний случай, если в скрипте проблем нет, то , если Вы используете при компиляции UPX, некоторые "сильно продвинутые" антивирусы могут не давать отрабатывать скомпилированному скрипту.

В скрипте проблем нет. На всех машинках установлен Касперский. На всех машинках одинаковая операционка WindowsXP. Но на двух машинках запускается - а на третьей нет.

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


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

CreatoR сказал(а):
Yura1970 [?]
вот и сам листинг программы
Который нужно заключать в тег autoit.

Пофиксил.
 

snoitaleR

AutoIT Гуру
Сообщения
855
Репутация
223
Yura1970
Я думаю, что если скрипт отрабатывает без проблем на двух машинах, значит, он не отработает на третьей из-за условий, которые связаны только с самой машиной...
Это может быть брэндмауэр (файервол), антивирус, ограничение прав пользователя и многое другое... Установить это можно только в режиме эксперимента...
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
Yura1970
AutoIt3 он практически портабельный, попробуй на флешке перенести AutoIt3 на тот комп, где не работает и кинуть скрипт на AutoIt3.exe. Обычно скомпилированный скрипт ничего вменяемого не показывает, а не скомпилированный покажет ошибку в строке.

Команды Run, ShellExecute нормально работают с ключами, вот примеры:
Код:
Run ( @Comspec&' /C REG LOAD HKLM\PE_SY_HI "'&$inputtmp0&'\tmp\base_wim\i386\system32\setupreg.hiv"', '', @SW_HIDE )
RunWait ( @Comspec & ' /C regedit /s "'&$inputtmp0&'\tmp\base4.reg"', '', @SW_HIDE )
Run(@ScriptDir&'\tools\imagex.exe /capture'&$boot1&'"'&$inputtmp0&'\tmp\base_wim" "'&$inputtmp0&'\'&$namewimpe&'_New.wim" "'&$labelwim0&'" /compress maximum', '', @SW_HIDE)
ShellExecute(@ScriptDir&'\ghost32.exe','-clone,mode=pload,src='&$gho&$Path5&':1,dst='&$dsk&' -sure','','', @SW_HIDE )
ShellExecuteWait (@ScriptDir&'\tools\imagex.exe','/apply "'&$inputwim0&'" "'&$labelwim0&'" "'&$inputtmp0&'\tmp\base_wim"','','', @SW_HIDE )
ShellExecuteWait(@ScriptDir&'\tools\subinacl.exe','/subkeyreg HKEY_LOCAL_MACHINE\PE_LM_SW /grant=Все=F','','', @SW_HIDE )
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Любая команда, которая может быть запущена из командной строки - может быть запущена и из Run. к примеру запуск command-line версии архиватора 7-zip на архивацию ее же папки lang будет выглядеть так:
Код:
$7z = "c:\program files\7-zip"
Run($7z & "\7z.exe a """ & $7z & "\test.zip"" " & """" & $7z & "\lang\""")

как видишь - главное это корректная запись путей + кавычки.
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
Yura1970
Посмотри примеры модификации скрипта:

Здесь единожды указываем путь, и далее только переменую
Запись в файл тоже одной строкой.

Код:
$myPath=@ScriptDir & "\Test.ini"
If Not FileExists($myPath) Then 
   $fileINI = FileOpen($myPath, 2) 
   FileWrite($fileINI, "[InBox]" & @CRLF & _
   "Path=C:\Box\In" & @CRLF & _
   "[OutBox]" & @CRLF & _
   "Path=C:\Box\Out" )
   FileClose($fileINI) 
EndIf


Цикл чтения потока

Код:
While 1 
   $WorkCMD &= StdoutRead($foo) 
   If @error Then ExitLoop
   Sleep(10)
Wend


строка старта

Код:
$foo=Run('"C:\Program Files\CheckFile\CheckFile.exe" /n "'& $PathInBox & '\' & $FileFind &'"', '' , @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)


И для слежения за ходом выполнения операций ставь между ними мессаги
MsgBox(0, 'Сообщение', '1')
с цифрами 1, 2 и т.д.
Они позволять следить на каком этапе вылет скрипта.
А для CheckFile.exe нужно ставить проверку существования файла.
 
Автор
Y

Yura1970

Новичок
Сообщения
5
Репутация
0
AZJIO сказал(а):
Yura1970
AutoIt3 он практически портабельный, попробуй на флешке перенести AutoIt3 на тот комп, где не работает и кинуть скрипт на AutoIt3.exe. Обычно скомпилированный скрипт ничего вменяемого не показывает, а не скомпилированный покажет ошибку в строке.

Да конечно надо было сразу так попробовать, только машинка эта стоит у главбуха, сложно пробиться :smile:

А по поводу второй части - я не спорю что он нормально работает с командами, только вот именно с той утилитой были проблемы - из командной строки идет а из любого батника не запускается (вернее запускается, но почему то съедались параметры). как-то интересно сам cmd.exe отрабатывал - поэтому понадобилось записывать всю строку команды в двойные кавычки, затем в cmd-файл и только потом его запускать.


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

AZJIO сказал(а):
Yura1970
Посмотри примеры модификации скрипта:

Здесь единожды указываем путь, и далее только переменую
Запись в файл тоже одной строкой.

Код:
$myPath=@ScriptDir & "\Test.ini"
If Not FileExists($myPath) Then 
   $fileINI = FileOpen($myPath, 2) 
   FileWrite($fileINI, "[InBox]" & @CRLF & _
   "Path=C:\Box\In" & @CRLF & _
   "[OutBox]" & @CRLF & _
   "Path=C:\Box\Out" )
   FileClose($fileINI) 
EndIf


Цикл чтения потока

Код:
While 1 
   $WorkCMD &= StdoutRead($foo) 
   If @error Then ExitLoop
   Sleep(10)
Wend


строка старта

Код:
$foo=Run('"C:\Program Files\CheckFile\CheckFile.exe" /n "'& $PathInBox & '\' & $FileFind &'"', '' , @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)


И для слежения за ходом выполнения операций ставь между ними мессаги
MsgBox(0, 'Сообщение', '1')
с цифрами 1, 2 и т.д.
Они позволять следить на каком этапе вылет скрипта.
А для CheckFile.exe нужно ставить проверку существования файла.

Да я вот сам голову ломал и пришел к тому же выводу, скорее всего скрипт по указанному пути не находит досовскую утилиту - может удалили или перенесли на другой диск. Завтра проверю на работе.

А для чего в цикле чтения потока поставил Sleep(10)?
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
Yura1970
А для чего в цикле чтения потока поставил Sleep(10)?
Можешь убрать, возможно это подгонка под определённые условия, возможно выходные данные большого размера и не успевают прочитаться, поэтому я сохранил это пример в оригинале.
 

seriych

Новичок
Сообщения
18
Репутация
0
Я еще до AutoIT узнал об UPX. Пробовал свои программы на C++ Builder сжимать. Так вот некоторые после сжатия тоже запускались только на компах с C++ Builder.
 
Автор
Y

Yura1970

Новичок
Сообщения
5
Репутация
0
:laugh: Всем спасибо. Дело действительно было в том что не находилась ДОСовская утилита, внес предлагаемые изменения - заработало.
:IL_AutoIt_1:
 
Верх