NotepadReplacer doesn't make the right-click Edit menu item in Win11 launch my preferred replacement (Notepad++). MS Notepad always launches. I've spent an afternoon looking for workarounds, without any luck. Here's as far as I got (trying to replace with Notepad++):
def installNotepadPlusPlus():
"""Notepad++"""
log("Installing Notepad++...", printit=True)
# remove any pre-existing choco install
output, return_code = do(R"choco uninstall notepadplusplus --remove-dependencies", suppress_errors=True) # in case there was a choco install previously
if return_code == 0:
log(f"Removed pre-existing Notepad++ choco install.", printit=True)
elif return_code == 1:
pass # wasn't any previous choco install
else:
raise RuntimeError(f"Error uninstalling Notepad++ with choco: {output}")
wingetInstall('Notepad++.Notepad++ -a x64') # force 64 bit version so it will be found in %ProgramFiles% (not %ProgramFiles(x86)%)
log("Creating edit.bat...")
with open(t.BinPath + R'\edit.bat', "w") as ed:
ed.write(R'@start /b "" "' + 'notepad++' + R'" %*')
unzip(R'auto_install\Notepad++_ROAMING.7z', os.environ[R'AppData'] + R'\Notepad++')
try:
log("Removing old plugins...")
shutil.rmtree(R'C:\Program Files\Notepad++\plugins')
except PermissionError:
pass # probably NP++ is running
output, return_code = unzip(R'auto_install\Notepad++_PLUGINS.7z', R'C:\Program Files\Notepad++\plugins', suppress_errors=True)
if return_code and "ERROR: Cannot delete output file" not in output: # this happens if NP++ is running
raise RuntimeError(f"Unable to install Notepad++ plugins: {output}")
x64_folder = os.path.expandvars(R'%ProgramFiles%\Notepad++')
nppp_exe = os.path.join(x64_folder, 'notepad++.exe')
do(R"choco install notepadreplacer --params='" + R'"/NOTEPAD:' + nppp_exe + R' /verysilent"' + R"' -y") # not available on winget as of 2024-12-10
# Notepad++ for editing text files (esp .log files)
do(R'ftype txtfile="' + nppp_exe + R'" "%%1"')
# Make files without any extension open in Notepad++
do(R'assoc .="(none)"')
do(R'ftype "(none)"="' + nppp_exe + R'" "%%1"')
do(R'assoc "(none)"\DefaultIcon=%SystemRoot%\System32\imageres.dll,-102') # use text file icon
# associate .xml files with NP++
do(R'assoc .xml=txtfile')
# make symlink to program for stuff like FileZilla that look in the wrong folder for it
x86_folder = os.path.expandvars(R"%ProgramFiles(x86)%\Notepad++")
try:
if not os.path.islink(x86_folder):
shutil.rmtree(x86_folder)
log(f"Removed old {x86_folder} to make room for a symlink to {x64_folder}")
except FileNotFoundError:
pass
symlinkFolder(x64_folder, x86_folder)
if WindowsVersion() >= 11: # added to support Win11
''' this doesn't work yet. I haven't found a robust solution that works in all cases
See: https://community.notepad-plus-plus.org/topic/21991/replace-notepad-on-windows-11/21
https://www.winhelponline.com/blog/replace-notepad-text-editor-notepad-plus-association/
'''
# remove app store version of Notepad (Win11 version)
# do(R'powershell -command "Get-AppxPackage *Microsoft.WindowsNotepad* | Remove-AppxPackage"')
# # create file that starts notepad++ in the path
# with open(os.path.join(t.LocalBinPath, "notepad.bat"), "w") as notepad_bat:
# notepad_bat.write("@" + nl.quote(nppp_exe) + ' %*')
# regAddKey(R'HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\notepad.exe', 'UseFilter', winreg.REG_DWORD, 0)
# regAddKey(R'HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\notepad.exe', 'Debugger', winreg.REG_SZ, R'%ProgramFiles%\Notepad++\notepad++.exe -notepadStyleCmdline -z')
# regDeleteKey(R'HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\notepad.exe', 'UseFilter')
# regDeleteKey(R'HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\notepad.exe', 'Debugger')
R''' # I don't know why this doesn't work - Win11 says it can't find the file to be edited (not a quoting issue)
notepad_exe_locations = [R'%SystemRoot%', R'%SystemRoot%\System32', R'%SystemRoot%\SysWOW64' ]
for location in notepad_exe_locations:
old_notepad_exe = os.path.join(os.path.expandvars(location), "notepad.exe") # old notepad.exe
if os.path.exists(old_notepad_exe):
# Take ownership and grant permissions
do(Rf'takeown /f {old_notepad_exe}')
do(Rf'icacls {old_notepad_exe} /grant administrators:F')
if not os.path.islink(old_notepad_exe):
os.rename(old_notepad_exe, old_notepad_exe + '.old')
symlinkFile(nppp_exe, old_notepad_exe)
'''
log(f"Installed and configured Notepad++ {x64_folder} to {x86_folder}", printit=True)