3

Some old tools are designed to work with an external text editor. I am stuck using a legacy tool that does this in the following way:

  1. Create a temporary file with the content to be edited.
  2. Launch the user specified application adding the path to the temporary file as an argument.
  3. Wait for the launched application to close (probably monitors the PID)
  4. Check to see if the temporary file has been updated using the Date Modified field and load in the updated data.

I have been trying to use this tool (which cannot be easily changed) with Notepad++. I have had some issues with this because the tool only monitors the temporary file until the application it launched closes. When a new instance of the Notepad++ process is launched the default behavior is to open the file in any already opened instance of Notepad++ as a tab and close the new process. This results in the tool thinking the editor was closed immediately and then missing any edits that actually take place.

I am able to work around this by forcing the Notepad++ to always launch in a new instance using the -multiInst command line argument. I would like to be able to open the temporary files as tabs as I am also using some Notepad++ plugins that work across tabs (but not across instances).

Has anyone got any ideas of a solution? It would be great if I could get Notepad++ to open a file as a tab but still have the launched process in memory while the file is still open. I guess this would be similar to the one process per tab model Chrome uses. I have also considered launching Notepad++ indirectly via a batch file or similar, but I don't know how I could detect when the tab/file was closed in Notepad++.

2 Answers 2

2

You have to provide PID of a separate process to your legacy application for span of file edition.

Unfortunately all easy ways to detect end of file edition I'm aware off don't work - Notepad++:

  • Don't keep file handles opened.
  • Have custom drawn tab controls.
  • Don't save recent files list in registry.

So without writing npp plugin - which handle NPPN_FILECLOSED notification - I don't see solution other than starting Notepad++ by below run_npp_cmd:

@echo off
start C:\your\path\to\notepad++.exe %1
echo Do your work and then let me go
pause

You can call run_npp_cmd C:\path\to\your\data.txt from your legacy application, and when you done your work you let commandline instance go...

5
  • Thank you for the answer, but to be honest I am hoping there is a neater solution out there. It would be quite easy to make a mistake with this approach. The command prompt could be closed before the tab is closed, or the tab could be closed and the command prompt left open.
    – Owen
    Dec 4, 2015 at 21:40
  • @Owen There are two ways to solve your problem. First: you can change a Notepad++ PID as soon as you end editing a file - unfortunately as far as I know change of process PID is impossible on Windows. Second: you have to provide PID of a separate process to your legacy application for span of file edition - I just give you IMO a simplest way of doing this. As after your comment I have an impression that you want a fish and not to be learned how to fish I just tell you that you always can extend my solution to your needs :P
    – g2mk
    Dec 5, 2015 at 12:06
  • I appreciate your help in trying to answer my question, but I did state at the end of my original post that I had already considered launching indirectly via a batch file. All I was hoping for was any ideas or suggestions beyond what I had already mentioned.
    – Owen
    Dec 5, 2015 at 15:04
  • @Owen You got me - sorry. Unfortunately all easy ways I'm aware off don't work - Notepad++ don't keep file handles opened, have custom tab controls, don't save recent files list in registry. I don't see solution other than writing npp plugin which handle NPPN_FILECLOSED notification... Sorry again.
    – g2mk
    Dec 5, 2015 at 19:21
  • Posted a partial solution as a self answer using notifications. Thanks for suggestion.
    – Owen
    Dec 6, 2015 at 17:42
0

I think I have come up with a proof of concept solution, but it is a little convoluted and (currently) causes a crash in Notepad++ so it probably isn't viable just yet. I thought I would post it anyway as others might be looking at solving similar problems.

The beta plugin Notepad++ Python Script adds supports for scripting in Notepad++ including hooking into existing Notepad++ notifications. The plugin includes a startup script that is always run as long as "ATSTARTUP" is selected in the plugin's configuration options.

  1. Launch a batch file from the legacy tool (it can be minimized at launch)
  2. Change command windows title to something known by Notepad++ and unique (the file name will probably do) so that it can be killed later on
  3. Launch Notepad++ from the batch file with the file as a command line argument
  4. Automatically register a python function as a callback on the FILEBEFORECLOSE notification at startup
  5. When a file is closed use the filename to reconstruct the window title of the command prompt and use that to kill it.

This successfully causes the command window to close but then Notepad++ locks up. I think this is an issue with the python plugin. It seems that calling console.run() from a notification callback causes problems. I know the command is well formated because it works without a crash when run from a user triggered script. This script runs every time a file is closed and it causes Notepad++ to hang so I don't recommend you use this solution in its current state

Command to run from legacy tool:

start /min nppblock.bat

notepadpp_blocker.bat:

@echo off
FOR %%i IN (%1) DO (
    set filename=%~nx1
)
title=nppblock_%filename%
echo Waiting for %filename% to be closed in Notepad++
"C:\Program Files (x86)\Notepad++\notepad++.exe" %1
pause

Added to C:\Program Files (x86)\Notepad++\plugins\PythonScript\scripts\startup.py:

import os.path
def fileBeforeCloseCallback(args):
    filename = os.path.basename(notepad.getBufferFilename(args["bufferID"]));
    killcmd = 'taskkill /f /fi "WINDOWTITLE eq nppblock_' + filename + '" /im cmd.exe'
    console.run(killcmd)

notepad.callback(fileBeforeCloseCallback, [NOTIFICATION.FILEBEFORECLOSE])

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .