Ru-Board.club
← Вернуться в раздел «Программы»

» AutoIT

Автор: Xecutioner
Дата сообщения: 28.07.2010 08:57
Добрый день!
Есть такая программка CheckXML для проверки налоговой отчетности и отчетности в ПФР, у нее есть своя динамическая библиотека CPSNXML.dll к которой существует описание.
При выполнении функции "cpsnValidate" autoit просто вылетает не говоря ни слова (появляется только окно отправить ошибку в мелкософт). Может быть я что-то неправильно делаю?

Вот как в описании обозначаются переменные этой функции на Visual Basic:


Код: Declare Function cpsnValidate Lib "CPSNXML" (ByVal sXmlFileName As String, ByRef nError As Long, ByRef nWarning As Long) As Long
Автор: Loopback
Дата сообщения: 28.07.2010 10:50
Xecutioner
По-видимому, в качестве второго-третьего параметра требуется указатель на целое (в VB "ByRef"). Попробуй записать так:

Код:
DllCall($dll,"long","cpsnValidate","str",$sPath,"long*",$iErrors,"long*",$iPredup)
Автор: AZJIO
Дата сообщения: 28.07.2010 11:12
madmasles
теперь вопрос встал как получить результат с мантисой и экспонентой, а не полной строкой, которая не влазиет в инпут.

Попробовал сделать вывод числа с мантисой, с двумя функциями обратной конвертации


Код: If StringLen($rech)>20 And Not(StringInStr($rech, 'e+') Or StringInStr($rech, 'e-')) Then
If StringLen(Int($rech))>20 Then
$r1 = StringMid($rech, 1, 1)
$exp=StringLen(Int($rech))-1
If StringLen($exp)<3 Then $exp='0'&$exp
If StringLen($exp)<3 Then $exp='0'&$exp
$rech=$r1&'.'&StringTrimLeft(StringTrimRight(Int($rech),5),1)&'e+'$exp
Else
If StringMid($rech, 1, 1)<>0 Then
$Npt = StringInStr($rech, '.')
$rech= Round($rech, 20-$Npt)
Else
$aRech1=StringRegExp($rech, '(0\.)(0*)(\d+)',3)
$exp=StringLen($aRech1[1])+1
$r1 = StringMid($aRech1[2], 1, 1)
$rech=$r1&'.'&StringTrimLeft($aRech1[2],1)
$rech= Round($rech, 15)&'e-'&$exp
EndIf
EndIf
EndIf

Func _ConvNumP($num)
$exp='1'
$aRech1=StringSplit($num, '+')
For $i = 1 to Execute($aRech1[2])
$exp&='0'
Next
$num = _BigNum_Mul(StringTrimRight($aRech1[1],1), $exp)
Return $num
EndFunc

