Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the ProgId or CLSID for IE9's Javascript engine (code-named "Chakra")

Using .NET, I can write an app that hosts a scripting engine that complies with Microsoft's IActiveScript conventions. This includes JScript and VBScript from Microsoft, and also PerlScript, RubyScript and I don't know what else from third-parties.

The way to do it in code is something like this:

    Type engine = Type.GetTypeFromProgID(progId, true);
    _engine = Activator.CreateInstance(engine) as IActiveScript;

where the progId can take the value Javascript, JScript, ECMAScript, VBScript, and others. You can do something similar when running cscript.exe, specifying the progId on the command line with the //E option. For example, this command:

cscript.exe  <file>  //e:JScript

..will run the specified file, regardless of its extension, through the JScript engine.

On my machine, if I look in HKLM\SW\Classes\ , the three progIds {Javascript, JScript, ECMAScript} all point to the same CLSID, which I guess is the JScript 5.8 script engine: {f414c260-6ac0-11cf-b6d1-00aa00bbbb58}

Is there a ProgId or CLSID I can specify to run IE9's Javascript engine, aka "Chakra"?

Does IE9's engine still get loaded by IActiveScript?
Microsoft's documentation suggests that it does, but does not specify a ProgId or CLSID.

like image 810
Cheeso Avatar asked Aug 23 '11 21:08

Cheeso


3 Answers

The CLSID for the Chakra Javascript engine installed with IE9 is
{16d51579-a30b-4c8b-a276-0ff4dc41e755}.

The InProcServer32 is %windir%\System32\jscript9.dll .

There is no ProgId that I could find. That's a bit odd; normally paired ProgId and CLSID entries refer to each other. For a given COM object, the ProgId key in the registry has a subkey called CLSID, and the CLSID registry key has a subkey called ProgId, and they refer to each other. But the ProgId subkey for the IE9 CLSID is "JScript", which of course refers to the v5.8 Jscript CLSID. Not sure if this was a mistake by Microsoft, or a purposeful bit of obfuscation, because they don't want anyone using the Chakra engine outside of IE9. Looks purposeful to me.


I learned of the CLSID by just searching the registry for jscript9.dll .


If you have .NET code that hosts scripting engines, you can instantiate the IActiveScript object for the IE9 javascript engine ("Chakra") by using the CLSID directly. The code needs to be something like this:

private const string clsIdPattern =
    @"^(?<curly>\{)?[a-zA-Z0-9]{8}(?:-[a-zA-Z0-9]{4}){3}-[a-zA-Z0-9]{12}(?(curly)\})$";

