Что нового

[Окна, Диалоги] Сохранение страницы как MHT в IE9

avmir

Новичок
Сообщения
28
Репутация
1
День добрый!

У меня есть программка, которая вызывает скрипт AutoIT и передает ему три параметра:
1. URL страницы,
2. Путь к рабочему каталогу, куда должны сохраняться страницы,
3. Имя файла под которым нужно сохранить страницу.

В результате скрипт сохранял нужную страницу в формате MHT в нужную папку с нужным именем.
Вот скрипт:
Код:
#Include <GUIComboBox.au3>
#include <IE.au3>
#Include <WinAPI.au3>
#Include <WinAPIEx.au3>

$sURL = $CmdLine[1]
$sWorkPaht = $CmdLine[2]
$sFileName = $CmdLine[3]

Opt("WinTitleMatchMode", 2)

$oIE = _IECreate ($sURL) ;, 0, 1, 1, 0) ; $sURL - первый параметр 'URL'

$win_handle = WinGetHandle("Windows Internet Explorer", $sURL)

_WinAPI_SetKeyboardLayout($win_handle, 0x0419)

;ControlSend ($win_handle, '', '', "{ALTDOWN}{ALTUP}фх", 0)
Send("{ALTDOWN}{ALTUP}")
Send("ф")
Send("х")

$sSaveAsWindow = "Сохранение веб-страницы"
WinWait($sSaveAsWindow,"")
If Not WinActive($sSaveAsWindow,"") Then WinActivate($sSaveAsWindow,"")
WinWaitActive($sSaveAsWindow,"")

ControlSetText ($sSaveAsWindow, "", "Edit1", $sWorkPaht) ; $sWorkPaht - второй параметр 'рабочая папка'
ControlClick ($sSaveAsWindow, "", "Button2")
_GUICtrlComboBox_SetCurSel(ControlGetHandle($sSaveAsWindow, '', 'ComboBox3'), 1)

;If FileExists($sWorkPaht & $sFileName) Then FileDelete($sWorkPaht & $sFileName)

ControlSetText ($sSaveAsWindow, "", "Edit1", $sFileName) ; "test" - третий параметр 'имя файла'
ControlClick ($sSaveAsWindow, "", "Button2")

$Timer = TimerInit()
While TimerDiff($Timer) < 50000000
    $hFile = _WinAPI_CreateFile($sWorkPaht & $sFileName, 2, 2, 0)
    If $hFile Then
        _WinAPI_CloseHandle($hFile)
        ExitLoop
    EndIf
    Sleep(1000)
WEnd

If Not $hFile Then
    ; Ошибка
    ConsoleWrite('File not found or time out.' & @CR)
Else
    ConsoleWrite('OK' & @CR)
EndIf

;Sleep(15000)


WinClose($win_handle)


Все это работало, пока исполнялось в Windows XP и IE8...

Теперь после перехода на Windows 7 появились проблемы.
С тем, что поменялись номера инстансов элементов управления в окне сохранения я разобрался.
Привел скрипт к нужному виду, но он все равно не работает.

Код:
#Include <GUIComboBox.au3>
#include <IE.au3>
#Include <WinAPI.au3>
#Include <WinAPIEx.au3>

$sURL = $CmdLine[1]
$sWorkPaht = $CmdLine[2]
$sFileName = $CmdLine[3]

Opt("WinTitleMatchMode", 2)

$oIE = _IECreate ($sURL) ;, 0, 1, 1, 0) ; $sURL - первый параметр 'URL'

$win_handle = WinGetHandle("Windows Internet Explorer", $sURL)

_WinAPI_SetKeyboardLayout($win_handle, 0x0419)

;ControlSend ($win_handle, '', '', "{ALTDOWN}{ALTUP}фх", 0)
Send("{ALTDOWN}{ALTUP}")
Send("ф")
Send("с")

