inno-setuppascalscriptwebview2

Detecting if WebView2 Runtime is installed with Inno Setup


There is a good discussion about this here on the Microsoft website:

Detect if a suitable WebView2 Runtime is already installed

In part, it states:

Inspect the pv (REG_SZ) regkey for the WebView2 Runtime at both of the following registry locations. The HKEY_LOCAL_MACHINE regkey is used for per-machine install. The HKEY_CURRENT_USER regkey is used for per-user install.

For WebView2 applications, at least one of these regkeys must be present and defined with a version greater than 0.0.0.0. If neither regkey exists, or if only one of these regkeys exists but its value is null, an empty string, or 0.0.0.0, this means that the WebView2 Runtime isn't installed on the client. Inspect these regkeys to detect whether the WebView2 Runtime is installed, and to get the version of the WebView2 Runtime. Find pv (REG_SZ) at the following two locations.

The two registry locations to inspect on 64-bit Windows:

  • HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}
  • HKEY_CURRENT_USER\Software\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}

The two registry locations to inspect on 32-bit Windows:

  • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}
  • HKEY_CURRENT_USER\Software\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}

My installer uses elevation so I have limited my checks to HKEY_LOCAL_MACHINE. I believe this was the correct thing to do. This is my attempt at writing this function:

function IsWebView2RuntimeNeeded(): boolean;
var
    Version: string;
    RuntimeNeeded: boolean;
    VerifyRuntime: boolean;
begin
    { See: https://learn.microsoft.com/en-us/microsoft-edge/webview2/concepts/distribution#detect-if-a-suitable-webview2-runtime-is-already-installed }

    RuntimeNeeded := true;
    VerifyRuntime := false;

    { Since we are using an elevated installer I am not checking HKCU }
    if (IsWin64) then
    begin
        { Test x64 }
        if (RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}', 'pv', Version)) then
        begin
            { We need to verify }
            VerifyRuntime := true;
        end
    else
    begin
        { Test x32 }
        if (RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}', 'pv', Version)) then
        begin
            { We need to verify }
            VerifyRuntime := true;
        end;
    end;

    { Verify the version information }
    if (VerifyRuntime) then
    begin
        if (not Version = '' and not Version = '0.0.0.0') then
            Log('WebView2 Runtime is installed');
            RuntimeNeeded := false;
        else
            Log('WebView2 Runtime needs to be downloaded and installed');
        end;
    end;

    Result := RuntimeNeeded;
end;

But it will not compile and says:

Column 40 type mismatch.

It doesn't like this line:

if (not Version = '' and not Version = '0.0.0.0') then

I am not confident writing native Pascal Script so I appreciate guidance on correcting or improving this code so that it works efficiently.


I am comfortable with the other aspects of actually downloading the file and starting its installer because I can follow the principle for the other downloads in my setup script. It is just putting this actual test together to verify if the WebView2 runtime is installed or not.


Solution

  • I was able to glean some advice from one of the comments to this question on another website:

    How to write an if and statement?


    My current code is now:

    function IsWebView2RuntimeNeeded(): boolean;
    var
        Version: string;
        RuntimeNeeded: boolean;
        VerifyRuntime: boolean;
    begin
        { See: https://learn.microsoft.com/en-us/microsoft-edge/webview2/concepts/distribution#detect-if-a-suitable-webview2-runtime-is-already-installed }
    
        RuntimeNeeded := true;
        VerifyRuntime := false;
    
        { Since we are using an elevated installer I am not checking HKCU }
        if (IsWin64) then
        begin
            { Test x64 }
            if (RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}', 'pv', Version)) then
            begin
                { We need to verify }
                VerifyRuntime := true;
            end
        else
        begin
            { Test x32 }
            if (RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}', 'pv', Version)) then
            begin
                { We need to verify }
                VerifyRuntime := true;
            end;
        end;
    
        { Verify the version information }
        if (VerifyRuntime) then
        begin
            if (Version <> '') and (Version <> '0.0.0.0') then
            begin
                Log('WebView2 Runtime is installed');
                RuntimeNeeded := false;
            end
            else
                Log('WebView2 Runtime needs to be downloaded and installed');
            end;
        end;
    
        Result := RuntimeNeeded;
    end;
    

    I also had to add the begin and end keywords to that if statement. Feel free to update or add your own answer if you can see a more efficient way to write this code. For example, the original article I linked to mentioned an alternative (GetAvailableCoreWebView2BrowserVersionString). I assume we can't use that approach.