Getting Quest 5.7 certified

Quest 5.7 is nearly ready for release, but I have hit an issue which I thought I would offer for discussion. This is only about the desktop version.

When you install software on a Windows PC you get a "User Account Control" message, asking you to confirm that you really want to install it. This has a friendly form, which you will see if you install Quest 5.6, and a scary form, with bright orange and a warning triangle, saying the publisher is untrusted.

Alex was certified as an open source developer with Certum, originally for free, recently for €14. I would have no problem paying that, but now Certum are charging €135 (including a USB reader). Another company will do it for $84 apparently, but still not a trivial amount. I had no idea I would have to pay that sort of money to keep Quest going (and neither did Alex!). There are also various hoops to jump through to prove I am me.

So I could ask for donations. I have a suspicion that would get the money with no problem, but that would involve setting up some way to donate, so more hassle.

Or not bother. Does it matter if it has the scary warning? I doubt most of the regulars here would worry, but the real issue is how it will impact on new users. I would guess most people try the web version first, and I imagine that would help build trust.

Do I release 5.7 with the scary warning and see how it goes and look at a better solution for 5.8 if it seems to have a bad impact (and how do we measure that)?

Just go with the scary warning and ask the web admin to update the blurb on the download page giving people a heads up about it.
Obvs I'd donate if you decide to go that route.


I'd definately post this information on the website (explain the situation with the money needed to be 'officially trusted/certified' and explain what the 'officially trusted/certified' is even about, and how it relates to the person's computer's UAC warning), and just go with the non-trusted/certified, and see if it becomes an issue of people worrying about not having that 'trusted/certified' official-label/guarantee, and if it does... then can go about how to pay/fund it... if you don't mind the hassle of it...

Is/does Quest 5.7 have better error messaging???
At least a line number for an error message???

I just used Outlook as a spell checker to correct my bad spelling...
Between correcting description misspelling, and a cat that likes to walk on my keyboard...
I now got the dreaded...
"failed to load game due to the following errors:
Error: Object reference not set to an instance of an object"
I assume that means I have a room exit to a room that does not exist...
or something similar...
(somewhere in 500 lines of code!!!)

I think we have a solution (thanks to Luis).

DarkLizerd, some error messages are improved, in particular in the text processor. However, this update does not change the underlying C# or Visual Basic, as I have yet to get my head round that. When you find the error, let me know what caused it, so I can reproduce it and perhaps sort it for 5.8.

I know VB....
Any chance I could help there?
I've re-read every line 3 times... nothing seems to be out of place.

You need to know .NET, using C# and VB. If you do, then sure! They is a guide to getting going here:

To trouble-shoot, I would back up your game, then cut chunks out of it. Delete the commands, and see if it will load. Delete a few rooms, and see if it will load. Delete a few more. Etc. Then delete functions. Each step you need to also delete any reference to the things you delete, eg exits goings to the rooms you are deleting. Eventually you should find it loads okay, and you will know it was in the bit you just deleted.

Sorry... just VB6... Never dove into
And thanks, I'll try "deleting" exits and find out that way...

I think I may have found it...
"white spaces"
Space= h20
but outlook inserted "other white spaces" that replaced h20...
IE: hc2 ha0
can't see them, but they trip-up quest...
I will need some time to replace all the spaces to see if that works...

Either the white spaces was the issue, or a room that got deleted...
Between coping and pasting between 2 copies of my game, I got it working again....

Good (though it wouldf have been useful to know exactly what caused it).

I think, if Quest would have loaded my game, despite the error, I may have noticed the missing room...
Could that feature be added to Quest 5.8???

I'd just go with the scary warning, and tell newcomers not to freak out about it.

We may well be going for the scary warning. I have been trying to get a certificate from KSoft/Comodo, and after paying the money, they are now demanding certified copies of my passport, utilities bill and phone bill, and also to register my company with Dun and Bradstreet.

ETA: In fairness to KSoft, they responded quickly admitting that Comodo had "made the individual validation requirements very difficult" and have refunded my money.

Why not do it the proper way?

Does Quest need administrated/elevated privileges? Does Quest perform administrative tasks? No?

Install Quest into C:\Users[usernamehere]\AppData\Local\Programs\Quest\ for example. (do not use that url directly though, please use the correct API calls to get the local folder of the current user).
No need for elevation, no scary warning prompts.

Microsoft created the UAC primarily to force developers to stop requiring admin privileges.

For WIndows 7 and later see
FOLDERID_UserProgramFiles {5CD7AEE2-2219-4A67-B85D-6C9CE15660CB} will give you the path to %LocalAppData%\Programs

For Windows Vista and older see for more info, the CSIDL you are looking for is {F1B32785-6FBA-4FCF-9D55-7B8E7F157091} also known as %LOCALAPPDATA% or %USERPROFILE%\AppData\Local
And just make a application folder under that.

I avoid software that require elevation, even I do not need a elevated user most the working day. And most programs that require elevation tend to install under the wrong user, so that the shortcuts etc. are on the admin account rather than the current user account that I'm actually using daily.

If a administrator wishes to install it elevated they can simply right click the installer and manually do that. You can even detect that and offer to install at the Known folder for all users, or simply just prompt the admin for the path.

My suggestion, default to the appdata local folder, but let the user choose another location if they want.

PS! Make sure the manifest for the installer is set to requestedExecutionLevel level="asInvoker"

PPS! A object code signing certificate only have two advantages, it provides a way to check if the file has been manipulated (you can post CRC32 and MD5 and SHA1 and SHA256 and SHA512 hashes of the installer on the download page and people can check themselves if they are worried. The other advantage is that you probably won't get the "this files was downloaded from the internet" but that should go away once enough people have downloaded it (as Microsoft's virus checker will get a report back from Microsoft that the installer file is "widespread" and no known issues). The site has https and so does github so "safe" download is not an issue either.

Roger Hågensen, interesting suggest. That is not the proper way, however, Appdata is for data, not software. That is not to say developers do not use it for software, and that may be an option.

I have recently installed JRuby and Libre Office, two big open source projects, and both have the scary orange warning when installing, and so I am less bothered about this than I was.

@The PIxie
AppData is the proper location, as per. Microsoft themselves,

I do notice I stated the wrong path though. It should be %LocalAppData%\Programs (I'll edit the post above)
But I blame that on me not finding the CSIDL (which does not exist for this as per user program install is only added to Windows 7 and later. With prior version of Windows it's OK to just make a application folder in %LocalAppData%

JRuby and Libre Office probably ask for admin access due to Java, however they do not need to do that as Java could be run from the application's folder as well. With later Windows versions you can't go all bonkers with filetypes/handlers anyway (Windows 10 will ensure the user has to set up such instead)
There is no reason why LIbre Office should require admin access to be installed (does it require root access on Linux too?)
Admin/root access is bad behaviour, especially if the software is not part of/integrate with the OS directly, Anti Virus or Firewalls or security software can understand. But word processing, nope.
And half the software that demand admin on install screw things up anyway, the shortcut icons in the startmenu and desktop end up on the admin desktop and not under my actual user (which I installed from).

This stuff isn't hard to do, I'm a dev and it's easy to do with something like NSIS3.

Just to put my mouth where my foot is, this is NSIS3 script used for a actively used program/installer.

Note! The formatting on this forum is going bonkers with this, but it seems to be just the layout, the text seems unharmed so just copy'n'paste it all into notepad and save it as something.nsi and it should work.

The NSIS script uses FileFunc.nsh and LogicLib.nsh and WinVer.nsh but these are bundled with NSIS3.

;GridStream Player Installer

Unicode true
SetCompressor /SOLID lzma
CRCCheck on
XPStyle on
SetFont $(^Font) 9

Icon "GridStream Player Installer.ico"
UninstallIcon "GridStream Player Installer.ico"

!define COMPANYNAME "GridStream Productions"
!define COMPANYSITE ""
!define PROGRAMNAME "GridStream Player"
!define AUTHORNAME "Roger Hågensen"
!define PROGRAMID "{77585712-e0d0-11e1-b641-0008c7a4704e}"
!define DISKSPACE 2048


!define YEAR 2017

RequestExecutionLevel user

!define UNINSTALLKEY "Software\Microsoft\Windows\CurrentVersion\Uninstall${PROGRAMID}"

!include "WordFunc.nsh"
!insertmacro VersionCompare
!insertmacro un.VersionCompare

!define HWND_TOPMOST -1
!define SWP_NOSIZE 0x0001
!define SWP_NOMOVE 0x0002

VIProductVersion "${FILEVERSION}"
VIAddVersionKey "ProductName" "${PROGRAMNAME} Installer"
VIAddVersionKey "CompanyName" "${COMPANYNAME}"
VIAddVersionKey "LegalCopyright" "© ${YEAR} ${AUTHORNAME}, ${COMPANYNAME}"
VIAddVersionKey "FileDescription" "Installer for ${PROGRAMNAME}"
VIAddVersionKey "FileVersion" "${FILEVERSION}"
VIAddVersionKey "ProductVersion" "${FILEVERSION}"

InstallColors /windows

Caption "${PROGRAMNAME} Installer"
OutFile "${PROGRAMNAME} Installer.exe"
InstallDirRegKey ${HKREGISTRY} ${UNINSTALLKEY} "InstallLocation"

!define FOLDERID_UserProgramFiles "{5CD7AEE2-2219-4A67-B85D-6C9CE15660CB}"
!define KF_FLAG_CREATE 0x00008000
!include FileFunc.nsh
!include LogicLib.nsh

!include WinVer.nsh

Var isupdate
Var runprogram
Var installpath

ShowInstDetails show
ShowUninstDetails show

BrandingText "Version ${FILEVERSION}"

SubCaption 0 " "
SubCaption 1 " "
SubCaption 2 " "
SubCaption 3 " "
SubCaption 4 " "
UninstallSubCaption 0 " "
UninstallSubCaption 1 " "
UninstallSubCaption 2 " "

CompletedText "Done!"

UninstallText "Ready to begin the removal!" "Uninstall:"

SpaceTexts none none

ComponentText "Ready to begin the installation!" " " "Optional action(s):"

Page components skipIfUpdate
Page instfiles
UninstPage uninstConfirm
UninstPage instfiles

!define sysGetDiskFreeSpaceEx 'kernel32::GetDiskFreeSpaceEx(t, *l, *l, *l) i'

function FreeDiskSpace
System::Call '${sysGetDiskFreeSpaceEx}(r0,.,,.r1)'
; convert the large integer byte values into manageable kb
System::Int64Op $1 / 1024
; Return the free space
Pop $1

Function .onInit
;Our default for installpath. (UserProgramFiles is %LOCALAPPDATA%\Programs by default, so we use that as our default)
StrCpy $0 "$LOCALAPPDATA\Programs"
StrCpy $installpath "$LOCALAPPDATA\Programs"

;Make sure we don't overwrite $INSTDIR if specified on the command line or from InstallDirRegKey
${If} $INSTDIR == ""
	${If} ${AtLeastWin2000}
		${If} ${AtLeastWin7}
			;Windows 7 has a per-user programfiles "known" folder and this could be a non-default location!
			System::Call 'Shell32::SHGetKnownFolderPath(g "${FOLDERID_UserProgramFiles}",i ${KF_FLAG_CREATE},i0,*i.r2)i.r1'
			${If} $1 == 0
				System::Call '*$2(&w${NSIS_MAX_STRLEN} .r1)'
				StrCpy $0 $1
				System::Call 'Ole32::CoTaskMemFree(ir2)'
		;We only support Windows 2000 or later.
		MessageBox MB_OK|MB_ICONINFORMATION|MB_TOPMOST "Windows 2000 or later required!" /SD IDOK
	StrCpy $installpath $0
	IfFileExists "$INSTDIR\${PROGRAMNAME}.exe" InstallCheckVersion
	Goto InstallClean
	GetDLLVersion "$INSTDIR\${PROGRAMNAME}.exe" $R0 $R1
	IntOp $R2 $R0 >> 16
	IntOp $R2 $R2 & 0x0000FFFF ; $R2 now contains major version
	IntOp $R3 $R0 & 0x0000FFFF ; $R3 now contains minor version
	IntOp $R4 $R1 >> 16
	IntOp $R4 $R4 & 0x0000FFFF ; $R4 now contains release
	IntOp $R5 $R1 & 0x0000FFFF ; $R5 now contains build
	StrCpy $R0 "$R2.$R3.$R4.$R5" ; $0 now contains a string like ""
	${VersionCompare} "${FILEVERSION}" "$R0" $R0
	StrCmp $R0 "0" 0 InstallVersionSameNot
	MessageBox MB_YESNO|MB_ICONQUESTION|MB_TOPMOST "This version is currently installed!$\r$\rRe-Install v${FILEVERSION}?" /SD IDNO IDYES InstallReInstall
	StrCmp $R0 "2" 0 InstallVersionNewerNot
	MessageBox MB_OK|MB_ICONINFORMATION|MB_TOPMOST "The version installed is more recent!" /SD IDOK
	StrCpy $isupdate "true"

System::Call 'kernel32::OpenMutex(i 0x100000, b 0, t"${PROGRAMID}") i .r0 ?e'
System::Call 'kernel32::CloseHandle(i $0)'
Pop $0
${If} $0 == 127
	StrCpy $runprogram "true"
	MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION|MB_TOPMOST "${PROGRAMNAME} is running. Please close it before continuing!" /SD IDCANCEL IDOK InstallProgramNotRunning
	Goto InstallClean

IfFileExists "$INSTDIR" FolderExists
CreateDirectory "$INSTDIR"
StrCpy $0 "$INSTDIR"
Call FreeDiskSpace
StrCpy $2 ${DISKSPACE}
System::Int64Op $1 > $2
Pop $2
IntCmp $2 1 InstallCleanOk
MessageBox MB_OK|MB_ICONEXCLAMATION|MB_TOPMOST "Not enough disk space! (${DISKSPACE} KB needed)" /SD IDOK


Function .onInstSuccess
StrCmp $runprogram "true" 0 InstallSkipRunProgram

Function skipIfUpdate
StrCmp $isupdate "true" 0 +2

Function .onGUIInit
System::Call "User32::SetWindowPos(i, i, i, i, i, i, i) b ($HWNDPARENT, ${HWND_TOPMOST}, 0, 0, 0, 0, ${SWP_NOMOVE}|${SWP_NOSIZE})"

Function un.onGUIInit
System::Call "User32::SetWindowPos(i, i, i, i, i, i, i) b ($HWNDPARENT, ${HWND_TOPMOST}, 0, 0, 0, 0, ${SWP_NOMOVE}|${SWP_NOSIZE})"

Section "-hidden GridStream Player"
SectionIn RO

IfFileExists "$INSTDIR\${PROGRAMNAME}.exe" 0 InstallStarting
IfErrors 0 +3
MessageBox MB_OK|MB_ICONEXCLAMATION|MB_TOPMOST "Unable to remove old installation!" /SD IDOK

SetOutPath "$INSTDIR"
File /a /r "${PROGRAMNAME}\*.*"
WriteUninstaller "$INSTDIR\${PROGRAMNAME} Uninstaller.exe"

${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2
IntFmt $0 "0x%08X" $0
WriteRegDWORD ${HKREGISTRY} ${UNINSTALLKEY} "EstimatedSize" "$0"

WriteRegExpandStr ${HKREGISTRY} ${UNINSTALLKEY} "UninstallString" '"$INSTDIR\${PROGRAMNAME} Uninstaller.exe"'
WriteRegExpandStr ${HKREGISTRY} ${UNINSTALLKEY} "InstallLocation" "$INSTDIR"
WriteRegExpandStr ${HKREGISTRY} ${UNINSTALLKEY} "DisplayIcon" "$INSTDIR\${PROGRAMNAME}.exe,0"


StrCmp $isupdate "true" 0 InstallSkipDesktopShortcutUpdate
IfFileExists "$DESKTOP\${PROGRAMNAME}.lnk" 0 InstallSkipDesktopShortcutUpdate


Section /o "Create a desktop shortcut"

Section /o "Start program after installation"
StrCpy $runprogram "true"

Function un.onInit

Section "Uninstall"

System::Call 'kernel32::OpenMutex(i 0x100000, b 0, t"${PROGRAMID}") i .r0 ?e'
System::Call 'kernel32::CloseHandle(i $0)'
Pop $0
${If} $0 == 127
	MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION|MB_TOPMOST "${PROGRAMNAME} is running. Please close it before continuing!" /SD IDCANCEL IDOK UnInstallProgramNotRunning
	Goto UnInstall

IfFileExists "$APPDATA\${PROGRAMID}" 0 UnInstallKeepPreferences
MessageBox MB_YESNO|MB_ICONQUESTION|MB_TOPMOST "Keep ${PROGRAMNAME} preferences?" /SD IDYES IDYES UnInstallKeepPreferences
IfErrors 0 +3
MessageBox MB_OK|MB_ICONEXCLAMATION|MB_TOPMOST "Unable to remove installation!" /SD IDOK


Log in to post a reply.