AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi PreviewHandler PDF Problem Windows 8 und höher

PreviewHandler PDF Problem Windows 8 und höher

Offene Frage von "himitsu"
Ein Thema von Aviator · begonnen am 13. Okt 2015 · letzter Beitrag vom 10. Aug 2016
Antwort Antwort
Seite 1 von 2  1 2   
Aviator

Registriert seit: 3. Jun 2010
1.610 Beiträge
 
Delphi 10.3 Rio
 
#1

PreviewHandler PDF Problem Windows 8 und höher

  Alt 13. Okt 2015, 22:04
Hallo DPler,
aktuell arbeite ich wieder an meiner Dokumentenverwaltung weiter. Vor längerer Zeit ist mir bereits aufgefallen, dass ich Probleme beim Anzeigen der Vorschau für PDF Dateien habe. Bis Windows 7 funktioniert die Vorschau und es wird auch alles angezeigt wie es im Explorer oder in Outlook auch gemacht wird. Ab Windows 8, Windows 8.1, Server 2012 (R2) und Windows 10 habe ich das Problem, dass die Vorschau für PDF Dateien nicht mehr angezeigt wird. Als PDF Programm (und auch als Preview Handler) ist der Adobe Reader hinterlegt. Andere PDF-Programme komme leider nicht in Frage. Getestet hatte ich es dennoch mit einem dessen Name ich jetzt leider nicht mehr weiß (ist schon zu lange her). Jedoch auch hier der gleiche Fehler. Die Vorschau von Excel, Word, PowerPoint und was weiß ich noch alles funktioniert einwandfrei. Alles wird direkt geladen und angezeigt.

Beim Vorschau der PDF-Datei sieht man im TaskManager, dass der AdobeReader kurzzeitig gestartet wird, sich aber 2 Sekunden später wieder beendet. Lasse ich mir die PDF-Datei als Vorschau im Windows Explorer anzeigen, bleibt der Prozess gestartet und die Datei wird angezeigt. Es scheint also etwas mit der Art der Programmierung zu tun zu haben. Den SourceCode habe ich von TheRoadToDelphi. Nach diesem Thread, den ich vor ca. 1,75 Jahren geöffnet hatte, hatte ich den Code minimal abgeändert. Hier ist meine angepasste Version, welche auch bis Windows 7 fehlerfrei funktioniert hatte:

Delphi-Quellcode:
unit PreviewHandlerUnt;

interface

uses
  ShlObj, Classes, Messages, Controls, System.Variants, Vcl.Dialogs;

type
  THostPreviewHandler = class(TCustomControl)
  private
    FFileStream: TFileStream;
    FPreviewGUIDStr: string;
    FFileName: string;
    FLoaded: Boolean;
    FPreviewHandler: IPreviewHandler;
    procedure SetFileName(const Value: string);
    procedure LoadPreviewHandler;
    procedure WMSize(var Message: TWMSize); message WM_SIZE;
  protected
    procedure Paint; override;
  public
    property FileName: string read FFileName write SetFileName;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

implementation

uses
  SysUtils, Windows, Graphics, ComObj, ActiveX, Registry, PropSys;

constructor THostPreviewHandler.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FPreviewHandler := nil;
  FPreviewGUIDStr := EmptyStr;
  FFileStream := nil;
end;

procedure THostPreviewHandler.Paint;
const
  Msg = 'Keine Vorschau verfügbar.';
var
  lpRect: TRect;
begin
  if (FPreviewGUIDStr <> EmptyStr) and Assigned(FPreviewHandler) and not FLoaded then
  begin
    FLoaded := True;
    FPreviewHandler.DoPreview;
    FPreviewHandler.SetFocus;
  end else if FPreviewGUIDStr = 'then begin
    lpRect := Rect(0, 0, Self.Width, Self.Height);
    Canvas.Brush.Style := bsClear;
    Canvas.Font.Color := clWindowText;
    DrawText(Canvas.Handle, PChar(Msg), Length(Msg), lpRect, DT_VCENTER or DT_CENTER or DT_SINGLELINE);
  end;
end;

destructor THostPreviewHandler.Destroy;
begin
  if Assigned(FPreviewHandler) then
    FPreviewHandler.Unload;

  inherited;
end;

function GetPreviewHandlerCLSID(const AFileName: string): string;
var
  LRegistry: TRegistry;
  LKey: String;
