Shellexecute

Pages: 12
Hi guys i am trying to open a URL (internet site) via code (C++) i tried the Shellexecute thingy but it gives me the same error no matter what here is the error line:

'ShellExecuteW' : cannot convert parameter 2 from 'const char [5]' to 'LPCWSTR'

Any help on this to why it happens or a quick little source code on opening a web browser would be greatly appreciated.

best regards.
Shellexecute? That sounds to me like an even more platform dependent form of system(), which accepts character arrays.

-Albatross
Hm well it could be i am very new to this you see, got any examples or a little quick tutorial on how to load a URL? or is it a longer thing?
Last edited on
Hi again Albatross. I am sorry i understated my noob ness in this particular area of C++ if i could get a little more detailed or atleast a commented source code or part of one it would put my search to rest. Where to put what etc.

Thank you and best regards
Don't suggest the use of system() to do stupid stuff. The ShellExecute() function is ideally suited for this job.

You are compiling with UNICODE flags enabled, which is causing type error compatabilities between your string types. The function expects a wchar_t string, but you are giving it a char string.

You can use the Windows API to convert to the proper type, but the STL also provides the std::copy() algorithm:
 
#include <algorithm> 
1
2
3
4
5
6
7
const char* urlA = "http://www.cplusplus.com/";
wchar_t urlW[ MAX_PATH ];
std::copy( urlA, urlA + lstrlenA( urlA ) + 1, urlW );
if ((int)ShellExecuteW( NULL, L"open", urlW, NULL, NULL, SW_SHOW ) < 32)
  {
  fooey();
  }

Hope this helps.
Ah thank you Duoas! it works great thank you so much.

If i may add one more question to this post. If i want to create a timer starting on zero going to lets say 3000 in seconds, how would i go about ensuring that it moves 1 numerical each second (1,2,3,4.... and so on)
EDIT: Way late... that's what I get for not refreshing this site enough times an hour.

EDIT2: So... ShellExecute() is a bit more than system()? I need to brush up on my Windows APIs...

@Melander:
http://cplusplus.com/reference/clibrary/ctime/clock/
http://cplusplus.com/reference/clibrary/ctime/CLOCKS_PER_SEC/

-Albatross
Last edited on
that's what I get for not refreshing this site enough times an hour.
Happens to me all the time. I've just graduated from feeling it is obnoxious to taking it as it comes...

The ShellExecute() function's purpose is to activate a document. So if you have a Word .doc file, it starts Word (or OO or whatever program you have associated with the file). Likewise an .html file loads your chosen browser and displays it. And .txt files start notepad (or whatever you have associated). Etc.

It will take any properly formatted URL, according to Windoze standards, of course.

Hope this helps.
Thank you all for your responses if i may ask one final question.

Presume i use Duoas build for loading a URL, but i want user input to decide the URL how would i do it? cin >> gives me no luck is it about it cant get input for a const char ?

the best regards Jonas.
Get the input into an std::string, then use the c_str() method to get a const char*.
If i can have a short example/test source code please my noobness comes into play again.

Best regards Jonas.
I've already given you an example.

But I have to warn you about doing this. You should avoid passing user input directly into functions that do things.
Yes Duoas i was just meaning the wat to input a URL not the function to open it im sorry if i wasent clear on that.

Hm ok, many errors or? and if so is there a way to pass the URL before initializing the actually sequence assosiated with this function so it still will have a complete const char* when any component is called?
Make sure the first letters of the string are "http://" or "https://".
Actually, could we see the code that's giving you trouble?

-Albatross
Certainly but it is not giving me trouble i just wanna add a user input to it.
Note that void rpeatFunc () is not ready so just remove that of so.

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include "stdafx.h"
#include <iostream>
#include <windows.h>
//#include <algorithm>
//#include <stdio.h>

void rpeatFunc()

int main()
{
	using namespace std;

	// Time variables.
	int AIM_TIME;

	// Title screen. still CMD oriented but understand able.
	cout << endl;
	cout << " ________________________________________________________ \n";
	cout << "|  ____________________________________________________  |\n";
	cout << "| |  ________________________________________________  | |\n";
	cout << "| | |  ____________________________________________  | | |\n";
	cout << "| | | |                                                                                          | | | |\n";
	cout << "| | | |                                                                                          | | | |\n";
	cout << "| | | |_____________________________________________| | | |\n";
	cout << "| | |________________________________________________| | |\n";
	cout << "| |____________________________________________________| |\n";
	cout << "|________________________________________________________|\n";
	cout << endl;
	cout << " ________________________________________________________ \n";
	cout << "| 1) 10 minutes delay                                    |\n" << "\a";
	cout << "| 2) 20 minutes delay                                    |\n";
	cout << "| 3) 40 minutes delay                                    |\n";
	cout << "| 4) 60 minutes delay                                    |\n";
	cout << "| Please enter a time: ";

	cin >> AIM_TIME;

	switch (AIM_TIME)
	{
		case 1:
			{
				printf ( "Delaying process for 10 minutes\n" );
				Sleep ( 600000 );
				printf ( "Done!\n" );

				cout << "\a \a \a";

				const char* urlA = "http://www.cplusplus.com/";
				wchar_t urlW[ MAX_PATH ];
				std::copy( urlA, urlA + lstrlenA( urlA ) + 1, urlW );
				if ((int)ShellExecuteW( NULL, L"open", urlW, NULL, NULL, SW_SHOW ) < 32);
				break;
			}
		case 2:
			{
				printf ( "Delaying process for 20 minutes\n" );
				Sleep ( 1200000 );
				printf ( "Done!\n" );

				cout << "\a \a \a";

				const char* urlB = "http://www.cplusplus.com/";
				wchar_t urlW[ MAX_PATH ];
				std::copy( urlB, urlB + lstrlenA( urlB ) + 1, urlW );
				if ((int)ShellExecuteW( NULL, L"open", urlW, NULL, NULL, SW_SHOW ) < 32);
				break;
			}
		case 3:
			{
				printf ( "Delaying process for 40 minutes\n" );
				Sleep ( 2400000 );
				printf ( "Done!\n" );

				cout << "\a \a \a";

				const char* urlC = "http://www.cplusplus.com/";
				wchar_t urlW[ MAX_PATH ];
				std::copy( urlC, urlC + lstrlenA( urlC ) + 1, urlW );
				if ((int)ShellExecuteW( NULL, L"open", urlW, NULL, NULL, SW_SHOW ) < 32);
				break;
			}
		case 4:
			{
				printf ( "Delaying process for 60 minutes\n" );
				Sleep ( 3600000 );
				printf ( "Done!\n" );

				cout << "\a \a \a";

				const char* urlD = "http://www.cplusplus.com/";
				wchar_t urlW[ MAX_PATH ];
				std::copy( urlD, urlD + lstrlenA( urlD ) + 1, urlW );
				if ((int)ShellExecuteW( NULL, L"open", urlW, NULL, NULL, SW_SHOW ) < 32);
				break;
			}
			
	}


	return 0;
}
Last edited on
If you are just going to pass in constant literals, why bother with the copying?
1
2
// When using char strings
ShellExecuteA( NULL, "open", "http://www.cplusplus.com/", NULL, NULL, SW_SHOW );
1
2
// When using wchar_t strings
ShellExecuteW( NULL, L"open", L"http://www.cplusplus.com/", NULL, NULL, SW_SHOW );
1
2
// When you aren't sure
ShellExecute( NULL, TEXT( "open" ), TEXT( "http://www.cplusplus.com/" ), NULL, NULL, SW_SHOW );

Also, only the code that is not identical needs to go in in the switch... You can also make it easier using some const arrays:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const unsigned int AIM_times[] = { 10, 20, 40, 60 };

cin >> AIM_TIME;

if ((AIM_TIME < 1) || (AIM_TIME > (sizeof( AIM_times ) / sizeof( AIM_times[ 0 ] ))))
  {
  fooey();
  }

printf ( "Delaying process for %u minutes\n", AIM_times[ AIM_TIME - 1 ] );
Sleep ( 6000 * AIM_times[ AIM_TIME - 1 ] );
printf ( "Done!\n" );

ShellExecute( NULL, TEXT( ...

Also, you are mixing C and C++ I/O. Don't do that. If you are using C++, stick with C++ I/O:
1
2
3
cout << "Delaying process for " << AIM_times[ AIM_TIME - 1 ] << " minutes\n";
Sleep ( 6000 * AIM_times[ AIM_TIME - 1 ] );
cout << "Done!\n";

Finally, I'm not sure exactly what you are trying to accomplish, but putting your program to sleep for so long without any escape is obnoxious. You might want to look at the WaitForSingleObject() function to give the user the ability to abort it.
http://www.cplusplus.com/forum/beginner/4572/#msg20150
http://www.cplusplus.com/forum/beginner/5619/#msg25047
That should be enough to start.

Hope this helps.
Last edited on
Hey again i have now been going over this every way possible and i think i am to big of a nuub to understand the explanation.

If say i wanna pass in the URL to a web site then open it How exactly would i do it? i always get the very same errors;

Either it cant convert it into a string i dont got the exact words but its something like: cant convert const char into LBRM(something like that) or it gives me the longest error code possible but the main and first fault is:

error C2679: binary '>>' : no operator found which takes a right-hand operand of type 'const char *' (or there is no acceptable conversion)

I cant wrap my head around this...
this is my last try at entering a URL to later be opened:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
				const char* urlT1;
				cout << "Please enter URL: ";
				cin >> urlT1;

				printf ( "Delaying process for 60 minutes\n" );
				Sleep ( 600000 );
				printf ( "Done!\n" );

				cout << "\a \a \a";

				wchar_t urlT01[ MAX_PATH ];
				std::copy( urlT1, urlT1 + lstrlenA( urlT1 ) + 1, urlT01 );
				if ((int)ShellExecuteW( NULL, L"open", urlT01, NULL, NULL, SW_SHOW ) < 32);
				break;


the rest of the code is the same as before.

NOTE: still converting from C to C++ so thats why there is printf statements they will be removed soon.
You cannot modify a constant character string.
Further, you must have memory somewhere to do stuff with it.

Use a std::string to handle character strings.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <string>
#include <windows.h>
...
using namespace std;
...

string url;
cout << "Please enter URL: ";
getline( cin, url );

cout << "Delaying process for 60 minutes.\n" );
Sleep( 3600000 );  // (1000 ms)(60 s)(60 min)
cout << "Done!\n";
MessageBeep( 0xFFFFFFFF );
MessageBeep( 0xFFFFFFFF );
MessageBeep( 0xFFFFFFFF );

ShellExecuteA( NULL, "open", url.c_str(), NULL, NULL, SW_SHOW );

Good luck.
[edit]Oops! Fixed.
Last edited on
Pages: 12