Problem with detecting dotnet

549 views
Skip to first unread message

Andrew Truckle

unread,
May 13, 2022, 4:28:29 PM5/13/22
to innosetup
Hi
I am getting an issue with a user when Inno gives a fatal internal error when detecting dotnet.
I already have all the info here:


Please have a look. The issue is related to the DotNet.pas file and the places where it displays a Interal - .NET Framework not found.

In the  comments to my question someone pointed to:


They said:

"The approach your script uses (InstallRoot) is long out of date. Microsoft documents the official way in docs.microsoft.com/en-us/dotnet/framework/migration-guide/… and shouldn't be that hard for you to translate to Pascal Script as you already get examples. "

Since this is part of the actual Inno Setup core code, can I please ask for this secondary way to test to be implemented? Thank you.

Andrew Truckle

unread,
May 13, 2022, 4:53:20 PM5/13/22
to innosetup
So the code here does it fine - the new way:


Would be nice to be part of Inno...

Andrew Truckle

unread,
May 14, 2022, 1:22:32 AM5/14/22
to innosetup
Turns out, that whilst the revised code was needed, that the user had another step to perform. Because of a recent Windows 11 update:


Turns out he had to switch on the .NET Framework 3.5 setting. I don't really understand why though because my app required 4.6.2 for the supporting tools. Does Inno Setup itself use anything that has an underlying need on that older framework?

I have asked the user for an updated error message for when this option is not ticked. I will also check my development PC.

Martijn Laan

unread,
May 14, 2022, 5:00:15 AM5/14/22
to innosetup
This is already the same code as IsDotNetInstalled uses.

Also see https://github.com/jrsoftware/issrc/blob/cb9c3e94593724ea062bb3070bb034abdd009652/Projects/DotNet.pas#L183

Greetings,
Martijn

> Op 13 mei 2022 om 22:53 heeft Andrew Truckle <truc...@gmail.com> het volgende geschreven:
>
Message has been deleted

Andrew Truckle

unread,
May 14, 2022, 12:11:00 PM5/14/22
to innosetup
Ok, I checked the code some more:

  else if Cnst = 'dotnet11' then Result := GetDotNetVersionInstallRoot(rv32Bit, netbase11)
  else if Cnst = 'dotnet20' then Result := GetDotNetVersionInstallRoot(InstallDefaultRegView, netbase20)
  else if Cnst = 'dotnet2032' then Result := GetDotNetVersionInstallRoot(rv32Bit, netbase20)
  else if Cnst = 'dotnet2064' then begin
    if IsWin64 then
      Result := GetDotNetVersionInstallRoot(rv64Bit, netbase20)
    else
      InternalError('Cannot expand "' + OriginalCnst + '" constant on this version of Windows');
  end
  else if Cnst = 'dotnet40' then Result := GetDotNetVersionInstallRoot(InstallDefaultRegView, netbase40)
  else if Cnst = 'dotnet4032' then Result := GetDotNetVersionInstallRoot(rv32Bit, netbase40)
  else if Cnst = 'dotnet4064' then begin
    if IsWin64 then
      Result := GetDotNetVersionInstallRoot(rv64Bit, netbase40)
    else
      InternalError('Cannot expand "' + OriginalCnst + '" constant on this version of Windows');
  end

I have this in my script:

Filename: "{dotnet40}\regasm.exe"; Parameters: "MSAToolsLibrary_x86.dll /codebase"; WorkingDir: "{app}"; Flags: runhidden
Filename: "{dotnet4064}\regasm.exe"; Parameters: "MSAToolsLibrary_x64.dll /codebase"; WorkingDir: "{app}"; Flags: runhidden; Check: IsWin64
Filename: "{dotnet40}\regasm.exe"; Parameters: "MSAToolsGMailLibrary_x86.dll /codebase"; WorkingDir: "{app}\MSAToolsGMailLibrary"; Flags: runhidden
Filename: "{dotnet4064}\regasm.exe"; Parameters: "MSAToolsGMailLibrary_x64.dll /codebase"; WorkingDir: "{app}\MSAToolsGMailLibrary"; Flags: runhidden; Check: IsWin64
Filename: "{dotnet40}\regasm.exe"; \

Since Inno is calling the legacy code for these constants, it is why his system crashed with the old message. As he does not have the InstallPath.


On Saturday, 14 May 2022 at 16:32:19 UTC+1 Andrew Truckle wrote:
Thanks. But when was it changed?
I had been using 6.2.0 and I assumed the source code I downloaded would have been the latest.

I have now just downloaded 6.2.1 but I am still using my code. The reason I say this is because this user was getting that Internal Error and it specifically showed up in the obsolete way of doing things. And in his case teh InstallRoot was missing which also threw the wobbly. Your code does not show that error. So when was it introduced? Pre 6.2.1? If yes, then why did my user get that older error message?