public ScriptEngine(string language)
{
    if (language == null)
        throw new ArgumentNullException("language");

    Type engineType = null;

    if (Regex.IsMatch(language, clsIdPattern))
    {
        // it's a CLSID
        var guid = new System.Guid(language);
        engineType = Type.GetTypeFromCLSID(guid, true);
    }
    else
    {
        // assume vanilla progId
        engineType = Type.GetTypeFromProgID(language, true);
    }

    var engine = Activator.CreateInstance(engineType) as IActiveScript;

In the above, clsIdPattern is a regular expression that matches the familiar GUID format, either with or without surrounding curlies.

Given the code above, you could pass "jscript", "Javascript", or "ECMAScript" and get the v5.8 JScript engine. Or you could pass "{16d51579-a30b-4c8b-a276-0ff4dc41e755}" and get the IE9 Javascript engine. Obviously you need to have IE9 installed in order for this to work.

I just tried this and it works for simple cases. I'll be playing with that some more, real soon.


If you want to run Chakra from WSH, like from cscript.exe, then you will need a ProgId, I think.
If I create "Chakra" as a Progid in the registry, referring to the correct CLSID, I can run JS files through IE9's engine like this:

cscript.exe  module.js  //E:Chakra 

For example, after inserting the new "Chakra" ProgId, given a script like this:

WScript.Echo( ScriptEngineMajorVersion() + "." +
              ScriptEngineMinorVersion() + "." +
              ScriptEngineBuildVersion());

...the output is like this:

C:\dev\js>Version.js
5.8.16982

C:\dev\js>cscript.exe Version.js  //E:Chakra
9.0.16434

And here's the result of a test of AES encryption in Javascript, comparing Chakra with JScript 5.8:

C:\dev\js\SlowAES>cscript.exe test.aes.js
AES encryption in Javascript.
password  : Albatros1
salt      : saltines (73616c74696e6573)
iterations: 1000
key       : 172,52,20,51,98,71,49,195,14,31,141,51,129,8,94,66
iv        : 212,27,28,156,83,245,0,35,176,157,45,141,209,143,158,248
plaintext : Hello, /r/javascript.
ciphertext: fdebac9f1ed1a13bac58f3cc6558e8b0367a94245dbbfe53cacc4979799fc182
decrypted : Hello, /r/javascript.
elapsed   : 5011ms

C:\dev\js\SlowAES>cscript.exe test.aes.js //E:Chakra
AES encryption in Javascript.
password  : Albatros1
salt      : saltines (73616c74696e6573)
iterations: 1000
key       : 172,52,20,51,98,71,49,195,14,31,141,51,129,8,94,66
iv        : 212,27,28,156,83,245,0,35,176,157,45,141,209,143,158,248
plaintext : Hello, /r/javascript.
ciphertext: fdebac9f1ed1a13bac58f3cc6558e8b0367a94245dbbfe53cacc4979799fc182
decrypted : Hello, /r/javascript.
elapsed   : 2593ms

To set the ProgId in my registry, I used this:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{16d51579-a30b-4c8b-a276-0ff4dc41e755}\ProgID]
@="Chakra"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Wow6432Node\CLSID\{16d51579-a30b-4c8b-a276-0ff4dc41e755}\ProgID]
@="Chakra"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Chakra]
@="JScript Language"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Chakra\CLSID]
@="{16d51579-a30b-4c8b-a276-0ff4dc41e755}"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Chakra\OLEScript]

and to unexpose Chakra, or revert the registry, I did this:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{16d51579-a30b-4c8b-a276-0ff4dc41e755}\ProgID]
@="JScript"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Wow6432Node\CLSID\{16d51579-a30b-4c8b-a276-0ff4dc41e755}\ProgID]
@="JScript"

[-HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Chakra]

This registry script worked with x64 Windows; if you don't have x64, then you'll need to remove the WOW6432Node lines.

like image 88
Cheeso Avatar answered Oct 23 '22 02:10

Cheeso


Might be a bit late, but:

You can also simply specify the CLSID of the engine you want to use via the //E argument:

cscript.exe  <file>  //E:{16d51579-a30b-4c8b-a276-0ff4dc41e755}

Edit: According to Cheeso's answer I found that it is enough to add the following registry entries to be able to use jscript9 without specifying the CLSID. I use the key name JScript9 here, you may replace it with Chakra if you like. The key name is what you specify after //E: then:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\JScript9]
@="JScript9 Language"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\JScript9\CLSID]
@="{16d51579-a30b-4c8b-a276-0ff4dc41e755}"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\JScript9\OLEScript]

And then:

cscript.exe  <file>  //E:JScript9
like image 24
imagiro Avatar answered Oct 23 '22 03:10

imagiro


You can now call the Chakra runtime directly through published API's and you don't have to use IActiveScript anymore.

Here is an article on MSDN showing how to host the Chakra runtime in C++ or C#:

https://web.archive.org/web/20151103122111/https://code.msdn.microsoft.com/windowsdesktop/JavaScript-Runtime-Hosting-d3a13880

(Note: As of 2019, The code example is on github.com/microsoft/Chakra-Samples)

like image 2
justin.m.chase Avatar answered Oct 23 '22 02:10

justin.m.chase