PDA

Ver la Versión Completa : ActiveX AcroPdf no funciona


radenf
17-05-2014, 14:31:06
Hola amigos:

He desarrollado algunos programas en los que he utilizado el componente ActiveX AcroPdf, para visualizar archivos PDF.
La última actualización de Adobe Reader modifica la AcroPdf.dll a la versión 11.0.7.79, con lo cual el componente deja de funcionar al igual que los programas que lo utilizan, enviando un mensaje de AccessViolation.
Si restauro mi sistema a un punto anterior a esta actualización todo vuelve a la normalidad, pero lamentablemente Adobe Reader se actualiza automáticamente a pesar de que tenga desactivadas las actualizaciones en este programa.
Como he visto que muchas personas han hecho consultas aquí en el foro en relación al uso de este componente, me imagino que también podrían verse afectados sus programas.
En el foro de Adobe ya se han publicado varios casos que apuntan al mismo problema.
¿Alguien dispone de alguna información al respecto?

Saludos

dec
17-05-2014, 16:10:02
Hola,

Lo que yo haría (y quizá no sirva para nada) es:

1º Intentar actualizar el componente en cuestión de manera que use la última versión de la DLL de marras, tal vez "importándola" para crear otro "ActiveX" o algo así...

2º Mostrar al usuario los PDF dentro de un "WebBrowser" preparado para tal efecto. De este modo el "WebBrowser" lidiaría con la última versión instalada en el equipo.

3º No mostrar, pero, "lanzar" los documentos PDF de manera que el usuario los visualize usando el programa que prefiera y tenga instalado: Acrobat Reader u otro.

Nota: el orden los puntos anteriores tal vez no sea el esperado, sino que podríamos empezar por el final y aquí paz y después gloria. ;)

radenf
17-05-2014, 16:54:07
Muchas gracias por responder dec.
Lo que tú señalas ya lo intenté y como bien acotas no sirvió de nada.
Por lo que he leído en los foros de Adobe se trataría de un bug no considerado en la última actualización, que pretende corregir algún problema de seguridad.
Al parecer habrá que esperar que los gurus de Adobe corrijan el problema y ojalá lo tengan presente en futuras actualizaciones.
Saludos

dec
17-05-2014, 19:00:31
Hola,

Hombre, si se puede esperar... ¿pero qué hay de la segunda o tercera soluciones propuestas?

camino
17-05-2014, 20:10:16
Despues de haber dejado el tema ( por cansancio) sin solucion, ayer decidi darle unas vueltas mas y, parece que descubri la solucion:

AcroPDFLib_TLB no basta con colocarlo en el uses de la form que hace el display del PDF.

Se me ocurrio colocarlo en todas las Unit que llama a la form del PDF.

Esto dio el resultado que yo esperaba.

Ojala sirva para los que aun no han encontrado una solucion. Yo se lo que es eso.

nlsgarcia
17-05-2014, 20:17:04
radenf,


...La última actualización de Adobe Reader modifica la AcroPdf.dll a la versión 11.0.7.79, con lo cual el componente deja de funcionar al igual que los programas que lo utilizan...

Momentáneamente mientras Adobe resuelve el problema, puedes hacer un workaroud copiando la versión del DLL que funciona de un directorio de respaldo antes de hacer uso de cualquier función de este, donde y como copiar el DLL depende de como este implementado en tu aplicación.


...No mostrar, pero, "lanzar" los documentos PDF de manera que el usuario los visualice usando el programa que prefiera y tenga instalado: Acrobat Reader u otro...
Esta opción también es válida (Temporalmente si es el caso por medio de un ShellExecute) y funciona independientemente del View PDF instalado.

Espero sea útil :)

Nelson.

radenf
17-05-2014, 22:14:18
Muchas gracias por sus opiniones y aportes.
Creo que esperaré la solución que provea Adobe.
Esto me ha abierto los ojos a la vulnerabilidad de los programas que desarrollamos cuando se utilizan componentes de terceros o cuando a través de componentes nativos, como es el caso, se llama a programas de terceros(Adobe Reader).
Intentaré a futuro encontrar alguna alternativa que no utilice Adobe Reader, aunque sea de pago..
Un abrazo

apicito
19-05-2014, 11:07:08
Mi casuística es la siguiente:
Funciona con windows Vista y 7 con Acrobat XI.
Falla con Windows XP SP2 en todos los casos y la única solución que he encontrado ha sido downgrade a Adobe 10.
Funciona con windows XP SP3 totalmente actualizado y falla (ocasionalmente) cuando falta alguna actualización.
Un saludo.

radenf
19-05-2014, 13:12:41
Estimado apicito:

Gracias por tu respuesta.
El error se produce sólo con la versión 11.0.7.79 de AcroPdf.dll que corresponde a la última actualización de Adobe Reader XI.
Yo utilizo Windows 7 64 bits.
Saludos

nlsgarcia
21-05-2014, 08:47:04
radenf,


...La última actualización de Adobe Reader modifica la AcroPdf.dll a la versión 11.0.7.79, con lo cual el componente deja de funcionar al igual que los programas que lo utilizan...



...No mostrar, pero, "lanzar" los documentos PDF de manera que el usuario los visualice usando el programa que prefiera y tenga instalado: Acrobat Reader u otro...



...Esto me ha abierto los ojos a la vulnerabilidad de los programas que desarrollamos cuando se utilizan componentes de terceros...


Revisa este código:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Menus, ShellAPI, ExtCtrls, TlHelp32;

type
TForm1 = class(TForm)
Panel1: TPanel;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
procedure ExecuteApp(AppName, CmdLine, WindowName : String);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
HWindow : THandle;

implementation

{$R *.dfm}

// Verifica si un Proceso esta Activo
function ProcessExists(ExeFileName: String): Boolean;
var
ContinueLoop: BOOL;
FSnapshotHandle: THandle;
FProcessEntry32: TProcessEntry32;

begin

FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);

while Integer(ContinueLoop) <> 0 do
begin
if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase(ExeFileName))
or (UpperCase(FProcessEntry32.szExeFile) = UpperCase(ExeFileName))) then
begin
Result := True;
Exit;
end;
ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
end;

CloseHandle(FSnapshotHandle);

Result := False;

end;

// Elimina un Proceso Activo
function KillTask(ExeFileName: String): Integer;
const
PROCESS_TERMINATE = $0001;
var
ContinueLoop: BOOL;
FSnapshotHandle: THandle;
FProcessEntry32: TProcessEntry32;

begin

Result := 0;

FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);

while Integer(ContinueLoop) <> 0 do
begin
if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase(ExeFileName))
or (UpperCase(FProcessEntry32.szExeFile) = UpperCase(ExeFileName))) then
Result := Integer(TerminateProcess(OpenProcess(PROCESS_TERMINATE,
BOOL(0),
FProcessEntry32.th32ProcessID),
0));
ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
end;

CloseHandle(FSnapshotHandle);

end;

// Visualiza un Archivo PDF en un TPanel (Ejecución)
procedure TForm1.ExecuteApp(AppName, CmdLine, WindowName : String);
var
HndApp : THandle;
i : Integer;
Command : String;
Parameters : String;

begin

// Cierra cualquier instancia previa de Acrobat Reader que este activa
if ProcessExists('AcroRd32.exe') then
KillTask('AcroRd32.exe');

// Abre una nueva instancia de Acrobat Reader con el Documento Seleccionado
HndApp := ShellExecute(0, nil, PChar(AppName), PChar(CmdLine), nil, SW_SHOWMINIMIZED);

// Busca la ventana de Acrobat Reader con el Documento Seleccionado y la asigna al TPanel
if (HndApp > 32) then
begin

for i := 1 to 10 do
begin
HWindow := FindWindow(nil,PChar(WindowName));
if HWindow > 0 then
Break
else
Sleep(100);
end;

if HWindow > 0 then
begin
Windows.SetParent(HWindow, Panel1.Handle);
Windows.MoveWindow(HWindow, 0, 0, ClientWidth, ClientHeight, True);
Windows.ShowWindow(HWindow,SW_MAXIMIZE);
Windows.SetFocus(HWindow);
end;

end;

end;

// Visualiza un Archivo PDF en un TPanel (LLamada)
procedure TForm1.Button1Click(Sender: TObject);
var
AppName, CmdLine, WindowName : String;
openDialog : TOpenDialog;
Msg : String;

begin

if (HWindow = 0) then
begin

openDialog := TOpenDialog.Create(self);
openDialog.InitialDir := GetCurrentDir;
openDialog.Options := [ofFileMustExist];
openDialog.Filter := 'PDF files|*.pdf';
openDialog.FilterIndex := 1;

if openDialog.Execute then
begin
AppName := 'C:\Program Files\Adobe\Reader 11.0\Reader\AcroRd32.exe';
CmdLine := openDialog.FileName;
WindowName := ExtractFileName(openDialog.FileName) + ' - Adobe Reader';
ExecuteApp(AppName, CmdLine, WindowName);
end
else
begin
Msg := 'No Se Selecciono Ningún Archivo PDF a Visualizar';
MessageDlg(Msg, mtInformation, [mbOK],0);
end;

end;

end;

// Cierra la ventana de un Archivo PDF en un TPanel
procedure TForm1.Button2Click(Sender: TObject);
begin
if HWindow > 0 then
begin
SendMessage(HWindow, WM_CLOSE, 0, 0);
HWindow := 0;
end;
end;

// Maximiza la ventana de un Archivo PDF en un TPanel
procedure TForm1.Button3Click(Sender: TObject);
begin
if HWindow > 0 then
ShowWindow(HWindow, SW_MAXIMIZE);
end;

// Minimiza la ventana de un Archivo PDF en un TPanel
procedure TForm1.Button4Click(Sender: TObject);
begin
if HWindow > 0 then
ShowWindow(HWindow, SW_MINIMIZE);
end;

// Inicializa el Handle de la Ventanna del TPanel
procedure TForm1.FormCreate(Sender: TObject);
begin
HWindow := 0;
end;

// Cierra la ventana de un Archivo PDF en un TPanel al finalizar la Aplicación
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if HWindow > 0 then
SendMessage(HWindow, WM_CLOSE, 0, 0);
Action := caFree;
end;

end.

El código anterior en Delphi 7 bajo Windows 7 Professional x32, permite abrir un documento PDF en un TPanel por medio de la función ShellExecute, como se muestra en la siguiente imagen:

http://i42.photobucket.com/albums/e305/nlsgarcia/ViewPDF_zpse50c3a96.jpg

Nota:

1- En esta versión es mandatorio finalizar cualquier instancia previa de Acrobat Reader para poder visualizar el documento seleccionado en el TPanel.

2- Esta versión no depende de ningún componente de terceros, solo de las APIs de Windows y de la versión instalada de Acrobat Reader.

Espero sea útil :)

Nelson.

radenf
21-05-2014, 13:42:35
Muchas gracias Nelson.
Excelente alternativa.
Probaré tu código adaptándolo a mi programa.
Saludos

Noruca5
30-07-2014, 11:40:08
Hola

Estoy intentando imprimir varios ficheros Pdf con el componente TAcroPDF, segun lo que he leido se puede enviar a la impresora sin visualizar los documentos.

Mi problema es que me descargo el fichero Pdf de un servidor y despues lanzo la impresión, solo me imprime el último fichero cargado en el componente.

ademas solo me permite imprimirlo si ejecuto primero un Show sobre el componente antes de ejecutar PrintAll, ya que Print no funciona tampoco.

¿Sabeis alguna solución? o ¿alguno otro componente que permita enviar a la impresora vairos documentos pdf?

Muchas gracias.

Casimiro Notevi
30-07-2014, 12:55:17
Bienvenido a clubdelphi, ¿ya leiste nuestra guía de estilo (http://www.clubdelphi.com/foros/guiaestilo.php)?, gracias por tu colaboración :)