UAC - Required Elevation and Privileges

You can share your experience with HMG. Share with some screenshots/project details so that others will also be benefited.

Moderator: Rathinagiri

User avatar
Pablo César
Posts: 4059
Joined: Wed Sep 08, 2010 1:18 pm
Location: Curitiba - Brasil
Has thanked: 100 times
Been thanked: 182 times

UAC - Required Elevation and Privileges

Post by Pablo César » Mon Jan 16, 2017 4:04 pm

Ok Serge, good to know all is clear. These examples can be of great help to others and serve as a reference.

Especially when you need to write in the Windows's REGISTRY. Some keys are strict with rights must be elevated. Otherwise it will be not able to write it.

Have you Serge understood the difference between the four examples I posted ?

After this experience, you will see to my new project (HMG utility) which I will finish soon. ;)
HMGing a better world
"Matter tells space how to curve, space tells matter how to move."
Albert Einstein

User avatar
srvet_claudio
Posts: 2044
Joined: Thu Feb 25, 2010 8:43 pm
Location: Uruguay
Has thanked: 35 times
Been thanked: 147 times
Contact:

Post by srvet_claudio » Mon Jan 16, 2017 10:07 pm

Pablo, creo que no necesitas la mascara
SEE_MASK_NOCLOSEPROCESS
Sin esa máscara no es necesario matar el proceso.
Best regards.
Dr. Claudio Soto
(from Uruguay)
http://srvet.blogspot.com

User avatar
Pablo César
Posts: 4059
Joined: Wed Sep 08, 2010 1:18 pm
Location: Curitiba - Brasil
Has thanked: 100 times
Been thanked: 182 times

Post by Pablo César » Mon Jan 16, 2017 10:13 pm

Ahhh bueno gracias Claudio.
 
Voy a probar y haré cambios para saber si la función fué ejecutada o no.
HMGing a better world
"Matter tells space how to curve, space tells matter how to move."
Albert Einstein

User avatar
Pablo César
Posts: 4059
Joined: Wed Sep 08, 2010 1:18 pm
Location: Curitiba - Brasil
Has thanked: 100 times
Been thanked: 182 times

Post by Pablo César » Mon Jan 16, 2017 11:03 pm

Probé con SEE_MASK_FLAG_DDEWAIT pero lamentablemente no hay como dejar de matar el proceso y al mismo tiempo obtener el retorno cuando el UAC permite o no la ejecucion. Volví con SEE_MASK_NOCLOSEPROCESS e hice esta alteraciones:

Code: Select all

HB_FUNC( SHELLEXECUTEEX )
{
    SHELLEXECUTEINFO SHExecInfo;
    ZeroMemory(&SHExecInfo, sizeof(SHExecInfo));

    SHExecInfo.cbSize       = sizeof(SHExecInfo);
    SHExecInfo.fMask        = SEE_MASK_NOCLOSEPROCESS;
    SHExecInfo.hwnd         = HB_ISNIL( 1 ) ? GetActiveWindow() : (HWND) HMG_parnl( 1 );
    SHExecInfo.lpVerb       = (LPCSTR) HMG_parc( 2 );
    SHExecInfo.lpFile       = (LPCSTR) HMG_parc( 3 );
    SHExecInfo.lpParameters = (LPCSTR) HMG_parc( 4 );
    SHExecInfo.lpDirectory  = (LPCSTR) HMG_parc( 5 );
    SHExecInfo.nShow        = hb_parni( 6 );
    
    if( ShellExecuteEx(&SHExecInfo) )
    {
        CloseHandle(SHExecInfo.hProcess);
		hb_retnl( (LONG) SHExecInfo.hProcess );
	}	
	else 
	{
		CloseHandle(SHExecInfo.hProcess);
		hb_retnl(0);
	}
}
 
De esta forma en el PRG me quedó mejor asi, porque pude implemetar las dos cosas que quiero (retorno y que no quede ningún proceso abierto):
 

Code: Select all

If ShellExecuteEx( , 'runas', cFileRun, "/ADMIN", , SW_SHOWNORMAL ) > 0 // Re-run app (recursive method)
   hb_IdleSleep( 1 )
Endif
Quit
 
Es redundante la forma que lo hice ? Le dí tiempo con hb_IdleSleep para que el proceso no quede abierto y no deje de ejecutarlo.
 
Googled
 
I tried with SEE_MASK_FLAG_DDEWAIT but unfortunately there is no way to stop killing the process and at the same time get the feedback when the UAC allows execution or not. I came back with SEE_MASK_NOCLOSEPROCESS and made these changes:

This way in the PRG it was better this way, because I could implement the two things I want (return and that there is no process open):

Is it redundant the way I did it? I gave time with hb_IdleSleep so that the process does not remain open and do not stop executing it.
HMGing a better world
"Matter tells space how to curve, space tells matter how to move."
Albert Einstein

User avatar
srvet_claudio
Posts: 2044
Joined: Thu Feb 25, 2010 8:43 pm
Location: Uruguay
Has thanked: 35 times
Been thanked: 147 times
Contact:

Post by srvet_claudio » Mon Jan 16, 2017 11:27 pm

Usa la máscara SEE_MASK_NOASYNC para que retorne luego de terminada la ejecución.

Al inicio de la función tenes que poner:
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE)
Best regards.
Dr. Claudio Soto
(from Uruguay)
http://srvet.blogspot.com

User avatar
srvet_claudio
Posts: 2044
Joined: Thu Feb 25, 2010 8:43 pm
Location: Uruguay
Has thanked: 35 times
Been thanked: 147 times
Contact:

Post by srvet_claudio » Mon Jan 16, 2017 11:29 pm

En tu código anterior el
CloseHandle(SHExecInfo.hProcess);
del else no va.
Best regards.
Dr. Claudio Soto
(from Uruguay)
http://srvet.blogspot.com

User avatar
Pablo César
Posts: 4059
Joined: Wed Sep 08, 2010 1:18 pm
Location: Curitiba - Brasil
Has thanked: 100 times
Been thanked: 182 times

Post by Pablo César » Thu Jan 26, 2017 10:50 am

Hola Claudio, gracias por tus indicaciones. Estoy casi consiguiendo mejor resultado. Le hé agregado WaitForSingleObject y GetExitCodeProcess para garantir que puedo eliminar los archivos temporários pero la funcion me devuelve 0 o NIL y me gustaria que retorne .T. o .F.
 

Code: Select all

If ShellExecuteEx( , 'runas', cFileRun, cRunParam, , SW_HIDE )
   MsgInfo("Ok - Well done !")
Endif
// hb_IdleSleep( 1 )  // Not needs anymore: waiting time to deletes the file upto finish procedure
Delete File(cRunParam)

Code: Select all

HB_FUNC( SHELLEXECUTEEX )
  {
    DWORD code;
    SHELLEXECUTEINFO SHExecInfo;
    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
    ZeroMemory(&SHExecInfo, sizeof(SHExecInfo));
  
    SHExecInfo.cbSize       = sizeof(SHExecInfo);
    SHExecInfo.fMask        = SEE_MASK_NOASYNC;
    SHExecInfo.hwnd         = HB_ISNIL( 1 ) ? GetActiveWindow() : (HWND) HMG_parnl( 1 );
    SHExecInfo.lpVerb       = (LPCSTR) HMG_parc( 2 );
    SHExecInfo.lpFile       = (LPCSTR) HMG_parc( 3 );
    SHExecInfo.lpParameters = (LPCSTR) HMG_parc( 4 );
    SHExecInfo.lpDirectory  = (LPCSTR) HMG_parc( 5 );
    SHExecInfo.nShow        = hb_parni( 6 );
    
    if (ShellExecuteEx(&SHExecInfo) == FALSE || SHExecInfo.hProcess == NULL)
    {
        return -1;
    }
    
    WaitForSingleObject(SHExecInfo.hProcess, INFINITE);

    if (GetExitCodeProcess(SHExecInfo.hProcess, &code) == 0)
    {
        return -1;
    }

    return code;
    
  }
Sin dudas estoy haciendo mal. Me gustó probar con SUCCEEDED(nResult) pero a mi se me complica por saber poco... :oops:

Podrías corregirme el código ?
 
Googled
 
Hi Claudio, thank you for your directions. I'm almost getting a better result. I have added WaitForSingleObject and GetExitCodeProcess to ensure that I can delete temporary files but the function returns 0 or NIL and I would like it to return .T. Or .F.

No doubt I'm doing wrong. I like to try with SUCCEEDED (nResult) but it complicates me to know little ... :oops:

Could you correct my code ?
HMGing a better world
"Matter tells space how to curve, space tells matter how to move."
Albert Einstein

User avatar
srvet_claudio
Posts: 2044
Joined: Thu Feb 25, 2010 8:43 pm
Location: Uruguay
Has thanked: 35 times
Been thanked: 147 times
Contact:

Post by srvet_claudio » Thu Jan 26, 2017 4:16 pm

Pablo,
hb_retl ( TRUE | FALSE );
Best regards.
Dr. Claudio Soto
(from Uruguay)
http://srvet.blogspot.com

User avatar
Pablo César
Posts: 4059
Joined: Wed Sep 08, 2010 1:18 pm
Location: Curitiba - Brasil
Has thanked: 100 times
Been thanked: 182 times

Post by Pablo César » Thu Jan 26, 2017 10:45 pm

Gracias Claudio. Eso era óbvio y lo que más queria es saber si estaba correcto lo otro que agregué por ultimo.

Mismo asi, no puedo deletar el archivo scriptado porque no lo ejecuta. Pero si le doy un tiempito con hb_IdleSleep( 1 ) funciona.
Y otro inconveniente que hay es que mismo que el usuáriio responda "NO" ejecutar en la ventana del UAC, este lo dá como ejecutado.

Code: Select all

ShellExecuteEx( , 'runas', cFileRun, cRunParam, , SW_HIDE )
// hb_IdleSleep( 1 )  // Gives time to run and then deletes the file 
Delete File(cRunParam)
:(
 
Googled
 
Thank you Claudio. That was obvious and what I wanted most is to know if it was correct the other that I added last.

Same as that, I can not delete the scripted file because it does not execute it. But if I give it a little time with hb_IdleSleep (1) it works.
And another drawback is that even if the user responds "NOT" to execute in the window of the UAC, it gives it as executed.
HMGing a better world
"Matter tells space how to curve, space tells matter how to move."
Albert Einstein

User avatar
Pablo César
Posts: 4059
Joined: Wed Sep 08, 2010 1:18 pm
Location: Curitiba - Brasil
Has thanked: 100 times
Been thanked: 182 times

Post by Pablo César » Fri Jan 27, 2017 12:37 am

Creo haber conseguido con este código que acabo de alterar:

Code: Select all

HB_FUNC( SHELLEXECUTEEX )
  {
    DWORD code;
    SHELLEXECUTEINFO SHExecInfo;

    ZeroMemory(&SHExecInfo, sizeof(SHExecInfo));
  
    SHExecInfo.cbSize       = sizeof(SHExecInfo);
    SHExecInfo.fMask        = SEE_MASK_NOCLOSEPROCESS;
    SHExecInfo.hwnd         = HB_ISNIL( 1 ) ? GetActiveWindow() : (HWND) HMG_parnl( 1 );
    SHExecInfo.lpVerb       = (LPCSTR) HMG_parc( 2 );
    SHExecInfo.lpFile       = (LPCSTR) HMG_parc( 3 );
    SHExecInfo.lpParameters = (LPCSTR) HMG_parc( 4 );
    SHExecInfo.lpDirectory  = (LPCSTR) HMG_parc( 5 );
    SHExecInfo.nShow        = hb_parni( 6 );
    
    if (ShellExecuteEx(&SHExecInfo) == FALSE || SHExecInfo.hProcess == NULL)
    {
		hb_retnl(-1);
    }
    
    WaitForSingleObject(SHExecInfo.hProcess, INFINITE);

    if (GetExitCodeProcess(SHExecInfo.hProcess, &code) == 0)
    {
        hb_retnl(-1);
    }

    hb_retnl( (LONG) code );
    
  }
Le saqué la funcion CoInitializeEx y coloqué SEE_MASK_NOCLOSEPROCESS para fMask. Como ya le habia puesto WaitForSingleObject/INFINITE y la funcion WaitForSingleObject, pienso que no habrá problemas ni necesidad de encerrar el proceso. Lo bueno que no tengo más que poner hb_IdleSleep para despues apagar el archivo vbs.

Lo único que está diferente es que me devuelve 0 (cero) cuando es ejecutado consuceso y diferente de cero cuando no ejecuta, sea por respuesta NO del UAC o por otra causa. Totalmente diferente del enunciado sobre GetExitCodeProcess. Pero debe ser porque adiconé al final del vbs script: wscript.quit Err.number que me devuelve error cuando lo hay.

Interesante este mi aprendizaje. Nada mejor que aprender a los golpes... :)

Claudio si te parece válido hacer alguna observacion sobre mis cambios, bien venido será y buscaré testear tus sugerencias.

Gracias Claudio por tu atencion y ayuda.
 
Googled
 
I think I have gotten with this code that I have just altered:
 
<source code>
 
I took the CoInitializeEx function and placed SEE_MASK_NOCLOSEPROCESS for fMask. As I have already put WaitForSingleObject / INFINITE and the WaitForSingleObject function, I think there will be no problems or need to lock the process. The good thing I do not have to do is to put hb_IdleSleep to shut down the vbs file.

The only thing that is different is that it returns 0 (zero) when it is executed conspiracy and nonzero when it does not execute, either by NO response of the UAC or for another cause. Totally different from the GetExitCodeProcess statement. But it must be because I added at the end of the vbs script: wscript.quit Err.number which returns me error when there is.

Interesting is my learning. Nothing better than learning thru the blows ... :)

Claudio if it seems valid to you to make some observation about my changes, well it will be and I will try to test your suggestions.

Thank you Claudio for your attention and help.
HMGing a better world
"Matter tells space how to curve, space tells matter how to move."
Albert Einstein

Post Reply