0

If I manually edit %appdata%\Notepad++\shortcuts.xml and manually add a find replace macro (See MACRO below), then close shortcuts.xml and then restart Notepad++, the macro is available to run from the Macro Menu button:

enter image description here

I wrote a program that programmatically edits shortcuts.xml and inserts the very same macro. Notepad++ is not up when I run my program. I know my program is working based on diffing copies of manually modified and programmatically modified shortcuts.xml files. However, when I restart Notepad++ after running my program, the Macro button is "dead", i.e., all macros, although present in shortcuts.xml, disappear from the Macro button.

enter image description here

Is Notepad++ somehow sensitive to its shortcuts.xml file being programmatically manipulated?

MACRO Screenshot (text version follows)

shortcuts.xml

Text Version

<Macro name="Redactor" Ctrl="no" Alt="no" Shift="no" Key="0">
  <Action type="0" message="2422" wParam="0" lParam="0" sParam="" />
  <Action type="0" message="2325" wParam="0" lParam="0" sParam="" />
  <Action type="3" message="1700" wParam="0" lParam="0" sParam="" />
  <Action type="3" message="1601" wParam="0" lParam="0" sParam="(?:[0-9]{1,3}\.){3}[0-9]{1,3}" />
  <Action type="3" message="1625" wParam="0" lParam="2" sParam="" />
  <Action type="3" message="1602" wParam="0" lParam="0" sParam="IP-Placeholder" />
  <Action type="3" message="1702" wParam="0" lParam="768" sParam="" />
  <Action type="3" message="1701" wParam="0" lParam="1609" sParam="" />
  <Action type="0" message="2422" wParam="0" lParam="0" sParam="" />
  <Action type="0" message="2325" wParam="0" lParam="0" sParam="" />
  <Action type="3" message="1700" wParam="0" lParam="0" sParam="" />
  <Action type="3" message="1601" wParam="0" lParam="0" sParam="\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b" />
  <Action type="3" message="1625" wParam="0" lParam="2" sParam="" />
  <Action type="3" message="1602" wParam="0" lParam="0" sParam="email-placeholder" />
  <Action type="3" message="1702" wParam="0" lParam="768" sParam="" />
  <Action type="3" message="1701" wParam="0" lParam="1609" sParam="" />
</Macro>
VA systems engineer
  • 2,856
  • 2
  • 14
  • 38
  • So how are you diffing them -- in particular, do you know for sure your edits aren't messing up the encoding of the file in the process, which your diff tool might paper over? – Jeroen Mostert Nov 28 '22 at 20:55
  • Hard to know for sure what is the cause, but if your are curious here is [their github](https://github.com/notepad-plus-plus/notepad-plus-plus) in case you want to dig into their code or file a bug or [info about their author](https://notepad-plus-plus.org/author/) – Cleptus Nov 28 '22 at 20:55
  • Are you sure the `shortcuts.xml` your program is modifying is the same one that Notepad++ is using? Possible you have two files with the same name in different locations. – Ibrennan208 Nov 28 '22 at 20:58
  • @ibrennan: yes, for sure, same one in %appdata%\Notepad++\shortcuts.xml – VA systems engineer Nov 28 '22 at 21:14
  • @jeroenmostert: I didn't diff them good enough. When I open the original shortcuts.xml using NotePad++ and click on the encoding menu button, it shows UTF-8. After I run my program, the same file (modified) shows UTF-8 BOM. So, I'll assume that's the problem and work to make shortcuts.xml stay as UTF-8 – VA systems engineer Nov 28 '22 at 21:16

1 Answers1

0

It's working now.

My original (non-working) code did this:

// shortcuts.xml is encoded UTF-8, no BOMs
string shortCutsXmlFilepath = Path.Combine($"{System.Environment.GetEnvironmentVariable("APPDATA")}\\NotePad++", "shortcuts.xml");

XDocument shortCutsXmlDocument = XDocument.Load(shortCutsXmlFilepath);

// manipulate xDocument elements .......

shortCutsXmlDocument.Save(shortCutsXmlFilepath);

The result was that shortcuts.xml had UTF-8 byte order marks (BOM) inserted (EF BB BF) at the beginning of the file. When I next executed Notepad++ and it read shortcuts.xml, it silently failed to read shortcuts.xml and so no macros were displayed under the Macro menu button.

The Fix

The fix is to read shortcuts.xml using a StreamReader and write it using a StreamWriter. I explicitly asserted the 'no BOM' option in both so that there's no chance of the saved version of shortcuts.xml having the BOMs inserted (the 'no BOM' option is the default).

Note: To enable BOM, use new UTF8Encoding(true) instead.

XDocument shortCutsXmlDocument = LoadNotepadPpShortcutsXmlDocument();

// manipulate xDocument elements .......

SaveNotepadPpShortcutsXmlDocument(shortCutsXmlDocument);

//
//
//

private static XDocument LoadNotepadPpShortcutsXmlDocument()
{
    string shortCutsXmlFilepath = Path.Combine($"{System.Environment.GetEnvironmentVariable("APPDATA")}\\NotePad++", "shortcuts.xml");

    if (File.Exists(shortCutsXmlFilepath) == false)
    {
        MessageBox.Show($"Can't find '{shortCutsXmlFilepath}'");
        Application.Exit();
    }

    XDocument xDocument = new XDocument();

    using (StreamReader stream = new StreamReader(path: shortCutsXmlFilepath, new UTF8Encoding(false)))
    {
        xDocument = XDocument.Load(stream);
    }

    return (xDocument);
}

private static XDocument SaveNotepadPpShortcutsXmlDocument(XDocument document)
{
    string shortCutsXmlFilepath = Path.Combine($"{System.Environment.GetEnvironmentVariable("APPDATA")}\\NotePad++", "shortcuts.xml");

    //todo Verify that Path.Combine($"{System.Environment.GetEnvironmentVariable("APPDATA")}", "\\NotePad++") exists before writing shortcuts.xml

    using (StreamWriter stream = new StreamWriter(shortCutsXmlFilepath, append: false, new UTF8Encoding(false)))
    {
        document.Save(stream);
    }

    return (document);
}
VA systems engineer
  • 2,856
  • 2
  • 14
  • 38
  • Please have a look at [Can I answer my own question?](http://stackoverflow.com/help/self-answer) and come back two days later and check as answered if you have more than 15 reputation (See also: [Accept Your Own Answers](https://stackoverflow.blog/2009/01/06/accept-your-own-answers/). – help-info.de Nov 30 '22 at 18:57