- NSIS Discussion
- Capturing Error returned from UAC::ExecCodeSegment
Archive: Capturing Error returned from UAC::ExecCodeSegment
mj_blue
14th December 2009 14:40 UTC
Capturing Error returned from UAC::ExecCodeSegment
Hi,
I have the scneario that I need to check the state of a user registry key and if that key exists then do some work that is required to be ran as admin.
I used the Code:
Function un.CheckVSPluginInstall
ReadRegStr $2 HKCU "SOFTWARE\Company\Product" "VSSupport"
FunctionEnd
ClearErrors
GetFunctionAddress $0 un.CheckVSPluginInstall
UAC::ExecCodeSegment $0
IfErrors noVSplugin 0
#DO the admin things
novsplugin:
This has always appeared to work but on Vista it seem that it doesn't as when the VSSupport key is not there no Error is flagged back from the un.CheckVSPluginInstall function.
This works okay in XP but not in Vista when running as a non-admin user
This seems like a common thing to do and I'm sure it used to work..I'm using v0.0.11d of UAC
How do othe rpeople do this type of thing?
Anders
14th December 2009 16:05 UTC
You need to switch to v0.2, it synchronizes the registers both ways (Not sure if it handles the error flag, if not, use a register)
mj_blue
14th December 2009 16:14 UTC
I did just download V0.2.1, so If I use a register in the Function I can query it in the main admin code? If that is the new functionality in V0.2.1 this solves a lot of the workarounds I have in place and is the missing link for this plugin.
I'll give that a go
Thanks
Mark
mj_blue
14th December 2009 22:28 UTC
Hi Anders,
I'll admit I'm slightly confused. I have upgraded my AUC.sh and UAC.dll (ANSI version) but none of the UAC:: commands now work, I get:
Invalid command: UAC::ExecCodeSegment
lookig athe trace it only seems to load:
- UAC::_
whereas in previous version it loads:
- UAC::Exec
- UAC::ExecCodeSegment
- UAC::ExecWait
- UAC::GetElevationType
- UAC::GetOuterHwnd
- UAC::GetShellFolderPath
- UAC::IsAdmin
- UAC::RunElevated
- UAC::ShellExec
- UAC::ShellExecWait
- UAC::StackPush
- UAC::SupportsUAC
- UAC::Unload
I may be missing something and it's obvious but the Main wiki plugin page still shows these commands as the ones to use
Anders
14th December 2009 23:25 UTC
you need to use the uac.nsh header file
fashtas
21st December 2009 06:31 UTC
Originally posted by Anders
you need to use the uac.nsh header file
I have the same issue. The code I have working with v0.0.11d compiles fine, but if I replace the uac.nsh (into includes) and the uac.dll (into plugins) from v0.2.1 all that shows up is UAC::_ and it obviously can't find the ExecCodeSegment stuff
I tried:
!include UAC.nsh
but that made no difference. And in fact was there already anyway
I was trying to upgrade to 0.2.1 so I could capture returns from ExecCodeSegments
MSG
21st December 2009 07:17 UTC
Allow me to expand on Anders' statement:
You need to use the new macros in the uac.nsh header file.
fashtas
21st December 2009 08:57 UTC
Originally posted by MSG
Allow me to expand on Anders' statement:
You need to use the new macros in the uac.nsh header file.
Ahh thanks for that, I went through the header looking for the old functions and could not find references to them so thought maybe I was using the wrong nsh or something.
For anyone else, old code like:
GetFunctionAddress $0 GetInstallPath
UAC::ExecCodeSegment $0
can be easily replaced with
!insertmacro UAC_AsUser_Call Function GetInstallPath ${UAC_SYNCREGISTERS}
Without documentation, I am unsure what the .oninit code is supposed to be, the examples have a lot of stuff in them and not sure what is required. I'm currently using:
!insertmacro UAC_PageElevation_OnInit
${If} ${UAC_IsInnerInstance}
${AndIfNot} ${UAC_IsAdmin}
SetErrorLevel 0x666666 ;special return value for outer instance so it knows we did not have admin rights
Quit
${EndIf}
I am unsure about the uninstaller (if it needs to be elevated?) and any UnLoad requirements. Still, it's a start, thanks! I'll fiddle around more to see whats needed
mj_blue
21st December 2009 09:10 UTC
Originally posted by fashtas
For anyone else, old code like:
GetFunctionAddress $0 GetInstallPath
UAC::ExecCodeSegment $0
can be easily replaced with
!insertmacro UAC_AsUser_Call Function GetInstallPath ${UAC_SYNCREGISTERS}
Thanks for this. I assumed it needed re-writing to use new syntax and this looked like the correct call but wasn't sure of the parameters.
I'll have a go at making all these changes and see what happens.
MSG
21st December 2009 09:54 UTC
Without documentation, I am unsure what the .oninit code is supposed to be, the examples have a lot of stuff in them and not sure what is required. I'm currently using:
!insertmacro UAC_PageElevation_OnInit
${If} ${UAC_IsInnerInstance}
${AndIfNot} ${UAC_IsAdmin}
SetErrorLevel 0x666666 ;special return value for outer instance so it knows we did not have admin rights
Quit
${EndIf}
I am unsure about the uninstaller (if it needs to be elevated?) and any UnLoad requirements. Still, it's a start, thanks! I'll fiddle around more to see whats needed
Of course you'll also need to *do* something with that 0x666666 return value you set. Use it after you call the self-elevation macro:
!insertmacro UAC_RunElevated
${If} $2 = 0x666666 ;our special return, the new process was not admin after all
MessageBox mb_iconExclamation "You need to login with an account that is a member of the admin group to continue..."
Abort
${EndIf}
fashtas
21st December 2009 10:49 UTC
Originally posted by MSG
Of course you'll also need to *do* something with that 0x666666 return value you set. Use it after you call the self-elevation macro:
Thanks again :) After reading what you had there and re-reading the example apps, I realize that the UAC_AdminOnly.nis has a good example of the onInit code too!
fashtas
21st December 2009 11:16 UTC
Hurm, it seems to work well now, a few issues with the Uninstaller (But I haven't yet looked at that, I have a feeling I am doing stuff to admin that should be done to user)
One issue is if you run the installer from (say) explorer, the Installer appears BEHIND any forms on the screen. I looked at:
Function GuiInit
!insertmacro UAC_PageElevation_OnGuiInit
FunctionEnd
but wasn't too sure if this was the right direction. I also know BringToFront doesn't work on Vista/Win7 after MS changed it. Are there any recommendations?
Anders
21st December 2009 12:54 UTC
The init stuff is for page jumping (Elevation on a installer page like UAC_DualMode)
@fashtas: Are you doing the elevation in .onInit? That can cause focus issues since at some point, there is no window
fashtas
21st December 2009 20:08 UTC
Originally posted by Anders
@fashtas: Are you doing the elevation in .onInit? That can cause focus issues since at some point, there is no window
Yes I am, in fact I am doing the Elevation in the same way as the UAC_AdminOnly example, although my installer is using the MUI GUI stuff.
I moved the elevation to a custom pre_ function of the first visible window and the forms now show up on top of everything.
I have to run through some tests now (and uninstall the right stuff now), but otherwise it seems to be working nicely, thanks very much for the help everyone!