REBOL/SDK - Windows Registry Functions
Return to Contents
Contents:
1. Purpose
2. Registry Structure
3. Functions
3.1 Standard Key Handles
3.2 Create-Reg Function
3.3 Exists-Reg? Function
3.4 Set-Reg Function
3.5 Get-Reg Function
3.6 Delete-Reg Function
3.7 List-Reg Function
3.8 Unset-Reg-Funcs Function
4. Examples
4.1 Registry Keys in HTML
4.2 Registry Key Browser
4.3 Install Program
4.4 Uninstall Program
4.5 Check for Install
1. Purpose
The SDK extends REBOL with a subset of Windows registry access
functions. These functions are useful for installing and
uninstalling your REBOL programs and can also be used for
storing important program configuration options within the
registry (although to enable scripts to run on a variety of
platforms, we recommend that values be stored in regular text
files whenever possible).
Because these functions are intended primarily for program
installation and configuration, they are not fully general
purpose Windows registry operations; nevertheless, a broad range
of registry operations can be performed with what is supplied.
| Important Warning | |
Access the windows registry at your own risk. Be very careful
with these registry functions. Mistakes can cause problems with
your computer and even render it unbootable. The Windows
registry access functions do not warn you about improper values
or deletions, they just "do" it.
We strongly recommend that you backup your registry before using
any of these functions. There are many ways to do so.
- Run the ScanReg program provided by Microsoft (note that
windows will run this program automatically once a day).
- Use RegEdit to save a .reg file with the contents of the registry.
- Use the Microsoft backup utility.
- Manually copy your system.dat and user.dat files if necessary.
|
Also note that if you use these functions to access values other
than those stored by REBOL, various programs save data in
different formats. For example, one program may save a filename
as a string, while another saves it as a binary value.
2. Registry Structure
For the purposes of writing REBOL installation programs, you do
not need a deep knowledge of the registry. The functions we
provide are easy to use. See Microsoft's documentation if you
need a more complete description of the registry and how it
works.
The Windows Registry is composed of three primary sections.
Each of these sections includes a set of key-names and values,
and each may contain groups of sub-keys (forming a tree, very
similar to that of files and directories.) The HK letters are
Microsoft's standard abbreviation for a "Handle to a Key".
| | HKLM | Holds keys and values related to the local machine. This
information is related to the computer as a whole (rather than
for a specific user of the computer). HKLM includes information
about the hardware, device drivers, services, security, and
software application info.
|
| | HKU | Holds values related to specific users. Each user gets
different settings here. Includes information about user's
control panel settings, keyboard layout, selected event sounds,
and software application settings.
|
| | HKDD | Holds dynamic data. This information is not saved
to disk and is built each time the system is booted.
|
In addition to those areas above, there are a few sections that
are important enough to have their own aliases. These point into
the above structures.
| | HKCU | Current user. Points into HKU at the current user.
|
| | HKCR | Classes root. Points into HKLM software/classes.
|
| | HKCC | Current config. Points into HKLM/config/profile.
|
For the purposes of REBOL application installation, HKCU
(current user information) will be the most common, and it is
the default for the functions described below.
3. Functions
The REBOL registry access functions have been designed to be
consistent with the methods provided by Microsoft (thus making
them easier to learn and understand relative to existing
registry books and documentation).
However, one difference is that these functions will always
close their registry access each time they are called. The
registry is never left open, so you don't need to be concerned
with registry corruption when errors in your code cause your
program to stop.
| Access Permissions | |
These functions use and require standard access permissions to
the registry. In some environments such as schools or
businesses access to the registry may be restricted. In such
cases if the user cannot login as the system administrator,
then you may have no choice but to save your configuration
information in local files, rather than in the registry.
|
3.1 Standard Key Handles
All of the functions below allow you to specify any one of the
standard reserved handle mentioned above. They are provided as
refinements. The list includes:
- /HKCU - current user (default)
- /HKCC - current config
- /HKCR - classes root
- /HKLM - local machine
- /HKDD - dynamic data
- /HKU - user data
3.2 Create-Reg Function
Create a registry key. The function syntax is:
The key is a string that describes a path within the
registry. The path uses backslashes "\" rather than forward
slashes to specify higher level keys. The path is relative to
HKCU (current user) unless another refinement is used.
The function returns TRUE if it was successful, or FALSE if it
failed.
A typical example using create-reg to install a new "Product"
made by "Maker":
either create-reg "Software\Maker\Product" [
print "key added"
][
print "cannot add key - contact administrator"
]
|
Notes:
- The newly created key will have no values, but you can use the
set-reg function described below to set specific key values.
- Note that you cannot create keys directly under HKU or HKLM.
3.3 Exists-Reg? Function
Return TRUE if the key exists, else return FALSE. The syntax is:
The key is a string that describes a path within the registry.
The path uses backslashes "\" rather than forward slashes to
specify higher level keys. The path is relative to HKCU (current
user) unless another refinement is used.
This function provides an efficient way to detect if your
product has been installed (to prompt for installation if
necessary). For example:
if not exists-reg? "Software\Maker\Product" [
print "product has not been installed"
]
|
3.4 Set-Reg Function
Set a value within a key. The syntax is:
This function stores data in a new or existing value field of an
existing registry key.
The key is a string that describes a path within the
registry. The path uses backslashes "\" rather than forward
slashes to specify higher level keys. The path is relative to
HKCU (current user) unless another refinement is used.
The name is a a string containing the name of the value to
set. If the name does not already exist in the key, it will be
added.
For example, to add a value to the key created in the prior
section:
set-reg "Software\Maker\Product" "version" "1.2.0"
|
Notes:
- If the registry key does not exist, this function returns
NONE.
- If a binary datatype is provided at the value, the registry
entry will be tagged as a binary type.
- BETA 1 version of this function does not properly handle
registry datatypes other than string and binary values. This
will be fixed in a future BETA release.
- If the value string is longer than 2048 bytes, it should be
stored a file with the filename stored in the registry. This
helps the registry perform efficiently. Do not store application
elements such as icons, bitmaps, and executable files in the
registry.
- If the name field is an empty string this function sets the
default value stored for the key. (A Win95 compatibility
option).
- If the value begins with a "%", it will be treated specially
and marked as expanded reference to an environment variable.
When the value is fetched with get-reg, it will automatically be
expanded.
3.5 Get-Reg Function
Get a value from within a key. The syntax is:
This function retrieves data from an existing value field of a
registry key.
The key is a string that describes a path within the
registry. The path uses backslashes "\" rather than forward
slashes to specify higher level keys. The path is relative to
HKCU (current user) unless another refinement is used.
The name argument is a string containing the name of the value
to fetched. If either the key or the name do not exist, a NONE
value is returned.
This example fetches and prints the value stored in the previous
section:
value: get-reg "Software\Maker\Product" "version"
print value
|
Notes:
- BETA 1 version of this function does not properly handle
registry datatypes other than strings. This will be fixed in
a future BETA release.
- If environment-variables are stored as part of the value field,
this function will expand them according to the Windows
ExpandEnvironmentStrings function.
3.6 Delete-Reg Function
Delete a registry key. The syntax is:
This function removes the specified key from the registry
including all of its values.
The key is a string that describes a path within the
registry. The path uses backslashes "\" rather than forward
slashes to specify higher level keys. The path is relative to
HKCU (current user) unless another refinement is used.
A TRUE is returned on success and a FALSE is returned on
failure.
Notes:
- The behavior of this function varies between versions of the
Windows operating system. For example, under 95 type systems,
this function deletes a key and all its descendents. Under NT
systems, the function deletes the specified key and will not
delete a key that has subkeys (you will need to do that manually
yourself).
- We will be providing a delete-reg/deep refinement in a future
BETA release to solve the above problem.
3.7 List-Reg Function
Returns subkeys for an existing key. The syntax is:
This function returns a block that contains the names of all
subkeys that belongs to the specified key. The order of the
subkeys is not specified and may vary.
The key is a string that describes a path within the registry.
The path uses backslashes "\" rather than forward slashes to
specify higher level keys. The path is relative to HKCU (current
user) unless another refinement is used.
This example will print the names of all keys found in the
current user software key:
foreach key list-reg "software" [
print key
]
|
If the key does not exist, a NONE is returned.
3.8 Unset-Reg-Funcs Function
Disable the above functions. Syntax is:
This function will remove all of the above functions from REBOL.
This should be done for security purposes when your code no
longer needs these functions after boot each time.
4. Examples
| Warning | |
These are provided as simple examples for your use and revision.
Verify the proper operation of all examples before using them in
your applications. It is suggested that you backup your registry
before experimenting with these functions. REBOL Technologies
will not be responsible for damage to your system.
|
4.1 Registry Keys in HTML
This program creates an HTML file that shows all subkeys for
your current user (HKCU) software key.
Note that this output can get rather large on systems that have
a lot of software installed.
REBOL [Title: "Dump Registry Keys in HTML"]
html: make string! 2040
emit: func [data] [append repend html data newline]
emit-reg-keys: func [path /local keys] [
if not keys: list-reg path [exit]
emit <UL>
foreach key keys [
emit [<LI> key]
emit-reg-keys rejoin [path pick ["" "\"] empty? path key]
]
emit </UL>
]
title: "Registry Dump for Current User Software"
emit [
<HTML>
<TITLE> title </TITLE>
<BODY BGCOLOR="WHITE">
<H2> title </H2>
]
emit-reg-keys "Software"
emit [
</BODY>
</HTML>
]
write %reg-out.html html
;browse %reg-out.html
|
4.2 Registry Key Browser
The following example lets you interactively browse the keys
of the local machine (HKLM) section of the registry:
REBOL [Title: "Registry SubKey Browser"]
list-reg-path: func [path /local keys val n] [
print ["Keys for:" mold path]
;-- Get list of subkeys:
if not keys: list-reg/HKLM path [
print ["Invalid key:" path]
clear any [find/reverse tail path "\" path]
list-reg-path path
exit
]
;-- Print subkey list:
n: 1
foreach key keys [
print [n "-" key]
n: n + 1
]
;-- Ask user for subkey:
val: ask "Key number, enter to backup, escape to quit: "
either integer? attempt [val: load val] [
if val: pick keys val [
if not empty? path [append path "\"]
append path val
list-reg-path path
]
][
clear any [find/reverse tail path "\" path]
list-reg-path path
]
]
list-reg-path ""
|
4.3 Install Program
Here is the main function for installing a new program in the
registry. It adds HOME, VERSION, and DATE registry values to a
new key that it creates in the current user software subkeys.
(This is nearly identical to how REBOL products install
themselves).
This function will also set up an "uninstall" entry (for
add/remove programs). The uninstall calls your program with a -u
option, which you must provide.
;-- Primary software keys:
ms-base: "Software\Microsoft\Windows\CurrentVersion"
ms-uninstall: join ms-base "\Uninstall\"
;-- Function to build our key:
reg-base: func [maker name] [
rejoin ["Software\" maker #"\" name #"\"]
]
register: func [
"Install program by setting registry values."
maker [string!] "company name"
name [string!] "application name"
version [tuple!] "application version"
home [file!] "application home directory"
target [file!] "application executable file"
/local key
][
;-- Create the uninstall link (optional):
key: join ms-uninstall reform [maker name]
if not create-reg/hklm key [return false]
set-reg/hklm key "DisplayName" reform [maker name]
set-reg/hklm key "UninstallString" rejoin [
{"} to-local-file target {" -u}
]
;-- Create main registry key:
key: reg-base maker name
if not create-reg key [return false]
set-reg key "Home" form to-local-file home
set-reg key "Version" form version
set-reg key "Date" form now
return true
]
|
The function will return TRUE on success and FALSE on failure.
4.4 Uninstall Program
Here is a simple uninstaller function. It will remove the key
for an application as installed above, and will remove the
company key if it is empty as a result.
Due to inconsistent Microsoft Windows registry API
implementations (between 98 and NT versions), the following
function is required to delete subkeys:
delete-keys: func [
"Recursively delete registry keys."
path ; registry path
/hklm
/local keys
][
keys: either hklm [list-reg/hklm path] [list-reg path]
if none? keys [exit]
foreach key keys [
delete-keys rejoin [path #"\" key]
]
either hklm [delete-reg/hklm path] [delete-reg path]
]
|
Here is the uninstaller function:
uninstall: [
"Uninstall the program from Windows registry."
maker [string!] "company name"
name [string!] "application name"
/local keys
][
if not confirm rejoin [
"Please confirm that you want to uninstall " name "."
][quit]
;-- Remove product key:
delete-keys reg-base maker name
;-- Find all products. Delete base key if no more products.
keys: list-reg join "Software\" maker
if all [keys empty? keys] [delete-keys join "Software\" maker]
delete-keys/hklm join ms-uninstall reform [maker name]
]
|
4.5 Check for Install
This function can be called each time your application starts
to determine if it needs to be installed. It also checks for
the +i and -i options (+i for reinstall and -i for do not install).
The function will return TRUE if installation is required, and
you can call the Register function described above.
install?: func [
"Return true if program needs to be installed."
maker [string!] "company name"
name [string!] "application name"
version [tuple!] "current version"
/local vers program-args
][
program-args: system/options/args
;-- Reinstall option +i specified. Always force reinstall.
if all [block? program-args find program-args "+i"][return true]
;-- Command line -i option forces program to run w/o installing
if all [
block? program-args
find program-args "-i"
][return none]
vers: attempt [load get-reg reg-base maker name "Version"]
;-- If the reg version is less than the current version,
; then a reinstall will happen.
any [
system/options/install = 1 ; command line reinstall flag
not tuple? vers ; invalid version, force reinstall
version > vers ; older version, force reinstall
] ; returns NONE otherwise
]
|
This function can be called to check for the uninstall (-u) option:
uninstall?: has [program-args] [
"Return true if program needs to be uninstalled."
program-args: system/options/args
any [
all [
block? program-args
find program-args "-u"
]
]
]
|
| | REBOL/MakeDoc 2.0 | REBOL is a registered trademark of REBOL Technologies Copyright 2003 REBOL Technologies | 5-Aug-2003 |
|