Okay, trying to compile followong code i get the three (also) follownig messages from my IDE.

#include "windows.h"
#include "shellapi.h"


int _tmain(int argc, _TCHAR* argv[])
{
      SHELLEXECUTEINFO shExecInfo;

      shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);

      shExecInfo.fMask = NULL;
      shExecInfo.hwnd = NULL;
      shExecInfo.lpVerb = L"runas";
      shExecInfo.lpFile = L"notepad.exe";
      shExecInfo.lpParameters = NULL;
      shExecInfo.lpDirectory = NULL;
      shExecInfo.nShow = SW_MAXIMIZE;
      shExecInfo.hInstApp = NULL;

      ShellExecuteEx(&shExecInfo);

      return 0;
}

Line 11 warning: converting to non-pointer type `ulong' from NULL
Line 13 error: cannot convert `const wchar_t[6]' to `const CHAR*' in assignment
Line 14 error: cannot convert `const wchar_t[12]' to `const CHAR*' in assignment

Remove the two capital 'L' s on line 13 and 14.

Okay, i removed the L's but now it says :

undefined reference to `_WinMain@16'

:/

replace '_tmain' with 'main' :)

(I have serious doubts if this solution will work at all, so we might be just wasting our time...)

commented: Whew... +10

I allready did ;- ) didn't work. hmm I'll try again when i get home, just to make sure.

You're trying to compile it as a windows gui program, so it's saying that you're missing WinMain (which is the entry point for such a program). You need to compile it as a console program.

^^ i Know ;- ) but I'm pretty sure I am compiling it as a console program? if not, how would i know the difference?

Depends on your IDE. In Dev-C++ you go to Project Options and set the type to a Console program.

I'm using code::blocks, but if that is the case^^ then i am compling as a console program :/

int _tmain(int argc, _TCHAR* argv[]) to int main(int argc, char **argv) , but I doubt that is going to make a big difference. Just so you know, in code::blocks IDE, windows XP SP2, this compiles (and works) just fine:

#include "windows.h"
#include "shellapi.h"


int main(int argc, char **argv[])
{
      SHELLEXECUTEINFO shExecInfo;

      shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);

      shExecInfo.fMask = 0; // NULL;
      shExecInfo.hwnd = NULL;
      shExecInfo.lpVerb = "runas";
      shExecInfo.lpFile = "notepad.exe";
      shExecInfo.lpParameters = NULL;
      shExecInfo.lpDirectory = NULL;
      shExecInfo.nShow = SW_MAXIMIZE;
      shExecInfo.hInstApp = NULL;

      ShellExecuteEx(&shExecInfo);

      return 0;
}

Although, the runas portion comes up with a dialog box... wanting me to ok it and login or whatever... but I'm sure if we can pass something like "/password" or whatever runas takes to lpParameters, we should be able to make it happen seemlessly.

Yes! that is exactly what makes me go crazy! it compiles and runs perfectly on my 64-vista aswell. but when i go "test.bat" instead of "notepad.exe" and then run it, i get a message box claming that test.bat cannot be found. i really don't get it

I noticed that a while back you tried calling cmd.exe with parameters, but your parameters were not correct. You pass a command to cmd.exe with the /c flag, so assuming test.bat is in the root dir, try something like this:

ShellExecute (NULL, "open", "cmd.exe", "/c test.bat", "c:\\", SW_NORMAL);

or this (modified from Comatose's last post):

int main(int argc, char **argv[])
{
      SHELLEXECUTEINFO shExecInfo;

      shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);

      shExecInfo.fMask = 0; // NULL;
      shExecInfo.hwnd = NULL;
      shExecInfo.lpVerb = "runas";
      shExecInfo.lpFile = "cmd.exe";
      shExecInfo.lpParameters = "/c c:\\test.bat";
      shExecInfo.lpDirectory = NULL;
      shExecInfo.nShow = SW_MAXIMIZE;
      shExecInfo.hInstApp = NULL;

      ShellExecuteEx(&shExecInfo);

      return 0;
}

Hmm when i run that^^ something odd happens. a window sort of "flashes by" by it's to fast, so i can't see what it is. still not working though :/ (maybe this window has appeared earlier without me noticing, i really can't say for sure)

Try adding "pause" to the end of your test.bat.

As expectet^^ The message would stay open, pause or not, but THANK YOU, it made the flashing-by message stay :-D
It says, 'msg' is not reconized as a internal o external command or operatable program or batch file :/ which is of course rubbish?

Presumably it has an empty environment, which means no path variable. So you will have to use the full pathname of msg. Something like: c:\windows\system32\msg

And probably need to use \\ instead of \

Hmm still not working, maybe I did something wrong? i have tried different variations of:

int main(int argc, char **argv[])
{
      SHELLEXECUTEINFO shExecInfo;

      shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);

      shExecInfo.fMask = 0; // NULL;
      shExecInfo.hwnd = NULL;
      shExecInfo.lpVerb = "runas";
      shExecInfo.lpFile = "c:\\windows\\system32\\msg";
      shExecInfo.lpParameters = "";
      shExecInfo.lpDirectory = NULL;
      shExecInfo.nShow = SW_MAXIMIZE;
      shExecInfo.hInstApp = NULL;

      ShellExecuteEx(&shExecInfo);

      return 0;
}

I altso tried changing "test.bat" to variations of

cd C:\windows\system32
msg * Hallu
pause

and then "just" calling "test.bat" with no parameters.

set shExecInfo.lpDirectory = to the path where your .bat file resides...

I don't remember if anyone's suggested initializing COM. Try this.

#include <iostream>
#include <windows.h>
#include <objbase.h>
// Link with ole32 (add -lole32 to the linker command line)


#define FILE "c:\\test.bat"
//#define FILE "c:\\windows\system32\msg.exe"

#define VERB "runas"
//#define VERB "open"


int main(int argc, char **argv[])
{
    SHELLEXECUTEINFO shExecInfo;

    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED |
                         COINIT_DISABLE_OLE1DDE);

    shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
    shExecInfo.fMask = 0;
    shExecInfo.hwnd = 0;
    shExecInfo.lpVerb = VERB;
    shExecInfo.lpFile = FILE;
    shExecInfo.lpParameters = 0;
    shExecInfo.lpDirectory = 0;
    shExecInfo.nShow = SW_MAXIMIZE;
    shExecInfo.hInstApp = 0;

    if (!ShellExecuteEx(&shExecInfo))
        std::cout << "Error: " << GetLastError() << "\n";

    CoUninitialize();

std::cin.get();

    return 0;
}
int main()
{
    system("C:\\test.bat");

    return 0;
}

works just fine for me on WinXP. same batch file as yours.

If nothing else works, change "msg" to "C:\Windows\System32\msg.exe"

int main()
{
    system("C:\\test.bat");

    return 0;
}

works just fine for me on WinXP. same batch file as yours.

If nothing else works, change "msg" to "C:\Windows\System32\msg.exe"

>i dont wish to run it "trough" my program, just as if i had found the destination and doubleclick'ed it.

I believe using system, execl, and the like, will force the C++ program to wait until the program returns.... I don't think shellexecute is going to force the c++ program to wait for the shelled application to return.

>I believe using system, execl, and the like, will force the C++ program to wait until the program returns
Oh, sorry, I didn't see that... :P

In which case,

ShellExecute (NULL, "open", "cmd.exe", "/c C:\\test.bat", "C:\\", SW_NORMAL);

works for me too... hmm...

Nice. You are in vista like he is?

Well, it would be fine by me to use system, but that doesn't work either:/
i tried the above shellexecute and got this from my IDE:
\main.cpp|3|error: expected constructor, destructor, or type conversion before '(' token

I'm trying out Code::Blocks. It's pretty nice!
Try this code. I've included instuctions on how to link it with ole32 in Code::Blocks. Also, it shows the formatted error message in a message box.

#include <windows.h>
#include <objbase.h>

// Link with ole32. In CodeBlocks, add "ole32" (no quotes) to
// Project/Build options/Linker settings/Link libraries

void showError(char *msgin)
{
    char *msgbuf, *displaybuf;
    DWORD dw = GetLastError();
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (char*)&msgbuf, 0, NULL);
    displaybuf = (char*)LocalAlloc(LMEM_ZEROINIT,
        strlen(msgbuf) + strlen(msgin) + 40);
    wsprintf(displaybuf, "%s failed with error %d: %s",
        msgin, dw, msgbuf);
    MessageBox(NULL, displaybuf, "Error", MB_OK);
    LocalFree(msgbuf);
    LocalFree(displaybuf);
}

int main(int argc, char *argv[])
{
    SHELLEXECUTEINFO sei = {sizeof(sei)};

    CoInitializeEx(NULL,
        COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);

    sei.lpVerb = "runas";
//    sei.lpVerb = "open";
    sei.lpFile = "c:\\test.bat";
//    sei.lpFile = "c:\\windows\system32\msg.exe";
    sei.nShow = SW_SHOWNORMAL;
//    sei.lpParameters = "";
//    sei.lpDirectory = "";

    if (!ShellExecuteEx(&sei)) showError("ShellExecuteEx");

    CoUninitialize();

    return 0;
}

Err, all that does (for me at least) is open the casual command prompt-like window with "hello world" in it? :)

Sounds like it's running a test.bat. Is that's what's in the at c:\ or is there another in the current directory?

It's at the root. full path:
C:/test.bat

So c:\test.bat has something like "echo hello world" in it??? If so then it seems to be working.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.