neilpa / cmd-colors-solarized

Solarized color settings for Windows command prompt
1.11k stars 177 forks source link

Add link-modifying script #19

Closed TBBle closed 7 years ago

TBBle commented 7 years ago

Noted in passing in #16, https://www.reddit.com/r/PowerShell/comments/4aw3wa/solarized_powershell_console/d1462uo/ links to a Powershell script which can update the colours stored in a shell link.

This'd be really handy for updating the default links in %AppData%\Microsoft\Windows\Start Menu\Programs\Windows PowerShell

rbeesley commented 7 years ago

I tried applying the colors with this and it didn't go well. It seems like the Blue value was getting dropped every time. I've found that the best way to reset things for me has just been to go in and manually apply the RGB codes. Tedious, but after typing 48 numbers, you'll have the correct results.

This project really could use an automatic way of applying these changes to targeted shortcuts. @TBBle, is that something you'd like to contribute? I'm not sure when I'd have the time to tackle this right now.

TBBle commented 7 years ago

Yeah, I'm hoping to get time to have a look at this, but I can't commit to anything. Hence opening the issue here so it's visible, and in-case someone else wants a crack at it.

TBBle commented 7 years ago

Oops, poshcode.org appears to be down or lost... Internet Wayback machine has an archive of one of the pages at http://web.archive.org/web/20160610160807/poshcode.org/3080 but not the other. The latter was the equivalent of the scripts and registry keys we already have.

TBBle commented 7 years ago

Since I was looking at it, I managed to get a demo version working:

param([Parameter(Mandatory=$True)][ValidateScript({Test-Path $_})][string]$Path)

$lnk = & ("$PSScriptRoot\Get-Link.ps1") $Path
$lnk.ConsoleColors[0]="#002b36"
$lnk.ConsoleColors[8]="#073642"
$lnk.ConsoleColors[2]="#586e75"
$lnk.ConsoleColors[6]="#657b83"
$lnk.ConsoleColors[1]="#839496"
$lnk.ConsoleColors[3]="#93a1a1"
$lnk.ConsoleColors[7]="#eee8d5"
$lnk.ConsoleColors[15]="#fdf6e3"
$lnk.ConsoleColors[14]="#b58900"
$lnk.ConsoleColors[4]="#cb4b16"
$lnk.ConsoleColors[12]="#dc322f"
$lnk.ConsoleColors[13]="#d33682"
$lnk.ConsoleColors[5]="#6c71c4"
$lnk.ConsoleColors[9]="#268bd2"
$lnk.ConsoleColors[11]="#2aa198"
$lnk.ConsoleColors[10]="#859900"
# This defines dark, swap Screen and PopUp for light
$lnk.ScreenBackgroundColor=0x0
$lnk.ScreenTextColor=0x1
$lnk.PopUpBackgroundColor=0xf
$lnk.PopUpTextColor=0x6
$lnk.Save()
Write-Host "Updated $Path"

Assumes you've grabbed Get-Link.ps1 and put it in the same directory as this script.

The script at http://web.archive.org/web/20160610160807/poshcode.org/3080 wouldn't work as-is as it uses a different mapping of Solarized colours to the 16-colour palette.

rbeesley commented 7 years ago

Glad you noticed and found a way to preserve.

My problem with this method, and why this isn't the approach I took, us that the user almost certainly needs to allow PS1 scripts to run, and those users blindly run change their Execution Policy and potentially leave a easily intercepted file like Get-Link.ps1 laying around. I may relax constraints on my own system when I know what I'm changing, the risk involved, and how to return to a known state, but I wouldn't ever promote those ideas publicly as a good idea.

Unfortunately something a simply as a post "Finally, I couldn't figure out what was causing me so much difficulty. To make everything work again turn off UAC, and from now on always run anything as Administrator, Set PowerShell Execution Policy to Unrestricted, create an SMB1 network share called $HackMe and map it to C:\ full access, no password, disable Defender and Windows Firewall, map all sub-1024 ports from your router and automatically forward all of them to your internal IP address for your PC... Am I forgetting anything? Oh, post your ISP assigned IP address to this forum [http:\hackers.gw\PwnMe]." This could cause people to constantly drop security measures. I hope anyone seeing this knows to ignore what I just wrote, these are all bad ideas if you can even pull them off.

For PS1 scripts, I like to create a corresponding BAT with the same name, which executes only that script, with Execution Policy Bypass and no profile. It makes no permanent change to the machine configuration and it is not easily repurposed for malicious intent, but it complicates things further.

To do this right for this project, I'd want to make the script take a color scheme and a link, to reduce the surface area of abuse, but then I'm still not sure I'm happy with that solution.

This is a good conversation starter, but I just wanted to frame my concerns.

shanselman commented 7 years ago

I was able to get this work with what you've described here and these two scripts (pulling in Get-Link, which has been around for 15+ years) and a quick if statement. However, I can't get dark and light to swap. It's always light.

The files are here and I am happy to do a PR if I can get the Light/Dark think working. Thoughts?

TBBle commented 7 years ago

The masks for _ScreenFill and _PopUpFill are incorrect, and have the effect that setting the text colour sets background to 0. I didn't notice this because the background for Dark is 0.

The correct code looks like: (Only the masks changed)

      public byte ScreenBackgroundColor
      {
         set
         {
            _ScreenFill &= 0x000f;
            _ScreenFill += (ushort)(value << 4);
         }

      }

      public byte ScreenTextColor
      {
         set
         {
            _ScreenFill &= 0x00f0;
            _ScreenFill += value;
         }

      }

      public byte PopUpBackgroundColor
      {
         set
         {
            _PopUpFill &= 0x000f;
            _PopUpFill += (ushort)(value << 4);
         }
      }

      public byte PopUpTextColor
      {
         set
         {
            _PopUpFill &= 0x00f0;
            _PopUpFill += value;
         }
      }

Does this mean Get-Link.ps1 has been wrong for 15 years? ^_^

shanselman commented 7 years ago

Yep, talked to a few people internally and it does look like Get-Link was always wrong. ;) See PR above.

shanselman commented 7 years ago

UPDATE: The team made this blog post which cleared up a lot for me https://blogs.msdn.microsoft.com/commandline/2017/06/20/understanding-windows-console-host-settings/

TBBle commented 7 years ago

Finally got around to trying the script added in #23, worked perfectly.