Interestingly, Apple has created a Quicktime detection script that is essentially the same as my script and may be based on it. So this script definitely works for more plugins than just Flash.
This combination of JavaScript and VBScript will detect if your users have installed the Flash plugin and, if so, which version. After you have detected the presence/absence of the plugin, you can take appropriate measures.
First of all, let's see if you have Flash installed and, if so, which version:
The theoretical way to detect the Flash plugin is to check
either the array navigator.plugins
or navigator.mimeTypes
.
These arrays are filled with all plugins and mime types the browser
can handle and you can check them to see if it can deal with Flash movies.
Netscape 2 and Konqueror do not support either array, so you cannot detect Flash in those browsers.
The plugins array is by far the most interesting because it also contains version
information, while the mimeTypes array only tells us whether the browser can handle the
application/x-shockwave-flash
mime type (= if Flash is installed). The mime type
hasn't changed with Flash versions, though, so you cannot tell which version of Flash
the user has.
Since Opera on Mac and Linux, iCab and Hotjava only support the mimeTypes array, detecting which Flash version is present is not possible in these browsers.
Explorer confuses the issue by leaving the arrays empty, even though both exist, so that according to JavaScript Explorer never has any plugins and does not support any mime types. The only exception to this rule is Explorer 5 on Mac, which supports both arrays (sensible decision!).
The only way to check for plugins in Explorer is by using VBScript. Here we encounter a new complication: Explorers on Mac do not support VBScript, so it is fundamentally impossible to detect any plugin in Explorer 3 and 4 on Mac. As I said, Explorer 5 on Mac supports the Netscape way.
Finally, the VBScript is supposed to produce error messages, so it is not exactly an example of clean coding. Until now I have found no better way.
That said, let's go to the script:
<SCRIPT LANGUAGE="Javascript"> <!-- var flashinstalled = 0; var flashversion = 0; MSDetect = "false"; if (navigator.plugins && navigator.plugins.length) { x = navigator.plugins["Shockwave Flash"]; if (x) { flashinstalled = 2; if (x.description) { y = x.description; flashversion = y.charAt(y.indexOf('.')-1); } } else flashinstalled = 1; if (navigator.plugins["Shockwave Flash 2.0"]) { flashinstalled = 2; flashversion = 2; } } else if (navigator.mimeTypes && navigator.mimeTypes.length) { x = navigator.mimeTypes['application/x-shockwave-flash']; if (x && x.enabledPlugin) flashinstalled = 2; else flashinstalled = 1; } else MSDetect = "true"; // --> </SCRIPT> <SCRIPT LANGUAGE="VBScript"> on error resume next If MSDetect = "true" Then For i = 2 to 6 If Not(IsObject(CreateObject("ShockwaveFlash.ShockwaveFlash." & i))) Then Else flashinstalled = 2 flashversion = i End If Next End If If flashinstalled = 0 Then flashinstalled = 1 End If </SCRIPT>
After the detect, the variable flashinstalled
can have three values:
The variable flashversion
contains the version of Flash. If the version is
unknown, it is 0.
In this page I document.write
a little message based on the value of these two variables. You'll
have to decide exactly what to do with the information this script provides, especially what to do if you don't know
if Flash is installed.
First of all, make flashdetect
and flashversion
0
(we don't yet know if Flash is installed and which version it is) and make MSDetect
false.
If we need the VBScript, it will be set to true
.
var flashinstalled = 0; var flashversion = 0; MSDetect = "false";
We start the detect by seeing if navigator.plugins
exists and, if it exists, if its length
is larger than zero. After all, the array itself exists in Explorer, but it does not contain any data
so its length is zero. The Netscape-style detect script that follows should only be executed if
the array is actually filled with data.
if (navigator.plugins && navigator.plugins.length) {
Then we try to find the plugin Shockwave Flash
.
x = navigator.plugins["Shockwave Flash"];
If it exists
if (x) {
we know that Flash is installed, so we set flashinstalled
to 2.
flashinstalled = 2;
Then we see if the plugin object has a property description
.
(As far as
I know every browser that supports navigator.plugins
also supports description
,
but let's be careful)
if (x.description) {
If it's supported, we extract the Flash version from it. The description is always something
like Flash 4.0 r47
. Therefore we take the number before the dot and put it in flashversion
.
y = x.description; flashversion = y.charAt(y.indexOf('.')-1); } }
If navigator.plugins["Shockwave Flash"]
does not exist, Flash is probably not installed
so we set flashinstalled
to 1.
else flashinstalled = 1;
Finally a special case: Flash 2 has a special plugin name Shockwave Flash 2.0
. If
this plugin is present, set the variables to Flash 2 detected:
if (navigator.plugins["Shockwave Flash 2.0"]) { flashinstalled = 2; flashversion = 2; } }
If the plugins array is not supported, we see if the browser supports navigator.mimeTypes
.
Again check the length for Explorer's sake.
else if (navigator.mimeTypes && navigator.mimeTypes.length) {
Now we see if navigator.mimeTypes['application/x-shockwave-flash']
exists, that is if this
MIME type can be handled by the browser. If it can, we check its property .enabledPlugin
, which
is true if the plugin is actually installed
(I don't really understand why there is an enabledPlugin
property,
in my view any plugin that's present is enabled by definition).
If it is, we set flashinstalled
to 2, if it isn't we set it to 1.
Unfortunately, navigator.mimeTypes
doesn't tell us which version is installed.
x = navigator.mimeTypes['application/x-shockwave-flash']; if (x && x.enabledPlugin) flashinstalled = 2; else flashinstalled = 1; }
Netscape and the minor browsers are ready now.
If neither array is supported we make MSDetect
true so that the VBScript
will be executed. Of course this doesn't help Netscape 2, Konqueror and Explorer 3 and 4 on
Mac a bit, since they don't support VBScript. Too Bad.
else MSDetect = "true";
The VBScript is not exactly an example of beautiful coding. In fact, the script is supposed to produce errors.
The main problem is that the detect is done by trying to create an object
ShockwaveFlash.ShockwaveFlash.[versionNumber]
. If this is done succesfully, the browser
supports this version of Flash. If this version of the plugin is not installed, however, Explorer
gives an error message because it cannot create the object.
Therefore we need to use the VBScript on error
event handler to tell Explorer to continue
the script, no matter what.
<SCRIPT LANGUAGE="VBScript"> on error resume next
Then for the actual detect. First of all we check if MSDetect
is true. If it is, we execute the rest of the VBScript.
If MSDetect = "true" Then
Now we try to create objects. Flash 2 is called ShockwaveFlash.ShockwaveFlash.2
,
Flash 3 is called ShockwaveFlash.ShockwaveFlash.3
etc. So what we need to do is create
all these objects and see which one of them doesn't give an error.
So we go through the versions
For i = 2 to 6
and try to create an object for Flash version i
If Not(IsObject(CreateObject("ShockwaveFlash.ShockwaveFlash." & i))) Then
Now we come to the dirty bit. If Flash version i
is not supported,
the browser gives an error, but since we told it to resume next
it will nonetheless
execute the next command. However, if the Flash version is not supported, we don't want
anything to happen. That's why we check if the object is not present
(Not(IsObject(etc))
) and if it isn't (if the error occurs) nothing should be done:
[that's right, nothing]
If the object can be created and is present, we've found the installed Flash version.
We set flashinstalled
to 2 and flashversion
to i
.
Else flashinstalled = 2 flashversion = i
End all stuff, this is required in VBScript, it's the equivalent of closing brackets
}
in JavaScript.
End If Next End If
If, after we've checked all possible versions, flashinstalled
is still 0, it means that
Flash is not installed. Therefore we make it 1. We've tried to find Flash, but didn't find it.
If flashinstalled = 0 Then flashinstalled = 1 End If
That's it. Now you only have to write a little script that reads out flashinstalled
and flashversion
and gives commands
for the several situations. Think carefully about what should happen if you don't know if Flash is installed.
There is a way of detecting Flash without JavaScript. You have to create a tiny Flash movie that redirects the user to the Flash page and place it on a page with a META refresh that redirects the user to the non-Flash page. If Flash works, the Flash redirect comes first, if it doesn't work the browser executes the META refresh. For more details see the Macromedia site.
Theoretically, using this script you should be able to detect other plugins. However, it rarely succeeds. You have to find the correct MIME type for the Netscape style detect and the correct VB Object for the Explorer style detect. Find the object by starting up your registry editor (Start -> Run -> Regedit), opening to HKEY_CLASSES_ROOT and selecting the file extension of the plugin you want to detect. The 'Content Type' entry holds the MIME type, the 'Default' entry contains the VB Object we need.
Rewrite the function for the new objects, then try it. Unfortunately I cannot guarantee anything, some plugins work differently.
However, a reader has succeeded in implementing this detect for Real Player:
It's also rumoured to work for Adobe Acrobat:
So to detect a specific version of Acrobat you have to use a loop similar to the one in the VBScript above.
If you succesfully use this function for another plugin, please tell me.