Func _ConvNumM($num)
$exp='1'
$aRech1=StringSplit($num, '-')
For $i = 1 to $aRech1[2]
$exp&='0'
Next
$num = _BigNum_Div(StringTrimRight($aRech1[1],1), $exp,'200')
Return $num
EndFunc
Автор: AZJIO
Дата сообщения: 28.07.2010 13:19
Строки деления требуют указать величину разрядности, например 200
MsgBox(0, 'Message',_BigNum_Div('0.0001', '41','200'))
MsgBox(0, 'Message',_BigNum_Div(0.0001, 41,200)
Автор: Xecutioner
Дата сообщения: 28.07.2010 14:19
Loopback
Спасибо! все замечательно работает.
Раз DllCall сам по себе является массивом с результатом выполненных функций, а не записывает их в переменные, то $iErrors и $iPredup в моем примере не нужны.

Цитата:
По-видимому, в качестве второго-третьего параметра требуется указатель на целое (в VB "ByRef"). Попробуй записать так:

Код:

DllCall($dll,"long","cpsnValidate","str",$sPath,"long*",$iErrors,"long*",$iPredup)



Кстати, Autoit не вернет число ошибок в $iErrors, это значение надо будет брать из массива, который возвращает DllCall.

Автор: Kar1son
Дата сообщения: 28.07.2010 15:21
иногда подвисает iexplorer.exe, те окна не видно, а процесс висит. как бы определить такой процесс и убить? можно сравнить количество процессов со списком окон, но как потом выбрать какой из процессов убить а какой живой?
Автор: AZJIO
Дата сообщения: 29.07.2010 02:43
Обновил секундомер, избавил индикатор от мерцания, добавлены горячие клавиши, авторестарт времени при выборе сигнала, возможность остановить сигнал.
Автор: Lovec
Дата сообщения: 01.08.2010 23:42
Народ!
Третий час сижу туплю, не могу понять почему DllCall не ищет простейший Блокнот....


Код: $a = DllCall("User32.dll", "hwnd", "FindWindowA", _
"str", "", _
"str", "Безымянный - Блокнот")

MsgBox (0, '', $a[0])
Автор: ViSiToR
Дата сообщения: 02.08.2010 00:12
Lovec 00:42 02-08-2010
Цитата:
почему DllCall не ищет простейший Блокнот

Потому что функции нужны оба параметра, как заголовок окна, так и его класс:


Код: $a = DllCall("User32.dll", "hwnd", "FindWindow", _
"str", "Notepad", _ ;Class
"str", "Безымянный - Блокнот")

MsgBox (0, '', $a[0])
Автор: Lovec
Дата сообщения: 02.08.2010 10:50
ViSiToR
Спасибо, уважаемый. Так действительно работает

Но вот вопрос. смотрим MSDN:

Код: HWND WINAPI FindWindow(
__in_opt LPCTSTR lpClassName,
__in_opt LPCTSTR lpWindowName
);
Автор: ViSiToR
Дата сообщения: 02.08.2010 11:18
Lovec 11:50 02-08-2010
Цитата:
Вот я, веря MSDN и пытался использовать только один параметр

Нет, пустая строка ("") совсем не означает Null , нужно указать там «"int", 0».
Автор: Lovec
Дата сообщения: 02.08.2010 15:18
ViSiToR
И снова ты прав Сенкс.

Может подскажешь еще... Вот есть API-функция GetDiskFreeSpace.
Вот откуда простой человек, не работающий в Microsoft, может знать что она возвращает массив данных и что именно в каком элементе массива хранится?? Ведь в MSDN об этом ни слова Все справочники по API что я видел - лишь жалкая копия MSDN и от них толку не более.
Откуда же люди берут эту инфу???
Автор: Kar1son
Дата сообщения: 02.08.2010 15:31
Можно ли как-то в локалке получить имена машин, зная ИП адреса? на всех машинах есть права админа
Автор: ViSiToR
Дата сообщения: 02.08.2010 16:17
Lovec 16:18 02-08-2010
Цитата:
откуда простой человек, не работающий в Microsoft, может знать что она возвращает массив данных и что именно в каком элементе массива хранится?

Она возвращает не массив, а число > 0 (при удачной обработке). А данные хранятся в структурах чий указатели должны быть переданы функции в качестве параметров.
Автор: Lovec
Дата сообщения: 02.08.2010 17:00
ViSiToR


Вод код примера работы этой функции:

Код:
Local $SectorsPerCluster
Local $BytesPerSector
Local $NumberOfFreeClusters
Local $TotalNumberOfClusters

$calldata=DllCall("Kernel32.dll","int","GetDiskFreeSpaceW", _
"wstr", "C:\", _
"dword*", $SectorsPerCluster, _
"dword*", $BytesPerSector, _
"dword*", $NumberOfFreeClusters, _
"dword*", $TotalNumberOfClusters)

; Данные возвращаются в виде массива, не изменяя значения передаваемых в функцию переменных
$SectorsPerCluster = $calldata[2]
$BytesPerSector = $calldata[3]
$NumberOfFreeClusters = $calldata[4]
$TotalNumberOfClusters = $calldata[5]

MsgBox (0, "", "Всего кластеров: " & $TotalNumberOfClusters & @CR & _
"Количество свободных кластеров: " & $NumberOfFreeClusters & @CR & _
"Количество байт в одном секторе: " & $BytesPerSector & @CR & _
"Количество секторов в одном кластере: " & $SectorsPerCluster & @CR & @CR & _
"Итого: " & @CR & @CR & _
"Количество байт в одном кластере: " & $BytesPerSector * $SectorsPerCluster & @CR & _
"Всего байт на диске С: " & $BytesPerSector * $SectorsPerCluster * $TotalNumberOfClusters & @CR & _
"Свободно байт на диске С: " & $BytesPerSector * $SectorsPerCluster * $NumberOfFreeClusters)
Автор: ViSiToR
Дата сообщения: 02.08.2010 17:29
Lovec 18:00 02-08-2010
Цитата:
возвращается масив $calldata

Ну об этом написано в справке по AutoIt:


Цитата:
If the function call fails then @error is set to 1. Otherwise an array is returned that contains the function return value and a copy of all the parameters (including parameters that the function may have modified when passed by reference).


И вообще это не совсем правильное использование функции:


Код: #Include <WinAPI.au3>

$tSectorsPerCluster = DllStructCreate("int64")
$tBytesPerSector = DllStructCreate("int64")
$tNumberOfFreeClusters = DllStructCreate("int64")
$tTotalNumberOfClusters = DllStructCreate("int64")

$calldata = DllCall("Kernel32.dll", "int", "GetDiskFreeSpaceW", _
"wstr", "C:\", _
"ptr", DllStructGetPtr($tSectorsPerCluster), _
"ptr", DllStructGetPtr($tBytesPerSector), _
"ptr", DllStructGetPtr($tNumberOfFreeClusters), _
"ptr", DllStructGetPtr($tTotalNumberOfClusters))

If Not $calldata[0] Then
MsgBox(48, 'Error', 'Failed: ' & _WinAPI_GetLastErrorMessage())
Exit
EndIf

$SectorsPerCluster = DllStructGetData($tSectorsPerCluster, 1)
$BytesPerSector = DllStructGetData($tBytesPerSector, 1)
$NumberOfFreeClusters = DllStructGetData($tNumberOfFreeClusters, 1)
$TotalNumberOfClusters = DllStructGetData($tTotalNumberOfClusters, 1)

MsgBox(0, "", "Всего кластеров: " & $TotalNumberOfClusters & @CR & _
"Количество свободных кластеров: " & $NumberOfFreeClusters & @CR & _
"Количество байт в одном секторе: " & $BytesPerSector & @CR & _
"Количество секторов в одном кластере: " & $SectorsPerCluster & @CR & @CR & _
"Итого: " & @CR & @CR & _
"Количество байт в одном кластере: " & $BytesPerSector * $SectorsPerCluster & @CR & _
"Всего байт на диске С: " & $BytesPerSector * $SectorsPerCluster * $TotalNumberOfClusters & @CR & _
"Свободно байт на диске С: " & $BytesPerSector * $SectorsPerCluster * $NumberOfFreeClusters)
Автор: Lovec
Дата сообщения: 02.08.2010 17:45
ViSiToR
Ок. Спасибо.

Цитата:
Кстати, эта функция не справится со значениями больше 2 gb, нужно использовать GetDiskFreeSpaceEx

С этим не согласен. Ведь на своем компе пробовал прежде чем писать. И на диске С:\ места поболее 2ГБ (в том числе и свободного).
Автор: ViSiToR
Дата сообщения: 02.08.2010 17:57
Lovec 18:45 02-08-2010
Цитата:
С этим не согласен

Это не я придумал , так утверждает MSDN:


Цитата:
The GetDiskFreeSpace function cannot report volume sizes that are greater than 2 gigabytes (GB). To ensure that your application works with large capacity hard drives, use the GetDiskFreeSpaceEx function.
Автор: AZJIO
Дата сообщения: 02.08.2010 19:00
NIKZZZZ
Можно как нибудь в функцию поиска файлов добавить тригер - "поиск файлов только в корневом каталоге"? Как разновидность функции. Чтобы всю конструкцию обработаки файлов между While - WEnd не переписывать ещё в отдельную функцию.
Автор: Sergey_Demchuk
Дата сообщения: 03.08.2010 01:22
Как правильно присвоить переменной строку
sldb.ExecSQL('insert into test2 (domain,subdomain,key,value) values("'+'fff'+'","'+'fffffff'+'","'+'eer'+'","'+'eerr'+'")')

Надо наверное по коду вводить символы кавычек?
Автор: Kar1son
Дата сообщения: 03.08.2010 08:11
Lovec
Спасибо! я для себя уже сделал по третьему примеру но с использованием утилитки psexec(удаленный запуск команд) :
Run('psexec \\'& $IP &' hostname', '', @SW_HIDE, $STDOUT_CHILD)

nslookup не подходит потому что в ДНС на один ИП адрес несколько имен хостов и он возвращает их по очереди(первый запуск - имя1, второй запуск - имя2, потом снова имя 1 и тд)
Автор: Kastermight
Дата сообщения: 03.08.2010 10:16
Sergey_Demchuk
Зависит от того, в какие кавычки заключаешь строку.
Если в одинарные, то все двойные содержащиеся в самой строке можешь смело оставлять так как есть, а все одинарные дублировать. Аналогично с двойными кавычками. Если строку обрамляют двойные кавычки, то все одинарные в самое строке оставляешь как есть, а все двойные дублируешь.

Код: $str = 'sldb.ExecSQL(''insert into test2 (domain,subdomain,key,value) values("''+''fff''+''","''+''fffffff''+''","''+''eer''+''","''+''eerr''+''")'')'
$str = "sldb.ExecSQL('insert into test2 (domain,subdomain,key,value) values(""'+'fff'+'"",""'+'fffffff'+'"",""'+'eer'+'"",""'+'eerr'+'"")')"
Автор: Kar1son
Дата сообщения: 03.08.2010 11:10
Lovec

Код: $CompName = "192.168.3.4" ; IP компьютера к которому подключаемся
$UserName = "domain\Administrator" ; имя пользователя от чьего имени подключаемся
$Pass = "*****" ; пароль пользователя $UserName

$oMyError = ObjEvent("AutoIt.Error","MyErrFunc") ; Устанавливаем перехватчик COM-ошибок

$objSWbemLocator = ObjCreate("WbemScripting.SWbemLocator")
$objWMIService = $objSWbemLocator.ConnectServer($CompName, "root\CIMV2", $UserName, $Pass, "", "", 0)
$colItems = $objWMIService.ExecQuery("Select * from Win32_ComputerSystem")

If IsObj($colItems) Then
For $objComputer In $colItems
MsgBox (0, '', $objComputer.Name)
Next
EndIf

Func MyErrFunc()
Msgbox(0,"COM error","Возникла ошибка при работе с COM объектом !" & @CRLF & @CRLF & _
"err.description is: " & @TAB & $oMyError.description & @CRLF & _
"err.windescription:" & @TAB & $oMyError.windescription & @CRLF & _
"err.number is: " & @TAB & hex($oMyError.number,8) & @CRLF & _
"err.lastdllerror is: " & @TAB & $oMyError.lastdllerror & @CRLF & _
"err.scriptline is: " & @TAB & $oMyError.scriptline & @CRLF & _
"err.source is: " & @TAB & $oMyError.source & @CRLF & _
"err.helpfile is: " & @TAB & $oMyError.helpfile & @CRLF & _
"err.helpcontext is: " & @TAB & $oMyError.helpcontext _
)
Endfunc
Автор: Lovec
Дата сообщения: 03.08.2010 11:51
Kar1son

Цитата:
там оказывается пара серверов на которых у меня нет прав

Без прав доступа через WMI не получится. Ищи другие варианты.
Автор: Kar1son
Дата сообщения: 03.08.2010 11:58
Lovec
не в этом вопрос, пусть бы те машины на которых нет прав просто пропустились а остальные бы отработали, но скрипт их не пропускает а с ошибкой падает...

Код: $UserName = "Dom\User" ; имя пользователя от чьего имени подключаемся
$Pass = "pass" ; пароль пользователя $UserName

$oMyError=ObjEvent("AutoIt.Error", "MyErrFunc") ; Устанавливаем перехватчик COM-ошибок

For $i = 0 To UBound($arr) - 1
$CompName = $arr[$i] ; IP компьютера к которому подключаемся
ConsoleWrite($arr[$i] & @CRLF)

$objSWbemLocator = ObjCreate("WbemScripting.SWbemLocator")
$objWMIService = $objSWbemLocator.ConnectServer($CompName, "root\CIMV2", $UserName, $Pass, "", "", 0)
If IsObj($oMyError) And StringInStr($oMyError.description,'Отказано') Then ContinueLoop
$colItems = $objWMIService.ExecQuery("Select * from Win32_ComputerSystem")

If IsObj($colItems) Then
For $objComputer In $colItems
MsgBox(0, '', $objComputer.Name)
Next
EndIf
Next

Func MyErrFunc()
EndFunc ;==>MyErrFunc
Автор: Lovec
Дата сообщения: 03.08.2010 13:16

Цитата:
падает в строке:
$colItems = $objWMIService.ExecQuery("Select * from Win32_ComputerSystem")

Это значит что скрипт доходит до этой строки при ошибке, а не должен. Значит твое условие

Код: If IsObj($oMyError) And StringInStr($oMyError.description,'Отказано') Then ContinueLoop

Страницы: 12345678910111213

Предыдущая тема: Проблемы с VMware Workstation (часть 4)


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.