Click here to Skip to main content
12,072,536 members (62,577 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

50.1K views
32 bookmarked
Posted

How to Elevate Your Application at Windows Startup in Vista

, 17 May 2008 CPOL
Rate this:
Please Sign up or sign in to vote.
An article on elevating an application at Windows startup in Vista

Introduction

This article describes how to elevate your program in Windows startup in Vista. Elevating an application is so easy, but it's not easy registering an application in startup.

Background

This article requires readers to have some background.
Firstly, it's important to understanding Vista's UAC. UAC is too complex to understand. Hence, this article does not have any information about UAC.
Secondly, MFC and API knowledge are required since the sample code of this article uses MFC and API.

Vista and Windows Startup

Many programs need to run at Windows startup.

In Windows XP, run at startup was not big deal. But, it became a big deal in Windows Vista. Windows Vista's new protection features restrict a startup program which wants to run as administrator. (It needs to elevate.)

If your application does not need an administrator privilege, there is nothing to do for migration to Windows Vista. But, if your application need an administrator privilege, your application can't run at startup because Vista's new protection blocks your program.

It seems to be impossible to run an administrator privileged program at Windows startup in Vista. But, there is a way to do it (even if it is not the same as XP).

This article describes Windows Vista's protection and a possible method to figure out our problem.

Another Way

To find another way, we have to think about the architecture of protection software. Start with this:

"Windows Vista is allowed to run software which does not need an administrator privilege."

So, one possible method is as follows:

  • We have to create a normal program which does not need an administrator privilege. (New protection does not block none privilege application.)
  • That normally has to elevate itself with CreateProcess and terminate.

The following pseudo code shows it:

void Main()
{
    if(IsVista() == TRUE && Elevation() == FALSE) {
        ElevationItself();
        Terminate();
    }
}

C++ Code (MFC)

Pseudo code is easy, but real code is not.

CString g_szProgramFolder;
CString g_szCmdLine;

BOOL RunAsAdministrator(LPSTR lpszFileName, LPSTR lpszDirectory)
{
    SHELLEXECUTEINFOA TempInfo = {0};

    TempInfo.cbSize = sizeof(SHELLEXECUTEINFOA);
    TempInfo.fMask = 0;
    TempInfo.hwnd = NULL;
    TempInfo.lpVerb = "runas";
    TempInfo.lpFile = lpszFileName;
    TempInfo.lpParameters = "runasadmin";
    TempInfo.lpDirectory = lpszDirectory;
    TempInfo.nShow = SW_NORMAL;

    BOOL bRet = ::ShellExecuteExA(&TempInfo);

    return bRet;
}

BOOL CMFCApplication::InitInstance()
{
    char szCurFolder[1024] = { 0, };
    GetModuleFileName(GetModuleHandle(NULL), szCurFolder, 1023);

    CString szFullPath = szCurFolder;
    szFullPath = szFullPath.Left(szFullPath.ReverseFind('\\'));

    g_szProgramFolder = szFullPath;

    CCommandLineInfo oCmdLineInfo;
    ParseCommandLine(oCmdLineInfo);

    g_szCmdLine = oCmdLineInfo.m_strFileName;

    if(IsVista()) {
        if(stricmp(g_szCmdLine, "elevation") == 0) {
            char szCmdLine[1024] = { 0, };
            char szCurFileName[1024] = { 0, };
            GetModuleFileName(GetModuleHandle(NULL), szCurFileName, 1023);

            BOOL bRet = 
                RunAsAdministrator( szCurFileName, (LPSTR)(LPCTSTR)g_szProgramFolder );

            if(bRet == TRUE) {
                return FALSE;
            }
        } else if(stricmp(g_szCmdLine, "runasadmin") == 0) {
            //
            // go trough!.
            //
        } else {
            char szCmdLine[1024] = { 0, };
            char szCurFileName[1024] = { 0, };
            GetModuleFileName(GetModuleHandle(NULL), szCurFileName, 1023);

            sprintf(szCmdLine, "\"%s\" elevation", szCurFileName);

            WinExec(szCmdLine, SW_SHOW);

            return FALSE;
        }
    }
    .
    .
    .
}

Points of Interest

RunAsAdministrator function returns FALSE when a user selects 'Cancel'. So, you can execute a program repeatedly until the user selects 'Allow'.

History

  • 2008-05-16: First released

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Yonghwi Kwon
Software Developer
United States United States
I started to write software since 1999 and have developed various products including security solutions and system utilities.

Microsoft Visual C++ MVP (from 2008 to present)
Website: http://rodream.net

You may also be interested in...

Comments and Discussions

 
GeneralWindows damaged after run application as elevated to write to registry [modified] Pin
Ha_Tim15-Nov-09 21:22
memberHa_Tim15-Nov-09 21:22 
GeneralFull source code Pin
lemonlyt31-Mar-09 1:41
memberlemonlyt31-Mar-09 1:41 
GeneralProcessShellCommand() reports error Pin
kuan deng18-Mar-09 7:05
memberkuan deng18-Mar-09 7:05 
After adding your code and run it in a Vista-32 machine, the ProcessShellCommand() reports error of "c:\...\runasadmin was not found."

Here is my code. The 1st part is your code; the 2nd part is my original code for Windows XP and below OSs.

What caould be the problem of coding?

Thanks!

BOOL CTrayIconApp::InitInstance()
{
char szMsg[256];
char szCurFolder[1024] = { 0, };
GetModuleFileName(GetModuleHandle(NULL), szCurFolder, 1023);

CString szFullPath = szCurFolder;
szFullPath = szFullPath.Left(szFullPath.ReverseFind('\\'));

g_szProgramFolder = szFullPath;

CCommandLineInfo oCmdLineInfo;
ParseCommandLine(oCmdLineInfo);

g_szCmdLine = oCmdLineInfo.m_strFileName;

if( IsWindowsVista() )
{
if(stricmp(g_szCmdLine, "elevation") == 0)
{
char szCmdLine[1024] = { 0, };
char szCurFileName[1024] = { 0, };
GetModuleFileName(GetModuleHandle(NULL), szCurFileName, 1023);
BOOL bRet = RunAsAdministrator( szCurFileName, (LPSTR)(LPCTSTR)g_szProgramFolder );
if(bRet == TRUE)
{
return FALSE;
}
}
else if(stricmp(g_szCmdLine, "runasadmin") == 0) {
//
// go trough!.
//
}
else
{
char szCmdLine[1024] = { 0, };
char szCurFileName[1024] = { 0, };
GetModuleFileName(GetModuleHandle(NULL), szCurFileName, 1023);

sprintf(szCmdLine, "\"%s\" elevation", szCurFileName);
WinExec(szCmdLine, SW_SHOW);
return FALSE;
}
} //IsWindowsVista


//
// Below are the original code!!!
//
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.


#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif

// Change the registry key under which our settings are stored.
// You should modify this string to be something appropriate
// such as the name of your company or organization.
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
LoadStdProfileSettings(); // Load standard INI file options (including MRU)

// Register the application's document templates. Document templates
// serve as the connection between documents, frame windows and views.

CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CTrayIconDoc),
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CTrayIconView));
AddDocTemplate(pDocTemplate);

// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);

// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
return FALSE;

//Application stuff
char traceTime[200];
initGlobals();

processMutex = OpenMutex(MUTEX_ALL_ACCESS, TRUE, LUCENTTRAYICON_MUTEX) ;
if(!processMutex)
{
processMutex = CreateMutex(0, FALSE, LUCENTTRAYICON_MUTEX) ;
}
else
{
writeTrace("\r\r\n%s:: A instance of TrayIcon is already running, so not starting a new instance\r\r\n", getTime(traceTime));
return FALSE;
}

// Spawn a seperate thread to poll/communicate with another app
contactIKEApp();

return TRUE;

}

GeneralRe: ProcessShellCommand() reports error Pin
Ha_Tim16-Nov-09 18:09
memberHa_Tim16-Nov-09 18:09 
GeneralSource code Pin
MasterPr23-Jun-08 0:38
memberMasterPr23-Jun-08 0:38 
GeneralRe: Source code Pin
Member 392808218-Sep-08 1:21
memberMember 392808218-Sep-08 1:21 
GeneralRe: Source code Pin
lzf897724-Oct-08 2:00
memberlzf897724-Oct-08 2:00 
GeneralBuffer overflow Pin
mav.northwind17-May-08 21:51
membermav.northwind17-May-08 21:51 
GeneralRe: Buffer overflow Pin
Kwon Yong Hwi18-May-08 5:36
memberKwon Yong Hwi18-May-08 5:36 
GeneralRe: Buffer overflow Pin
SteveKing18-May-08 20:23
memberSteveKing18-May-08 20:23 
GeneralRe: Buffer overflow Pin
Kwon Yong Hwi19-May-08 4:54
memberKwon Yong Hwi19-May-08 4:54 
GeneralRe: Buffer overflow Pin
Mihai Nita19-May-08 9:26
memberMihai Nita19-May-08 9:26 
GeneralRe: Buffer overflow Pin
Kwon Yong Hwi19-May-08 14:45
memberKwon Yong Hwi19-May-08 14:45 
GeneralRe: Buffer overflow Pin
Mihai Nita22-May-08 14:42
memberMihai Nita22-May-08 14:42 
GeneralYou shouldn't display an elevation prompt at login Pin
Daniel Grunwald17-May-08 7:13
memberDaniel Grunwald17-May-08 7:13 
GeneralRe: You shouldn't display an elevation prompt at login Pin
axelriet17-May-08 16:00
memberaxelriet17-May-08 16:00 
GeneralRe: You shouldn't display an elevation prompt at login Pin
Leo Davidson18-May-08 8:36
memberLeo Davidson18-May-08 8:36 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160208.1 | Last Updated 17 May 2008
Article Copyright 2008 by Yonghwi Kwon
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid