I have tried the following:
#import "shell32.dll"
int ShellExecuteW(int hwnd,string operation,string file,string parameters,string directory,int showCmd);
#import
string strParameters = "/c python c:\\createFiles.py ";
int result = ShellExecuteW(0, "open", "cmd.exe", strParameters, NULL, 1);
if (result <= 32) Print("Shell Execute Failed: ", result);
The above command is creating the command prompt to open and then execute the respective commands on it. Meanwhile if I am clicking on something and suddenly the execution occurs then the complete windows is hanged and nothing is executed till I reclick outside the cmd prompt.
Kindly, let me know how I can run the command silently without opening the cmd prompt on the screen.
Related
I have built a networking app for MacOS for private usage. It uses shell commands and runs bash files.
Most of my colleagues are using MacOS, but still need to publish the same app for Windows.
Is there any ways to hide a cmd window when I runs shell script?
Thanks in advance.
On Windows app, you can do that changing the folowing lines in windows/runner/resources/main.cpp
if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) {
CreateAndAttachConsole();
}
to this:
if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) {
CreateAndAttachConsole();
}else {
STARTUPINFO si = { 0 };
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
PROCESS_INFORMATION pi = { 0 };
WCHAR lpszCmd[MAX_PATH] = L"cmd.exe";
if (::CreateProcess(NULL, lpszCmd, NULL, NULL, FALSE, CREATE_NEW_CONSOLE | CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
do {
if (::AttachConsole(pi.dwProcessId)) {
::TerminateProcess(pi.hProcess, 0);
break;
}
} while (ERROR_INVALID_HANDLE == GetLastError());
::CloseHandle(pi.hProcess);
::CloseHandle(pi.hThread);
}
}
More information here: https://github.com/flutter/flutter/issues/47891
There are some options to run a cmd hidden on Windows for example:
start a cmd window as hidden by using the "hide" option on a bat script or programmatically using the Windows API ShowWindow(SW_HIDE). Hidden in this case means you won't see the GUI and it has no presence on the task-bar.
run it through "Task Scheduler"
run it as background service
Some examples:
Bat script: How to run .BAT files invisibly without displaying the Command Prompt
C-sharp: Hide Command Window in Application
C-sharp: Run CMD command without displaying it
C-sharp: Sample code to schedule a task using WindowsTask Scheduler
I'm creating a custom build of node.js that should not show a console window to the user.
I've tried changing the linker config in the gyp file to 2 (which should set the linker flag /SUBSYSTEM:WINDOWS), but I still get a console window when I run the resulting node.exe binary.
How can I prevent the console window from appearing?
Edit: Further investigation reveals that the linker config in node.gyp is not taking effect. The generated node.vcxproj still has <Link><SubSystem>Console</SubSystem></Link> (which is very strange to me, since adding 'UACUIAccess': 'true' in the same part of node.gyp did take effect), so the built binary is incorrectly linked.
Solution 1
Save this one line of text as file invisible.vbs:
CreateObject(“Wscript.Shell”).Run “”"” & WScript.Arguments(0) & “”"”, 0, False
To run any program or batch file invisibly, use it like this:
wscript.exe “C:\Wherever\invisible.vbs” “C:\Some Other Place\MyBatchFile.bat”
To also be able to pass-on/relay a list of arguments use only two double quotes
CreateObject(“Wscript.Shell”).Run “” & WScript.Arguments(0) & “”, 0, False
eg: Invisible.vbs “Kill.vbs ME.exe”
Solution 2
Use a command line tool to silently launch a process : Quiet.
Solution 3
Roll your own C++ Win32 App:
PROCESS_INFORMATION procInfo = {0};
STARTUPINFOstartupInfo = {0};
SECURITY_ATTRIBUTESsaAttr = {0};
HANDLEhStdIn = GetStdHandle(STD_INPUT_HANDLE);
HANDLEhStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLEhStdErr = GetStdHandle(STD_ERROR_HANDLE);
// build up security attributes
saAttr.nLength = sizeof(saAttr);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
// set file handles for process to be created
startupInfo.cb = sizeof(startupInfo);
startupInfo.dwFlags = STARTF_USESTDHANDLES;
startupInfo.hStdInput = hStdIn;
startupInfo.hStdOutput = hStdOut;
startupInfo.hStdError = hStdErr;
// build command line: format is [cmd.exe /c "%batchScript%" %batchArgs%]
if (-1 == _snprintf_s(cmd, sizeof(cmd),"cmd.exe /c \"%s\" %s", batchScript, batchArgs))
errorExit("_snprintf_s(\"cmd.exe /c \"%%s\" %%s\"), \"%s\", \"%s\") failed.", batchScript, batchArgs);
rc = CreateProcess(NULL, cmd, NULL, &saAttr, TRUE, CREATE_NO_WINDOW, NULL, tempPath, &startupInfo, &procInfo);
You have to change the SubSystem field value in node.exe PE optional header. The current value is 3 which is defined as Windows Console. If you change it to 2 (which is defined as Windows GUI) there would be no console window. In order to patch the executable file, you have to use utilities to change Optional Header of PE.
One example of such a tool is PE tools.
Click on Optinal Header and then change the Subsystem from 3 to 2.
That`s all.
Remember that with this change you can only run js files. You can not use interactive mode.
It appears that you must:
Comment out the 'SubSystem': 1 line in common.gypi. (Changing it to 2 causes the build to fail in mksnapshot.)
Change SubSystem to 2 in node.gyp
Also add 'EntryPointSymbol': 'wmainCRTStartup' to node.gyp.
This builds a node.exe that does not create a console window.
I'm using D as a scripting language for Windows 7 console stuff to automate boring tasks. One of my scripts (open.exe) is supposed to allow me to open stuff from the command line without me having to specify which program I use (I have a configuration file with this stuff). Now, I use executeShell to do this, and call something like start [name of program I want to use] [name of input file]. If I do this directly from the shell, it returns immediately, but if I do it using my D script, it doesn't return until the program that it opens is closed. What should I do to allow it to return immediately?
For reference purposes, this is the business logic of my script (the main method just does some argument parsing for piping purposes):
immutable path = "some//path//going//to//config//file.conf";
void process(string input) {
string extension = split(input,".")[1]; //get file extension from input
auto config = File(path,"r"); auto found = false;
while (!config.eof()){
auto line = chomp(config.readln());
if (line[0]!='#') { //skip comment lines
auto divided = split(line, ":");
if (divided[0] == extension) {
found = true;
auto command = "start " ~ divided[1] ~ " " ~ input;
auto result = executeShell(command);
//test for error code and output if necessary
writeln(result.output);
}
}
}
if (!found)
writeln("ERROR: Don't know how to open " ~ input);
}
From the top of the std.process documentation:
Execute and wait for completion, collect output - executeShell
The Windows start program spawns a process and exits immediately. D's executeShell does something else. If you'd like to spawn another program, use the appropriate functions: spawnProcess or spawnShell.
I have a command line application that runs on a windows server. The command prompt remains open when the program is running, and log messages are output to the command prompt window as the program functions.
My need is to read the messages that appear on the command prompt as the program runs, and then run particular commands if a specific set of words appear in the messages.
What's the easiest way to do this on a windows machine? (without modifying the app)
Reading those two posts will give you the solution:
ProcessStartInfo
Capturing console output.
The idea is to to run your app (not modifying it) from your new app (written in C#) and redirect its input-output here, reading and writing as you please.
An example could be:
Process proc;
void RunApp()
{
proc = new Process();
proc.StartInfo.FileName = "your_app.exe";
proc.StartInfo.Arguments = ""; // If needed
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardInput = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.OutputDataReceived += new DataReceivedEventHandler(InterProcOutputHandler);
proc.Start();
proc.WaitForExit();
}
void InterProcOutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
// Read data here
...
// Send command if necessary
proc.StandardInput.WriteLine("your_command");
}
I have subversion server with a post-commit hook to do something.
I want the checkin finish soon, not wait the hook script.
But by design, the Subversion post-commit hook script will run until all child process exit, so using somthing like:
start another_prog...
in the hook bat file has no use.
So I want to know how to run another program in Windows bat file which not create child process or let the child process detach from the parent.
Synchronous. The second notepad won't launch until you close the first.
notepad.exe c:\temp\a.txt
notepad.exe c:\temp\b.txt
Asynchronous: The second notepad will launch even if you haven't closed the first.
start notepad.exe c:\temp\a.txt
start notepad.exe c:\temp\b.txt
More info about the start command:
http://www.robvanderwoude.com/ntstart.php
EDIT: The following comment was made elsewhere by #zhongshu, the original poster. I'm only copying it here:
start cmd /c doesn't work because SVN
post-commit hook will wait for the
hook and the child process created by
the hook exit. It's the design of SVN.
I have found a solution, Please refer:
http://svn.haxx.se/users/archive-2008-11/0301.shtml
Assuming that he knows what he's talking about, I'm wrong and...undeserving.
I found a method to resolve my question, compile the following c code and named the exe output as runjob.exe, and then in the hook bat file, use " runjob another_prog " , now it's ok.
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
int _tmain()
{
char * pCmd = ::GetCommandLine();
// skip the executable
if (*pCmd++ == L'"')
{
while (*pCmd++ != L'"');
}
else
{
while (*pCmd != NULL && *pCmd != L' ')
++pCmd;
}
while (*pCmd == L' ')
pCmd++;
STARTUPINFO si;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
PROCESS_INFORMATION pi;
ZeroMemory( &pi, sizeof(pi) );
// Start the child process.
BOOL result = CreateProcess
(
NULL, // No module name (use command line)
pCmd, // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set bInheritHandles to FALSE
DETACHED_PROCESS, // Detach process
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi // Pointer to PROCESS_INFORMATION structure (returned)
);
if (result) return 0;
char msg[2048];
FormatMessage
(
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
::GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT),
msg, sizeof(msg),
NULL
);
fputs(msg, stderr);
_flushall();
return -1;
}
What you can do is create a Scheduled Task that executes the batch script or other executable that runs for a long time. Set it to run once, in the past and don't set it to delete the task when no more runs are scheduled. Then in your Subversion hook script, put the following line in:
schtasks /run /tn NameOfYourTaskHere
I confirmed with a test by having my scheduled task run Notepad++ and the Notepad++ executable showed up as a child of svchost.exe, not the cmd.exe window that I executed the schtasks command from.
Use:
start cmd /c "your command"
Cheers.
Try cmd /c "your command"
Could you use the windows task scheduler command line interface "schtasks /run" to start a job that runs the "another_prog"? You'd have to create the job ahead of time. There also used to be a "SOON" program with the Windows (NT) Resource Kit that would create dynamic entries for the "AT" command scheduler to run a job in a few minutes that would not require setting up a job ahead of time, it can still be found with a little searching.
You can create a hybrid batch/JScript file (i.e. a batch file able to run embedded JScript) where the JScript part will run another_prog in detached mode with shell.Run(prog, 0, false):
#if (#X)==(#Y) #end /* JScript comment
rem put any batch code that runs before another_prog here
#cscript //E:JScript //nologo "%~f0" "another_prog" 0 false
rem put any batch code that runs after another_prog here
exit /b %errorlevel%
#if (#X)==(#Y) #end JScript comment */
var ARGS = WScript.Arguments;
var shell = new ActiveXObject("WScript.Shell");
shell.Run(ARGS.Item(0),ARGS.Item(1),ARGS.Item(2));`