ShellExecuteEx not launching exe

I am using regular C++, not Visual C++. I need to run an exe as admin from my C++ application. The C++ application cannot have a manifest that makes it run as admin because I am using it as a "middle man" for a Java application. When I run the code below it sits with a wait cursor for 45 seconds or so and then nothing. No error, no warning, doesn't launch the exe, nothing. I looked at it in task manager and it shows up for 45 seconds and then disappears. Why is it not doing anything and how can I make it work?

Also, I am using MingW compiler & Code::Blocks if that is any help...

Here is the code:

main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include "main.h"

char* PathRemoveFile(char* path)
{
    std::string p = path;
    p.erase(p.rfind("\\"),std::string::npos);
    std::vector<char> writable(p.size() + 1);
    std::copy(p.begin(), p.end(), writable.begin());
    return &writable[0];
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int cmdShow)
{
    char module_name[MAX_PATH];
    GetModuleFileName(0, module_name, MAX_PATH);
    HRESULT ret = SUCCESS;
    SHELLEXECUTEINFO sinfo;
		sinfo.cbSize       = sizeof(sinfo);
		sinfo.hwnd         = NULL;
		sinfo.lpFile       = strcat(PathRemoveFile(module_name), "\\uac.exe");
		sinfo.lpVerb       = (char *)"runas"; //I tried "open" as well, but with no luck.
		sinfo.nShow        = SW_NORMAL;
    BOOL result = ShellExecuteEx(&sinfo);
    if (result)
    {
        WaitForSingleObject(sinfo.hProcess, INFINITE);
        CloseHandle(sinfo.hProcess);
        ret = SUCCESS;
    }
    else
    {
        ret = FAILURE;
    }
    return ret;
}


main.h
1
2
3
4
5
6
7
8
#include <string>
#include <vector>

#include <Windows.h>

#define SUCCESS					0
#define FAILURE					1
#define MAXPATHLEN				MAX_PATH 


Any and all help, suggestions, and comments are very appreciated.
Last edited on
bump
I think no one has tried to help because you are directly contradicting yourself and it looks like you don't even have a question formed yet. By first saying "... an exe that MUST be run as admin." then in the next sentence "However I need it to not require admin, ...".

I'll give you the benefit of the doubt and ask you to reword your request. What are you trying to do? Don't be vague.
I completely reworded it, and the next sentence was talking about the C++ app - not the exe.
Last edited on
Your PathRemoveFile() function is incorrect, you are returning a vector allocated on the stack, which can be freed at any time. Use new opoerator if you want to do that. Windows already has PathRemoveFileSpec() from shlwapi.dll which do exactly the same thing.

If the child process does show up in task manager for 45 seconds, then there is nothing wrong with your code, the process is created and running. Maybe there is a problem with 3rd party application, try renaming it from "uac.exe" into something else.

Does right-click and choose "run as administrator" works for 3rd party application directly from windows explorer ?
1. I tried that PathRemoveFileSpec() and it said something like it was called in the wrong scope.
2. The child process does not show up, the parent process shows for 45 seconds.
3. The application I am trying to run has a manifest that forces admin.
4. I found that code for the function somewhere, I don't remember where, on the internet.

EDIT:
It wasn't wrong scope, here is the error
C:\Users\Timberwolf\Documents\C++ Projects\Tool Belt UAC Launcher\main.cpp|7|undefined reference to `_imp__PathRemoveFileSpecA@4'|


and here is the modified code
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include "main.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int cmdShow)
{
    char module_name[MAX_PATH];
    GetModuleFileName(0, module_name, MAX_PATH);
    PathRemoveFileSpec(module_name);
    HRESULT ret = SUCCESS;
    SHELLEXECUTEINFO sinfo;
		sinfo.cbSize       = sizeof(sinfo);
		sinfo.hwnd         = NULL;
		sinfo.lpFile       = strcat(module_name, "\\uac.exe");
		sinfo.lpVerb       = (char *)"runas";
		sinfo.nShow        = SW_NORMAL;
    BOOL result = ShellExecuteEx(&sinfo);
    if (result)
    {
        WaitForSingleObject(sinfo.hProcess, INFINITE);
        CloseHandle(sinfo.hProcess);
        ret = SUCCESS;
    }
    else
    {
        ret = FAILURE;
    }
    return ret;
}

main.h
1
2
3
4
5
6
7
8
9
#include <string>
#include <vector>

#include <Windows.h>
#include "shlwapi.h"

#define SUCCESS					0
#define FAILURE					1
#define MAXPATHLEN				MAX_PATH 


EDIT:
I fixed the error by linking shlwapi in the linker settings under build options. However it is doing the exact same thing.
Last edited on
bump
bump
bump...
bump
bump... Has this topic been lost in an abyss? I have not received a reply other than my own in 7 days...
BUMP
PathRemoveFileSpec() may be the wrong function:

http://msdn.microsoft.com/en-us/library/windows/desktop/bb773748%28v=vs.85%29.aspx

it leaves the drive name in the path



PathFindFileName() is what you need?

http://msdn.microsoft.com/en-us/library/windows/desktop/bb773589%28v=vs.85%29.aspx


why would you want remove the path anyway?
I want to find the folder the exe is in (ie Program: "M:\TOOLS\WIN\IOBIT\app.exe" and I want this: "M:\TOOLS\WIN\IOBIT"). Basically I want to launch uac.exe and it is in the same path as app.exe (this is the C++ app).

So I have:
"M:\TOOLS\WIN\IOBIT\app.exe" and "M:\TOOLS\WIN\IOBIT\uac.exe"

I want to run:
"M:\TOOLS\WIN\IOBIT\uac.exe" from "M:\TOOLS\WIN\IOBIT\app.exe" as Admin in Windows 7 and Vista.
I fixed my own problem.
Code before:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include "main.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int cmdShow)
{
    char module_name[MAX_PATH];
    GetModuleFileName(0, module_name, MAX_PATH);
    PathRemoveFileSpec(module_name);
    HRESULT ret = SUCCESS;
    SHELLEXECUTEINFO sinfo;
		sinfo.cbSize       = sizeof(sinfo);
		sinfo.hwnd         = NULL;
		sinfo.lpFile       = strcat(module_name, "\\uac.exe");
		sinfo.lpVerb       = (char *)"open";
		sinfo.nShow        = SW_NORMAL;
    BOOL result = ShellExecuteEx(&sinfo);
    if (result)
    {
        WaitForSingleObject(sinfo.hProcess, INFINITE);
        CloseHandle(sinfo.hProcess);
        ret = SUCCESS;
    }
    else
    {
        ret = FAILURE;
    }
    return ret;
}


and code after:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include "main.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int cmdShow)
{
    char module_name[MAX_PATH];
    GetModuleFileName(0, module_name, MAX_PATH);
    PathRemoveFileSpec(module_name);
    strcat(module_name, "\\uac.exe");
    SHELLEXECUTEINFO sinfo;
		sinfo.cbSize       = sizeof(SHELLEXECUTEINFO);
		sinfo.hwnd         = NULL;
		sinfo.fMask        = SEE_MASK_NOCLOSEPROCESS;
		sinfo.lpParameters = "";
		sinfo.nShow        = SW_SHOW;
		sinfo.lpDirectory  = NULL;
		sinfo.hInstApp     = NULL;
		sinfo.lpFile       = module_name;
		sinfo.lpVerb       = (char *)"open";
		sinfo.nShow        = SW_NORMAL;
    ShellExecuteEx(&sinfo);
    WaitForSingleObject(sinfo.hProcess, INFINITE);
    CloseHandle(sinfo.hProcess);
    return 0;
}


@modoran: Thank you for pointing me in the direction of PathRemoveFileSpec()
@computergeek01: Thank you for letting me know my post was unclear
Last edited on
Topic archived. No new replies allowed.