begin
  LRegistry := TRegistry.Create();
  Result := EmptyStr;
  try
    LRegistry.RootKey := HKEY_CLASSES_ROOT;
    LKey := ExtractFileExt(AFileName) + '\shellex\{8895b1c6-b41f-4c1c-a562-0d564250836f}';
    if LRegistry.OpenKeyReadOnly(LKey) then begin
      Result := LRegistry.ReadString('');
      LRegistry.CloseKey;
    end else begin
      LKey := 'SystemFileAssociations\' + ExtractFileExt(AFileName) + '\shellex\{8895b1c6-b41f-4c1c-a562-0d564250836f}';
      if LRegistry.OpenKeyReadOnly(LKey) then begin
        Result := LRegistry.ReadString('');
        LRegistry.CloseKey;
      end else begin
        LRegistry.RootKey := HKEY_LOCAL_MACHINE;
        LKey := '\Software\Classes\' + ExtractFileExt(AFileName) + '\shellex\{8895b1c6-b41f-4c1c-a562-0d564250836f}';
        if LRegistry.OpenKeyReadOnly(LKey) then begin
          Result := LRegistry.ReadString('');
          LRegistry.CloseKey;
        end else begin
          LKey := '\Software\Classes\SystemFileAssociations\' + ExtractFileExt(AFileName) +
            '\shellex\{8895b1c6-b41f-4c1c-a562-0d564250836f}';
          if LRegistry.OpenKeyReadOnly(LKey) then begin
            Result := LRegistry.ReadString('');
            LRegistry.CloseKey;
          end;
        end;
      end;
    end;
  finally
    LRegistry.Free;
  end;
end;

procedure THostPreviewHandler.LoadPreviewHandler;
const
  GUID_ISHELLITEM = '{43826d1e-e718-42ee-bc55-a1e261c37bfe}';
var
  prc: TRect;
  LPreviewGUID: TGUID;
  LInitializeWithFile: IInitializeWithFile;
  LInitializeWithStream: IInitializeWithStream;
  LInitializeWithItem: IInitializeWithItem;
  LIStream: IStream;
  LShellItem: IShellItem;
// PreviewHandle: HWND;
begin
// PreviewHandle := 0;
  FLoaded := False;
  FPreviewGUIDStr := GetPreviewHandlerCLSID(FFileName);
  if FPreviewGUIDStr = 'then
    Exit;

  LPreviewGUID := StringToGUID(FPreviewGUIDStr);

  FPreviewHandler := CreateComObject(LPreviewGUID) As IPreviewHandler;
  if (FPreviewHandler = nil) then
    Exit;

  if FPreviewHandler.QueryInterface(IInitializeWithFile, LInitializeWithFile) = S_OK then
    LInitializeWithFile.Initialize(StringToOleStr(FFileName), STGM_READ)
  else if FPreviewHandler.QueryInterface(IInitializeWithStream, LInitializeWithStream) = S_OK then begin
    FFileStream := TFileStream.Create(FFileName, fmOpenRead or fmShareDenyNone);
    LIStream := TStreamAdapter.Create(FFileStream, soOwned) as IStream;
    LInitializeWithStream.Initialize(LIStream, STGM_READ);
  end else if FPreviewHandler.QueryInterface(IInitializeWithItem, LInitializeWithItem) = S_OK then begin
    SHCreateItemFromParsingName(PChar(FileName), nil, StringToGUID(GUID_ISHELLITEM), LShellItem);
    LInitializeWithItem.Initialize(LShellItem, 0);
  end else begin
    FPreviewHandler.Unload;
    FPreviewHandler := nil;
    exit;
  end;

  prc := ClientRect;
  FPreviewHandler.SetWindow(Self.Handle, prc);
// FPreviewHandler.QueryFocus(PreviewHandle);
end;

procedure THostPreviewHandler.SetFileName(const Value: string);
begin
  FFileName := Value;

// if not HandleAllocated then // Handle zum Anzeigen der Vorschau anfordern
    HandleNeeded;

  LoadPreviewHandler;
end;

procedure THostPreviewHandler.WMSize(var Message: TWMSize);
var
  prc: TRect;
begin
  inherited;
  if FPreviewHandler <> nil then begin
    prc := ClientRect;
    FPreviewHandler.SetRect(prc);
  end;
end;

end.
Es wäre super, wenn sich vielleicht jemand die Mühe machen und mir sagen könnte, was genau an diesem Code falsch ist und warum es nicht mehr funktioniert. Oder gab es seit Windows 8 größere Änderungen was die Vorschau angeht? Ich habe mir auch den neuesten Code von GitHub gezogen, den RRUZ (der Ersteller dieser Unit) dort zur Verfügung gestellt hat. Angeblich soll es damit möglich sein, PDF Dateien (auch auf Windows 10) anzuzeigen. Ein Test auf einem Windows 8.1 System hat bei mir leider nicht funktioniert.

Bin für jede Hilfe dankbar. Wenn ihr noch weitere Informationen benötigt, dann einfach fragen. Hauptsache ich bekomme das Problem irgendwie gelöst.
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
3.896 Beiträge
 
Delphi 12 Athens
 
#2

AW: PreviewHandler PDF Problem Windows 8 und höher

  Alt 14. Okt 2015, 07:09
Hallo Aviator,

du hast gesehen das hier eine neue Version von vor 9 Tagen steht.
Vielleicht hilft dir das weiter ?

Rollo
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.610 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: PreviewHandler PDF Problem Windows 8 und höher

  Alt 14. Okt 2015, 07:17
Hallo Rollo. Ja die habe ich gesehen. Hatte das auch gestern Abend bevor ich diesen Trend hier eröffnet habe noch einmal extra probiert. Funktioniert aber leider trotzdem nicht. Bei dem Beispiel bekomme ich sogar beim Beenden des Programms eine Zugriffsverletzung in der "previewhndlr.dll" von Adobe.
Ich wäre ja froh wenn ich irgendetwas falsch mache damit das Problem schnell behoben ist. Nur wenn sogar das Beispielprogramm nicht funktioniert dann weiß ich auch nicht weiter.

Trotzdem danke für den Hinweis. Hast du vvielleicht noch eine Idee oder eine funktionierende Lösung? Alle anderen Hinweise sind natürlich auch willkommen.
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.169 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: PreviewHandler PDF Problem Windows 8 und höher

  Alt 14. Okt 2015, 07:54
Kann es sein das es mit 64-Bit zu tun hat?
Also unter Win7 und älter hattest du 32-Bit Windows, jetzt ein 64-Bit Windows.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

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

AW: PreviewHandler PDF Problem Windows 8 und höher

  Alt 14. Okt 2015, 14:04
Genau in die Richtung denke ich auch, wenn ich irgendwas mit Registry sehe und darin kein Hinweis auf die entsprechenden Flags auftaucht. Dazu kommt noch, dass der Server ab 2008 R2 AFAIK immer 64 Bit ist. Das könnte also sehr gut sein.

Übrigens sind in dem Code ein paar Speicherlecks drin, denn da wird z.B. im Destruktor das Objekt FFileStream nicht wieder weggeräumt. Und noch eine andere Sache ist mir aufgefallen: Warum wird in GetPreviewHandlerCLSID() immer wieder die CLSID geschrieben statt die als Konstante zu deklarieren und diese zu benutzen? Sowas ist anfällig für Tippfehler etc, verstößt gegen DRY usw.

Zum Debuggen würde ich wahrscheinlich ein paar OutputDebugString() an den richtigen Stellen reinpacken, wenn das im normalen Debugger nicht möglich oder sinnvoll zu machen ist.

MfG Dalai
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.610 Beiträge
 
Delphi 10.3 Rio
 
#6

AW: PreviewHandler PDF Problem Windows 8 und höher

  Alt 14. Okt 2015, 14:26
Kann es sein das es mit 64-Bit zu tun hat?
Also unter Win7 und älter hattest du 32-Bit Windows, jetzt ein 64-Bit Windows.
Nein leider auch nicht. War vorher auch immer schon 64-bit und es hatte alles funktioniert.
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.680 Beiträge
 
Delphi 5 Professional
 
#7

AW: PreviewHandler PDF Problem Windows 8 und höher

  Alt 14. Okt 2015, 18:19
War vorher auch immer schon 64-bit und es hatte alles funktioniert.
Das sagt leider überhaupt nichts aus. Hast du denn mal geschaut, was in den jeweiligen Registry-Zweigen zu finden ist, sowohl 32 als auch 64 Bit? Vielleicht ist auf dem einen System der Handler nur für 64 Bit registriert, auf dem anderen aber für beide.

MfG Dalai
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.610 Beiträge
 
Delphi 10.3 Rio
 
#8

AW: PreviewHandler PDF Problem Windows 8 und höher

  Alt 14. Okt 2015, 21:04
Hallo Dalai,
habe jetzt einmal alle mir bekannten Registry Zweige durchsucht und ein Windows 8 bei dem es nicht funktioniert mit einem Windows 7 System bei dem die Vorschau startet verglichen. Mir sind keine Unterschiede aufgefallen. Beide Systeme sind 64-bit. Es ist sogar eher so herum, dass die PreviewHandler alle in den Wow6432Node auffindbar sind, als direkt im CLSID Zweig. Mein Programm ist nicht speziell für 64-bit kompiliert, sondern läuft als 32-bit Anwendung. Wäre es möglich, dass Windows 8 hier anders reagiert als Windows 7?

Die Hinweise auf die mehrfache Einträge von CLSID werde ich in meiner Kopie des Codes verbessern und daraus eine Konstante machen. Von der Freigabe des FileStreams wurde mir damals von Jeanicke bereits abgeraten, da der TStreamAdapter mit soOwned erzeugt wird. Also hatte ich das entfernt. Siehe hierzu den Beitrag im anderen Thread. Bisher hatte ich auch trotz ReportMemoryLeaksOnShutdown := True; keine Fehler mehr beim Beenden des Programms erhalten.

Ich möchte an dieser Stelle schon einmal ein Dankeschön für die vielen Beiträge einwerfen. Das Problem ist aber leider immer noch nicht gelöst.
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

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

AW: PreviewHandler PDF Problem Windows 8 und höher

  Alt 14. Okt 2015, 21:43
Es ist sogar eher so herum, dass die PreviewHandler alle in den Wow6432Node auffindbar sind, als direkt im CLSID Zweig.
Du meinst HKEY_CLASSES_ROOT-Zweig? Vorsicht, der ist - jedenfalls bestimmte Unterzweige davon - ebenfalls der Redirection unterworfen! HKEY_CLASSES_ROOT ist die Summe aus HKEY_LOCAL_MACHINE\Software\Classes und HKEY_CURRENT_USER\Software\Classes - und ersterer wird umgeleitet (auf einem x64 System).

Zitat:
Wäre es möglich, dass Windows 8 hier anders reagiert als Windows 7?
Denkbar. Aber das wirst du debuggen müssen; wenn es nicht anders geht, dann eben mit OutputDebugString, wie ich bereits ansprach.

Zitat:
Von der Freigabe des FileStreams wurde mir damals von Jeanicke bereits abgeraten, da der TStreamAdapter mit soOwned erzeugt wird. Also hatte ich das entfernt. Siehe hierzu den Beitrag im anderen Thread.
Ah, OK.

Zitat:
Bisher hatte ich auch trotz ReportMemoryLeaksOnShutdown := True; keine Fehler mehr beim Beenden des Programms erhalten.
Nun, dessen Nutzen ist auch (stark) begrenzt, wie ich selbst erfahren habe. IIRC werden alle Sachen, die Nicht-Delphi-Objekte sind, nicht gemeldet, also direkte WinAPI-Aufrufe usw.

MfG Dalai
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.610 Beiträge
 
Delphi 10.3 Rio
 
#10

AW: PreviewHandler PDF Problem Windows 8 und höher

  Alt 14. Okt 2015, 22:29
Hallo zusammen,
ich habe gerade noch einmal das Testprogramm von GitHub kompiliert und dieses mal die Zielplattform auf 64-bit umgestellt. Und siehe da es funktioniert tatsächlich unter Windows 8. Also scheint es wirklich eine 64-bit Inkompatibilität in Sachen PDF-Preview mit einem 32-bit Programm zu geben. Der Tipp mit der Registry und dem nicht registrierten Handler für 32-bit scheint dann auch in die richtige Richtung zu gehen. Jetzt ist nur die Frage, ob ich mein Programm so einfach auf 64-bit portiert bekomme, da ich keine Ahnung habe, was man hierfür alles beachten muss. Bisher liefen alle meine Programme als 32-bit Programm ohne Probleme. Und ein weiterer Punkt ist, dass die Anwendung in einer Netzwerkumgebung gestartet und nicht installiert wird. Somit starten alle Benutzer die 32-bit Version. Ich kann aber auch nicht einfach eine 64-bit Version kompilieren und diese reinstellen. Oder kann man unter 32-bit auch eine 64-bit Software einfach so laufen lassen? Ich glaube es ja nicht.

Der einfachere Weg wäre der, dass ich es irgendwie schaffe, den PreviewHandler auf einem Windows 8 System für 32-bit nachzuregistrieren. Ist das irgendwie möglich? Damit wäre mir sehr geholfen.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 06:56 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