Wilenty org

unread,
May 14, 2022, 6:07:32 PM5/14/22
to innosetup
---

Maybe it's to obvious, but did you asked your user how he/she installed the .NET framework? From original M$ installer, or via WU (Windows Update), or from some other repacks?
Either, you can ask your user to export the .NET framework registry location - you can import it on VM (Virtual Machine) and you will be able to check the problem by yourself.

For second - we are no able to check you part of your script without the files you used, so:
I am asking Martijn Laan to add in the InnoSetup forum title that we need: InnoSetup Version; full-script (with files, if they used) or well described function in the [code] and what failed; other included files (if used), then we can check if we can help them in any way - otherwise it's a guessing...

Andrew Truckle

unread,
May 14, 2022, 7:44:18 PM5/14/22
to innosetup
Hey, maybe consider adding a similar popup message like indicated in this chat?


So:

"Please set registry key HKLM \ Software \ Microsoft \ .NETFramework \ InstallRoot to point to the .NET Framework install location"

or similar (both keys are needed).

Andrew

Andrew Truckle

unread,
May 15, 2022, 4:01:00 AM5/15/22
to innosetup
Also, note that after the recent Windows 11 update:


For my user, just activating the Framework 3.5 setting stopped the Inno warning. It is documented.

Wilenty org

unread,
May 15, 2022, 5:58:47 AM5/15/22
to innosetup
Hello,
at the outset, I am not a part of the InnoSetup team. :) But I am trying to help other users here, if there's a problem and I see how to solve it.


"Also, note that after the recent Windows 11 update:

May 10, 2022—KB5013943 (OS Build 22000.675) (microsoft.com)

For my user, just activating the Framework 3.5 setting stopped the Inno warning. It is documented."
I installed W11 on VM just to check it, but I don't use that early version on real computers.


"Hey, maybe consider adding a similar popup message like indicated in this chat?

Fixing "Please set registry key HKLM \ Software \ Microsoft \ .NETFramework \ InstallRoot to point to the .NET Framework install location" error on a 64-bit Windows PC (download3k.com)

So:

"Please set registry key HKLM \ Software \ Microsoft \ .NETFramework \ InstallRoot to point to the .NET Framework install location"

or similar (both keys are needed).

Andrew"
I got the [code] from your previous post, i.e. http://www.kynosarges.de/DotNetVersion.html
And I modified it a bit, so, now it displays above mentioned message, if the install reg-key of the .NET framework does not exists. I showed in the [code] how to track/get these messages.
I set non-existent version of .Net, i.e. "v.4.9" to test it, so you need to specify correct version of .NET in my example.

BTW, I won't post source of my example script to not make this message so long. Get the example script, compile it, and test it.
DotNet.iss

Andrew Truckle

unread,
May 15, 2022, 12:33:19 PM5/15/22
to innosetup
Hi Wilenty

Thanks for the code. But please note that all my questions have been directed to the Inno maintainers for possible review in Inno setup as opposed to personal code customizations.

Andrew Truckle

unread,
May 17, 2022, 7:06:09 AM5/17/22
to innosetup
Thoughts Martyn?

Andrew Truckle

unread,
May 29, 2022, 7:46:06 AM5/29/22
to innosetup
Is this going to be considered as an issue? Atleast for official inno to die more gracefully because the app path reg key is missing? I had to find it out by looking at the code of inno. 

Martijn Laan

unread,
May 31, 2022, 10:22:41 AM5/31/22
to inno...@googlegroups.com
Op 29-5-2022 om 13:46 schreef Andrew Truckle:
Atleast for official inno to die more gracefully because the app path reg key is missing?

It doesn't die, it throws an exception, as documented. You should always catch exceptions (using try...except) if you want it to continue after the exception.

Greetings,
Martijn

Andrew Truckle

unread,
Jun 1, 2022, 5:51:23 PM6/1/22
to innosetup
That is a fair point Martyn. But I have obviously overlooked this clarification in the docs.

Please direct me to the URL. For example, this documentation plus example does not use a try / catch block nor tell us to use it:

Pascal Scripting: IsDotNetInstalled
Prototype:

function IsDotNetInstalled(const MinVersion: TDotNetVersion; const MinServicePack: Cardinal): Boolean;

Description:

Returns True if the .NET Framework with the specified MinVersion and MinServicePack parameters is installed.

TDotNetVersion is defined as:

TDotNetVersion = (net11, net20, net30, net35, net4Client, net4Full, net45, net451, net452, net46, net461, net462, net47, net471, net472, net48);

Example:
function InitializeSetup: Boolean; begin Result := IsDotNetInstalled(net462, 0); //Returns True if .NET Framework version 4.6.2 is installed, or a compatible version such as 4.8 if not Result then SuppressibleMsgBox(FmtMessage(SetupMessage(msgWinVersionTooLowError), ['.NET Framework', '4.6.2']), mbCriticalError, MB_OK, IDOK); end;

