I think that code was an older version. This looks more complete:
//* createProcess.cpp: create a process and return.
#include "stdafx.h"
#include "windows.h"
#include "shellapi.h"
#include <iostream> // cerr, endl, flush
#include <stdlib.h> // exit()
using namespace std;
#define BUFSZ 2048
int _tmain(int argc, wchar_t* argv[])
{ int SHOWFLAG = SW_NORMAL;
if (argc < 2)
{ wcout << "Syntax is:" << endl;
wcout << " " << argv[0] << " [/h or /m] <executable> [arg1 arg2 ...]" <<
endl;
wcout << "To run <executable>, [hide or minimize window] with optional
arguments, as stand-alone process." << endl;
wcout << "E.g." << endl;
wcout << argv[0] << " C:\\Windows\\system32\\notepad.exe someFile.txt" <<
endl;
return -1;
}
SHELLEXECUTEINFO shExecInfo;
shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
shExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
shExecInfo.hwnd = NULL;
shExecInfo.lpVerb = L"runas";
wchar_t args[BUFSZ]; args[0] = L'\0';
if (argc > 1)
{ int StartIx = 1;
if( 0==_wcsicmp( argv[StartIx], L"/h")) { StartIx = 2; SHOWFLAG =
SW_HIDE;} // Flag "/h" means "hide window"
if( 0==_wcsicmp( argv[StartIx], L"/m")) { StartIx = 2; SHOWFLAG =
SW_SHOWMINIMIZED;} // Flag "/m" means "minimize window"
shExecInfo.lpFile = argv[StartIx];
if (argc > (StartIx+1)) wcscpy_s(args, BUFSZ, argv[StartIx+1]);
for (int ii = StartIx+2; ii < argc; ii++)
{ wcscat_s(args, BUFSZ, L" \0"); wcscat_s(args, BUFSZ, argv[ii]);
}
args[wcslen(args)] = L'\0';
} else
{ shExecInfo.lpFile = L"CrapOut";
}
shExecInfo.lpParameters = args;
shExecInfo.lpDirectory = NULL;
shExecInfo.nShow = SHOWFLAG;
/*
vShow [in, optional] / Type: Variant
A recommendation as to how the application window should be displayed
initially. The application can ignore this recommendation. This parameter
can be one of the following values. If this parameter is not specified, the
application uses its default value.
Value Meaning
0 Open the application with a hidden window.
1 Open the application with a normal window. If the window is
minimized or maximized, the system restores it to its original size and
position.
2 Open the application with a minimized window.
3 Open the application with a maximized window.
4 Open the application with its window at its most recent size and
position. The active window remains active.
5 Open the application with its window at its current size and
position.
7 Open the application with a minimized window. The active window
remains active.
10 Open the application with its window in the default state
specified by the application.
*/
shExecInfo.hInstApp = NULL;
ShellExecuteEx(&shExecInfo);
/*
wcout << L"Process: " << shExecInfo.hProcess << endl;
wcout << L"Handle: " << shExecInfo.hwnd << endl;
wcout << L"Instance: " << shExecInfo.hInstApp << endl;
wcout << L"IDList: " << shExecInfo.lpIDList << endl;
*/
return 0;
}
bool cmdOptionExists(char** begin, char** end, const std::string& option)
{ return std::find(begin, end, option) != end;
}
On Fri, Dec 13, 2019 at 12:32 PM Devon McCormick <[email protected]> wrote:
> Hi - I get different behavior than this running "shell" from a J-console
> session running under emacs: control returns to the J session after the
> spreadsheet starts up. This is under Windows, which you appear to be
> running. Also, I get the same behavior under JQt.
>
> However, I have seen the behavior you're reporting when I invoke a .bat
> file. For this reason, I wrote a little C module, called "createProcess",
> to spin off a process and return.
>
> The code for that follows, if you are interested.
>
> Regards,
>
> Devon
> ---
> //* createProcess.cpp: create a process and return.
>
> #include "stdafx.h"
> #include "windows.h"
> #include "shellapi.h"
> #include <iostream> // cerr, endl, flush
> #include <stdlib.h> // exit()
>
> using namespace std;
>
> #define BUFSZ 2048
>
> int _tmain(int argc, wchar_t* argv[])
> {
> SHELLEXECUTEINFO shExecInfo;
> shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
> shExecInfo.fMask = NULL;
> shExecInfo.hwnd = NULL;
> shExecInfo.lpVerb = L"runas";
>
> wchar_t args[BUFSZ]; args[0] = L'\0';
> if (argc > 1)
> { shExecInfo.lpFile = argv[1];
> if (argc > 2) wcscpy_s(args, BUFSZ, argv[2]);
> for (int ii = 3; ii < argc; ii++)
> { wcscat_s(args, BUFSZ, L" \0"); wcscat_s(args, BUFSZ, argv[ii]);
> }
> args[wcslen(args)] = L'\0';
> } else
> { shExecInfo.lpFile = L"foo";
> }
> shExecInfo.lpParameters = args;
> shExecInfo.lpDirectory = NULL;
> shExecInfo.nShow = SW_NORMAL;
> shExecInfo.hInstApp = NULL;
>
> ShellExecuteEx(&shExecInfo);
> //WaitForSingleObject(ShExecInfo.hProcess,INFINITE);
> return 0;
> }
>
> On Fri, Dec 13, 2019 at 8:56 AM 'Mike Day' via Programming <
> [email protected]> wrote:
>
>> I've just tried firing up a spreadsheet from J, and appear to find that
>> J has to wait for
>> the spreadsheet to be closed before the JQT terminal session can proceed.
>>
>> Specifically, if I enter the following from the terminal:
>> shell_jtask_ 'c:/d/j901/user/temp/test1.ods' NB. Open Office
>> document
>>
>> the cursor hangs at that line until I close the spreadsheet cleanly or
>> messily using
>> taskmaster.
>>
>> Odd perhaps, as shell is a cover for spawn:
>> ''&$: :(spawn ('cmd /c ' , ]))
>>
>>
>> and MSDOS help tells me that cmd/c terminates:
>>
>> "
>>
>> C:\Windows\System32>cmd/?
>> Starts a new instance of the Windows command interpreter
>>
>> CMD [/A | /U] [/Q] [/D] [/E:ON | /E:OFF] [/F:ON | /F:OFF] [/V:ON | /V:OFF]
>> [[/S] [/C | /K] string]
>>
>> /C Carries out the command specified by string and then terminates
>>
>> "
>>
>>
>> Not too important for me - just puzzling.
>>
>>
>> Thanks,
>>
>>
>> Mike
>>
>>
>>
>>
>> ----------------------------------------------------------------------
>> For information about J forums see http://www.jsoftware.com/forums.htm
>>
>
>
> --
>
> Devon McCormick, CFA
>
> Quantitative Consultant
>
>
--
Devon McCormick, CFA
Quantitative Consultant
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm