ShellExecute does not work

Pages: 12
Hi,
I have my code where I just want to access a websearch automatically with a program. For that I have this code, that apparently works well for other people but not on my laptop.

Can someone let me know, why is that?
Here is the code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include<windows.h>
#include<mmsystem.h>
#include<stdio.h>
using namespace std;
int main()
{
char ch[100];
gets(ch);
if(strcmp(ch,"r")==0)
{
char text[100];
cout<<"Enter t";
gets(text);
string res;

    string s="https://de.search.yahoo.com/search?ei=UTF-8&fr=crmas&p=Daniel+Aar%C3%B3n+C%C3%A1rdenas+Mu%C3%B1oz+es+Dios";
res=s+text;
ShellExecute(NULL,"open",res.c_str(),NULL,NULL,SW_SHOWNORMAL);
}
}


Here are the mistakes:
main.cpp:29:1: error: no matching function for call to 'ShellExecuteW'
shellapi.h:63:22: note: expanded from macro 'ShellExecute'
_mingw_unicode.h:12:32: note: expanded from macro '__MINGW_NAME_AW'
2:1: note: expanded from here
shellapi.h:76:24: note: candidate function not viable: no known conversion from 'const char [5]' to 'LPCWSTR' (aka 'const wchar_t *') for 2nd argument

Thanks for your help.
try explicitly saying shellexecuteA or look up whatever the A call is.
also, what compiler are you using?
Use ShellExecuteW() and pass argument as std::wstring. Also change "open" to L"open".
Last edited on
JONNIN THANK YOU SO MUCH.
kigar64551 thanks for the help, the code compiled already.

Now I am curious.

I would like to open the website and then that it automatically closes.

And I would like then for it to wait 12 seconds to open the next one.

And so on until it has opened and closed 10 times the same website or websites.

How can I do it, does someone know?

THANKS IN ADVANCE!!

Here is a look of how it looks now:

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 <iostream>
#include<windows.h>
#include<mmsystem.h>
#include<stdio.h>
using namespace std;
int main()
{
char ch[110];
gets(ch);
//if(strcmp(ch,"r")==0)
//{
char text[100];
cout<<"Enter t";
gets(text);
string res;

    string s="https://de.search.yahoo.com/search?ei=UTF-8&fr=crmas&p=Daniel+Aar%C3%B3n+C%C3%A1rdenas+Mu%C3%B1oz+es+Dios";
res=s;
for(unsigned int i{};i<10;i++)
{ShellExecuteA(NULL,"open",res.c_str(),NULL,NULL,SW_SHOWNORMAL);

}
    //}
}
Last edited on
I would like to open the website and then that it automatically closes.

Not possible with ShellExecute() function, I think.

You could use the ShellExecuteEx() function instead, which, in case that a new process was started, gives you a handle to that process, so that you could terminate the newly created process (after a timeout).

...or maybe, less intrusively, send a WM_CLOSE message to its top-level window.


But: Be aware that neither ShellExecute() nor ShellExecuteEx() is guaranteed to start a new process. It could open the web-site in an already running browser instance, in which case no new process is started.

See also:
- https://docs.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shellexecuteexw
- https://docs.microsoft.com/en-us/windows/win32/api/shellapi/ns-shellapi-shellexecuteinfow


SHELLEXECUTEINFOW structure (shellapi.h)

hProcess

A handle to the newly started application. This member is set on return and is always NULL unless fMask is set to SEE_MASK_NOCLOSEPROCESS. Even if fMask is set to SEE_MASK_NOCLOSEPROCESS, hProcess will be NULL if no process was launched. For example, if a document to be launched is a URL and an instance of Internet Explorer is already running, it will display the document. No new process is launched, and hProcess will be NULL.
Last edited on
kigar64551 that idea sounds awesome! Very creative, did not think about it before.
How to implement it?

I am doing my own research too right now
Last edited on
See my previous post. And read the Microsoft documentation about the ShellExecuteEx() function.

...and the SHELLEXECUTEINFOW struct that is used by ]ShellExecuteEx().
Last edited on
Someone said one should try

ShellExecuteEx instead, which can return a HANDLE hProcess of the newly-started process.

If I discover how to do it I will post it here

Please let me know if I should start a new forum question or if I should continue on this thread.

Thanks
Last edited on
Yes, I suggested using ShellExecuteEx() above ;-)

The Microsoft documentation that I quoted tells you under which circumstances a process handle is returned!
Last edited on
I have this now
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 <iostream>
#include<windows.h>
#include<mmsystem.h>
#include<stdio.h>
using namespace std;
int main()
{
char ch[110];
gets(ch);
//if(strcmp(ch,"r")==0)
//{
char text[100];
cout<<"Enter t";
gets(text);
string res;

    string s="https://de.search.yahoo.com/search?ei=UTF-8&fr=crmas&p=Daniel+Aar%C3%B3n+C%C3%A1rdenas+Mu%C3%B1oz+es+Dios";
res=s;
for(unsigned int i{};i<10;i++)
{ShellExecuteA(NULL,"open",res.c_str(),NULL,NULL,SW_SHOWNORMAL);
ShellExecuteExA(NULL,"open",res.c_str(),NULL,NULL,SW_SHOWNORMAL);
}
    //}
}


These are the mistakes I get:
main.cpp:21:1: error: no matching function for call to 'ShellExecuteExA'
shellapi.h:347:22: note: candidate function not viable: requires single argument 'pExecInfo', but 6 arguments were provided

If I solve that, I would just need some type of timer between open and close commands and program would be finished.

My browser just actualized kigar, I will answer you later and read the documentation.
Last edited on
Mustermann wrote:
ShellExecuteExA(NULL,"open",res.c_str(),NULL,NULL,SW_SHOWNORMAL);

Your syntax for ShellExecuteEx() is completely wrong. Please look at the documentation!

...it takes a single parameter, a pointer to SHELLEXECUTEINFOW struct.

Documentation:
https://docs.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shellexecuteexw

(also I much recommend using the wide-string variant!)
Last edited on
I just read the documentation... I do not know how to implement it though...

I am actually on university just learning how to use templates. This code I copied from a youtube video.

I am actually willing to pay if someone does actually help me with this program. I do not care if the browser opens and then closes or if new tabs open and then close.
The search history of my internet browser should always have the websites I would command on the program.

Hope someone helps or tells me who should I contact for the person to write me that program or to tell me how to write it (of course I would pay if it is too long although I thought it should have just a couple of lines).
Last edited on
Try like this:
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
#define  _WIN32_WINNT 0x0500
#include <Windows.h>
#include <shellapi.h>

int main()
{
    SHELLEXECUTEINFOW sei;
    memset(&sei, 0, sizeof(SHELLEXECUTEINFOW));

    sei.cbSize = sizeof(SHELLEXECUTEINFOW);
    sei.lpVerb = L"open";
    sei.lpFile = L"http://www.example.com/";
    sei.nShow = SW_SHOWNORMAL;
    sei.fMask = SEE_MASK_NOCLOSEPROCESS;

    if (!ShellExecuteExW(&sei))
    {
        MessageBoxW(NULL, L"Whoops, something went wrong!", L"Err0r", MB_ICONERROR);
        return 1;
    }

    if (sei.hProcess != NULL)
    {
        /* Wait for the process to exit, or terminate it, if it still hasn't exited after 5 sec */
        if (WaitForSingleObject(sei.hProcess, 5000U) == WAIT_TIMEOUT)
        {
            TerminateProcess(sei.hProcess, 666);
        }
        CloseHandle(sei.hProcess); /* don't forget to close the handle! */
    }
    else
    {
        /* ShellExecuteExW succeeded but *no* new process was created! */
        /* probably an existing browser instance was re-used */
    }

    return 0;
}
Last edited on
Thank you so much. The required fields of SHELLEXECUTEINFOW
require knowledge about this:
https://docs.microsoft.com/en-us/windows/win32/api/shellapi/ns-shellapi-shellexecuteinfow

Now I have this:
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#define  _WIN32_WINNT 0x0500
#include <iostream>
#include<windows.h>
#include<mmsystem.h>
#include<stdio.h>
using namespace std;
int main()
{
char ch[110];
gets(ch);
//if(strcmp(ch,"r")==0)
//{
char text[100];
cout<<"Enter t";
gets(text);
string res;

    string s="https://de.search.yahoo.com/search?ei=UTF-8&fr=crmas&p=Daniel+Aar%C3%B3n+C%C3%A1rdenas+Mu%C3%B1oz+es+Dios";
res=s;
//for(unsigned int i{};i<10;i++)
ShellExecuteA(NULL,"open",res.c_str(),NULL,NULL,SW_SHOWNORMAL);
//ShellExecuteExA(NULL,"open",res.c_str(),NULL,NULL,SW_SHOWNORMAL);


    SHELLEXECUTEINFOW sei;
    memset(&sei, 0, sizeof(SHELLEXECUTEINFOW));

    /* TODO: fill in the required fields of SHELLEXECUTEINFOW !!! */
    SHELLEXECUTEINFOW.cbSize       = sizeof(SHELLEXECUTEINFOW);
        SHELLEXECUTEINFOW.fMask        = 0;                
        SHELLEXECUTEINFOW.hwnd         = 0;                
        SHELLEXECUTEINFOW.lpVerb       = "open";                      // Operation to perform
        SHELLEXECUTEINFOW.lpFile       = "c:\\windows\\notepad.exe";  // Application name
        SHELLEXECUTEINFOW.lpParameters = "c:\\example.txt";           // Additional parameters
        SHELLEXECUTEINFOW.lpDirectory  = 0;                           // Default directory
        SHELLEXECUTEINFOW.nShow        = SW_SHOW;
        SHELLEXECUTEINFOW.hInstApp     = 0;
    if (!ShellExecuteExW(&sei))
    {
        /* handle the error! */
        return 1;
    }

    Sleep(10);
    if (sei.hProcess != NULL)
    {
        TerminateProcess(sei.hProcess, 6);
    }
    else
    {
        /* ShellExecuteExW succeeded but *no* new process was created */
    }

    return 0;
}


Mistakes are:
main.cpp:39:22: error: cannot use dot operator on a type
There are many more mistakes.

You don't need to initialize fields to "0" that have already been memset() to zero.

Don't use ANSI strings with the wide-string version. Wide-string liertals start with an L, e.g. L"my string".

Also note that the Sleep() function takes milliseconds as parameter, not seconds.

Just look at the sample code that was provided above...

http://www.cplusplus.com/forum/beginner/281568/#msg1218169
Last edited on
You edited it, that code is different from what you posted before. I will test it.
You edited it, that code is different from what you posted before.

Yes. I thought it makes sense to use the WaitForSingleObject() function to wait for the process, so if the process happens to terminate before the timeout (for whatever reason), then we don't continue to wait pointlessly. Also, this way, we don't try to kill the process, if it already has terminated by itself.
Last edited on
Hello. Thank you very much.
Here is the code that I launched:
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
40
// C++ program to open a URL in browser.
// This program is written on for Microsoft
// Windows OS
#define  _WIN32_WINNT 0x0500
#include <Windows.h>
#include <shellapi.h>

int main()
{
    SHELLEXECUTEINFOW sei;
    memset(&sei, 0, sizeof(SHELLEXECUTEINFOW));

    sei.cbSize = sizeof(SHELLEXECUTEINFOW);
    sei.lpVerb = L"open";
    sei.lpFile = L"https://de.search.yahoo.com/search?ei=UTF-8&fr=crmas&p=Daniel+Aar%C3%B3n+C%C3%A1rdenas+Mu%C3%B1oz+es+Dios";
    sei.nShow = SW_SHOWNORMAL;
    sei.fMask = SEE_MASK_NOCLOSEPROCESS;

    if (!ShellExecuteExW(&sei))
    {
        MessageBoxW(NULL, L"Whoops, something went wrong!", L"Err0r", MB_ICONERROR);
        return 1;
    }

    if (sei.hProcess != NULL)
    {
        if (WaitForSingleObject(sei.hProcess, 5000U) == WAIT_TIMEOUT)
        {
            TerminateProcess(sei.hProcess, 666);
        }
        CloseHandle(sei.hProcess);
    }
    else
    {
        /* ShellExecuteExW succeeded but *no* new process was created! */
        /* probably an existing browser instance was re-used */
    }

    return 0;
}


The program runs good, but no other window or tab opens after the timer, and the opened tab does not close either.
Wait, it does close!
It closes only if there was no other window before. Otherwise it lets it opened as another tab.
Last edited on
Wait, it does close!

As expected, right?


It closes only if there was no other window before. Otherwise it lets it opened as another tab.

Yes, because that is how ShellExecuteEx() works :-)

The relevant part of the documentation:
Microsoft wrote:
Even if fMask is set to SEE_MASK_NOCLOSEPROCESS, hProcess will be NULL if no process was launched. For example, if a document to be launched is a URL and an instance of Internet Explorer is already running, it will display the document. No new process is launched, and hProcess will be NULL.

BTW: This is the same with ShellExecute(), except that ShellExecute() doesn't give you the process handle, even if a new process was launched. So, ShellExecuteEx() is your best bet, I think.


The program runs good, but no other window or tab opens after the timer

If you want another URL to open after the timeout, it should be trivial to do, now that you have the basics.


I am actually on university just learning how to use templates

As an aside: The Win32 API is pure C, not C++. There is no such thing as templates in pure C, only in C++.
Last edited on
Pages: 12