This question could be generalized as: How to launch a given process with any intermediate process spawned having the same lifetime as the launched process, and without showing a console window. Specific arguments must be passed to the final process, but no arguments can be passed in the initial call.
To use Notepad++ as editor for 7zip you would need to launch notepad++.exe
with the -multiInst
command line parameter, otherwise it instantly closes and forwards arguments to the existing instance. Since 7zip picks up the changes you did to its temp file when the invoked program closes, you never get a chance to edit it.
Problem is, 7zip doesn't allow you to enter arguments for whatever program you're configuring as editor.
Obvious solutions that don't work, already tried:
start
to call Notepad++ : the console window does close, but unfortunately the batch executor process which is what Notepad++ was watching is gone, so it thinks you're already done editing, i.e. back to the initial problem.How would you go about this? No solution I've tried myself or read about has been fully satisfying.
Note: this is not exactly the same question as Execute Batch File without Command line visible since this has the added requirement that whatever launcher used must stay open for the whole lifetime of the launched process, and that you can't pass command line arguments to the launcher.
I ended up writing my own utility which I'm tentatively calling NoConsoleProgramLauncher to serve as an intermediate between 7z and Notepad++. It's rough first draft code, but I thought sharing it might still be useful since this question has been without answer for three years.
#include <fstream>
#include <string>
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <filesystem>
HINSTANCE hInst;
void launchProcess(std::wstring commandLine);
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
//Get current executable's location
HMODULE hModule = GetModuleHandleW(NULL);
WCHAR executableFolder[MAX_PATH];
GetModuleFileNameW(hModule, executableFolder, MAX_PATH);
std::experimental::filesystem::v1::path path(executableFolder);
path.remove_filename();
path.append(L"NoConsoleProgramLauncher_Arguments.txt");
std::wifstream infile(path);
std::wstring commandLine;
std::getline(infile, commandLine);
commandLine += L" ";
commandLine += lpCmdLine;
launchProcess(commandLine);
}
void launchProcess(std::wstring commandLine)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
// Start the child process.
if (!CreateProcess(NULL, // No module name (use command line)
&commandLine[0], // Command line - C++ 11 guarantees that string's internal buffer is contiguous and null-terminated.
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
CREATE_NO_WINDOW, // 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
)
{
printf("CreateProcess failed (%d).\n", GetLastError());
return;
}
// Wait until child process exits.
WaitForSingleObject(pi.hProcess, INFINITE);
// Close process and thread handles.
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
Basically, if you've done a minimum of C++ coding before, it's a matter of pasting this into a new Visual Studio 2017 Windows Desktop Application project, fixing up the includes if needed, and building.
As you can see in the source code, when launched the executable looks for a file in the same folder as itself named "NoConsoleProgramLauncher_Arguments.txt", and calls the command line it finds in there. As specified in the question, no console window will be shown, and the program will wait for the spawned process to terminate before exiting, so 7zip keeps waiting to pick up the changes.
This is what I put in my NoConsoleProgramLauncher_Arguments.txt
file:
"C:\Program Files (x86)\Notepad++\notepad++.exe" -multiInst -nosession
And in the 7zip configuration, I've set the editor to point to my NoConsoleProgramLauncher.exe program.
The real solution would of course be to gently pester the 7z authors about this, or better, submit a pull request to 7z to implement passing arguments to your editor of choice.