I am launching Chrome with the app="http://..." parameter (a Chrome application shortcut) via C++. Now it seems to open with a size of roughly 400x800 which is crazy. I'd like to open it maximized or at least have it remember the size.
Is there a way to achieve this?
If you don't mind using the default browser (which, in my opinion, is the best option) instead of forcing the use of Chrome, you can simply open your URL with ShellExecute specifying that you want the window to be maximized:
#include <windows.h>
#include <Shellapi.h>
// requires linking towards Shell32.lib
// ...
if(ShellExecute(NULL, "open", "http://www.stackoverflow.com", NULL, NULL, SW_SHOWMAXIMIZED)<=32)
{
/* an error occurred */
}
I must open Chrome, and I have its path known in a variable. I also need to specify one parameter. Is this a problem?
Well, in this case it's better to use CreateProcess:
#include <windows.h>
// ...
// Assuming that the path to chrome is inside the chromePath variable
// and the URL inside targetURL
// Important: targetURL *must be* a writable buffer, not a string literal
// (otherwise the application may crash on Unicode builds)
PROCESS_INFORMATION processInformation;
STARTUPINFO startupInfo;
memset(&processInformation, 0, sizeof(processInformation));
memset(&startupInfo, 0, sizeof(startupInfo));
startupInfo.cb = sizeof(startupInfo);
startupInfo.wShowWindow = SW_SHOWMAXIMIZED;
BOOL result= CreateProcess(chromePath, targetURL, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &startupInfo, &processInformation);
if(result)
{
WaitForSingleObject( processInformation.hProcess, INFINITE );
CloseHandle( processInformation.hProcess );
CloseHandle( processInformation.hThread );
}
else
{
// An error happened
}
Notice that you can try to specify a default size/posizion for the window using the dwX/dwY/dwXSize/dwYSize members of the STARTUPINFO structure, but I'm not sure if Chrome respects these settings.
--start-maximized should do the trick.
Taken from http://peter.sh/experiments/chromium-command-line-switches/
Haven't tested it myself though..
Related
The saga continues...
I've searched the web, i've searched on StackOverflow, i found many hope giving answers/solutions, but somehow they have all failed (up)on me (including the ones related to ShellExecute(Ex) ).
How to hide a (flashing) CMD window (incl. arguments) using CreateProcess??
I basically want to call/execute a set of conditional/native cmd.exe commands (i.e. FOR /F, and ||), but also an external command FIND(STR).exe. And this, without showing a (flashing) CMD window.
But even hiding something as simple as "cmd.exe /C ECHO ...flashing window is bad..." seems impossible to do.
The code i've tried (including many variations related to the dwFlags and wShowWindow flags
#include <windows.h>
int main()
{
char cmdline[] = "cmd.exe /c ECHO ...flashing window is bad...";
PROCESS_INFORMATION pi;
STARTUPINFO si;
// memset(&si,0,sizeof(STARTUPINFO));
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
// si.dwFlags = STARTF_USESTDHANDLES;
// si.dwFlags = CREATE_NO_WINDOW;
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
// si.wShowWindow = CREATE_NO_WINDOW;
CreateProcess(NULL, (LPSTR) cmdline, NULL, NULL, 0, 0, NULL, NULL, &si, &pi);
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
// ExitProcess;
return 0;
}
I don't want to rely on external programs i.e. .vbs (Windows Scripting Host) or shortcut tricks, but simply a standalone compiled .exe.
Is this (really) too much to ask, or am i doing it (completely) wrong?
Thanks...
Update: You also seem to confuse CreateProcess flags (its dwCreationFlags argument) with the member of STARTUPINFO structure. These are different flags, CREATE_NO_WINDOW should not be in STARTUPINFO.
You have to pass the CREATE_NO_WINDOW flag, then the console window won't show. Originally I've answered that you have to redirect the standard handles which is not correct (but still highly recommanded).
Set STARTF_USESTDHANDLES and fill in appropriate handles. If you are interested in the output of the process, create pipes, otherwise you can just open nul an pass that.
Try Using ProcessBuilder. Here is an example of some code that I have that seems to work just fine. In my code below, the shellScript is a StringBuilder that I am dynamically creating that contains the command and it's parameters that I want to execute.
String[] scriptArray = shellScript.toString().split(" ");
ProcessBuilder builder = new ProcessBuilder(scriptArray);
File outputFile = new File("/logs/AgentOutputLog.txt");
File errorFile = new File("/logs/AgentErrorLog.txt");
builder.redirectOutput(outputFile);
builder.redirectError(errorFile);
Process process = builder.start();
int errCode = process.waitFor();
//errCode = 0 means online
if(errCode == 0){
success = true;
break;
//errCode = 1 means offline
} else if (errCode == 1){
success = false;
break;
}
I'm trying to figure out how to pass filename from within an existing executable to a newly generated executable of same type & then the new exe load said file name. Following is something I'm working on but I'm bit lost really.
CString cstrExePathLoc;
GetModuleFileName(NULL, cstrExePathLoc.GetBuffer(MAX_PATH), MAX_PATH);
wchar_t szCommandLine[1024] = _T("C:\\Users\\Home\\Desktop\\testfile.tmp");
PROCESS_INFORMATION processInfo;
STARTUPINFO startupInfo;
::ZeroMemory(&startupInfo, sizeof(startupInfo));
startupInfo.cb = sizeof(startupInfo);
CreateProcess(
cstrExePathLoc, szCommandLine, NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE, NULL, NULL,
&startupInfo, &processInfo
);
EDIT: this still doesn't open the file. A new ExeApp is started but no file is loaded. No errors generated at all.
I've searched net but no examples I've come across clearly explain how to do this. Any help would be appreciated. Thanks.
EDIT: simple solution here that's worked thanks to Robson Filho Colodeti below.
CString cstrExeFilePathAndFilePath2Open = cstrExePathLoc;
cstrExeFilePathAndFilePath2Open += L" \"";
cstrExeFilePathAndFilePath2Open += cstrFilePath2Open;
cstrExeFilePathAndFilePath2Open += L"\"";
CreateProcess(csExePath, cstrExeFilePathAndFilePath2Open.GetBuffer(0), NULL, NULL, TRUE, NULL, NULL, NULL, &sui, &pi);
Opening the other program
Using CreateProcess
you are in the right way, you can use the CreateProcess method.
BOOL fSuccess;
CString csDir = L"c:\your\working\directory\";
CString csParameters = L"parameter1 parameter2 parameter3 /parameter4=value";
CString csCommand = L"c:\folder\of\the\executable\executable.exe";
csCommand+= L" ";
csCommand+= csParameters;
// Create the child process.
fSuccess = CreateProcess(NULL, csCommand.GetBuffer(0), NULL, NULL, TRUE, 0, NULL,
csDir, &startupInfo, &processInfo);
Using ShellExecute
an easier way is to use the ShellExecute method because the create process method is a more "advanced" way to call a process since it gives you a lot of possibilities to control the results etc...
Reading the parameters inside the other program
then you will have to read these parameters from the other executable: check this thread
I created a windows service in c++ using visual studios and now I want the service to run an exe file. The service is set to start every time the computer starts
i know i need to use code to locate the path of the exe like C:\MyDirectory\MyFile.exe but how to I actually run the file from the service?
i read about the process start method here but i am not sure how to use it
You can use createprocess function in your service to run an exe.
TCHAR* path = L"C:\\MyDirectory\\MyFile.exe";
STARTUPINFO info;
PROCESS_INFORMATION processInfo;
ZeroMemory( &info, sizeof(info) );
info.cb = sizeof(info);
ZeroMemory( &processInfo, sizeof(processInfo) );
if (CreateProcess(path, NULL, NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo))
{
::WaitForSingleObject(processInfo.hProcess, INFINITE);
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
}
I am using CreateProcess, but I can't start a process I am using the following code but I am getting the error "Invalid access to memory location" but I don't know why.
Is there any problem with my code?
#include <Windows.h>
#include <stdio.h>
//#include "common.h"
int main(void)
{
DWORD creation_flags = DEBUG_PROCESS;
STARTUPINFO startupinfo;
PROCESS_INFORMATION process_information;
char *path_to_exe = "D:\\dbg\\calc.exe";
startupinfo.dwFlags = 0x1;
startupinfo.wShowWindow = 0x0;
startupinfo.cb = sizeof(startupinfo);
if(CreateProcess( path_to_exe,
NULL,
NULL,
NULL,
NULL,
creation_flags,
NULL,
NULL,
&startupinfo,
&process_information)){
printf("We have successfully launched the process!\n");
printf("[*] PID: %d\n", process_information.dwProcessId);
}
else
printf("[*] Error: %d.\n", GetLastError());
}
You have only filled in 3 fields of the startupinfo Structure.
The remaining fields are filled with garbage, and some of that garbage is likely leading to bad problems.
You should fully initialize the structure, explicitly putting NULL, 0 and other "empty" values where you don't want to specify anything.
Try zeroing the startup info structure. Some of it's members (e.g. lpTitle) are used even if you don't set an explicit flag.
Also beware that CreateProcess may temporarily write to the application name string, so you may want to avoid passing a read-only string literal. This only happens with the unicode version of the function though, at least on recent versions of Windows.
I am trying to use the TerminateProcess to terminate an app launched by ShellExecuteEX like this:
SHELLEXECUTEINFO ExecuteInfo;
ExecuteInfo.fMask = SEE_MASK_FLAG_NO_UI; /* Odd but true */
ExecuteInfo.hwnd = NULL;
ExecuteInfo.cbSize = sizeof(ExecuteInfo);
ExecuteInfo.lpVerb = NULL;
ExecuteInfo.lpFile = "http://www.microsoft.com";
ExecuteInfo.lpParameters = "";
ExecuteInfo.lpDirectory = NULL;
ExecuteInfo.nShow = SW_SHOW;;
ShellExecuteEx(&ExecuteInfo);
//WaitForSingleObject(ExecuteInfo.hProcess, 0);
Sleep(4000);
TerminateProcess(ExecuteInfo.hProcess, 0);
IE gets opened but it never closes. Am I doing something wrong?
According to MSDN, fMask must be set to SEE_MASK_NOCLOSEPROCESS for .hProcess to get set. I would add a test to see if it is NULL. As a side note I've always had better luck using CreateProcess.
Edit:
This is how you do it using CreateProcess:
PROCESS_INFORMATION pi = {0};
STARTUPINFO si = {0};
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOW;
CreateProcess( NULL,
"C:\\Program Files\\Internet Explorer\\iexplore.exe http://www.google.com/",
NULL,
NULL,
FALSE,
NORMAL_PRIORITY_CLASS,
NULL,
NULL,
&si,
&pi );
Sleep(4000);
TerminateProcess(pi.hProcess, 0);
You should add error-checking and could query the path of the default browser using: AssocQueryString like this:
AssocQueryString(0,ASSOCSTR_EXECUTABLE,"http","open", szExe, &cchExe);
You can get more information by checking the returned hProcess (e.g., in a debugger). Also make sure you have the SEE_MASK_NOCLOSEPROCESS flag set.
But my psychic powers say: Opening an IE document doesn't necessarily create a new process. And, if it does, it may not be the one you think it is: The process you may have created may have spawned yet another process to actually host the document. Raymond Chen mentions that about halfway down this blog post.