Archive: Need help enforcing .Net installation.


Need help enforcing .Net installation.
I have run into this issue in the past, I thought I had it licked, but I have recently gotten some reports from users that .net 4 is not installing on their system as intended. I have a specific section of my installer set up to handle the .net installation.

Basically what is going on is at the start of our programs installation it checks to ensure that the client has .net4 full on their system, if not, then installs the bootstrapped file. However on some systems it seems that rather then install the file, the installer just keeps on going.

For now I will post the section dealing with dot net, if needed I can post more.


Section ".Net" SEC01
SetOutPath "$INSTDIR"
SetOverwrite ifnewer

; Begin Check .NET version
StrCpy $InstallDotNET "No"
${If} ${DOTNETVER_4_0} HasDotNetFullProfile 1
StrCpy $InstallDotNet "No"
${EndIf}
${If} ${DOTNETVER_4_0} HasDotNetFullProfile 0
StrCpy $InstallDotNET "Yes"
${EndIf}

; Get .NET if required
${If} $InstallDotNET == "Yes"
MessageBox MB_YESNO "Microsoft .NET 4 is required to run this application. Install the Microsoft .NET Framework 4 Redistributable?" /SD IDYES IDNO endNetCF
File "..\..\Redist\dotNetFx40_Full_x86_x64.exe"
ExecWait "$INSTDIR\dotNetFx40_Full_x86_x64.exe"
${EndIf}
endNetCF:
Delete "$INSTDIR\dotNetFx40_Full_x86_x64.exe"

SetDetailsView show

; Install Files
; save install location
WriteRegStr ${PRODUCT_DIR_ROOT_KEY} "${PRODUCT_DIR_REGKEY}" "InstallLocation" "$INSTDIR"
SectionEnd

How is the macro "${DOTNETVER_4_0}" defined?

Also I would add some more verbose output to installer, so you can find out whether it is your .NET detection that failed to detect the missing .NET framework or the installer that failed to execute.


I can tell you with almost perfect certainty that it has to do with the exewait function not waiting on some systems. I searched around a bit over the weekend, and I am a little unclear about how to resolve that problem; it would seem there is something I can add to the specific line, like

ExecWait "$INSTDIR\dotNetFx40_Full_x86_x64.exe /norestart /passive /showfinalerror"

but I am unclear where these arguments are found, and there does not seem to be a specific one for my installer, that or I am not looking for the right thing.

The Installer in question works fine on an XP 32/64, and on all the windows 7 32/64 machines I have set up in a VM environment. However it seems to fail on just a few systems; since these are client machines, I have limited information about their systems/settings, and I am not sure what I am looking for.

The macro is defined in an add on written by David Grinberg you can check it out here
Homepage: http://ontheperiphery.veraida.com/


Try like this:

ExecWait `"$INSTDIR\dotNetFx40_Full_x86_x64.exe" /norestart /passive /showfinalerror`


It's important to enclose command-line arguments that might contain whitespaces within quotes, such as the path to the installer! However you must put the whole command-line into quotes (a different kind of quotes), because ExecWait expects a single operand.

Also be aware that some installer executable (SFX files), which have not been made with NSIS, will only extract the setup files to some folder and then invoke the actual installer program from there. In that case 'ExecWait' would only wait for the first executable, but not for the second executable that was launched by the first one. This can still work if the first executable waits for the second one. But if it doesn't, then it won't work. AFAIK an ExecWait() that will also wait for all child-processes of the created process doesn't exist in NSIS.

AFAIK an ExecWait() that will also wait for all child-processes of the created process doesn't exist in NSIS.
That seems to be the general consensus, however that must be a consistent way of installing things such as .NET or other redistributes, otherwise the usefulness of this software drops dramatically. How can one use software like this that may install your product correctly on a consumers computer. As it stands I can tell users to manually install .NET4 full so our software will run, but I do not want to spend my day answering calls and explaining that. I can't be the only one in this community that is attempting to install a redistributable, and has run into this child process issue. I don't know that I am approaching this the write way, so I am open to suggestions on how to resolve this.

Originally posted by siegeon
That seems to be the general consensus, however that must be a consistent way of installing things such as .NET or other redistributes, otherwise the usefulness of this software drops dramatically.
Well, that's something to complain about at the author of the redistributable :rolleyes:

