Move Windows dev guide to its own repository.
It is now at: https://github.com/rkitover/windows-dev-guide Signed-off-by: Rafael Kitover <rkitover@gmail.com>
This commit is contained in:
parent
35d4d44a9b
commit
b9fb76043e
|
@ -201,591 +201,9 @@ For calling Windows APIs with strings, use the wide char `W` variants and the
|
|||
|
||||
### Windows Native Development Environment Setup
|
||||
|
||||
#### Install Chocolatey and Some Packages
|
||||
This guide has been moved to:
|
||||
|
||||
Make sure developer mode is turned on in Windows settings, this is necessary for
|
||||
making unprivileged symlinks.
|
||||
|
||||
- Press Win+X and open Windows PowerShell (administrator).
|
||||
|
||||
- Run these commands:
|
||||
|
||||
```powershell
|
||||
Set-ExecutionPolicy -Scope LocalMachine -Force RemoteSigned
|
||||
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
|
||||
```
|
||||
|
||||
Close the administrator PowerShell window and open it again.
|
||||
|
||||
Install some chocolatey packages:
|
||||
|
||||
```powershell
|
||||
choco install -y visualstudio2019community --params '--locale en-US'
|
||||
choco install -y visualstudio2019-workload-nativedesktop
|
||||
choco install -y hackfont dejavufonts ripgrep git gpg4win microsoft-windows-terminal powershell-core vim neovim zip unzip notepadplusplus diffutils ntop.portable grep gawk sed less transifex-client
|
||||
# Copy your .ssh over to your profile directly first preferrably:
|
||||
stop-service ssh-agent
|
||||
sc.exe delete ssh-agent
|
||||
choco install -y openssh --params '/SSHServerFeature /SSHAgentFeature /PathSpecsToProbeForShellEXEString:$env:programfiles\PowerShell\*\pwsh.exe'
|
||||
```
|
||||
|
||||
#### Chocolatey Usage Notes
|
||||
|
||||
Here are some commands for using the Chocolatey package manager.
|
||||
|
||||
To search for a package:
|
||||
|
||||
```powershell
|
||||
choco search patch
|
||||
```
|
||||
|
||||
To get the description of a package:
|
||||
|
||||
```powershell
|
||||
choco info patch
|
||||
```
|
||||
|
||||
To install a package:
|
||||
|
||||
```powershell
|
||||
choco install -y patch
|
||||
```
|
||||
|
||||
To uninstall a package:
|
||||
|
||||
|
||||
```powershell
|
||||
choco uninstall -y patch
|
||||
```
|
||||
|
||||
To list installed packages:
|
||||
|
||||
```powershell
|
||||
choco list --local
|
||||
```
|
||||
|
||||
To update all installed packages:
|
||||
|
||||
```powershell
|
||||
choco update -y all
|
||||
```
|
||||
|
||||
#### Configure the Terminal
|
||||
|
||||
Launch the terminal and choose Settings from the tab drop-down, this will open
|
||||
the settings json in visual studio.
|
||||
|
||||
In the global settings, above the `"profiles"` section, add:
|
||||
|
||||
```json
|
||||
"copyFormatting": "all",
|
||||
"focusFollowMouse": true,
|
||||
// If enabled, selections are automatically copied to your clipboard.
|
||||
"copyOnSelect": true,
|
||||
// If enabled, formatted data is also copied to your clipboard
|
||||
"copyFormatting": true,
|
||||
"tabSwitcherMode": "disabled",
|
||||
"tabWidthMode": "compact",
|
||||
"wordDelimiters": " ",
|
||||
"largePasteWarning": false,
|
||||
"multiLinePasteWarning": false,
|
||||
"windowingBehavior": "useAnyExisting",
|
||||
```
|
||||
|
||||
In the `"profiles"` `"defaults"` section add:
|
||||
|
||||
```json
|
||||
"defaults":
|
||||
{
|
||||
// Put settings here that you want to apply to all profiles.
|
||||
"adjustIndistinguishableColors": false,
|
||||
"font":
|
||||
{
|
||||
"face": "Hack",
|
||||
"size": 11
|
||||
},
|
||||
"antialiasingMode": "cleartype",
|
||||
"cursorShape": "filledBox",
|
||||
"colorScheme": "Tango Dark",
|
||||
"intenseTextStyle": "bold",
|
||||
"padding": "0",
|
||||
"scrollbarState": "hidden"
|
||||
"closeOnExit": "always"
|
||||
},
|
||||
```
|
||||
|
||||
I prefer `IBM Plex Mono` which you can install from:
|
||||
|
||||
https://github.com/IBM/plex
|
||||
|
||||
In the `"actions"` section add these keybindings:
|
||||
|
||||
```json
|
||||
{ "command": { "action": "newTab" }, "keys": "ctrl+shift+t" },
|
||||
{ "command": { "action": "nextTab" }, "keys": "ctrl+shift+right" },
|
||||
{ "command": { "action": "prevTab" }, "keys": "ctrl+shift+left" }
|
||||
```
|
||||
|
||||
And **REMOVE** the `ctrl+v` binding, if you want to use `ctrl+v` in vim (visual
|
||||
line selection.)
|
||||
|
||||
This gives you a sort of "tmux" for powershell using tabs.
|
||||
|
||||
Restart the terminal.
|
||||
|
||||
#### Setting up Vim
|
||||
|
||||
If you don't use vim, just add an alias for your favorite editor in your
|
||||
powershell `$profile`, and set `$env:EDITOR` so that git can open it for commit
|
||||
messages etc.. I will explain how to do this below.
|
||||
|
||||
If you are using neovim, make some adjustments to the following instructions,
|
||||
and do the following:
|
||||
|
||||
```powershell
|
||||
mkdir ~/.vim
|
||||
ni -itemtype symboliclink ~/AppData/Local/nvim -target ~/.vim
|
||||
ni -itemtype symboliclink ~/.vim/init.vim -target ~/.vimrc
|
||||
```
|
||||
|
||||
You can edit your powershell profile with `vim $profile`, and reload it with `.
|
||||
$profile`.
|
||||
|
||||
Add the following to your `$profile`:
|
||||
|
||||
```powershell
|
||||
if ($env:TERM) { ri env:TERM }
|
||||
$env:EDITOR = resolve-path ~/bin/vim.bat
|
||||
```
|
||||
|
||||
In `~/bin/vim.bat` put the following:
|
||||
|
||||
```bat
|
||||
@echo off
|
||||
set TERM=
|
||||
c:/windows/vim.bat %*
|
||||
```
|
||||
|
||||
This is needed for git to work correctly with native vim.
|
||||
|
||||
Some suggestions for your `~/.vimrc`:
|
||||
|
||||
```vim
|
||||
set encoding=utf8
|
||||
set langmenu=en_US.UTF-8
|
||||
let g:is_bash=1
|
||||
set formatlistpat=^\\s*\\%([-*][\ \\t]\\\|\\d+[\\]:.)}\\t\ ]\\)\\s*
|
||||
set ruler bg=dark nohlsearch bs=2 ai fo+=n modeline belloff=all
|
||||
set fileformats=unix,dos
|
||||
|
||||
" Add vcpkg includes to include search path to get completions for C++.
|
||||
let g:home = fnamemodify('~', ':p')
|
||||
|
||||
if isdirectory(g:home . 'source/repos/vcpkg/installed/x64-windows-static/include')
|
||||
let &path .= ',' . g:home . 'source/repos/vcpkg/installed/x64-windows-static/include'
|
||||
endif
|
||||
|
||||
if isdirectory(g:home . 'source/repos/vcpkg/installed/x64-windows-static/include/SDL2')
|
||||
let &path .= ',' . g:home . 'source/repos/vcpkg/installed/x64-windows-static/include/SDL2'
|
||||
endif
|
||||
|
||||
set termguicolors
|
||||
au ColorScheme * hi Normal guibg=#000000
|
||||
|
||||
if (has('win32') || has('gui_win32')) && executable('pwsh')
|
||||
set shell=pwsh
|
||||
set shellcmdflag=\ -ExecutionPolicy\ RemoteSigned\ -NoProfile\ -Nologo\ -NonInteractive\ -Command
|
||||
endif
|
||||
|
||||
filetype plugin indent on
|
||||
syntax enable
|
||||
|
||||
au BufRead COMMIT_EDITMSG,*.md setlocal spell
|
||||
```
|
||||
|
||||
I use this color scheme, which is a fork of Apprentice for black backgrounds:
|
||||
|
||||
https://github.com/rkitover/Apprentice
|
||||
|
||||
You can add with Plug or pathogen or whatever you prefer.
|
||||
|
||||
All of this works with neovim.
|
||||
|
||||
#### Set up PowerShell Profile
|
||||
|
||||
Now add some useful things to your powershell profile, I will present some of
|
||||
mine below:
|
||||
|
||||
Run:
|
||||
|
||||
```powershell
|
||||
vim $profile
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```powershell
|
||||
notepad $profile
|
||||
```
|
||||
|
||||
If you use my posh-git prompt, you'll need the git version of posh-git:
|
||||
|
||||
```powershell
|
||||
mkdir ~/source/repos
|
||||
cd ~/source/repos
|
||||
git clone https://github.com/dahlbyk/posh-git
|
||||
```
|
||||
|
||||
Here is a profile to get you started, it has a few examples of functions and
|
||||
aliases which you will invariably write for yourself:
|
||||
|
||||
```powershell
|
||||
chcp 65001 > $null
|
||||
|
||||
set-executionpolicy -scope currentuser remotesigned
|
||||
|
||||
set-culture en-US
|
||||
|
||||
$terminal_settings = resolve-path ~/AppData/Local/Packages/Microsoft.WindowsTerminal_*/LocalState/settings.json
|
||||
|
||||
if ($env:TERM) { ri env:TERM }
|
||||
$env:EDITOR = resolve-path ~/bin/vim.bat
|
||||
|
||||
function megs {
|
||||
gci -rec $args | select mode, lastwritetime, @{name="MegaBytes"; expression = { [math]::round($_.length / 1MB, 2) }}, name
|
||||
}
|
||||
|
||||
function cmconf {
|
||||
grep -E --color 'CMAKE_BUILD_TYPE|VCPKG_TARGET_TRIPLET|UPSTREAM_RELEASE' CMakeCache.txt
|
||||
}
|
||||
|
||||
function pgrep {
|
||||
get-ciminstance win32_process -filter "name like '%$($args[0])%' OR commandline like '%$($args[0])%'" | select processid, name, commandline
|
||||
}
|
||||
|
||||
function pkill {
|
||||
pgrep $args | %{ stop-process $_.processid }
|
||||
}
|
||||
|
||||
function taskslog {
|
||||
get-winevent 'Microsoft-Windows-TaskScheduler/Operational'
|
||||
}
|
||||
|
||||
function ltr { $input | sort lastwritetime }
|
||||
|
||||
function ntop { ntop.exe -s 'CPU%' $args }
|
||||
|
||||
function head {
|
||||
$lines = if ($args.length -and $args[0] -match '^-(.+)') { $null,$args = $args; $matches[1] } else { 10 }
|
||||
|
||||
if (!$args.length) {
|
||||
$input | select -first $lines
|
||||
}
|
||||
else {
|
||||
gc $args | select -first $lines
|
||||
}
|
||||
}
|
||||
|
||||
set-alias -name which -val get-command
|
||||
set-alias -name notepad -val '/program files/notepad++/notepad++'
|
||||
|
||||
if (test-path alias:diff) { remove-item -force alias:diff }
|
||||
|
||||
# Load VS env only once.
|
||||
foreach ($vs_type in 'buildtools','community') {
|
||||
$vs_path="/program files (x86)/microsoft visual studio/2019/${vs_type}/vc/auxiliary/build"
|
||||
|
||||
if (test-path $vs_path) {
|
||||
break
|
||||
}
|
||||
else {
|
||||
$vs_path=$null
|
||||
}
|
||||
}
|
||||
|
||||
if ($vs_path -and -not $env:VSCMD_VER) {
|
||||
pushd $vs_path
|
||||
cmd /c 'vcvars64.bat & set' | where { $_ -match '=' } | %{
|
||||
$var,$val = $_.split('=')
|
||||
set-item -force "env:$var" -value $val
|
||||
}
|
||||
popd
|
||||
}
|
||||
|
||||
# Chocolatey profile
|
||||
$chocolatey_profile = "$env:chocolateyinstall\helpers\chocolateyprofile.psm1"
|
||||
|
||||
if (test-path $chocolatey_profile) { import-module $chocolatey_profile }
|
||||
|
||||
import-module ~/source/repos/posh-git/src/posh-git.psd1
|
||||
|
||||
function global:PromptWriteErrorInfo() {
|
||||
if ($global:gitpromptvalues.dollarquestion) {
|
||||
([char]27) + '[0;32mv' + ([char]27) + '[0m'
|
||||
}
|
||||
else {
|
||||
([char]27) + '[0;31mx' + ([char]27) + '[0m'
|
||||
}
|
||||
}
|
||||
|
||||
$gitpromptsettings.defaultpromptabbreviatehomedirectory = $true
|
||||
|
||||
$gitpromptsettings.defaultpromptprefix.text = '$(PromptWriteErrorInfo) '
|
||||
|
||||
$gitpromptsettings.defaultpromptwritestatusfirst = $false
|
||||
$gitpromptsettings.defaultpromptbeforesuffix.text = "`n$env:USERNAME@$($env:COMPUTERNAME.ToLower()) "
|
||||
$gitpromptsettings.defaultpromptbeforesuffix.foregroundcolor = 0x87CEFA
|
||||
$gitpromptsettings.defaultpromptsuffix.foregroundcolor = 0xDC143C
|
||||
|
||||
import-module psreadline
|
||||
|
||||
set-psreadlineoption -editmode emacs
|
||||
set-psreadlinekeyhandler -key tab -function tabcompletenext
|
||||
set-psreadlinekeyhandler -key uparrow -function historysearchbackward
|
||||
set-psreadlinekeyhandler -key downarrow -function historysearchforward
|
||||
```
|
||||
|
||||
This profile works for "Windows PowerShell", the powershell you launch from the
|
||||
`Win+X` menu as well. But the profile is in a different file, so you will need
|
||||
to copy it there too:
|
||||
|
||||
```powershell
|
||||
mkdir ~/Documents/WindowsPowerShell
|
||||
cpi ~/Documents/PowerShell/Microsoft.Powershell_profile.ps1 ~/Documents/WindowsPowerShell
|
||||
```
|
||||
|
||||
#### Setting up gpg
|
||||
|
||||
Make this symlink:
|
||||
|
||||
```powershell
|
||||
sl ~
|
||||
mkdir .gnupg
|
||||
ni -itemtype symboliclink ~/AppData/Roaming/gnupg -target $(resolve-path ~/.gnupg)
|
||||
```
|
||||
|
||||
Then you can copy your `.gnupg` over, without the socket files.
|
||||
|
||||
To configure git to use it, do the following:
|
||||
|
||||
```powershell
|
||||
git config --global commit.gpgsign true
|
||||
git config --global gpg.program 'C:\Program Files (x86)\GnuPG\bin\gpg.exe'
|
||||
```
|
||||
|
||||
#### Setting up sshd
|
||||
|
||||
Edit `\ProgramData\ssh\sshd_config` and remove or comment out this section:
|
||||
|
||||
```
|
||||
Match Group administrators
|
||||
AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
|
||||
```
|
||||
|
||||
Then run:
|
||||
|
||||
```powershell
|
||||
restart-service sshd
|
||||
```
|
||||
|
||||
If you've installed openssh before copying over your `~/.ssh`, you will need to
|
||||
fix permissions on your `authorized_keys` files, the easiest way to do
|
||||
that is to re-run the installer with `--force`:
|
||||
|
||||
```powershell
|
||||
choco install -y --force openssh --params '/SSHServerFeature /SSHAgentFeature /PathSpecsToProbeForShellEXEString:$env:programfiles\PowerShell\*\pwsh.exe'
|
||||
```
|
||||
|
||||
If you need to fix permissions on your private key, follow these instructions:
|
||||
|
||||
https://superuser.com/a/1329702/226829
|
||||
|
||||
#### PowerShell Usage Notes
|
||||
|
||||
PowerShell is very different from unix shells, in both usage and programming.
|
||||
|
||||
This section won't teach you PowerShell, but it will give you enough
|
||||
information to use it as a shell and a springboard for further exploration.
|
||||
|
||||
You can get a list of aliases with `alias` and lookup specific aliases with e.g.
|
||||
`alias ri`. It allows globs, e.g. to see aliases starting with `s` do `alias
|
||||
s*`.
|
||||
|
||||
You can get help text for any cmdlet via its long name or alias with `help`. To
|
||||
use `less` instead of the default pager, do e.g.: `help gci | less`.
|
||||
|
||||
For the `git` man pages, do `git help <command>` to open the man page in your
|
||||
browser, e.g. `git help config`.
|
||||
|
||||
I suggest using the short forms of PowerShell aliases instead of the POSIX
|
||||
aliases, this forces your brain into PowerShell mode so you will mix things up
|
||||
less often, with the exception of a couple of things like `mkdir` and the alias
|
||||
above for `which`.
|
||||
|
||||
Here is a few:
|
||||
|
||||
| PowerShell alias | Full cmdlet + Params | POSIX command |
|
||||
|------------------|-------------------------------|-------------------|
|
||||
| sl | Set-Location | cd |
|
||||
| gci | Get-ChildItem | ls |
|
||||
| gi | Get-Item | ls -d |
|
||||
| cpi | Copy-Item | cp -r |
|
||||
| ri | Remove-Item | rm |
|
||||
| ri -for | Remove-Item -Force | rm -f |
|
||||
| ri -rec -for | Remove-Item -Force -Recurse | rm -rf |
|
||||
| gc | Get-Content | cat |
|
||||
| mi | Move-Item | mv |
|
||||
| mkdir | New-Item -ItemType Directory | mkdir |
|
||||
| which (custom) | Get-Command | command -v, which |
|
||||
| gci -rec | Get-ChildItem -Recurse | find |
|
||||
| ni | New-Item | touch <new-file> |
|
||||
| sort | Sort-Object | sort |
|
||||
| sort -u | Sort-Object -Unique | sort -u |
|
||||
|
||||
This will get you around and doing stuff, the usage is slightly different
|
||||
however.
|
||||
|
||||
For one thing commands like `cpi` (`Copy-Item`) take a list of files differently
|
||||
from POSIX, they must be a PowerShell list, which means separated by commas. For
|
||||
example, to copy `file1` and `file2` to `dest-dir`, you would do:
|
||||
|
||||
```powershell
|
||||
cpi file1,file2 dest-dir
|
||||
```
|
||||
|
||||
To remove `file1` and `file2` you would do:
|
||||
|
||||
```powershell
|
||||
ri file1,file2
|
||||
```
|
||||
|
||||
You can list multiple globs in these lists as well as files and directories
|
||||
etc., for example:
|
||||
|
||||
```powershell
|
||||
ri .*.un~,.*.sw?
|
||||
```
|
||||
|
||||
The commands `grep`, `sed`, `awk`, `rg`, `diff`, `patch`, `less`, `zip`,
|
||||
`unzip`, `ssh`, `vim`, `nvim` (neovim) are the same as in Linux and were
|
||||
installed in the list of packages installed from Chocolatey above.
|
||||
|
||||
The commands `curl` and `tar` are now standard Windows commands.
|
||||
|
||||
For an `htop` replacement, use `ntop` (installed in the list of Chocolatey
|
||||
packages above.) with my wrapper function in the sample `$profile`.
|
||||
|
||||
Redirection for files and commands works like in POSIX on a basic level, that
|
||||
is, you can expect `<`, `>` and `|` to redirect files and commands like you
|
||||
would expect on a POSIX shell. `/dev/null` is `$null`, so the equivalent of
|
||||
|
||||
```bash
|
||||
cmd >/dev/null 2>&1
|
||||
```
|
||||
|
||||
would be:
|
||||
|
||||
```powershell
|
||||
cmd *> $null
|
||||
```
|
||||
|
||||
For `ls -ltr` use:
|
||||
|
||||
```powershell
|
||||
gci | sort lastwritetime
|
||||
```
|
||||
|
||||
Or the alias in my profile:
|
||||
|
||||
```powershell
|
||||
gci | ltr
|
||||
```
|
||||
|
||||
Parameters can be completed with `tab`, so in the case above you could write
|
||||
`lastw<tab>`.
|
||||
|
||||
To make a symbolic link, do:
|
||||
|
||||
```powershell
|
||||
ni -itemtype symboliclink name-of-link -target path-to-source
|
||||
```
|
||||
|
||||
again the parameters `-ItemType` and `SymbolicLink` can be `tab` completed.
|
||||
|
||||
For a `find` replacement, use the `-Recurse` flag to `gci`, e.g.:
|
||||
|
||||
```powershell
|
||||
gci -rec *.cpp
|
||||
```
|
||||
|
||||
PowerShell supports an amazing new system called the "object pipeline", what
|
||||
this means is that you can pass objects around via pipelines and inspect their
|
||||
properties, call methods on them, etc..
|
||||
|
||||
Here is an example of using the object pipeline to delete all vim undo files:
|
||||
|
||||
```powershell
|
||||
gci -rec .*.un~ | ri
|
||||
```
|
||||
|
||||
it's that simple, `ri` notices that the input objects are files, and removes
|
||||
them.
|
||||
|
||||
You can access the piped-in input in your own functions as the special `$input`
|
||||
variable, like in the `head` example in the profile above.
|
||||
|
||||
Here is a more typical example:
|
||||
|
||||
```powershell
|
||||
get-process | ?{ $_.name -notmatch 'svchost' } | %{ $_.name } | sort -uniq
|
||||
```
|
||||
|
||||
here `?{ ... }` is like filter/grep block and `%{ ... }` is like apply/map.
|
||||
|
||||
In PowerShell, the backtick `` ` `` is the escape character, and you can use it
|
||||
at the end of a line, escaping the line end as a line continuation character. In
|
||||
regular expressions, the backslash `\` is the escape character, like everywhere
|
||||
else.
|
||||
|
||||
Here are a couple more example of PowerShell one-liners:
|
||||
|
||||
```powershell
|
||||
# Name and command mapping for aliases starting with 'se'.
|
||||
alias se* | select name, resolvedcommand
|
||||
|
||||
# Create new empty files foo1 .. foo7.
|
||||
1..7 | %{ ni "foo$_" }
|
||||
|
||||
# Find the import libraries in the Windows SDK with symbol names matching
|
||||
# 'MessageBox'.
|
||||
gci '/program files (x86)/windows kits/10/lib/10.*/um/x64/*.lib' | `
|
||||
%{ $_.name; dumpbin -headers $_ | grep MessageBox }
|
||||
```
|
||||
|
||||
#### Miscellaneous
|
||||
|
||||
To get transparency in Microsoft terminal, use this AutoHotkey script:
|
||||
|
||||
```autohotkey
|
||||
#NoEnv
|
||||
SendMode Input
|
||||
SetWorkingDir %A_ScriptDir%
|
||||
|
||||
; Toggle window transparency.
|
||||
#^Esc::
|
||||
WinGet, TransLevel, Transparent, A
|
||||
If (TransLevel = 255) {
|
||||
WinSet, Transparent, 205, A
|
||||
} Else {
|
||||
WinSet, Transparent, 255, A
|
||||
}
|
||||
return
|
||||
```
|
||||
|
||||
This will toggle transparency in a window when you press `Ctrl+Win+Esc`, you
|
||||
have to press it twice the first time.
|
||||
|
||||
Thanks to @munael for this tip.
|
||||
https://github.com/rkitover/windows-dev-guide
|
||||
|
||||
### Release Process
|
||||
|
||||
|
|
Loading…
Reference in New Issue