Newsgroup: it.comp.lang.javascript
Titolo: [Detect] Detect Acrobat

Ciao a tutti,
Qualcuno mi può dire se c'é uno script in grado di controllare se il
computer ha il plugin di acrobat e in caso negativo lanciarne l'installer?
Vi ringrazio

, 
pop...@pippa.org
 says...

Questo, derivato dalla faq: 
http://www.jsdir.com/faq/faq.asp?espandi=mostra&numero=60
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HEAD>
    <TITLE>JsDir - AcrobatReader Detect [incompleto!!!]</TITLE>
</HEAD>
<SCRIPT LANGUAGE="VBScript">
    Private i, x
    IEAcrobatReaderInstalled = False
    Set x = CreateObject("ShockwaveFlash.ShockwaveFlash")
    IEAcrobatReaderInstalled = IsObject(x)
</SCRIPT>
<SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript">
<!--
AcrobatReaderInstalled=false;
if (navigator.plugins && navigator.plugins["Adobe Acrobat"] || 
IEAcrobatReaderInstalled != null)
    AcrobatReaderInstalled = true;
if (AcrobatReaderInstalled)
    self.location.replace("PaginaAcrobat.html");
    else
    self.location.replace("PaginaNOAcrobat.html");
//-->
</SCRIPT>
<BODY BGCOLOR="#ffffff">
AcrobatReader Detecting Script <BR> <BR>
Basato sul <B>Flash Deployment Kit</B> di Macromedia
</BODY>
</HTML>
funziona per Netscape/Mozilla, ma non per Explorer perche' non esiste 
"navigator.plugins".
Qualcuno piu' skillato di me in fatto di IE sa come sistemarlo?
Cmq domani faccio un salto nel sito di Adobe.
Probabilmente basta trovare il nome dell'oggetto da sostituire in 
    Set x = CreateObject("ShockwaveFlash.ShockwaveFlash")
-- 
Ciao, Riccardo
------------------------------------------------------------------------
http://www.jsdir.com
 ---- Bring Your Site To Life!!!!
------------------------------------------------------------------------
http://www.dev2dev.it
 - La rete ha connesso nuove particelle - D2D006
------------------------------------------------------------------------
 ----> itALY = it <----

     Set x = CreateObject("ShockwaveFlash.ShockwaveFlash")
Si potrebbe fare cosě:
function checkAcrobat(){
 var obj = document.all["oAcrobat"];
 if(obj){alert("installato")}
}
self.onload=checkAcrobat;
E nel body della pagina (ovviamente sostituendo una o allo 0 in "object"):
<0bject ID="oAcrobat" classid="CLSID:CA8A9780-280D-11CF-A24D-444553540000"
width=0 height=0></object>
Questo perché istanziando l'oggetto direttamente da js si pone un problema
di versione non potendo richiamare l'oggetto né col "clsid" né col "version
indipendent progid", ma solo dal progid. Stesso problema ovviamente con
qualunque oggetto (vedi check di flash che hai usato come esempio sopra).
Quindi mi verrebbe da scrivere un mostro simile:
for(var i=1;i<10;i++){
 try{
  var obj = new ActiveXObject("PDF.PdfCtrl."+i);
  if(obj) break;
 }catch(err){}
}
if(obj) alert("installato");
obj=null;
Anche perché usando il tag object in html ho notato che Acrobat Reader 4.05
viene aperto, caricato e chiuso prima di poter dare messaggi all'utente (il
Reader 5 non si comporta cosě).
Leggendo su msdn non sembra possibile istanziare un oggetto ActiveX da
codice usando la clsid.
Qualcuno ha altre idee?

>  }catch(err){}
...quindi dipendente anche da versione di IE (>=5 per try...catch)

 ...quindi dipendente anche da versione di IE (>=5 per try...catch)
Certo, scusa l'omissione.
Anche per questo sarebbe preferibile il tag object (nonostante il fastidioso
comportamento sul Reader 4).


Mi rispondo da solo aggiungendo due cose che mi faceva notare Zer0 per
telefono:
1) che sono addormentato e che il caffe' non basta piu' a svegliarmi.
2) che basta scrivere un event handler sull'errore per mandare try & catch,
almeno in questo caso, a quel paese.

 almeno in questo caso, a quel paese.
Non ho capito...puoi fare un esempio?
Grazie

 Non ho capito...puoi fare un esempio?
Più o meno direi due strade:
window.onerror=null;
e vanno a farsi benedire gli errori che avvengono a livello di pagina,
oppure, per continuare a gestirli:
var arrErrors = [];
function errorHandler(){
 for(var i=0;i<arguments.length;i++)
  arrErrors[arrErrors.length] = arguments[i];
 return true;
}
window.onerror=errorHandler;
Dove l'array arrErrors ha questo formato: messaggio di errore, url, linea
dove è avvenuto.
Quindi il numero degli errori è arrErrors.length/3 e in un ciclo di
visualizzazione:
var s="";
for(var i=0;i<arrErrors.length;i+=3)
    s+="Errore nel file: "+arrErrors[i+1]+"\nLinea:
"+arrErrors[i+2]+"\nMessaggio: "+arrErrors[i]+"\n\n";
alert(s);
Saludos

Moooolto interessante...funziona con ie4 questa gestione degli errori?
Testo immediatamente
grazie

 grazie
De nada. Avrai sicuramente modo di rendere il favore...

, 
ascartab...@codice.it
 says...
Ma guarda che casini mi vieni a scrivere, vergognoso.. che poi, visto 
che partono da suggerimenti miei, pensano che io scriva codice in questo 
modo :P
Piu' semplicemente:
pOldCallBack=self.onerror;
self.onerror=function(){return true}
// qui fai il tuo ciclo per l'oggetto finche' non e' avvalorato
self.onerror=pOldCallBack;
pOldCallBack=null;
Non l'ho testato, ma a logica dovrebbe andare.
P.S.
Curioso cmq che IE ti dia problemi con l'assegnazione a "null"..
-- 
C'ya,
ZER0
  :. job profile - coder.gfxer.webDesigner
"Quanti angeli danzano sulla punta di uno spillo?"

 Curioso cmq che IE ti dia problemi con l'assegnazione a "null"..
Cito la bibbia Javascript: "window.onerror=null suppresses all error
reporting"; e ovviamente, per dirla tutta: "window.onerror=null suppresses
JavaScript error messages, not onError event handlers".
Visto che il risultato su IE6 e' un messaggio di errore saresti stato tu
solitamente a ricordarmi che Javascript non e' JScript, poi avremmo sorriso,
glissato e cercato di capire cosa fa IE5.5...  poi, se per qualche motivo
strano ci fossimo trovati di fianco i Balestra/Catarsi/Larghi di questo ng
saremmo stati giustamente schiaffeggiati per un qualche altro "comportamento
strano" avvenuto su un Mac (ricordo ostinato a portare in pari la tua mitica
library).
Tesi: sulla "fiscalita' matematica" siamo sempre stati d'accordo. Se siamo
su un newsgroup io scrivo a Cristiano i<arguments.length, nonostante
Cristiano conosca javascript; se scrivo un programma per i fatti miei scrivo
i<3 (mi riferisco a post precedente).
...ovviamente ti bacio dappertutto...

 tue polemiche...
:-)))


 ...ovviamente ti bacio dappertutto...
poVco.. :P
--------------------------------
Inviato via 
http://usenet.libero.it

Ho fatto un test e funziona pregiatamente (sotto lo scriptino di test che ho
fatto).
Non ho capito la logica dell'activex, a me indica installato già il primo;
se i numeri crescono col crescere delle versioni non sarebbe meglio fare il
ciclo al contrario (partendo magari da un valore moooolto alto per versioni
future)?
<html>
<head>
<title>Test Acrobat - cattura errori IE4</title>
<script language='JavaScript'>
 //mi salvo procedura di default per errori (logica callback di vb)
 var VecchiaCallBack=self.onerror;
 //disabilito gestione errori
 self.onerror=function(){return true;//qua se testo arguments.length ho
indicato l'errore che posso salvarmi in un array (sono 3 record per ogni
errore)
 }
 //alert sotto NON segnala errore
 //alert(document.all['nonesiste'].value);
 function checkAcrobat() {
  for(var i=1;i<10;i++) {
   var obj = new ActiveXObject("PDF.PdfCtrl."+i);
   if(obj) break;
  }
  if(obj) alert("installato "+i);
  obj=null;
  //riabilito errori
  self.onerror=VecchiaCallBack;
  VecchiaCallBack=null;
  //alert sotto dà errore...
  //alert(document.all['nonesiste'].value);
 }
 self.onload=checkAcrobat;
</script>
</head><body></body></html>

 }
Questo approccio potrebbe non funzionare con gli altri activeX (che
subiscono lo stesso "problema" del progid).. con Flash, ad esempio potresti
avere:
"ShockwaveFlash.ShockwaveFlash"
o
"ShockwaveFlash.ShockwaveFlash.1"
(almeno a quanto dice Andrea)
Io direi di fare una funzione standardizzata per il check di activeXobject,
tipo:
function getActiveX(sProgId){
    var pOldCallBack=self.onerror,
        objAX=null;
        self.onerror=function(){return true;}
 
        for (var i=0;i<10;i++){
            alert(sProgId+(i>0?"."+i:""))
            objAX=new ActiveXObject(sProgId+(i>0?"."+i:""));
            if (objAX) break;
        }
        self.onerror=pOldCallBack;
        pOldCallBack=null;
        return objAX;
}
e poi:
 
    var myobj=getActiveX("PDF.PdfCtrl");
 
    if (myobj)
        alert("Installed")
    else
        alert("not exist");
 