$sSaveAsWindow = "Сохранение веб-страницы"
WinWait($sSaveAsWindow,"")
If Not WinActive($sSaveAsWindow,"") Then WinActivate($sSaveAsWindow,"")
WinWaitActive($sSaveAsWindow,"")

; здесь переход в рабочую папку
ControlSetText ($sSaveAsWindow, "", "Edit1", $sWorkPaht, 1) ; $sWorkPaht - второй параметр 'рабочая папка'
ControlClick ($sSaveAsWindow, "", "Button1")

; выбор формата сохранения - MHT
_GUICtrlComboBox_SetCurSel(ControlGetHandle($sSaveAsWindow, '', 'ComboBox2'), 1)

;If FileExists($sWorkPaht & $sFileName) Then FileDelete($sWorkPaht & $sFileName)
ControlSetText ($sSaveAsWindow, "", "Edit1", $sFileName) ; "test" - третий параметр 'имя файла'
ControlClick ($sSaveAsWindow, "", "Button1")

$Timer = TimerInit()
While TimerDiff($Timer) < 50000000
    $hFile = _WinAPI_CreateFile($sWorkPaht & $sFileName, 2, 2, 0)
    If $hFile Then
        _WinAPI_CloseHandle($hFile)
        ExitLoop
    EndIf
    Sleep(1000)
WEnd

If Not $hFile Then
    ; Ошибка
    ConsoleWrite('File not found or time out.' & @CR)
Else
    ConsoleWrite('OK' & @CR)
EndIf

;Sleep(15000)


WinClose($win_handle)


Проблема вот в чем:
в куске кода, помечнном комментом "; здесь переход в рабочую папку" -
я подставлял в TextBox "Имя файла" - путь к рабочей папке со слешем в конце, и при нажатии на кнопку сохранить (ранее в IE8) открывалась нужнаяя папка.
Теперь, я подставляю в TextBox "Имя файла" - тоже путь к рабочей папке со слешем в конце, и при нажатии на кнопку сохранить происходит не переход, а сохранение файла с именем, которое предлагалось по умолчанию в момент открытия диалогового окна (тот текст что в шапке - имя страницы)...
Откуда оно берется и как от него избавиться?
 
Автор
A

avmir

Новичок
Сообщения
28
Репутация
1
Да, кстати, при выборе в ComboBox-е варианта "Веб-архив, один файл (*.mht)", зрительно он выбирается, НО сохраняется файл все равно в формате "Веб-страница полностью" с дополнительной папкой :wacko:


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

Короче говоря все зрительно меняется, но "в глубине элементов управления" остается то, что предлагало окно "Сохранить как..." :'(
 
Автор
A

avmir

Новичок
Сообщения
28
Репутация
1
На замечания отреагировал. Исправил.
 
Автор
A

avmir

Новичок
Сообщения
28
Репутация
1
Так что, никто с Windows 7 не работал?
Господа гуру, помогите пожалуйста!
 
Автор
A

avmir

Новичок
Сообщения
28
Репутация
1
Неужели ни у кого нет никаких идей? :'(
 

Zaramot

I ♥ AutoIt
Сообщения
1,160
Репутация
660
Попробуй-те так:
Код:
#include <GUIConstantsEx.au3>

$Form1 = GUICreate("Page Downloader", 267, 151, 192, 124)
$Label1 = GUICtrlCreateLabel("Полный адрес сайта:", 8, 8, 112, 15)
$Input1 = GUICtrlCreateInput("", 8, 24, 249, 21)
$Label2 = GUICtrlCreateLabel("Сохранить в папку:", 8, 56, 101, 15)
$Input2 = GUICtrlCreateInput("", 8, 72, 209, 21)
$Button1 = GUICtrlCreateButton("...", 224, 71, 35, 23)
$Input3 = GUICtrlCreateInput("", 8, 120, 121, 21)
$Label3 = GUICtrlCreateLabel("Имя фала:", 8, 104, 58, 15)
$Button2 = GUICtrlCreateButton("Сохранить", 136, 119, 123, 24)
GUISetState()

