2013-11-20 46 views
15

Nella mia applicazione VB6 apro altri file EXE. La mia applicazione funziona senza alcun prompt UAC, ma ho un EXE che controlla gli aggiornamenti del software. Questo richiede il prompt UAC. Quindi, in che modo Windows decide se mostrare il prompt UAC? Ho visto questo link. Quindi dipende dal codice che ho scritto nella mia applicazione? È interessante notare che la mia applicazione (ovvero il file EXE principale) non richiede il controllo dell'account utente, mentre un piccolo file EXE che controlla e scarica gli aggiornamenti richiede il controllo dell'account utente. Ho tutti i file EXE firmati digitalmente. Ho già avuto uno sguardo al seguente link:In che modo Windows decide se visualizzare il prompt UAC?

http://msdn.microsoft.com/en-us/library/windows/desktop/aa511445.aspx

http://technet.microsoft.com/en-us/library/cc505883.aspx e qualche altro.

Ma ancora non ne sono chiaro.

risposta

19

Quasi sicuramente si sta verificando una euristica di compatibilità con Windows Installer Detection Technology. Windows cercherà di rilevare quando un'applicazione è un programma di installazione e probabilmente deve essere elevata.

Installer Detection si applica solo a:

  1. 32 eseguibili bit
  2. Applicazioni senza un requestedExecutionLevel
  3. processi interattivi in ​​esecuzione come utente standard con LUA abilitato

Prima di una 32 processo di bit viene creato, i seguenti attributi vengono controllati per determinare se si tratta di un programma di installazione:

  • Nome file include parole chiave come "installazione", "messa a punto", "aggiornamento", ecc
  • Parole nei seguenti settori delle versioni di risorse: fornitore, il nome dell'azienda, il nome del prodotto, file di descrizione, originale nome del file, interno Nome ed Esporta nome.
  • Parole chiave nel file side-by-side incorporato nell'eseguibile.
  • Parole chiave in voci StringTable specifiche collegate nell'eseguibile.
  • Attributi chiave nei dati RC collegati nell'eseguibile.
  • Sequenze mirate di byte all'interno dell'eseguibile.

Quindi, come ha detto lei:

ma ho un exe che controlla la disponibilità di aggiornamenti per il software

La mia ipotesi è che questo CheckForUpdates.exe sta provocando l'euristica di compatibilità.

Il corretta cosa da fare è quella di un un'assemblea manifesta al "controllo" eseguibile, informando di Windows che dovrebbe non elevare l'utilità. Questo viene fatto con un requestedExecutionLevel di asInvoker nel manifesto:

AssemblyManifest.xml:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
    <assemblyIdentity 
     version="1.0.0.0" 
     processorArchitecture="X86" 
     name="client" 
     type="win32" 
    /> 

    <description>Update checker</description> 

    <!-- Run as standard user. Disable file and registry virtualization --> 
    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> 
     <security> 
     <requestedPrivileges> 
      <requestedExecutionLevel level="asInvoker" uiAccess="false"/> 
     </requestedPrivileges> 
     </security> 
    </trustInfo> 
</assembly> 

In questo modo il "Check for Updates" applicazione sarà mai elevare, e mai ottenere erroneamente privilegi amministrativi .

Se si desidera che il programma di aggiornamento sia effettivamente applicare gli aggiornamenti (aggiornamenti che richiedono privilegi di amministratore), si avvia l'applicazione di aggiornamento come amministratore.

codice di esempio

//Check if there are updates available 
if (!CheckForUpdatesAvailable()) 
    return; //no updates. We're done 

//If the user is an administrator, then get the update 
if (IsUserAnAdmin()) 
{ 
    //Maybe throw in a "Hey, user, wanna get the update now?" dialog 
    DownloadAndApplyUpdates(); 
    return; 
} 

//The user is not an admin. 
//Relaunch ourselves as administrator so we can download the update 
//Maybe throw in a "Hey, user, wanna get the update now?" dialog. A button with a UAC shield on it 
ExecuteAsAdmin(Application.ExecutablePath, "/downloadUpdate"); 

con le funzioni di supporto:

private Boolean IsUserAnAdmin() 
{ 
    //A user can be a member of the Administrator group, but not an administrator. 
    //Conversely, the user can be an administrator and not a member of the administrators group. 
    var identity = WindowsIdentity.GetCurrent(); 
    return (null != identity && new WindowsPrincipal(identity).IsInRole(WindowsBuiltInRole.Administrator)); 
} 

private void ExecuteAsAdmin(string Filename, string Arguments) 
{ 
    ProcessStartInfo startInfo = new ProcessStartInfo(Filename, Arguments); 
    startInfo.Verb = "runas"; 
    System.Diagnostics.Process.Start(startInfo); 
} 

Allora non vi resta che cercare il parametro di riga /downloadUpdate comando all'avvio per sapere che sei lavoro è effettivamente fare il lavoro:

public Form1() 
{ 
    InitializeComponent(); 

    //Ideally this would be in program.cs, before the call to Application.Run() 
    //But that would require me to refactor code out of the Form file, which is overkill for a demo 
    if (FindCmdLineSwitch("downloadUpdate", true)) 
    { 
     DownloadAndApplyUpdates(); 
     Environment.Exit(0); 
    } 
} 

Nota: Qualsiasi codice è rilasciato nel pubblico dominio. Nessuna attribuzione richiesta.

+0

Aggiungerò che le regole dei nomi dei file sopra elencate sono quasi certamente incomplete. Aneddoticamente un'app che richiede UAC se denominata come APP123.exe NON reqiure UAC se rinominata in APP.exe. – DaveInCaz

1

Qualcuno può specificare nella configurazione dell'exe che questo file deve essere eseguito con privilegi più alti.

How to request Admin Privileges

non so cosa questo aggiornamento è per, ma io suggerirei che ha bisogno di aggiornare un componente come un servizio, o di alcuni file che si trovano nella ProgramFiles-Dir. Pertanto ha bisogno dei privilegi di amministratore.

+0

Il mio dubbio è come Windows ha deciso che uac dovrebbe richiedere o meno. Il tuo metodo esegue il programma come amministratore e chiede all'utente di inserire la password di amministrazione. –

+0

Questo è comunque il modo in cui funziona, anche se l'articolo Codeproject non è molto completo. Hai una piccola scelta di diverse opzioni che puoi chiedere in quel manifest con differenze sottili o inesistenti (come richiedere il più alto privilegio o privilegio amministrativo, o bla), ma in fondo è solo questo. La sicurezza di Windows è abbastanza stupida, anche se d'altra parte vorrei poter citare un sistema che è meno stupido (Linux è anche _more stupido_, dato che ti fa digitare la password di root ...). – Damon

0

Il prompt UAC viene utilizzato quando è necessaria un'elevazione dei privilegi. La tua app VB6 non ne ha bisogno, quindi il comportamento predefinito è OK. Un programma di aggiornamento avrebbe bisogno del privilegio, quindi il suo autore ha contrassegnato l'eseguibile come richiesto. Windows rileva questo e visualizza il prompt UAC.

Ora, a seconda dell'esatta versione di Windows e degli aggiornamenti di sicurezza, tale privilegio rimane disponibile per un po ', anche per altri processi (secondari). Ciò potrebbe impedire i prompt UAC duplicati.

+0

Il programma di aggiornamento è stato creato da me. Quindi un po 'di codice che fa in modo che UAC richieda? Non ho eseguito il programma di aggiornamento exe come admin (eseguito come admin che induce UAC a richiedere sempre) nel mio codice. Quindi è un codice che innesca l'UAC? –

+1

Credo che Windows abbia delle euristiche aggiuntive: ha avuto bisogno di un controllo dell'account utente in passato, ad esempio? Si chiama "setup.exe"? – MSalters

+0

Il nome del file non è setup.exe. Ma UAC dipende anche dal nome del file? –

1

Probabilmente i programmi mancano di manifesti di applicazioni che li contrassegnano come non-legacy. Di conseguenza, Windows applicherà l'euristica di rilevamento degli script con script per decidere se il programma è un programma di installazione. Questo è praticamente l'unico modo in cui viene sollevata una richiesta UAC "inaspettata".

Queste euristiche includono le ricerche di parole chiave all'interno del nome file EXE e molte delle proprietà estese dell'EXE e possono anche cercare firme binarie note (cioè stringhe di byte) all'interno del file.

BTW, la tua crittografia non entra affatto in questo. E non aiuta nulla se non è stato rilasciato da una CA di fiducia.

Per quello che si fida del codice solo perché Windows riporta il nome commerciale sul prompt UAC è un pazzo. Gli autori di malware li rubano tutto il tempo, e per questo sono banali da ottenere e quasi mai segnalati dagli utenti quando i programmi di crap causano problemi. Salva i tuoi soldi, i certificati di firma del codice sono un concetto fallito.

+0

Ok. Quindi senza l'esecuzione come amministratore e con un file manifest appropriato puoi evitare i prompt UAC nel mio caso? –

+0

Inoltre, come creare un file manifest che renderà l'applicazione in esecuzione senza prompt UAC? –

+1

@ITresearcher: se questa è la tua vera domanda (come impedire il prompt), dovresti chiederlo - e fornire più informazioni che in questa domanda. Ma la risposta potrebbe benissimo essere "Il prompt UAC è lì per una buona ragione, stai cambiando il software installato, e questa dovrebbe essere una decisione intenzionale da parte dell'utente". – MSalters