Martijn Laan

unread,
Jun 3, 2022, 2:42:30 AM6/3/22
to inno...@googlegroups.com
Op 1-6-2022 om 23:51 schreef Andrew Truckle:
For example, this documentation plus example does not use a try / catch block nor tell us to use it:

Pascal Scripting: IsDotNetInstalled

The functionality to detect the .NET Framework root path (the {dotnet..} constants) and the functionality to detect the .NET Framework version (IsDotNetInstalled) are independant, have different requirements and should not be confused.

Greetings,
Martijn

Andrew Truckle

unread,
Jun 4, 2022, 2:19:14 PM6/4/22
to innosetup

Hi

I understand that. But you stated that it was documented to try / catch. Where in the help is it? I have missed it. 

Gavin Lambert

unread,
Jun 6, 2022, 7:02:59 PM6/6/22
to inno...@googlegroups.com
On 5/06/2022 06:19, Andrew Truckle wrote:
> I understand that. But you stated that it was documented to try / catch.
> Where in the help is it? I have missed it.

That's in the help for the {dotnet*} constants.

Wilenty

unread,
Jun 6, 2022, 8:23:38 PM6/6/22
to innosetup
Gavin wrote:
"That's in the help for the {dotnet*} constants."

I agree with you, it's written there: https://jrsoftware.org/ishelp/index.php?topic=consts&anchor=dotnet11

But, not there: https://jrsoftware.org/ishelp/index.php?topic=isxfunc_isdotnetinstalled

For new users of InnoSetup, or those who don't use much [code] it can be confusing or not understandable.

Martijn, can I ask you to add the description to use "Pascal Scripting: IsDotNetInstalled" in the try...except block in the [code] and in the example there?

Gavin Lambert

unread,
Jun 6, 2022, 10:46:49 PM6/6/22
to inno...@googlegroups.com
If it is the case that IsDotNetInstalled throws instead of returning
False then I would regard that as a bug-bug and not a doc-bug.

Looking at the implementation, it looks like the only condition that
might cause it to throw is if .NET 4.0 is installed but .NET 4.5 or
higher is not. Again, I would regard this as a bug in Inno.

Gavin Lambert

unread,
Jun 6, 2022, 11:00:07 PM6/6/22
to inno...@googlegroups.com
Mere moments ago, quoth I:
> If it is the case that IsDotNetInstalled throws instead of returning
> False then I would regard that as a bug-bug and not a doc-bug.
>
> Looking at the implementation, it looks like the only condition that
> might cause it to throw is if .NET 4.0 is installed but .NET 4.5 or
> higher is not.  Again, I would regard this as a bug in Inno.

Actually I might have misread the code. This is checking an internal
value, not the installed version. As such if that does throw then it
does indicate an internal problem in Inno, but there's also no good
reason for it to actually throw that I can see.

This thread has grown long and confusing enough (as well as being
disconnected from the original post at some point) that I don't think
it's entirely clear which code you're claiming throws when it shouldn't.

Can you please repost exactly that bit of code which is throwing
unexpectedly?

Wilenty

unread,
Jun 6, 2022, 11:21:27 PM6/6/22
to innosetup
Please look at the "InternalError(...);" from Martijn post: https://github.com/jrsoftware/issrc/blob/cb9c3e94593724ea062bb3070bb034abdd009652/Projects/DotNet.pas#L183

The main problem in short: InnoSetup throws (unexpected) internal error at user side.

Andrew Truckle

unread,
Jun 7, 2022, 12:25:06 AM6/7/22
to innosetup
The issue in this users case was as i described:

1. They HAD DOT NET installed.So the the linked comment about the expanded constant failing is misleading when it said that the framework was not istalled.
2. They DID NOT HAVE the App Path registry key detailing the location of DotNet.

That is a big difference. The constant failed to expand because the registry key was missing and not because the framework was not installed.

And I agree with other contributors to this discussion. The documentation needs to be consistent. If it is that important to use try / catch it would be advantageous to restate it in the IsDotNetInstalled doc. But I do feel the above warrants consideration.

Gavin Lambert

unread,
Jun 7, 2022, 2:56:26 AM6/7/22
to inno...@googlegroups.com
That does not answer my question. As I already stated, it should not be
possible to actually hit that InternalError line, unless you are somehow
passing invalid parameters or there is an internal memory corruption (or
some coding error that I am overlooking).

As such, your real problem is probably elsewhere.


On 7/06/2022 16:25, Andrew Truckle wrote:
> The issue in this users case was as i described:
[...]
> That is a big difference. The constant failed to expand because the
> registry key was missing and not because the framework was not
> installed.
The constant failing to expand is *entirely* unrelated to
IsDotNetInstalled (as both Martijn and I have already stated). This is
just confusing the issue.

