Как сохранить встроенный браузер от подсказок, куда сохранить загруженный файл?

Как загрузить файл после программного нажатия кнопки загрузки, и, следовательно, не нужно знать URL для загрузки файла.

После загрузки файла появляется запрос и спрашивает,Я хочу сохранить файл после нажатияда' другое приглашение спрашивает, где выЯ хотел бы сохранить файл. Итак, файл загружается первым, может быть, где-то в буфер, после начальной загрузки появляются подсказки.

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

(Любой метод для нажатия кнопки будет в порядке, следующее должно быть хорошо.)

procedure TForm1.Button1Click(Sender: TObject);
var
  x: integer;
  ovLinks: OleVariant;
begin
  WebBrowser1.Navigate('The web page');
  //wait for page to down load
  ovLinks := WebBrowser1.OleObject.Document.all.tags('A');
  if ovLinks.Length > 0 then
  begin
    for x := 0 to ovLinks.Length-1 do
      begin
        if Pos('id of button', ovLinks.Item(x).id) > 0 then
        //or if Pos('href of button', ovLinks.Item(x).href) > 0 then
        begin
          ovLinks.Item(x).click;
          Break;
        end;
      end;
  end;
end;

Причина этого вопроса: URL файла не всегда может быть найден. Например: на этомВеб-сайтЯ не могнайти URL программно, но после нажатия кнопки экспорта, используя IE, файл был загружен в 'Временные интернет файлы' папка. В IEВременные интернет файлы' папка имеет столбецИнтернет-адрес который показывает URL. Но в Chrome таких данных нет. НО, на этомВеб-сайтЯ могу найти URL программно, но когда я загружаю файл, нажимаяВот'файл не 'не появляются в IEВременные интернет файлы' папка. Для других веб-сайтов URL-адрес можно найти в папке и найти его программно, но на других сайтах URL-адрес не может быть найден в любом случае.

 TLama14 нояб. 2012 г., 21:24
@ Glenn1234, не совсем,экспорт кнопка на этомweb site вызывает функцию JavaScript.
 TLama14 нояб. 2012 г., 14:39
Вы можете использоватьEmbedded Web Browser в вашем проекте?
 Glenn123414 нояб. 2012 г., 21:11
Не уверен, как именно интерпретировать этот вопрос, но у меня первоначальное впечатление, что это пахнет как возможный дубликатstackoverflow.com/questions/8949965/controlling-file-downloads , Мой ответ будет там.
 TLama14 нояб. 2012 г., 14:59
Я скорее спрашивал, хочешь ли ты использовать это, чем если бы ты знал это. Это's бесплатная оболочка с открытым исходным кодом для Internet Explorer с использованием так же, какTWebBrowser, только что встроенный. Для вашего случая встроено путем реализацииIDownloadManager интерфейс. Я могу опубликовать вам пример, если хотите.
 Glenn123414 нояб. 2012 г., 22:11
@ Тама, я вижу, вопрос немного другой, чем кажется. Я сделал предложение ниже.
 Peter James14 нояб. 2012 г., 14:12
Веб-соскоб? Спасибо за ссылку. Но я предпочитаю придерживаться Delphi. Единственные другие языки, которые я знаю, это Android, еще начинающий, и немного Javascript.
 Peter James14 нояб. 2012 г., 14:45
@TLama Привет, Тлама, встроенный веб-браузер? Почему так много учиться? Я так думаю, это чего-нибудь стоит? Я думал, что, поскольку TWebBrowser оборачивается вокруг IE, просто использование TWebBrowser будет в порядке. Легко ли использовать встроенный веб-браузер?
 Peter James15 нояб. 2012 г., 00:23
@ Glenn1234, да, этона основе этого вопроса. Я нашел, что легко нажимать кнопки на любой веб-странице, но не всегда легко найти URL-адрес загружаемого файла (некоторые люди, вероятно, предпочитают не показывать его по соображениям безопасности). Итак, мой вопрос - раз и навсегда, решение этой проблемы.
 Stan14 нояб. 2012 г., 12:43
Если ты'ососкоблучше взглянуть на другие инструменты, чем на Delphi и COM-объекты. Например, рассмотрите возможность использования безголового браузера, такого какPhantomJS.

Ответы на вопрос(2)

Я неНе знаю, приведет ли это вас туда, куда вам нужно, но это выглядит многообещающе. С TWebBrowser у меня здесь (экспортируется из "Microsoft Internet Controls версия 1.1 "), вы можете использовать событие OnBeforeNavigate2 для отслеживания всех URL-адресов, обрабатываемых веб-браузером. Проблема, с которой вы столкнетесь, заключается в том, чтобы определить, что вам нужно сделать, захватить URL-адрес, а затем обработать его самостоятельно. Вот'Короткий пример из пяти минут, которые я играл с управлением напервый веб-сайт ты представил.

procedure TForm1.WebBrowser1BeforeNavigate2(Sender: TObject;
     pDisp: IDispatch; var URL, Flags, TargetFrameName, PostData,
     Headers: OleVariant; var Cancel: WordBool);
  begin
    Edit1.Text := String(URL);
    if Pos('CSV', Edit1.Text) > 0 then
      Cancel := true;
  end;

Как видите, таммного парм, а тыдолжен былнайти документацию чтобы увидеть, что это значит. Но в моем коротком примере то, что я делаю, это помещает перемещаемые URL-адреса в Edit1.Text (вероятно, лучше TMemo, если вы действительно хотите посмотреть, что происходит). Учитывая ваш пример, тамна самом деле ничего не указывает на этоЭто файл, загруженный напрямую, но используя приведенный выше код, я могу отменить браузер »s вещь (показать подсказки загрузки и т. д.), а затем URL-адрес в поле Edit1, чтобы действовать. Если копать дальше, яЯ уверен, что вы можете посмотреть на рассматриваемые заголовки и определить, намеревается ли веб-сайт отправить вам файл, который вы должны загружать, поскольку сам по себе URL не 'сказать "CSV файл " (вводhttp://financials.morningstar.com/ajax/ReportProcess4CSV.html?t=AAPL&область = США &культура = us_EN &= является Тип уведомления &Период = 12 &Datatype = А &порядок = возрастанию &columnYear = 5 &округление = 3 &вид = сырые &ProductCode = USA &г = 809199 &denominatorView = сырец &число = 3 в веб-браузер загрузит CSV-файл, о котором идет речь).

Надеюсь, этохорошее начало для вас.

 Peter James15 нояб. 2012 г., 00:29
Привет Глен, спасибо за ссылку на файл, я также нашел в папке временных файлов IE. И я'Я начну экспериментировать с WebBrowser1BeforeNavigate2. Еще раз спасибо.
 Peter James15 нояб. 2012 г., 03:44
Привет еще раз, по какой-то причине WebBrowser1BeforeNavigate2 неT вызывается автоматически. Я помещаю процедуру WebBrowser1BeforeNavigate2 (и т. Д.) В 'тип' раздел в верхней части блока, и поместите его после реализации, но это 'не работает. Есть идеи. Кроме того, TLama опубликовал решение, но прежде чем пройти через него, яЯ хотел бы заставить WebBrowser1BeforeNavigate2 работать. Спасибо за ваше время.
Решение Вопроса

РеализоватьIDownloadManager интерфейс с егоDownload метод контроля вашего веб-браузера, и вы можете просто контролировать то, что вам нужно.Download метод вызывается всякий раз, когда выВы собираетесь загрузить файл (только когда появится диалоговое окно «Сохранить как»).

1. Встроенный веб-браузер

Вы можете использоватьEmbedded Web Browser контроль, который имеет этот интерфейс уже реализован и который запускаетOnFileDownload это отличается от одноименного события вTWebBrowser, Смотри напримерthis thread о том, как его использовать.

2. Сделай сам

Другой вариант заключается в том, что вы можете реализовать его вTWebBrowser самостоятельно. В следующем примере ямы использовали вставленный класс только для того, чтобы показать принцип, но этоочень легко обернуть его как компонент (этопочему ямы сделалиOnBeforeFileDownload опубликовано).

2.1. Событие OnBeforeFileDownload

Единственное продолжениеTWebBrowser в этом вставленном классеOnBeforeFileDownload событие, которое запускается, когда файл будет загружен (перед сохранением как всплывающее диалоговое окно, но вместоOnFileDownload событие, а не когда сам документ загружен). Если ты выигралЕсли для него не написать обработчик событий, элемент управления веб-браузера будет работать так же, как и раньше (отображается диалоговое окно «Сохранить как»). Если вы напишите обработчик события и вернете False к егоAllowed объявленный параметр, сохранение файла будет отменено. Если вы вернете True кAllowed Параметр (что по умолчанию), появится диалог сохранения как. Обратите внимание, что если вы отмените загрузку, установивAllowed ложно, тыМне нужно будет загрузить файл самостоятельно (как я делал синхронно, используя Indy в этом примере). Для этого естьсFileSource постоянный параметр, который содержит URL загруженного файла. Вот обзор параметров события:

Отправитель (TObject) - отправитель событияFileSource (WideString) - URL исходного файлаAllowed (Boolean) - объявленный логический параметр, который решает, будет ли загрузка файла разрешена или нет (по умолчанию установлено значение True)

2.2. Реализация IDownloadManager

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  StdCtrls, OleServer, OleCtrls, Dialogs, ActiveX, MSHTML, UrlMon, SHDocVw,
  IdHTTP;

const
  IID_IDownloadManager: TGUID = '{988934A4-064B-11D3-BB80-00104B35E7F9}';
  SID_SDownloadManager: TGUID = '{988934A4-064B-11D3-BB80-00104B35E7F9}';

type
  IDownloadManager = interface(IUnknown)
    ['{988934A4-064B-11D3-BB80-00104B35E7F9}']
    function Download(pmk: IMoniker; pbc: IBindCtx; dwBindVerb: DWORD;
      grfBINDF: DWORD; pBindInfo: PBindInfo; pszHeaders: PWideChar;
      pszRedir: PWideChar; uiCP: UINT): HRESULT; stdcall;
  end;
  TBeforeFileDownloadEvent = procedure(Sender: TObject; const FileSource: WideString;
    var Allowed: Boolean) of object;
  TWebBrowser = class(SHDocVw.TWebBrowser, IServiceProvider, IDownloadManager)
  private
    FFileSource: WideString;
    FOnBeforeFileDownload: TBeforeFileDownloadEvent;
    function QueryService(const rsid, iid: TGUID; out Obj): HRESULT; stdcall;
    function Download(pmk: IMoniker; pbc: IBindCtx; dwBindVerb: DWORD;
      grfBINDF: DWORD; pBindInfo: PBindInfo; pszHeaders: PWideChar;
      pszRedir: PWideChar; uiCP: UINT): HRESULT; stdcall;
  protected
    procedure InvokeEvent(ADispID: TDispID; var AParams: TDispParams); override;
  published
    property OnBeforeFileDownload: TBeforeFileDownloadEvent read FOnBeforeFileDownload write FOnBeforeFileDownload;
  end;

type
  TForm1 = class(TForm)
    Button1: TButton;
    WebBrowser1: TWebBrowser;
    FileSourceLabel: TLabel;
    FileSourceEdit: TEdit;
    ShowDialogCheckBox: TCheckBox;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    procedure BeforeFileDownload(Sender: TObject; const FileSource: WideString;
      var Allowed: Boolean);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TWebBrowser }

function TWebBrowser.Download(pmk: IMoniker; pbc: IBindCtx; dwBindVerb,
  grfBINDF: DWORD; pBindInfo: PBindInfo; pszHeaders, pszRedir: PWideChar;
  uiCP: UINT): HRESULT;
var
  Allowed: Boolean;
begin
  Result := E_NOTIMPL;
  if Assigned(FOnBeforeFileDownload) then
  begin
    Allowed := True;
    if pszRedir  '' then
      FFileSource := pszRedir;
    FOnBeforeFileDownload(Self, FFileSource, Allowed);
    if not Allowed then
      Result := S_OK;
  end;
end;

procedure TWebBrowser.InvokeEvent(ADispID: TDispID; var AParams: TDispParams);
begin
  inherited;
  // DispID 250 is the BeforeNavigate2 dispinterface and to the FFileSource here
  // is stored the URL parameter (for cases, when the IDownloadManager::Download
  // won't redirect the URL and pass empty string to the pszRedir)
  if ADispID = 250 then
    FFileSource := OleVariant(AParams.rgvarg^[5]);
end;

function TWebBrowser.QueryService(const rsid, iid: TGUID; out Obj): HRESULT;
begin
  Result := E_NOINTERFACE;
  Pointer(Obj) := nil;
  if Assigned(FOnBeforeFileDownload) and IsEqualCLSID(rsid, SID_SDownloadManager) and
    IsEqualIID(iid, IID_IDownloadManager) then
  begin
    if Succeeded(QueryInterface(IID_IDownloadManager, Obj)) and
      Assigned(Pointer(Obj))
    then
      Result := S_OK;
  end;
end;

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var
  HTMLWindow: IHTMLWindow2;
  HTMLDocument: IHTMLDocument2;
begin
  WebBrowser1.Navigate('http://financials.morningstar.com/income-statement/is.html?t=AAPL&ops=clear');
  while WebBrowser1.ReadyState  READYSTATE_COMPLETE do
    Application.ProcessMessages;

  HTMLDocument := WebBrowser1.Document as IHTMLDocument2;
  if not Assigned(HTMLDocument) then
    Exit;
  HTMLWindow := HTMLDocument.parentWindow;
  if Assigned(HTMLWindow) then
  try
    HTMLWindow.execScript('SRT_stocFund.Export()', 'JavaScript');
  except
    on E: Exception do
      ShowMessage(E.Message);
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ReportMemoryLeaksOnShutdown := True;
  WebBrowser1.OnBeforeFileDownload := BeforeFileDownload;
end;

procedure TForm1.BeforeFileDownload(Sender: TObject; const FileSource: WideString;
  var Allowed: Boolean);
var
  IdHTTP: TIdHTTP;
  FileTarget: string;
  FileStream: TMemoryStream;
begin
  FileSourceEdit.Text := FileSource;
  Allowed := ShowDialogCheckBox.Checked;
  if not Allowed then
  try
    IdHTTP := TIdHTTP.Create(nil);
    try
      FileStream := TMemoryStream.Create;
      try
        IdHTTP.HandleRedirects := True;
        IdHTTP.Get(FileSource, FileStream);
        FileTarget := IdHTTP.URL.Document;
        if FileTarget = '' then
          FileTarget := 'File';
        FileTarget := ExtractFilePath(ParamStr(0)) + FileTarget;
        FileStream.SaveToFile(FileTarget);
      finally
        FileStream.Free;
      end;
    finally
      IdHTTP.Free;
    end;
    ShowMessage('Downloading finished! File has been saved as:' + sLineBreak +
      FileTarget);
  except
    on E: Exception do
      ShowMessage(E.Message);
  end;
end;

end.

2,3. Проект IDownloadManager

Вы можете скачать приведенный выше код (написанный на Delphi 2009) как законченный проект.from here

 TLama15 нояб. 2012 г., 04:18
Рад, что это помогло! Я знаю об этой слабости, но я не могне могу понять, как получить расширение файлаIDownloadManager::Download метод для данного URL (даже встроенный веб-браузер 's менеджер загрузок демо так воспринимает). Исходное диалоговое окно «Сохранить как» знает об этом, поэтому я думаю, чтоИзвестно, что в то время.
 Peter James15 нояб. 2012 г., 05:04
@ TLama It 'Это легко исправить после загрузки, может быть, я не долженЯ упоминал об этом.
 Peter James15 нояб. 2012 г., 14:49
@ TLama Я вроде получил его на работу. Он загружает файл, но без расширений. Он загружает файл и вызывает егоФайл' и ничего больше. Я'Загрузите второй патч D6 и попробуйте снова. Но это'все еще удивительно.
 Peter James15 нояб. 2012 г., 05:51
@TLama У меня есть 3 проблемы: когда я компилирую EmbeddedWB, '{$ VARPROPSETTER ON} ' а также 'MSHTML_EWB» ошибки. И в ДельфахReportMemoryLeaksOnShutdown» и URL в 'FileTarget: = IdHTTP.URL.Document; ' ошибки. Я'Я использую Delphi 6, так что, возможно, проблема в D6.
 Wouter van Nifterick15 нояб. 2012 г., 01:16
Если бы я мог дать дополнительные баллы за отличный ответ, я быЯ дал бы им за это.
 Peter James15 нояб. 2012 г., 04:11
Вау, это работает. Genius. Я'Я все еще пытаюсь заставить WebBrowser1BeforeNavigate2 работать на меня. Но после этого язагрузить и установитьВстроенный веб-браузер, Не придирчиво, но файл сохраняется как файл .html, но после изменения .html на .csv он прекрасно открывается в Excel. Далее я должен попытаться понять все это. Я могу только сказать Гений тебе чувак.
 TLama15 нояб. 2012 г., 06:09
Есть ошибки точно не говорит мне о том, какие у вас проблемы, но хорошо,IdHTTP.URL.Document отсутствует в Indy 9. ЭтоIdHTTP.URL.Document только для того, чтобы получить имя файла документа, что теперь все равно не так (япостараюсь выяснить, есть лиспособ получить имя файла вIDownloadManager::Download уровень).ReportMemoryLeaksOnShutdown это FastMM материал; еще не в Delphi 6. Просто удалите эту строку. И наконецEmbeddedWB ошибка компиляциикомментарий в исходном кодеВам нужно скачать и установить второй патч D6 для того, чтобы это скомпилировать ..

Ваш ответ на вопрос