Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Cygwin zsh and command availability
- X-seq: zsh-users 9993
- From: Phil Pennock <phil.pennock@xxxxxxxxxxx>
- To: zsh-users@xxxxxxxxxx
- Subject: Cygwin zsh and command availability
- Date: Sat, 4 Mar 2006 20:37:33 +0100
- Mail-followup-to: zsh-users@xxxxxxxxxx
- Mailing-list: contact zsh-users-help@xxxxxxxxxx; run by ezmlm
- Sender: Phil Pennock <phil@xxxxxxxxxxxxx>
Posting this in the hope that it might prove useful to others.
Under Windows, commands run by ShellExecute() look in multiple places,
including doing a registry key lookup under:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\
According to MSDN, the priority ordering of ShellExecute() varies by
Windows version, but as of WinXP SP1 the App Path items come before
%PATH%.
This is how you can do things like Start->Run "firefox" and get a
web-browser, despite Firefox not being in %PATH%.
This zsh solution is not perfectly robust but it appears to work for me.
It does not favour conciseness. Because I wanted to keep everything
safe, the script generates zsh command-lines. Rather than re-work it,
I've decided that I'm happy with:
function load_win32_registry_paths {
local t
/cygdrive/X/path/to/win32_registry_paths | while read t
do eval $t; done
}
Comments & improvements welcome.
Command dependency is "reg", which I think is a standard Windows
component; it says:
Console Registry Tool for Windows - version 3.0
Copyright (C) Microsoft Corp. 1981-2001. All rights reserved
-----------------------------< cut here >-------------------------------
#!/usr/bin/zsh -f
setopt extended_glob
typeset -a regout
oIFS="$IFS"
IFS=$'\n'
regout=($(reg query \
"HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths" /s | \
sed 's/\\/\\\\/g'))
IFS="$oIFS"
function path_convert_backslash
{
local loc="$1"
loc=${(Q)loc}
loc=${loc:gs,\\,/}
# for some reason, that results in // in the result, so:
# loc=${loc:gs,//,/}
print -r -- ${(q)loc}
}
function path_convert_drive
{
local loc="$1"
loc=${(Q)loc}
if [[ $loc == ?:* ]]
then
drive=${loc%%:*}
loc="/cygdrive/${drive}${loc#?:}"
fi
print -r -- ${(q)loc}
}
function path_expand_var
{
# %ProgramFiles% -> $PROGRAMFILES
local t="$1"
while [[ $t == *%*%* ]]
do
local prefix suffix var
prefix=${t%%\%*}
var=${t#${prefix}\%}
suffix=${var#*%}
var=${var%%\%*}
t="$(path_convert_backslash "${(qP)${(U)var}}")"
t="$(path_convert_drive "$t")"
t="${prefix}${t}${suffix}"
done
print -r -- $t
return 0
}
function get_path_expanded
{
#local src="${(p)1:gs/\t/ /}"
local src="$1" # we actually can just split on a tab, at present
local p t what drive
typeset -a list newlist
# Get the type and the rest
list=(${(ps:\t:)src})
what=$list[1]
list[1]=()
t="$(path_convert_backslash "${list[*]}")"
# expand out <drive-letter>: for each element in the ;-list
list=(${(s:;:)t})
newlist=()
for p in $list
do
newlist+=("$(path_convert_drive $p)")
done
t="${(j:;:)newlist[*]}"
case $what in
(REG_SZ)
print $t
return 0
;;
(REG_EXPAND_SZ)
# XXX: this probably doesn't deal well with variables whose value contains %,
# which shouldn't happen but we should protect against it anyway.
list=()
for p in $newlist
do
list+=("$(path_expand_var $p)")
done
print "${(j:;:)list}"
return 0
;;
(*)
print -u2 "Unhandled registry type: $what"
;;
esac
return 1
}
print "zmodload -i zsh/parameter"
typeset -A state
local rest n t
for ((i=0; i < ${#regout}; i++))
do
case ":${regout[$i]}:" in
(:HKEY*)
if [[ -n $state[name] && -n $state[cmd] ]]
then
n="${${(L)state[name]}%.exe}"
if [[ -n $state[path_add] ]]
then
t="\"${(j:" ":)${(qs:;:)state[path_add]}}\""
print "function $n { ( path=($t \$path); \"${state[cmd]}\" \\\"\$@\\\" ) }"
else
print "commands[$n]=\"${state[cmd]}\""
fi
fi
state=()
state[name]=${regout[$i]:t}
# print "NAME: $state[name]"
;;
(:[[:blank:]]##\<NO NAME\>*)
rest="${regout[$i]##[[:blank:]]##<NO NAME>}"
state[cmd]=$(get_path_expanded $rest)
# print " cmd: $state[cmd]"
;;
(:[[:blank:]]##Path[[:blank:]]*)
rest="${regout[$i]##[[:blank:]]##Path}"
state[path_add]=$(get_path_expanded $rest)
# print "path: $state[path_add]"
;;
# Alas, we lost the blank lines, so accumulate in HKEY
# (:[[:blank:]]#:)
# ;;
(*)
# Oooh, look at all those undocumented fields:
# print -u2 "Unhandled registry item for ${state[name]}: $regout[$i]"
;;
esac
done
Messages sorted by:
Reverse Date,
Date,
Thread,
Author