L'ho codata al volo, quindi non assicuro che non vi siano errori, volevo
solo mostrare l'approccio logico.
Cmq guardo se oggi ho un sec per mettermi a smanettare con l'ActiveX.


Allora.. ho fatto un paio di rapidissimi test sotto IE6.0 per quanto
riguarda gli activeX...
(ed ho telefonato ad Andrea per infamarlo mezzo in quanto mi aveva confuso
le idee con ShockwaveFlash :P )
Allora: Buttiamo all'ortiche tutto quel che abbiamo fatto fin'ora, a meno
che non si voglia rinominare il discorso in "becca la versione piu' recente
di un certo plug in"..
.. Allorche' va fatto un ciclo inverso come suggeriva Cristiano, anche se -
almeno per quanto mi riguarda personalmente - la vedo piuttosto inutile.
Il ProgID va seguito dal numero di versione.
PDF.PdfCtrl.5
E' corretta come sintassi e non ci vedo nulla di strano. Eventualmente uno
controlla per piu' versioni (tipo la quattro).
Per quanto riguarda Flash.. la confusione iniziale me l'aveva data Andrea
per telefono.. anche li' la sintassi segue sempre lo stesso percorso.
Da quanto mi aveva detto Andrea, installando MX il ProgID di ShockwaveFlash
"diventava" ShockwaveFlash.ShockwaveFlash.1.. e questo non mi tornava molto,
sembrava si andasse a sostituire accumulandosi.
In realta' il plugin di ShockwaveFlash ha SEMPRE avuto tale ProgID, perche'
sta - appunto - ad indentificare il numero di versione del controllo. E con
semplici e rapidi test, si puo' verificare che:
ShockwaveFlash.ShockwaveFlash.3
ShockwaveFlash.ShockwaveFlash.4
ShockwaveFlash.ShockwaveFlash.5
ShockwaveFlash.ShockwaveFlash.6
Restituiscono tutti oggetti validi se si possiede il plugIns di Flash MX.
Dal 7 in poi da', giustamente, errore.
Se invece si ha Flash 4 , l'errore viene generato dalla version 5 in poi, e
cosi' via.
Insomma, io ero entrato in tutto questo discorso convinto che vi fosse un
anomalia "di base" generata da ShockwaveFlash (il discorso tra me ed Andrea
e' partito telefonicamente da qui) e che si potesse estendere anche ad altri
oggetti.. Ovvero che si accodasse al progID un numero "incrementale" e non
di versione.
In realta' l'anomalia NON SUSSISTE, e quindi vige la regola per l'instanza
di oggetti ActiveX tramite ProgID+versione.


 (proprio il contrario di quel che volevi fare tu).
Cosa che non avviene in javascript. Mi riferisco alla citazione dalla bibbia
sulla soppressione dei messaggi di errore.
Ti faccio domanda in anticipo. OK la questione della versione (chiedo venia
ma come ti ho detto mi riferivo solo al caso di questo thread e non ho
ancora fatto prove), ma la mia curiosità era: è veramente impossibile da
codice fare un'istanza dell'oggetto usando un riferimento generico
(indipendente dalla versione) come si fa col classid nel tag object?

Quindi per sapere la versione installata (per flash è importante) o seguo il
metodo da 0 a n e testo quando NON è più un oggetto, oppure ciclo al
contrario e testo quando è un oggetto
Tutto chiaro; a me la confusione era nata perché un "antico" guru del
newsgroup (non faccio nomi perché non sono sicuro di chi l'aveva detto),
parlando di flash, diceva che con IE4 l'unico modo era di mandare in errore
il browser...invece con questo controllo/esclusione degli errori si sistema
il tutto anche per IE.
Grazie

 contrario e testo quando è un oggetto
Esatto.. Ma ti consiglio il secondo metodo.
Puoi semplicemente partire dall'ultima versione in commercio, e quindi
ciclare all'indietro finche' non diventa un oggetto oppure la versione e'
troppo bassa per quel che devi fare tu.
Ma a questo punto, un ciclo da "6 a 3" (per Flash, ad esempio) mi pare
piuttosto inutile, e puoi controllare DIRETTAMENTE il ProgID che ti
interessa, magari mantenendo il l'event handler per evitare che il browser
vada in errore.
Es:
    var pOldCallBack=self.onerror;
        objAX=null;
    self.onerror=function(){return true;}
    var objAX=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6")||new
ActiveXObject("ShockwaveFlash.ShockwaveFlash.5")||new
ActiveXObject("ShockwaveFlash.ShockwaveFlash.4")||null;
 
    self.onerror=pOldCallBack;
    pOldCallBack=null;
 
Sempre scritta al volo, quindi non sono sicuro se la sintassi che ho usato
su IE instanzi 3 volte l'oggetto.. ma era per non scrivere sul momento i 3
casi su costrutto IF ^^ L'approccio logico, cmq, e' questo.
