How to use Notepad++ as editor for 7zip, without showing a console window?

1.7k views Asked by At

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:

  • Call a batch file, but then I'm stuck with an unsightly (and easy to close accidentally) console window for the duration of the edition - not acceptable.
  • Call a batch file which uses 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.
  • Use wscript, which doesn't show a console window. Tracking the process lifetime is complex however (Wait for program to complete) and it makes you rely on old tech in maintenance mode that has a malware connotation.

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.

1

There are 1 answers

0
Gabriel Morin On BEST ANSWER

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.