Thursday, September 18, 2014

Easily modify UAC protected config files

Story behind this post

Especially on testing and development environments I have see the situation that I need manually modify config files.

Personally I mostly use Notepad++ for that task because it is free tool and with good syntax highlight feature. With Compare plugin it is also very powerful tool for finding errors from manually created configurations.

Challenge with UAC protected files

If you want modify example web.config file using Notepad++ you will notice that it can't save files which are protected by UAC (User Account Control).

I have seen people using three different solutions for this problem:
  1. Disable UAC
    1. This of course works but it is bad solution from security point of view.
  2. Run CMD or PowerShell using "Run as administrator" function and run command: notepad config.file on there.
    1. This also works but now you haven't syntax highlight in use so you can easily broke example XML syntax.
  3. Run CMD or PowerShell using "Run as administrator" function and start Notepad++ from there and open config file to it.
    1. This also works but there it is too painful way to do that.

Better solution

Once when I was plan what should be included to virtual machine templates I got idea that it would be nice to have "Edit with Notepad++ (Run as administrator)" function on right click menu.

What I tried to do on first place was just enable "Run this program as an administrator" feature to notepad++.exe unfortunately result wasn't so good:

Reason for error is way how "Edit with Notepad++" feature is implemented. It uses ShellExecute function which just not working here.

After some of Googling and testing I found solution to this. This can be done if it is configured to Windows registry differently. Just in case I created new function instead of touching the old one so now I have "Edit with Notepad++" and "Edit with Notepad++ (Run as administrator)" selections on right click menu.
Result looks like this:

Because like PowerShell here is script for you which do following tasks:
  • Install Notepad++
  • Install Compare plugin
  • Disable Notepad++ auto update
  • Disable plugins auto update
  • Create "Edit with Notepad++ (Run as administrator)" function to right click menu
You just need put this script to same folder with Notepad++ installer and Compare plugin's DLL file.

$ScriptPath = Split-Path $script:MyInvocation.MyCommand.Path
$NPPInstallerName = "$ScriptPath\npp.6.6.9.Installer.exe"
$NPPInstallerParameters = "/S"
$InstallFolder = "C:\Program Files (x86)\Notepad++"

# Install
Start-Process -NoNewWindow -Wait -FilePath $NPPInstallerName -ArgumentList $NPPInstallerParameters

# Install compare plugin
Copy-Item "$ScriptPath\ComparePlugin.dll" "$InstallFolder\plugins\"

# Disable Notepad++ updater
$CommonConfig = "C:\Program Files (x86)\Notepad++\config.model.xml"
[xml]$Config = Get-Content $CommonConfig 
($Config.NotepadPlus.GUIConfigs.GUIConfig | Where-Object {$ -eq "noUpdate"})."#text" = "yes"

# Disable plugins auto update on all profiles
$PluginManagerINI = @"
$ProfileFolders = Get-ChildItem C:\Users -Directory -Exclude Public,"Default User" -Force
ForEach ($ProfileFolder in $ProfileFolders) {
 New-Item -ItemType Directory -Path "$($ProfileFolder.FullName)\Notepad++\plugins\Config" -Force
 $PluginManagerINI | Out-File "$($ProfileFolder.FullName)\Notepad++\plugins\Config\PluginManager.ini"

# Create "Edit with &Notepad++ (Run as administrator)" to right click menu
Copy-Item "$InstallFolder\notepad++.exe" "$InstallFolder\notepad++admin.exe"
New-Item -Path 'HKLM:SOFTWARE\Classes\*\shell\OpenWithNotepad' -Force
New-Item -Path 'HKLM:SOFTWARE\Classes\*\shell\OpenWithNotepad\Command' -Force
New-Item -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers' -Force
Set-ItemProperty -Path 'HKLM:SOFTWARE\Classes\`*\shell\OpenWithNotepad' -Name "(Default)" -Value "Edit with &Notepad++ (Run as administrator)"
New-ItemProperty -Path 'HKLM:SOFTWARE\Classes\`*\shell\OpenWithNotepad' -Name "icon" -Value "%SystemRoot%\system32\imageres.dll,73"
Set-ItemProperty -Path 'HKLM:SOFTWARE\Classes\`*\shell\OpenWithNotepad\Command' -Name "(Default)" -Value '"C:\Program Files (x86)\Notepad++\notepad++admin.exe" "%1"'
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers" -Name "C:\Program Files (x86)\Notepad++\notepad++admin.exe" -Value "~ RUNASADMIN"

This is also reported to Notepad++ feature request. Hopefully it will be included to official version on some point of time: