AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke MsHtml in 64-Bit-Anwendung erzeugt Float Invalid Operation
Thema durchsuchen
Ansicht
Themen-Optionen

MsHtml in 64-Bit-Anwendung erzeugt Float Invalid Operation

Ein Thema von Perlsau · begonnen am 5. Mai 2015 · letzter Beitrag vom 5. Mai 2015
Antwort Antwort
Perlsau
(Gast)

n/a Beiträge
 
#1

MsHtml in 64-Bit-Anwendung erzeugt Float Invalid Operation

  Alt 5. Mai 2015, 17:23
IDE: Delphi XE7
OS: Windows 7 Ultimate 64-bit

Zum Extrahieren des reinen Textes aus einer HTML-Datei verwende ich MsHtml:
Delphi-Quellcode:
// ----- Extrahiert den Text der übergebenen HTML-Datei --------------------------------------------------------------------------
// ..... http://www.swissdelphicenter.ch/de/showcode.php?id=2352
Function GetHtmlBodyText(Const HtmlText : String) : String;
Var
  IDoc : IHTMLDocument2;
  v : Variant;

Begin
  Idoc := System.Win.ComObj.CreateComObject(Class_HTMLDOcument) as IHTMLDocument2;
  Try
    IDoc.designMode := 'on';
    While IDoc.readyState <> 'completeDo
      Application.ProcessMessages;
    v := VarArrayCreate([0, 0], VarVariant);
    v[0] := HtmlText;
    IDoc.Write(PSafeArray(System.TVarData(v).VArray));
    IDoc.designMode := 'off';
    While IDoc.readyState <> 'completeDo
      Application.ProcessMessages;
    Result := IDoc.Body.InnerText;
  Finally
    IDoc := Nil;
  End;
End;
Das funktioniert wunderbar, solange es sich um eine 32-Bit-Anwendung handelt. Lasse ich das Projekt jedoch als 64-Bit-Anwendung in der IDE (Debug-Modus) ausführen, erscheint diese Fehlermeldung und das Programm beendet sich sofort, nachdem ich auf Fortsetzen gedrückt habe:

... eine Exception der Klasse $C0000090 mit der Meldung 'c0000090 FLOAT_INVALID_OPERATION' aufgetreten.

Ohne IDE gestartet beendet sich das Programm kommentarlos.

Nun ist ja der Internet-Explorer in Win 7-64 eine 32-Bit-Anwendung, somit auch die DLL, auf die MsHtml zurückgreift. Okay, das hatten wir ja schon, daß man für das Einbinden einer DLL in eine 64-Bit-Anwendung eben auch die 64-Bit-DLL benötigt. Kein Problem, dachte ich mir, holst du dir eben den IE-64 für Win7-64. So einfach macht es mir Microsoft aber nicht, denn die Installation des IE-11-64bit bricht mit dem Hinweis auf notwendige Updates ab. Man landet dann auf dieser Seite. Gut, dann lade ich mir jetzt eben diese Updates runter und installiere sie.

Ich starte mit Windows6.1-KB2729094-v2-x64.msu
Ein Update ist für die Segoe UI-Symbol-Schriftart in Windows 7 und Windows Server 2008 R2 verfügbar. Dieses Update bietet Unterstützung für Emoji-Zeichen und einige Serversteuerelement-Glyphen, die in Windows 8 und Windows Server 2012 enthalten sind. Nach der Installation dieser Komponente müssen Sie den Computer neu starten.

Daraufhin erhalte ich folgende Fehlermeldung:

Eigenständiges Windows Update-Installationsprogramm
Das Installationsprogramm hat einen Fehler festgestellt: 0x80070422
Der angegebene Dienst kann nicht gestartet werden. Er ist deaktiviert oder nicht mit aktivierten Geräten verbunden.


Was ist das für ein Dienst? Der Windows-Installer-Service läuft (gestartet). Ich komme da erstmal nicht weiter ...

Alternativen wären:
  1. auf MsHtml zu verzichten und einen Html-Parser zu verwenden. Doch die guten kosten was, die kostenlosen taugen nichts (zumindest soweit mir bekannt). Das Projekt ist nicht kommerziell, sondern ein rein privater "Spaß", der eigentlich außer Zeit und Mühe nichts kosten sollte ...
  2. nur das 32-Bit-Kompilat zu verwenden (werde ich wohl machen müssen)
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.682 Beiträge
 
Delphi 5 Professional
 
#2

AW: MsHtml in 64-Bit-Anwendung erzeugt Float Invalid Operation

  Alt 5. Mai 2015, 17:52
Nun ist ja der Internet-Explorer in Win 7-64 eine 32-Bit-Anwendung, somit auch die DLL, auf die MsHtml zurückgreift.
Irrtum. Auf jedem Windows x64 gibt es den IE in beiden Ausführungen, 32 und 64 Bit, inkl. der mshtml.dll.

MfG Dalai
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.492 Beiträge
 
Delphi 7 Enterprise
 
#3

AW: MsHtml in 64-Bit-Anwendung erzeugt Float Invalid Operation

  Alt 5. Mai 2015, 17:55
In welcher Programmzeile wird denn die Exception geworfen?
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.176 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: MsHtml in 64-Bit-Anwendung erzeugt Float Invalid Operation

  Alt 5. Mai 2015, 17:58
Ist das nicht das "übliche" dass die Exception nicht in deinem Programm, sondern im IE Code kommt? Und zwar weil Delphi mit seinem Floating Point-Exception Masking sich nicht "standard-microsoftig" verhält?

Im Internet findet man auf den ersten Blick eine Menge zu TWebBrowser und Fließkomma-Exceptions, alle scheinen darauf hinauszulaufen, die FPU-Exceptions so zu drehen wie der IE-Code es auch erwartet:

z.B. http://stackoverflow.com/q/9359223/2298252
  Mit Zitat antworten Zitat
Perlsau
(Gast)

n/a Beiträge
 
#5

AW: MsHtml in 64-Bit-Anwendung erzeugt Float Invalid Operation

  Alt 5. Mai 2015, 18:43
Nun ist ja der Internet-Explorer in Win 7-64 eine 32-Bit-Anwendung, somit auch die DLL, auf die MsHtml zurückgreift.
Irrtum. Auf jedem Windows x64 gibt es den IE in beiden Ausführungen, 32 und 64 Bit, inkl. der mshtml.dll.
Danke für den Hinweis. Da war ich offensichtlich auf der falschen Fährte
Zwar konnte ich den IE-11-64 nun doch noch installieren (nach Aktivierung diverser Update-Services, die bei mir deaktiviert waren), doch tritt der Fehler weiterhin auf.

In welcher Programmzeile wird denn die Exception geworfen?
Delphi-Quellcode:
    While IDoc.readyState <> 'completeDo
      Application.ProcessMessages;
    Result := IDoc.Body.InnerText;
Entweder beim Abfragen von IDoc.readyState oder beim Zuweisen von IDoc.Body.InnerText . Genauer läßt sich das nicht eingrenzen, da beim Durchsteppen mehrere Male ReadyState abgefragt wird und der Fehler manchmal beim dritten, manchmal erst beim zehnten Durchlauf auftritt. Ich bin mir nicht sicher, ob die Zuweisung von IDoc.Body.InnerText den Fehler auslöst oder die Abfrage von IDoc.readyState .

Ist das nicht das "übliche" dass die Exception nicht in deinem Programm, sondern im IE Code kommt? Und zwar weil Delphi mit seinem Floating Point-Exception Masking sich nicht "standard-microsoftig" verhält? Im Internet findet man auf den ersten Blick eine Menge zu TWebBrowser und Fließkomma-Exceptions, alle scheinen darauf hinauszulaufen, die FPU-Exceptions so zu drehen wie der IE-Code es auch erwartet:
z.B. http://stackoverflow.com/q/9359223/2298252
Okay, da vermeine ich etwas Licht am Ende des Tunnels zu erkennen. Ich hab jetzt erstmal das gemacht, was im Emba-Beispielcode steht:
Delphi-Quellcode:
...
VAR
  FormMain : TFormMain;
  Saved8087CW : Word;

IMPLEMENTATION
...
Procedure TFormMain.FormCreate(Sender: TObject);
begin
  Saved8087CW := Default8087CW;
  {$IFDEF WIN64}
  Self.Caption := GLD.Programmtitel + '64-Bit-Version';
  System.Set8087CW($133f);
  {$ELSE}
  Self.Caption := GLD.Programmtitel + '32-Bit-Version';
  System.Set8087CW(Saved8087CW);
  {$ENDIF}
...

Procedure TFormMain.FormDestroy(Sender: TObject);
begin
  System.Set8087CW(Saved8087CW);
end;
Nach dem Neu-Erzeugen tritt der Fehler jedoch leider immer noch auf. Doch wir sind ja noch nicht am Ende der Fahnenstange, denn David Heffeman bietet bei StackOverFlow eine Alternative an:
Alternatively, you can call SetSSEExceptionMask and SetFPUExceptionMask passing exAllArithmeticExceptions to mask all exceptions. These convenience methods would make your code more readable. If you are satisfied that you only need to mask exceptions on 8087 under x86 and SSE under x64 then you can just call SetExceptionMask. This will change the 8087 control state under x86 and change the SSE control state under x64.

Allerdings muß ich gestehen, daß ich diese Alternative nicht wirklich verstehe. Wo und wie muß ich diese drei Methoden aufrufen?
  Mit Zitat antworten Zitat
hathor
(Gast)

n/a Beiträge
 
#6

AW: MsHtml in 64-Bit-Anwendung erzeugt Float Invalid Operation

  Alt 5. Mai 2015, 18:54
Man braucht die Unit Math.

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
SetExceptionMask(exAllArithmeticExceptions);
...
end;

Geändert von hathor ( 5. Mai 2015 um 18:57 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#7

AW: MsHtml in 64-Bit-Anwendung erzeugt Float Invalid Operation

  Alt 5. Mai 2015, 19:00
Laufen lassen und warten, wo der Debugger nach dem Knall hält, sagt dir nicht die Zeile?

Notlösung:
Delphi-Quellcode:
try
  while IDoc.readyState <> 'completeDo
    try
      Application.ProcessMessages;
    except
      raise; // hier einen Haltepunkt
    end;
except
  raise; // hier einen Haltepunkt
end;
try
  Result := IDoc.Body.InnerText;
except
  raise; // hier einen Haltepunkt
end;
Und da wo er zuerst hällt, hat es zuvor geknallt.
Vor dem Raise ein asm INT 3 end; geht im Win64 ja leider nicht mehr, um im Debugger einen Zwangsstopp zu veranlassen, falls es nicht von alleine anhält
Eventuell könnte man einen MSDN-Library durchsuchenDebugBreak aufrufen, aber das funktionierte ja auch nicht immer.
$2B or not $2B
  Mit Zitat antworten Zitat
Perlsau
(Gast)

n/a Beiträge
 
#8

AW: MsHtml in 64-Bit-Anwendung erzeugt Float Invalid Operation

  Alt 5. Mai 2015, 19:30
Man braucht die Unit Math.

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
SetExceptionMask(exAllArithmeticExceptions);
...
end;
Hathor, du bist ein Schatz
Das war der entscheidende Hinweis (asexuell natürlich) Damit läuft es nun auch im 64-Bit-Mode
Delphi-Quellcode:
Procedure TFormMain.FormCreate(Sender: TObject);
begin
  {$IFDEF WIN64}
  SetExceptionMask(exAllArithmeticExceptions);
  Self.Caption := GLD.Programmtitel + '64-Bit-Version';
  {$ELSE}
  Self.Caption := GLD.Programmtitel + '32-Bit-Version';
  {$ENDIF}
...
Laufen lassen und warten, wo der Debugger nach dem Knall hält, sagt dir nicht die Zeile?
Du natürlich auch Aber die genaue Zeile läßt sich damit auch nicht herausfinden. Der Cursor steht immer da, wo ich ihn zuletzt hingestellt habe, auch mit deiner "Notlösung". Es gibt da offenbar keinen Rücksprung zum Delphi-Programm ... von wo auch immer ...

Das hat auf die richtige Fährte geführt. Danke Günter, du bist auch ein Schatz
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:57 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz