DyadyaGenya
Знающий
- Сообщения
- 300
- Репутация
- 10
Доброго времени суток. Решил написать в стол заказов, потому что сам не могу осилить, а в обычной теме пока никто не стал разбираться. При этом время стало поджимать.
Сперва то, что нужно получить. В окошке выбирается файл эксель. По нажатии кнопки "Старт" он копируется в дефолтную папку (@ScriptDir & '\~TEST~'). При этом включается мониторинг за этой папкой. Мониторинг осуществляется с помощью UDF RDC от Yashied. Функция Exel() сохраняет файл с новым именем в (@DesktopDir & "\Отчеты\" & "new.xlsx"). После этого переименованный файл отправляется по почте. и мониторинг за папкой прекращается (возможно на предыдущем шаге, сразу после запуска переименования файла). И после этого по желанию окошко либо закрывается, либо выбирается новый файл, который опять копируется, переименовывается и отсылается по почте.
Из того, что у меня получается: Если папку не мониторить (закоментировать функцию мониторинга), то могу настроить переименование и отправку почты (потому что знаю, как называется выбранный файл). Но все дело в том, что это только часть скрипта. В полном я не сам копирую файл, поэтому и нужно мониторить папку. В полном стороння программа закидывает нужный файл и с ним необходимо произвести манипуляции, переименовать и отправить по почте. Эта стороння программа закидывает много разных файлов. Я могу лишь инициировать закидывание нужного мне, но не знаю как он будет называться. Для этого нужно включать мониторинг на тот промежуток, пока закидывается). Если же включить мониторинг, то файл "отлавливается" и может даже переименоваться, но почта не отправляется и не возможно закрыть окошко, нажать хоть на какую-то кнопку. Пробовал отменить мониторинг. Вроде отменяется, но окошко все равно висит и с ним ничего нельзя сделать. При этом ради эксперимента закидывал файл не через окошко и мониторинг уже не реагирует, а окошко продолжает "висеть".
Ниже код с посильными пояснениями.
Версия SciTE-Lite Version 3.5.4
Сперва то, что нужно получить. В окошке выбирается файл эксель. По нажатии кнопки "Старт" он копируется в дефолтную папку (@ScriptDir & '\~TEST~'). При этом включается мониторинг за этой папкой. Мониторинг осуществляется с помощью UDF RDC от Yashied. Функция Exel() сохраняет файл с новым именем в (@DesktopDir & "\Отчеты\" & "new.xlsx"). После этого переименованный файл отправляется по почте. и мониторинг за папкой прекращается (возможно на предыдущем шаге, сразу после запуска переименования файла). И после этого по желанию окошко либо закрывается, либо выбирается новый файл, который опять копируется, переименовывается и отсылается по почте.
Из того, что у меня получается: Если папку не мониторить (закоментировать функцию мониторинга), то могу настроить переименование и отправку почты (потому что знаю, как называется выбранный файл). Но все дело в том, что это только часть скрипта. В полном я не сам копирую файл, поэтому и нужно мониторить папку. В полном стороння программа закидывает нужный файл и с ним необходимо произвести манипуляции, переименовать и отправить по почте. Эта стороння программа закидывает много разных файлов. Я могу лишь инициировать закидывание нужного мне, но не знаю как он будет называться. Для этого нужно включать мониторинг на тот промежуток, пока закидывается). Если же включить мониторинг, то файл "отлавливается" и может даже переименоваться, но почта не отправляется и не возможно закрыть окошко, нажать хоть на какую-то кнопку. Пробовал отменить мониторинг. Вроде отменяется, но окошко все равно висит и с ним ничего нельзя сделать. При этом ради эксперимента закидывал файл не через окошко и мониторинг уже не реагирует, а окошко продолжает "висеть".
Ниже код с посильными пояснениями.
Код:
#include <Array.au3>
#Include <APIConstants.au3>
#include <APIFilesConstants.au3>
#include <AutoItConstants.au3>
#include <Constants.au3>
#include <Date.au3>
#include <Excel.au3>
#include <File.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <GUIDateTimePicker.au3>
#Include <RDC.au3>
#include <String.au3>
#include <WinAPI.au3>
#include <WinAPIProc.au3>
#include <WinAPIError.au3>
#include <WinAPIFiles.au3>
#include <WinAPIMem.au3>
#include <WindowsConstants.au3>
#RequireAdmin
#pragma compile(AutoItExecuteAllowed, True)
HotKeySet('{ESC}','_out');клавиша выхода - Esc
Opt('MustDeclareVars', 1)
Opt('TrayAutoPause', 0)
Global $sValidFName_Pattern = '^(?!~\$).*?\.xlsx$'
Global $sRenamed_FName = ''
Global $hWnd = GUICreate('')
Global $sEvents = ''
Global $stat, $Otchet
;Папка куда копируется выбранный файл и для которой включается мониторинг
Global Const $sDir = @ScriptDir & '\~TEST~'
Global $hGui = GUICreate('Окно копирования', 700, 680, -1, -1, -1, $WS_EX_TOPMOST)
Local $btStart = GUICtrlCreateButton('Старт', 392, 8, 75, 25)
Local $sPathSS = GUICtrlCreateInput('', 8, 96, 325, 21)
Local $sPathS = GUICtrlCreateButton('Откуда', 392, 96, 75, 25)
Local $btClear = GUICtrlCreateButton('Очистить', 392, 630, 75, 25)
GUISetState()
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
; ProcessClose($iPid)
Exit
Case $sPathS
GUICtrlSetData($sPathSS, '')
Local $sPS = FileOpenDialog('Выбор копируемого файла', '', "(*.xlsx)")
If Not @error Then GUICtrlSetData($sPathSS, $sPS)
Case $btStart
_Copy()
_Excel($sPS) ; Если раскомментировать эту строку и закоментировать строку ниже, то все работает и письмо отправляется
;_Dir() ; Если эта строка раскомментирована, то включается слежение за каталогом, но все остальное не работает.
Sleep(3000)
_Mail($Path, $Subject)
Case $btClear
GUICtrlSetData($sPathSS, '')
_Clear()
EndSwitch
WEnd
Func _Copy()
FileDelete('copy.txt')
If FileExists($sPS) Then ;And FileExists($sPD) Then
FileWrite('copy.txt', "$Shell = ObjCreate('Shell.Application')" & @CRLF & "$Shell.NameSpace('" & $sDir & "').CopyHere('" & $sPS & "', 16)")
Local $iPid = Run(@AutoItExe & ' /AutoIt3ExecuteScript copy.txt')
EndIf
EndFunc
Func _Clear()
Local $aRS = IniReadSection("Setting.ini", "Путь")
If Not @error Then
For $i = 1 To $aRS[0][0]
$aRS[$i][1] = ''
Next
IniWriteSection("Setting.ini", "Путь", $aRS)
EndIf
Local $LCC = IniReadSection("Setting.ini","Statistika")
If Not @error Then
For $j = 1 To $LCC[0][0]
$LCC[$j][1] = ''
IniWrite("Setting.ini","Statistika", $LCC[$j][0], '')
Next
EndIf
Local $IMG = IniReadSection("Setting.ini","ПутьСкрин")
If Not @error Then
For $k = 1 To $IMG[0][0]
$IMG[$k][1] = ''
FileDelete(IniRead("Setting.ini","ПутьСкрин", $IMG[$k][0], ''))
IniWrite("Setting.ini","ПутьСкрин", $IMG[$k][0], '')
Next
EndIf
EndFunc
Func _Excel($Otchet)
ConsoleWrite('Из РДЦ :' & $sDir & @CR)
Local $g_sPath=$sDir
Local $Otchet1 = _StringExplode($Otchet, '\')
Local $Otchet2 = $Otchet1[UBound($Otchet1)-1]
ConsoleWrite('новый эксель1 ' & '\' & $Otchet2 & @CR)
Local $oExcel = _Excel_Open()
Local $sWorkbook = $g_sPath & '\' & $Otchet2
ConsoleWrite('новый эксель2 ' & $sWorkbook & @CR)
Local $oWorkbook = _Excel_BookOpen($oExcel,$sWorkbook)
If @error Then Exit MsgBox($MB_SYSTEMMODAL, "Excel UDF: _Excel_BookOpen Example 1", "Error opening '" & $sWorkbook & "'." & @CRLF & "@error = " & @error & ", @extended = " & @extended)
;MsgBox($MB_SYSTEMMODAL, "Excel UDF: _Excel_BookOpen Example 1", "Workbook '" & $sWorkbook & "' has been opened successfully." & @CRLF & @CRLF & "Creation Date: " & $oWorkbook.BuiltinDocumentProperties("Creation Date").Value)
Local $Otchet4 = @DesktopDir & "\Отчеты\" & $Otchet2
ConsoleWrite('перед сохранением ' & $Otchet4 & @CR)
$sWorkbook = @DesktopDir & "\Отчеты\" & "new.xlsx"
ConsoleWrite('по идее сохранение ' & $sWorkbook & @CR)
_Excel_BookSaveAs($oWorkbook, $sWorkbook, $xlWorkbookDefault, True)
; Закрытие экселя
_Excel_BookClose($oWorkbook, False)
_Excel_Close($oExcel, False, True)
Global $Path = $sWorkbook
Global $Subject = "Отчет за " & _Now()
EndFunc
Func _Mail($Path, $Subject)
ConsoleWrite('Отправка почты ' & @CR)
Local $str = "http://schemas.microsoft.com/cdo/configuration/"
Local $hMAIL = ObjCreate ("CDO.Message")
With $hMAIL
.From = "****@gmail.com";
.To = "****@ukr.net"
.Subject = $Subject
.TextBody = "Письмо отправлено от " & _Now()
.AddAttachment ($Path) ;файл для отправки
EndWith
With $hMAIL.Configuration.Fields
.Item ($str & "sendusing") = 2
.Item ($str & "smtpserver") = "smtp.gmail.com" ;SMTP Server
.Item ($str & "smtpusessl") = True
.Item ($str & "smtpauthenticate") = 1
.Item ($str & "sendusername") = "****@gmail.com"
.Item ($str & "sendpassword") = "****" ;Пароль SMTP-сервер
.Item ($str & "smtpserverport") = 465 ;Порт
.Update
EndWith
$hMAIL.Send
If Not @error Then
MsgBox($MB_SYSTEMMODAL, "", $Subject & " создан , почта отправлена", 0, $hGUI)
Else
MsgBox($MB_SYSTEMMODAL, "", $Subject & " создан ,но почта не отправлена", 0, $hGUI)
EndIf
EndFunc
Func _Dir()
_RDC_OpenDll()
If @Error Then
ConsoleWrite('Error: _RDC_OpenDll() - ' & @Error & @CR)
Exit
EndIf
Global $hWnd = GUICreate('')
Global $sEvents = ''
If Not FileExists($sDir) Then
DirCreate($sDir)
EndIf
GUIRegisterMsg($WM_RDC, 'WM_RDC')
_RDC_Create($sDir, 1, BitOR($FILE_NOTIFY_CHANGE_FILE_NAME, $FILE_NOTIFY_CHANGE_DIR_NAME, $FILE_NOTIFY_CHANGE_SIZE), 0, $hWnd)
If @Error Then
ConsoleWrite('Error: _RDC_Create() - ' & @Error & ', ' & @Extended & @CR)
Exit
EndIf
While 1
Sleep(1000)
WEnd
EndFunc
Func WM_RDC($hWnd, $iMsg, $wParam, $lParam)
#forceref $hWnd, $iMsg, $wParam
Local $aData = _RDC_GetData($lParam)
If @Error Then
; Do something because notifications will not come from this thread!
ConsoleWrite('Error: _RDC_GetData() - ' & @Error & ', ' & @Extended & ', ' & _RDC_GetDirectory($lParam) & @CR)
_RDC_Delete($lParam)
Return 0
EndIf
For $i = 1 To $aData[0][0]
If $sEvents Then
$sEvents &= '|'
EndIf
$sEvents &= $aData[$i][1] & '?' & _RDC_GetDirectory($lParam) & '\' & $aData[$i][0]
Next
AdlibRegister('_RetrieveDirectoryChanges', 250)
Return 0
EndFunc ;==>WM_RDC
Func _RetrieveDirectoryChanges()
ConsoleWrite("следим за $sDir" & $sDir & @CR)
AdlibUnRegister('_RetrieveDirectoryChanges')
; ConsoleWrite('для закрытия1 ' & $iID & @CR)
Local $aData, $aText, $aPrev[2] = [0, ''], $sPrev = ''
$aData = StringSplit($sEvents, '|', 2)
$sEvents = ''
If Not IsArray($aData) Then
Return
EndIf
For $i = 0 To UBound($aData)
If $i < UBound($aData) Then
If $aData[$i] = $sPrev Then
ContinueLoop
EndIf
$sPrev = $aData[$i]
$aText = StringSplit($aData[$i], '?', 2)
If IsArray($aText) Then
;~ ConsoleWrite($aText[0] & ' - ' & $aText[1] & @CR)
;~ ContinueLoop
Switch Number($aText[0])
Case 1 ; FILE_ACTION_ADDED
Switch Number($aPrev[0])
Case 2
If StringRegExpReplace($aPrev[1], '^.*\\', '') = StringRegExpReplace($aText[1], '^.*\\', '') Then
If $aPrev[1] = $aText[1] Then
;~ If _IsDirectory($aText[1]) Then
;~ ; Nothing
;~ Else
;~ ; Nothing
;~ EndIf
$aPrev[0] = 0
ContinueLoop
Else
If _IsDirectory($aText[1]) Then
ConsoleWrite('DIRECTORY MOVED1: ' & $aPrev[1] & ' ---> ' & $aText[1] & @CR)
Else
ConsoleWrite('FILE MOVED1: ' & $aPrev[1] & ' ---> ' & $aText[1] & @CR)
EndIf
$aPrev[0] = 0
ContinueLoop
EndIf
EndIf
EndSwitch
Case 2 ; FILE_ACTION_REMOVED
; Nothing
Case 3 ; FILE_ACTION_MODIFIED
Switch Number($aPrev[0])
Case 1
;~ If True Then
If $aPrev[1] = $aText[1] Then
If _IsDirectory($aText[1]) Then
; Nothing
Else
Local $PathM = StringSplit($aText[1], '\')
Local $PathMA[0]
_ArrayAdd($PathMA, $PathM)
;_ArrayDisplay($PathMA)
Local $maxIn = UBound($PathMA)-1
ConsoleWrite('Путь ' & $PathMA[$maxIn] & @CR)
;Ничего не делаем если: файл не существует, не является валидным эксель файлом, или это наш переименованный файл
If Not StringRegExp($PathMA[$maxIn], $sValidFName_Pattern) Or $PathMA[$maxIn] = $sRenamed_FName Then
Return
Else
ConsoleWrite('появился файл ' & $PathMA[$maxIn] & @CR)
_Excel($PathMA[$maxIn])
; _LV_Delete($sDir) ; Если раскомментировать, то до прекращения слежения за каталогом не доходит
; _RDC_Destroy() ;
EndIf
; ContinueLoop
EndIf
$aPrev[0] = 0
ContinueLoop
EndIf
;~ EndIf
Case 2
If StringRegExpReplace($aPrev[1], '^.*\\', '') = StringRegExpReplace($aText[1], '^.*\\', '') Then
;~ If True Then
If _IsDirectory($aText[1]) Then
; Nothing
Else
ConsoleWrite('FILE DELETED1: ' & $aText[1] & @CR)
ConsoleWrite('FILE MOVED2: ' & $aPrev[1] & ' ---> ' & $aText[1] & @CR)
EndIf
$aPrev[0] = 0
ContinueLoop
;~ EndIf
EndIf
EndSwitch
Case 4 ; FILE_ACTION_RENAMED_OLD_NAME
; Nothing
Case 5 ; FILE_ACTION_RENAMED_NEW_NAME
Switch Number($aPrev[0])
Case 4
If StringRegExpReplace($aPrev[1], '\\[^\\]*\Z', '') = StringRegExpReplace($aText[1], '\\[^\\]*\Z', '') Then
;~ If True Then
If _IsDirectory($aText[1]) Then
ConsoleWrite('DIRECTORY RENAMED1: ' & $aPrev[1] & ' ---> ' & $aText[1] & @CR)
Else
ConsoleWrite('FILE RENAMED1: ' & $aPrev[1] & ' ---> ' & $aText[1] & @CR)
EndIf
$aPrev[0] = 0
ContinueLoop
;~ EndIf
EndIf
EndSwitch
EndSwitch
EndIf
EndIf
Switch Number($aPrev[0])
Case 1 ; FILE_ACTION_ADDED
If _IsDirectory($aPrev[1]) Then
ConsoleWrite('DIRECTORY ADDED2: ' & $aPrev[1] & @CR)
Else
ConsoleWrite('FILE ADDED2: ' & $aPrev[1] & @CR)
EndIf
Case 2 ; FILE_ACTION_REMOVED
;~ If True Then
ConsoleWrite('FILE OR DIRECTORY DELETED3: ' & $aPrev[1] & @CR)
ConsoleWrite('FILE OR DIRECTORY DELETED3: ' & StringRegExpReplace($aPrev[1], '\\[^\\]*\Z', '\') & @CR)
;~ EndIf
Case 3 ; FILE_ACTION_MODIFIED
If _IsDirectory($aPrev[1]) Then
; Nothing
Else
ConsoleWrite('FILE MODIFIED4: ' & $aPrev[1] & @CR)
EndIf
EndSwitch
$aPrev = $aText
Next
ConsoleWrite('---------------------------------------------' & @CR)
_LV_Delete($sDir) ; Если раскомментировать, то перестает следить за каталогом, но все остальное не работает
_RDC_Destroy()
EndFunc ;==>_RetrieveDirectoryChanges
Func _IsDirectory($sPath)
If StringInStr(FileGetAttrib($sPath), 'D') Then
Return 1
Else
Return 0
EndIf
EndFunc ;==>_IsDirectory
Func _LV_Delete($sDir)
If _RDC_Delete($sDir) Then
If _RDC_Delete($sDir) Then
_WinAPI_KillTimer(0, 1)
EndIf
EndIf
EndFunc ;==>_LV_Delete
;Функция для закрытия процесса аутоит, слежения за папкой.
Func _out()
Local $aData = _WinAPI_EnumChildProcess(_WinAPI_GetParentProcess())
;_ArrayDisplay($aData, '_WinAPI_EnumChildProcess')
ProcessClose($aData[1][0])
EndFunc
Последнее редактирование: