I have a program written in C++ which does some computer diagnostics. Before the program exits, I need it to launch Internet Explorer and navigate to a specific URL. How do I do that from C++?
Thanks.
Here you are... I am assuming that you're talking MSVC++ here...
// I do not recommend this... but will work for you
system("\"%ProgramFiles%\\Internet Explorer\\iexplore.exe\"");
// I would use this instead... give users what they want
#include <windows.h>
void main()
{
ShellExecute(NULL, "open", "http://stackoverflow.com/questions/982266/launch-ie-from-a-c-program", NULL, NULL, SW_SHOWNORMAL);
}
if you really need to launch internet explorer you should also look into using CoCreateInstance(CLSID_InternetExplorer, ...) and then navigating. depending on what else you want to do it might be a better option.
include <windows.h>
int main()
{
ShellExecute(0, "open",
"C:\\progra~1\\intern~1\\iexplore.exe",
"http://www.foo.com",
"",
SW_MAXIMIZE);
return 0;
}
Do you really need to launch IE or just some content in a browser? The ShellExecute function will launch whatever browser is configured to be the default. Call it like this:
ShellExecute(NULL, "open", szURL, NULL, NULL, SW_SHOW);
Using just standard C++, if iexplore is on the path then
#include <stdlib.h>
...
string foo ("iexplore.exe http://example.com");
system(foo.c_str());
If it's not on the path then you need to work out the path somehow and pass the whole thing to the system call.
string foo ("path\\to\\iexplore.exe http://example.com");
system(foo.c_str());
I'm with Glen and John, except I'd prefer to use CreateProcess instead. That way you have a process handle you can do something with. Examples might be Kill IE when you are done with it, or have a thread watching for IE to terminate (WaitForSingleObject with the process handle) so it could do something like restart it, or shut down your program too.
Try this
system("\"C:\Program Files\Internet Explorer\iexplore\" http://www.shail.com");
Works perfectly..
Related
I posted a thread about how to do this in batch but it turns out batch scripting isn't very popular and I barely even know it so now I'm asking for your help doing this in C++.
here's what I tried
#include <Windows.h>
using namespace std;
void openBat(char* path) {
system(path);
}
int main() {
for(;;) {
openBat("C:\\Users\\Ivan\\Desktop\\folder\\run.bat");
Sleep(1800000);
//kill opened process
}
return 0;
}
I'm not sure how to kill the opened process because every time I run the bat script it will have a new ID and I can't kill by name because I need to have 4 of these open. All help is appreciated.
What you're doing there isn't really C++. You're basically using windows to interprete the commands you pass it like batch would do. Here is what you want to do in C++, even if it only runs on Windows.
#include <Windows.h>
#include <string>
std::wstring GetEnvString()
{
wchar_t* env = GetEnvironmentStrings();
std::wstring result{ env };
FreeEnvironmentStrings(env);
result.push_back('\0');
return result;
}
int main()
{
//Setup needed structures
STARTUPINFO si{ sizeof si };
PROCESS_INFORMATION pi;
//Command line (read- and writeable)
wchar_t cmd[] = L"cmd.exe /C C:\\Users\\Ivan\\Desktop\\folder\\run.bat";
//Create process
CreateProcess(nullptr, cmd, nullptr, nullptr, false, CREATE_UNICODE_ENVIRONMENT,
const_cast<wchar_t*>(GetEnvString().c_str()), nullptr, &si, &pi);
Sleep(1800000);
//Process Termination
TerminateProcess(pi.hProcess, 0);
// Close process and thread handles.
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
I'd recommend you read up on the CreateProcess function, as well as the Terminate Process one. There is also an example from Microsoft about how to use the former of the two. I hope this information can help you.
edit: Fixed stuff. Should work now. Credits to user4581301, his links were really useful.
I think the solution can be killing the self process tree without killing process itself.
Terminate a process tree (C for Windows)
When you create a process, hold onto the process handle and use the handle to terminate the when you are done. With the handle you know exactly which of possibly thousands of instances of the same process you want dead.
Note: Terminating a process may have undesirable results. You are almost always better off writing the processes in such a way that you can message them and request that they terminate themselves politely. How you would do this with a batch file... Smurfed if I know. Someone else may have a waaaaay better answer to this problem, and I'm fine with that. One day I might need that better solution.
On Windows you likely want CreateProcess and TerminateProcess.
Running a batchfile with CreateProcess is covered here: Use CreateProcess to Run a Batch File
Terminating a process launched with Create process is covered here:
how to terminate a process created by CreateProcess()?
What I want to do is open an .exe from another .exe. I really don't know how to do this, so I searched the internet. I tried some suggested methods from the internet, but it didn't work.
Here's my code:
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
system ("OpenFile.exe");
system ("pause");
return 0;
}
When I run it in DEV C++, it compiles, but I get a error. Can someone please help me?
You should always avoid using system() because
It is resource heavy
It defeats security -- you don't know you it's a valid command or does the same thing on every system, you could even start up programs you didn't intend to start up.
The danger is that when you directly execute a program, it gets the same privileges as your program -- meaning that if, for example, you are running as system administrator then the malicious program you just inadvertently executed is also running as system administrator. If that doesn't scare you silly, check your pulse.
Anti virus programs hate it, your program could get flagged as a virus.
You should use CreateProcess().
You can use Createprocess() to just start up an .exe and creating a new process for it.
The application will run independent from the calling application.
Here's an example I used in one of my projects:
#include <windows.h>
VOID startup(LPCTSTR lpApplicationName)
{
// additional information
STARTUPINFO si;
PROCESS_INFORMATION pi;
// set the size of the structures
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
// start the program up
CreateProcess( lpApplicationName, // the path
argv[1], // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi // Pointer to PROCESS_INFORMATION structure (removed extra parentheses)
);
// Close process and thread handles.
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
}
EDIT: The error you are getting is because you need to specify the path of the .exe file not just the name. Openfile.exe probably doesn't exist.
I've had great success with this:
#include <iostream>
#include <windows.h>
int main() {
ShellExecute(NULL, "open", "path\\to\\file.exe", NULL, NULL, SW_SHOWDEFAULT);
}
If you're interested, the full documentation is here:
http://msdn.microsoft.com/en-us/library/bb762153(VS.85).aspx.
Try this:
#include <windows.h>
int main ()
{
system ("start notepad.exe") // As an example. Change [notepad] to any executable file //
return 0 ;
}
You are getting this error because you are not giving full path. (C:\Users...\file.exe)
If you want to remove this error then either give full path or copy that application (you want to open) to the folder where your project(.exe) is present/saved.
#include <windows.h>
using namespace std;
int main()
{
system ("start C:\\Users\\Folder\\chrome.exe https://www.stackoverflow.com"); //for opening stackoverflow through google chrome , if chorme.exe is in that folder..
return 0;
}
When executable path has whitespace in system, call
#include<iostream>
using namespace std;
int main()
{
system("explorer C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe ");
system("pause");
return 0;
}
Provide the full path of the file openfile.exe
and remember not to put forward slash / in the path such as
c:/users/username/etc....
instead of that use
c:\\Users\\username\etc
(for windows)
May be this will help you.
I know this is a bit late but this is to help all the new the c++ devs.
Basically I found that if you set the file path to the location then call the program you can bypass the error.
cout << "Opening Firefox";
system("cd C:\\Program Files\\Mozilla Firefox");
Sleep(1000);
system("start firefox.exe -P");
As you can see I set the file path to the location of Firefox then launch it. In my case I'm launching the Profile manager of Firefox, if you want to launch just Firefox remove the -P. I also put in a Sleep() to give my computer time to switch file paths. if you want to go back to the default file path use, system(cd C:\\Windows\\System32);. I made this by replicating commands in the command line for windows, though you would use Linux specific commands + file paths if that is what you are using.
Can I safely assume that Windows Explorer is always started from a Windows system directory? Also, is its process always named "explorer.exe"?
And if not, how to get its full file path?
EDIT: Forgot to mention -- I need this to later find out the process ID of the Windows Explorer running in a given user session. Thus my search for its full path.
EDIT 2: Thanks everyone who contributed, and especially to sehe! After his post I found this page that explains how to set up your own shell. I made a wild test by completely replacing explorer.exe with my own process and here's the result:
Here's the full-size link if you it gets re-sized.
As you can see, I can technically replace explorer.exe with whatever process I may come up with. As you can also see in my screenshot Windows gives me a complete control over the Shell (the screenshot is my entire window.)
So the bottom line, the only way to get "explorer.exe" file path (or whatever Shell process is used) is to use those registry keys from the link I quoted above -- pretty much close to what sehe suggested, with just a few more checks to do, but it's a pretty straightforward stuff.
As for Sean Cline's suggestion, it would be a very elegant solution ONLY if we have the "stock" Windows Explorer running that comes with a tray window with that specific class name.
It is probably safe to assume that explorer.exe is always in the %windir% or %SystemRoot% as it hasn't moved for years. But, if you are trying to invoke something via Explorer, chances are you want to use the ShellExecute() function instead.
If you really do need the path, the easiest way to get it is probably with a call to SHGetKnownFolderPath() using FOLDERID_Windows as the first argument.
Edit:
Here is my stab at some code knowing that you are looking for the PID of the shell process:
DWORD trayPID;
HWND trayWnd = FindWindow("Shell_TrayWnd", NULL);
GetWindowThreadProcessId(trayWnd, &trayPID);
It looks for the hWnd of the taskbar and finds the owning PID. You will likely need to add some error handling for the case that explorer is not running and that window does not exist - unlikely, but possible.
No you can't safely assume that and none of this has to do with C++.
Also, you didn't show any code. Here goes:
The registry key for this is Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Shell (see here).
#include <windows.h>
#include <malloc.h>
#include <stdio.h>
#include <string>
LONG GetStringRegKey(HKEY hKey, const std::wstring &strValueName, std::wstring &strValue, const std::wstring &strDefaultValue)
{
strValue = strDefaultValue;
WCHAR szBuffer[512];
DWORD dwBufferSize = sizeof(szBuffer);
ULONG nError;
nError = RegQueryValueExW(hKey, strValueName.c_str(), 0, NULL, (LPBYTE)szBuffer, &dwBufferSize);
if (ERROR_SUCCESS == nError)
{
strValue = szBuffer;
}
return nError;
}
int main()
{
HKEY hKey;
LONG lRes = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\WinLogon", 0, KEY_READ, &hKey);
bool bExistsAndSuccess (lRes == ERROR_SUCCESS);
bool bDoesNotExistsSpecifically (lRes == ERROR_FILE_NOT_FOUND);
std::wstring shell;
GetStringRegKey(hKey, L"Shell", shell, L"");
}
Yes to both. Windows Explorer is always located at %WINDIR%\Explorer.exe.
I have written a code in which i want to open a HTM file when i select a particular option...
To achieve this i have created a batch file and opened it using system() as shown in code..
This is my code:
code:
#include <iostream.h>
#include <stdlib.h>
#include <dos.h>
#include <process.h>
void main()
{
cout<<"Hello World";
delay(3000);
system("a.bat");
delay(1000);
}
a.bat code:
start iexplore.exe c:\Turbo\TC\BIN\Hello.htm
When i just use this line in command line it executes but when i want to execute it using c++ code i get a bad filename or command error...
Please tell me if i am going wrong somewhere here.. or what can i do.
Please help..
Thank You..:)
Since most of your code isn't particularly portable anyway, the right way is almost certainly to use ShellExecute to "execute" the HTML file directly. I, for one, would have to be pretty desperate before I'd put up with a program using IE to open HTML files.
ShellExecute is Windows-specific, but your code isn't particularly portable right now. I suppose Unix (or similar) systems wouldn't actually stop you from naming a shell script whatever.bat, but it's certainly uncommon. You certainly shouldn't expect iexplore.exe to be available on most though (nor for executables in general to have a '.exe' extension).
ShellExecute(NULL, NULL, "c:\\Turbo\\TC\\BIN\\Hello.htm", NULL, NULL, SW_SHOWNORMAL);
You can use CreateProcess() API (http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425.aspx)
Is there a simple way to open a file by its associated program in windows?
(like double clicking it in windows explorer but done automatically with my code)
For example, on computer A, "text.txt" will be opened in wordpad but on computer B it will be opened by Notepad++ because of the users file extension assignments.
I tried ShellExecute
ShellExecute(0, L"open", L"c:\\windows\\notepad.exe" ,L"c:\\outfile.txt" , 0 , SW_SHOW );
which works but if I omit the notepad.exe parameter weird things happen (a random explorer is shown).
You want to use the file to open as the file argument, not the parameter argument. No need to specify which program to use, ShellExecute will look it up for you.
ShellExecute(0, 0, L"c:\\outfile.txt", 0, 0 , SW_SHOW );
By leaving the verb as NULL (0) rather than L"open", you get the true default action for the file type - usually this is open but not always.
See Launching Applications:
ShellExecute(NULL, "open", L"c:\\outfile.txt", NULL, NULL, SW_SHOW);
On windows, a good memory hook is to think of all data-files being executable by the shell. You can also try it out in a command box, where you can just type a filename, and it will be opened up. Or, the other way around, every file in Windows can be opened, and the default opening-action for executable files is to execute them.
According to the MS Knowledge Base, ShellExecute should work (we do this in Delphi all the time):
ShellExecute(Handle, "Open", Filename, "", "C:\", SW_SHOWNORMAL)
A little more possibilities here:
If you want to open - for example - the file by default with Notepad++ (if installed), you could scan for it's registry key if it exists and where it is, (Usually HKLM\SOFTWARE\Wow6432Node\Notepad++ [tested Win7]) then take that path and open it.
std::wstring file = L"C:\\Outfile.txt";
if (NotepadPlusPlusExists()) //Open with Notepad++ or use an other program... (maybe your own ?)
{
std::wstring wsNPPPath = GetNotepadPlusPlusPath();
ShellExecuteW(HWND, L"open", wsNPPPath.c_str(), file.c_str(), NULL, SW_NORMAL);
}
else //Open with default associated program <---
ShellExecuteW(HWND, NULL, file.c_str(), NULL, NULL, SW_NORMAL);
If you want the user to be able to change the default program or select a program he/she wants to use, you may open the "Open with" dialog.
//std::wstring StringArgsW(const wchar_t *format, ...);
std::wstring wsCmdOpenWith = StringArgsW(L"C:\\Windows\\system32\\shell32.dll,OpenAs_RunDLL \"%s\"", file.c_str());
ShellExecuteW(HWND, L"open", L"C:\\Windows\\system32\\rundll32.exe", wsCmdOpenWith.c_str(), NULL, SW_NORMAL);
You can also open the file in explorer.
std::wstring wsCmdExplorer = StringArgsW(L"/select,\"%s\"", file.c_str());
ShellExecuteW(HWND, L"open", L"explorer.exe", wsCmdExplorer.c_str(), NULL, SW_NORMAL);
If lpFile specifies a document file, the flag is simply passed to the
associated application
So you need to substitute "c:\\windows\\notepad.exe" with the actual file you want to open and leave lpParameters null.
Maybe try start instead of open?