While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
		Case $Button1
			$SaveDir = FileSelectFolder('', '')
			If Not @error Then GUICtrlSetData($Input2, $SaveDir)
		Case $Button2
			$URL = GUICtrlRead($Input1)
			$Dir = GUICtrlRead($Input2)
			$Name = GUICtrlRead($Input3)
			If $URL = '' Then ContinueLoop MsgBox(64, 'Page Downloader', 'Вы не указали страницу.')
			If $Dir = '' Then ContinueLoop MsgBox(64, 'Page Downloader', 'Вы не выбрали папку для сохранения.')
			If $Name = '' Then ContinueLoop MsgBox(64, 'Page Downloader', 'Вы не задали имя.')
			_INetGetMHT($URL, $SaveDir & '\' & $Name & ".mht" )
			MsgBox(64, 'Page Downloader', 'Веб страница сохранена успешно.')
	EndSwitch
WEnd

Func _INetGetMHT($sURL, $sFILE)
    Local $msg = ObjCreate("CDO.Message")
    If @error Then Return False
    Local $ado = ObjCreate("ADODB.Stream")
    If @error Then Return False

    With $ado
        .Type = 2
        .Charset = "US-ASCII"
        .Open
    EndWith
    $msg.CreateMHTMLBody($sURL, 0)
    $msg.DataSource.SaveToObject($ado, "_Stream")
    FileDelete($sFILE)
    $ado.SaveToFile($sFILE, 1)
    $msg = ""
    $ado = ""
    Return True
EndFunc


PS У меня XP и не могу проверить :(
 
Автор
A

avmir

Новичок
Сообщения
28
Репутация
1
Zaramot

Где я только не обсуждал этот вопрос - "Как сохранить страницу в формате MHT"...

И на буржуйском форуме AutoIt тоже. Там одна американка предлагала сохранять страницу при помощи библиотек CDO и ADODB. Вроде бы, христоматийный код. Приводится и в MSDN, и по форумам валяется, причем везде буковка в буковку одинаковый...
НО, обнаружилась странная вещь - в оффлайне эти страницы не отображались корректно - все картинки и стили отсуствовали напрочь. Она поэкспериментировала с нужными мне страницами и согласилась - "Да невозможно..."

1 мая 2010 года я открыл на форуме тему [Окна, Диалоги] Как получить полный контроль над диалогом SaveAs в IE8

Вот цитата из первого поста этой темы.

avmir [?]
Встала такая задача:
Имеется список URL, нужно сохранить страницы соответствующие URL-ам как веб-архивы (MHT).
Так как через использование CDO веб страница сохраняется неполностью (вместо картинок и стилей - ссылки), было решено использовать для этих целей AutoIt и IE8. При сохранении через IE, веб-архив сохраняется полностью.

В результате активных обсуждений с форумчанами родился скрипт который без проблем работал по сей день в Windows XP и IE8 (он указан в начале первого поста текущей темы).

Теперь Вы Zaramot предлагаете мне тоже самое - использовать библиотеки CDO и ADODB.
Я не поленился - попробовал, и... О ЧУДО!!! Почти всё сохраняется!
Странно это... Что поменялось с тех пор? Неужели мелкософтовцы библиотеки дописали?...

Правда, IE8 или 9 длительно ждет пока не загрузятся все картинки со страницы, и только по прошествии какого-то времени "разрешает" сохранить страницу.
А CDO судя по всему не заморачивается с этим. "Картинка сейчас недоступна?" - "Ну и фиг с ней".

Zaramot всё равно большое спасибо!

Но вопрос остается открытым:
Почему мой скрипт меняет значение текстового поля "Имя файла" и выбирает в ComboBox "Тип файла" второй пункт "Веб-архив, один файл (*.mht)" (при этом на экране видны изменения!),
а при эмуляции нажатия на кнопку "Сохранить" файл сохраняется как HTML (с файлами в отдельной папке) (это превый пункт в ComboBox-е, т.е. по-умолчанию) да еще и с именем, которое предлагало окно "Сохранить веб-страницу" до изменений проделанных моим скриптом.
 
Автор
A

avmir

Новичок
Сообщения
28
Репутация
1
После некоторого редактирования скрипта

Код:
#Include <GUIComboBox.au3>
#Include <GUIComboBoxEx.au3>
#include <IE.au3>
#Include <WinAPI.au3>
#Include <WinAPIEx.au3>

$sURL = $CmdLine[1]
$sWorkPaht = $CmdLine[2]
$sFileName = $CmdLine[3]
$sSaveAsWindow = "Сохранение веб-страницы"

Opt("WinTitleMatchMode", 2)

If FileExists($sWorkPaht & $sFileName) Then FileDelete($sWorkPaht & $sFileName)

$oIE = _IECreate ($sURL) ;, 0, 1, 1, 0) ; $sURL - первый параметр 'URL'

$win_handle = WinGetHandle("Windows Internet Explorer", $sURL)

_WinAPI_SetKeyboardLayout($win_handle, 0x0419)

Do
	Send("{ALTDOWN}{ALTUP}")
	sleep(500)
	Send("ф")
	sleep(500)
	Send("с")
	sleep(500)
Until WinExists($sSaveAsWindow, "")

WinWait($sSaveAsWindow,"")
If Not WinActive($sSaveAsWindow,"") Then WinActivate($sSaveAsWindow,"")
WinWaitActive($sSaveAsWindow,"")
sleep(500)

; здесь мы переходим в папку в которую должны сохраняться страницы
ControlSetText ($sSaveAsWindow, "", "Edit1", $sWorkPaht) ; $sWorkPaht - второй параметр 'рабочая папка'
_GUICtrlComboBoxEx_SetCurSel(ControlGetHandle($sSaveAsWindow, "", "ComboBox2"), 1)
ControlClick ($sSaveAsWindow, "", "Button1")

; здесь сохраняем MHT файл с нужным именем
ControlSetText ($sSaveAsWindow, "", "Edit1", $sFileName, 1) ; "test" - третий параметр 'имя файла'
_GUICtrlComboBoxEx_SetCurSel(ControlGetHandle($sSaveAsWindow, "", "ComboBox2"), 1)
ControlClick ($sSaveAsWindow, "", "Button1")

sleep(500)

$Timer = TimerInit()
While TimerDiff($Timer) < 2000000000
    $hFile = _WinAPI_CreateFile($sWorkPaht & $sFileName, 2, 2, 0)
    If $hFile Then
        _WinAPI_CloseHandle($hFile)
        ExitLoop
    EndIf
    Sleep(1000)
WEnd

Sleep(1000)

If Not $hFile Then
    ; Ошибка
    ConsoleWrite('File not found or time out.' & @CR)
Else
    ConsoleWrite('OK' & @CR)
EndIf

WinClose($win_handle)

Exit($win_handle)


он стал сохранять файл с нужным именем, но всё также несмотря на то, что он выбирает в ComboBox "Тип файла" второй пункт "Веб-архив, один файл (*.mht)" (при этом на экране видны изменения!), а при эмуляции нажатия на кнопку "Сохранить" файл сохраняется как HTML (с файлами в отдельной папке) (это превый пункт в ComboBox-е, т.е. по-умолчанию).

Как заставить скрипт сохрянять файл в формате MHT?

Господа помогите пожалуйста, уже столько времени ничего не получается :wacko:
 
Автор
A

avmir

Новичок
Сообщения
28
Репутация
1
Может кликами можно как-то сделать? Пробовал, во время исполнения скрипта, кликами повторить выбор пунката "Веб-архив, один файл (*.mht)" - всё сохранилось правильно.

Да, и еще мысль - в IE всегда этот выбор запоминался. Я так думаю, в момент выбора элемента данные заносились в реестр. Может при сохранении IE берет "тип файла" не из ComboBox-а, а как раз из реестра? Может, весь этот гемор связан как раз с параноидальностью "семерки"?
 
Автор
A

avmir

Новичок
Сообщения
28
Репутация
1
Прошло 1,5 года.
Пересел на Windows 7 64.
IE уже 10-ой версии.
Возвращаюсь к своему вопросу. Помогите пожалуйста его решить. :'(
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
avmir
Проверил на Win7 x32, IE10
Код:
#include <IE.au3>

$sURL = $CmdLine[1]
$sFullFileName = $CmdLine[2] ; полное имя файла (с путём)

$oIE = _IECreate($sURL)
$winIE = WinWaitActive("[class:IEFrame]", $sURL)
ControlSend($winIE, "", "", "^s")
$sSaveAsWindow = WinWaitActive("Сохранение веб-страницы")

ControlSetText ($sSaveAsWindow, "", "Edit1", $sFullFileName)
ControlCommand($sSaveAsWindow, "", "ComboBox2", "SelectString", "Веб-архив, один файл (*.mht)")
ControlClick ($sSaveAsWindow, "", "Button1")
If WinWaitActive("Подтвердить сохранение", "", 2) Then ControlClick("Подтвердить сохранение", "", "Button1")
 
Автор
A

avmir

Новичок
Сообщения
28
Репутация
1
Большущее спасибо!!!

Поменял функцию

Код:
_GUICtrlComboBoxEx_SetCurSel(ControlGetHandle($sSaveAsWindow, "", "ComboBox2"), 1)


на

Код:
ControlCommand($sSaveAsWindow, "", "ComboBox2", "SelectString", "Веб-архив, один файл (*.mht)")


и почти всё заработало!!!

Почему почти?
Потому, что я заметил, в отличие от XP, в Win 7 ссылка открывается, но без авторизации на сайте...
Т.е. создаваемый экземпляр IE не читает сохраненные файлы Cookies...
Это можно как-то реализовать?
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
avmir [?]
ссылка открывается, но без авторизации на сайте
Попробовал на этом сайте.
Если скрипт запускать под пользователем (как я обычно сюда и захожу), то авторизация проходит автоматически, т.е. cookies читаются. Если запустить скрипт с правами администратора, то запросит авторизацию. Но... Если пройти авторизацию "под администратором", то следующие запуски с правами администратора будут авторизоваться автоматически.
Мне кажется у вас подобная проблема - авторизация была пройдена под одним пользователем, а скрипт запускается под другим.
 
Автор
A

avmir

Новичок
Сообщения
28
Репутация
1
Комп личный. Пользователь - один. И он (т.е. - Я), естественно - администратор со всеми привилегиями :smile:
Запускаю IE - авторизация автоматическая.
Попробовал различные сочетания: программа которая запускает скрипт (запуск от имени администратора и обычный запуск) и, собственно, сам скомпилированный скрипт (запуск от имени администратора и обычный запуск). Четыре варианта. Во всех случаях авторизация автоматом не происходила.
Потом во время запуска скрипта решил поставить его на паузу когда экземпляр IE был создан. В этом экземпляре прошел ручками авторизацию. И... О чудо!!! Всё заработало! При последующих запусках скрипта - авторизация автоматическая!!!

Огромнейшее спасибо InnI!!! Я не хотел переходить на семерку, потому, что скрипт в ней никак не хотел работать. Теперь вопрос решен :smile:

Однако, всё же остался "осадок" в пытливом уме - "Почему это происходит???" :scratch:
Я про авторизацию в "родном Windows-овском IE" и про повторную авторизацию в экземпляре, созданном скриптом. Получается, что для IE, запущенного скриптом, создаются отдельные cookies???
 
Верх