From: Phil Pennock <phil.pennock@globnix.org>
To: zsh-users@sunsite.dk
Subject: Cygwin zsh and command availability
Date: Sat, 4 Mar 2006 20:37:33 +0100 [thread overview]
Message-ID: <20060304193733.GA22944@parhelion.globnix.org> (raw)
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
reply other threads:[~2006-03-04 19:37 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20060304193733.GA22944@parhelion.globnix.org \
--to=phil.pennock@globnix.org \
--cc=zsh-users@sunsite.dk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).