Originally posted by siegeon
How can one use software like this that may install your product correctly on a consumers computer. As it stands I can tell users to manually install .NET4 full so our software will run, but I do not want to spend my day answering calls and explaining that.
1) Don't use .NET, there are plenty of alternatives that don't require to user to install a bloated framework separately. With GUI framworks like Qt or WxWidgets you put a few runtime DLL's into the install folder (or even link everything statically into the EXE file) and that's it.

2) Add the required version of the .NET framework to the system requirements of your software and simply abort setup with an error message, if the framework is not installed yet. AFAIK obtaining the .NET framwrok via Windows Update is the recommend way anyway. But you can also offer the user to open the .NET download site in the browser, within your error message dialog.

Originally posted by siegeon
I can't be the only one in this community that is attempting to install a redistributable, and has run into this child process issue. I don't know that I am approaching this the write way, so I am open to suggestions on how to resolve this.
As said before, if that is really the problem, it's a problem of the individual redistributable installer and only the developers of the installer could fix the issue. If a self-extractor extracts setup files and then launches setup, the self-extractor is supposed to wait for the setup program to terminate and perform a clean-up afterwards. At least when running in non-interactive mode.

(I don't use .NET, but all other redistributable installers I came across so far work that way. And it would be strange if only .NET doesn't)

Sorry to come off as a complainer, that is not the case. I don't really have time to learn and port over to QT, I have inherited this software from a previous developer, and the rate at which I have to create deliverables prevents me from making any meaningful or fundamental changes, let alone learn a system like QT. I have enough time to get small things done here and there. I was hoping to keep things in the installer department about the same for the newest version of the software. Ill keep looking; thanks again.


Another option would be:

Manually extract the .NET installer redistributable package. Something like 7-Zip or Universal Extractor should be able to do the job. Then make your installer extract the .NET setup files to a temporary folder (you can use $PLUGINSDIR or a sub-folder thereof) and let ExecWait() run the actual installer executable directly. NSIS will clean-up the $PLUGINSDIR folder automatically when the installer exists.


Now that is not a bad idea Mulder; I will see if I cant get that to work, all in all I am very green when it comes to this installer software and I am learning as I go. Thank you for the time you spend on this!


Today I started the above mentioned process, since I'm still new to NSIS I am not sure that I have gone about this correctly.

I extracted all of the files from the redistributable placing them in a folder called redist.

Then I edited the code (see bold lines below) but the installer now does not want to install, am I missing a step?


Section ".Net" SEC01
SetOutPath "$INSTDIR"
SetOverwrite ifnewer

; Begin Check .NET version
StrCpy $InstallDotNET "No"
${If} ${DOTNETVER_4_0} HasDotNetFullProfile 1
StrCpy $InstallDotNet "No"
${EndIf}
${If} ${DOTNETVER_4_0} HasDotNetFullProfile 0
StrCpy $InstallDotNET "Yes"
${EndIf}

; Get .NET if required
${If} $InstallDotNET == "Yes"
MessageBox MB_YESNO "Microsoft .NET 4 is required to run this application. Install the Microsoft .NET Framework 4 Redistributable?" /SD IDYES IDNO endNetCF
SetOutPath "$PLUGINSDIR"
File /nonfatal /r "..\..\Redist\*.*"
ExecWait "$PLUGINSDIR\Setup.exe"

${EndIf}
endNetCF:
Delete "$INSTDIR\dotNetFx40_Full_x86_x64.exe"

SetDetailsView show

; Install Files
; save install location
WriteRegStr ${PRODUCT_DIR_ROOT_KEY} "${PRODUCT_DIR_REGKEY}" "InstallLocation" "$INSTDIR"
SectionEnd


I'd probably use:

SetOutPath "$PLUGINSDIR\dotNetInstall"
File /r "..\..\Redist\*.*"
ExecWait '"$PLUGINSDIR\dotNetInstall\Setup.exe" <more parameters>'

Ha, turns our Microsoft locked down this installer, you can not run it directly from the Setup.exe and their command line parameter options are weak sauce. Other then chainingpackage I have tried them all, but to no avail. Though I understand the problem much better now, thank you.

/q
/norestart
/repair
/chainingpackage


I've no problem installing the .Net redistributable from my setup. Try:

ExecWait '$INSTDIR\dotnetfx40_Full_x86_x64.exe /passive /log $INSTDIR\Log\dotNetFx40.log /c:"Install /q"'


@lim56:
You are missing quotes around the executable path.

Stu


Yes, you're right, to handle spaces in the executable path as pointed out before.


Thank You
Thank you Thank you Thank.