It is documented that trying to expand the constant can throw an
exception in some situations (including the key being missing). This
requires your script to protect against it, either via try/catch or via
Check or similar.

It is not documented that calling IsDotNetInstalled might, but on the
other hand as far as I can see there should not be any conditions (other
than programmer error, either in Inno itself or by a very badly behaved
user script) that this exception could actually be thrown in the first
place (hence why it's an *internal* error). In particular, the key
being missing or something not being installed will *not* cause this
exception. Thus you should *not* need to put it in a try/catch in your
script -- if it does somehow happen, something severe is wrong anyway
(and not just what they have installed).


Hence, again: please (re)post actual MCVE code that throws an exception
unexpectedly.

Martijn Laan

unread,
Jun 7, 2022, 3:23:48 AM6/7/22
to inno...@googlegroups.com
Op 7-6-2022 om 02:23 schreef Wilenty:
Martijn, can I ask you to add the description to use "Pascal Scripting: IsDotNetInstalled" in the try...except block in the [code] and in the example there?

IsDotNetInstalled returns False to indicate failure instead of throwing an exception, as documented.

Greetings,
Martijn

Gavin Lambert

unread,
Jun 7, 2022, 3:25:57 AM6/7/22
to inno...@googlegroups.com
Mere moments ago, quoth I:
> It is documented that trying to expand the constant can throw an
> exception in some situations (including the key being missing).  This
> requires your script to protect against it, either via try/catch or via
> Check or similar.

Further to this, I should add that on further inspection I have noticed
that it is indeed possible (though unlikely, where compatible parameters
are used) for IsDotNetInstalled to return True while expanding the
constant still throws.

As such, it's not safe to use Check: IsDotNetInstalled(...) to try to
protect usage of a {dotnet*} constant (if perhaps that is what you were
assuming).

Instead, you should try to expand it inside a try/catch block somewhere
(e.g. InitializeSetup or PrepareToInstall) and use the result of that
for your Check (or cache the resulting path and use that instead of
re-expanding the constant).

Wilenty

unread,
Jun 7, 2022, 6:43:02 AM6/7/22
to innosetup
To Gavin: it's not my problem, but Andrew problem.

Sorry Martijn but you were the right, it throws the error only in the "{dotnet*}". Andrew wrote about the "Pascal Scripting: IsDotNetInstalled" and we followed him unnecessarily. (Probably I was tired yesterday and I missed that.)

Today I created example script and checked it with existing registry entry "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\InstallRoot" and without it.

The results I show on the screenshots.
With:
With_InstallRoot_Reg-Key.png
Without:
Without_InstallRoot_Reg-Key.png

Andrew uses the [files] section, for example:

Filename: "{dotnet40}\regasm.exe"; (...)
Filename: "{dotnet4064}\regasm.exe"; (...)

So, it calls the function "ExpandConstant(...)" in the IS code with the above constants.

As I understand correctly, Andrew's installer can't continue installation because the registry key "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\InstallRoot" is missing at the client side, even if the .NET is installed and works. So, Andrew's installer can't continue and breaks whole installation with error message (about which Andrew is a bit annoying).

I leave this conversation, because it should be discussion between the Andrew (OP) and the Martijn. There's nothing more to add here.

Andrew Truckle

unread,
Jun 7, 2022, 7:34:17 AM6/7/22
to inno...@googlegroups.com
Thanks guys. Wilenty has shown and explained it.
But I too am gonna leave this. In the end it all boils down to what I have repeated stated:

InstallRoot is assumed to exist if the framework is installed, and in this users case it was not and thus the internal error.

Atleast it is all noted here for others benefit if they encounter the issue and it is up to Martyn if he wants to do anything. I take on board all the suggestions but to be honest I don't think I have ever "tested" any constant for expansion in a try / catch block until this issue appeared :)

Virus-free. www.avast.com

--
You received this message because you are subscribed to a topic in the Google Groups "innosetup" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/innosetup/u3ty6tfi4Ek/unsubscribe.
To unsubscribe from this group and all its topics, send an email to innosetup+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/innosetup/c6db38dc-798f-4e3b-8547-16eae52a423fn%40googlegroups.com.

Gavin Lambert

unread,
Jun 7, 2022, 7:44:59 PM6/7/22
to inno...@googlegroups.com
On 7/06/2022 23:34, Andrew Truckle wrote:
> Atleast it is all noted here for others benefit if they encounter the
> issue and it is up to Martyn if he wants to do anything. I take on board
> all the suggestions but to be honest I don't think I have ever "tested"
> any constant for expansion in a try / catch block until this issue
> appeared :)

It's behaving as documented; it's up to you to check that the constants
are valid before using them, as previously described.
Reply all
Reply to author
Forward
0 new messages