Windows cannot find '<LETTER HERE>'.

I tried both my C drive and my M drive (flash drive). I am trying to run a program as admin from my C++ executable. When I run it gives the following error:
Windows cannot find 'M'. Make sure you typed the name correctly, and then try again.

Replacing M with whatever drive I put it in. Here is my 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"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int cmdShow)
{
    char module_name[MAX_PATH];
    GetModuleFileName(0, module_name, MAX_PATH);
    const size_t cSize = strlen(module_name)+1;
    wchar_t* wc = new wchar_t[cSize];
    mbstowcs (wc, module_name, cSize);
    std::wstring p(wc);
    p.erase(p.find_last_of('\\'), std::wstring::npos);
    p.append(L"\\uac.exe");
    LPSTR path = (LPSTR) p.c_str();
    LPSTR r = "runas";
    HRESULT ret = SUCCESS;
    SHELLEXECUTEINFO sinfo;
		memset(&sinfo, 0, sizeof(SHELLEXECUTEINFO));
		sinfo.cbSize       = sizeof(SHELLEXECUTEINFO);
		sinfo.hwnd         = NULL;
		sinfo.lpFile       = path;
		sinfo.lpVerb       = r;
		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
10
11
12
13
14
15
16
17
18
#include <string>
#include <cstring>

#include <Windows.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <shellapi.h>
#include <process.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>

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


Any help, suggestions, and comments are welcome and appreciated.
Last edited on
Tip: Use PathRemoveFileSpec() API instead of std::wstring.
http://msdn.microsoft.com/en-us/library/windows/desktop/bb773748(v=vs.85).aspx

Mixing strlen() and wchar_t as you do in your code will give you unexpected results, learn about UNICODE prepocessor definition, it is an article on this website.
I will try the PathRemoveFileSpec() but I noticed you linked an article on MSDN, I am using pure C++, not VC++. I am not a big fan of .NET framework when it can be done in the same/similar language. And on the strlen() and wchar_t, I don't understand, I didn't use strlen() on the wchar_t I used it on char...

UPDATE:
I tried the PathRemoveFileSpec() and got this error
C:\Users\Timberwolf\Documents\C++ Projects\Tool Belt UAC Launcher\main.cpp|7|error: 'PathRemoveFileSpec' was not declared in this scope|



and here is main.cpp
 
removed to shorten post


and main.h
 
removed to shorten post


EDIT:

Added
#include "Shlwapi.h"
to main.h
and got a different error:
C:\Users\Timberwolf\Documents\C++ Projects\Tool Belt UAC Launcher\main.cpp|7|undefined reference to `_imp__PathRemoveFileSpecA@4'|


EDIT:
Removed the include and created a function that works the way I want...

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
36
37
38
39
#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);
    PathRemoveFile(module_name);
    strcat(module_name, "\\uac.exe");
    LPSTR r = (char *)"runas";
    HRESULT ret = SUCCESS;
    SHELLEXECUTEINFO sinfo;
		memset(&sinfo, 0, sizeof(SHELLEXECUTEINFO));
		sinfo.cbSize       = sizeof(SHELLEXECUTEINFO);
		sinfo.hwnd         = NULL;
		sinfo.lpFile       = module_name;
		sinfo.lpVerb       = r;
		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 
Last edited on
ok, I got it to "find" M. However its starting itself up in an endless loop... I don't uderstand that because I used this, which points to uac.exe and not app.exe:
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
36
37
38
#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);
    strcat(PathRemoveFile(module_name), "\\uac.exe");
    LPSTR r = (char *)"runas";
    HRESULT ret = SUCCESS;
    SHELLEXECUTEINFO sinfo;
		memset(&sinfo, 0, sizeof(SHELLEXECUTEINFO));
		sinfo.cbSize       = sizeof(SHELLEXECUTEINFO);
		sinfo.hwnd         = NULL;
		sinfo.lpFile       = module_name;
		sinfo.lpVerb       = r;
		sinfo.nShow        = SW_NORMAL;
    BOOL result = ShellExecuteEx(&sinfo);
    if (result)
    {
        WaitForSingleObject(sinfo.hProcess, INFINITE);
        CloseHandle(sinfo.hProcess);
        ret = SUCCESS;
    }
    else
    {
        ret = FAILURE;
    }
    return ret;
}


EDIT:
Never mind I found my mistake. I feel stupid now...
Last edited on
Topic archived. No new replies allowed.