Windows OS Utilities
This library is a collection of assorted functions specific to the Windows operating system. It requires Franz Allegro Common Lisp for Windows, version 6 or greater. Note that this library replaces the single file qrg\code-library\lisp\win-utils.lsp and use of that file is now discouraged. See "Notes on Upgrading from Win-Utils.lsp" for information on upgrading your old code to this new library.
File-System
(wu:file-readonly? path)
Returns non-nil if and only if the specified file has its read-only flag set.
(setf (wu:file-readonly? pathspec) <non-nil | nil >)
Changes the specified file's read-only flag. Note that this function won't change the flag if it's already set to the requested value, thus saving time, since it's faster to check the read-only flag than it is to set it. An error may be signalled if the code is running in a user account that does not have permission to change file attributes.
(wu:make-directory-writable directory-path &key recurse?)
Makes all the files in the directory writable. Returns non-nil on success. If recurse? is non-nil then all subdirectories will be modified as well.
(wu:directory? path)
Returns non-nil if and only if the specified path is a directory.
Miscellaneous Operating System Functionality
(wu:shell-execute filename &key (operation :open) (parameters nil)
(show-command win:SW_SHOWNORMAL) (default-directory nil))
This command runs an executable file or acts upon a document using its associated application. The arguments are as follows:
- filename should be a string or pathname representing an executable, document, or folder.
- operation should be one of :open, :print, :explore, :edit, or :find.
- parameters is a string containing the command line arguments for the executable file. These are only used if filename is an executable.
- default-directory is a string or pathname representing the default directory to be used by the application.
- show-command controls how the application's window should be opened.
It should be one of the following values:
- win:SW_HIDE — hides the window
- win:SW_MAXIMIZE — maximizes the window
- win:SW_MINIMIZE — minimizes the window
- win:SW_RESTORE — activates and displays the window while restoring it from a minimized or maximized state
- win:SW_SHOW — activates the window and displays it in its current size and position
- win:SW_SHOWMAXIMIZED — activates the window and maximizes it
- win:SW_SHOWMINIMIZED — activates the window and minimizes it
- win:SW_MINNOACTIVE — minimizes the window but does not make it the active one
- win:SW_SHOWNA — displays the window in its current state but does not make it the active one.
- win:SW_SHOWNOACTIVATE — displays the window in its current size and position but does not make it the active one
- win:SW_SHOWNORMAL — activates and displays the window in a normal state (this is the default)
- 0 — out of memory or resources
- 2 — specified file was not found
- 3 — specified path was not found
- 5 — OS is denied access to the file
- 8 — not enough memory
- 11 — specified .EXE file is not a recognized executable format
- 26 — sharing violation occurred
- 27 — filename association is invalid
- 28 — DDE request timed-out
- 29 — DDE transaction failed
- 30 — other DDE transactions are being processed
- 31 — no association with the filename extension
- 32 — specified DLL file was not found
(wu:describe-OS)
- a string description of the currently running operating system
- a symbol indicating the OS platform (:windows or :NT)
- a numeric version indicator (4, 5, etc. for NT; 1995, 1998, etc. for :windows)
(wu:os-shell-path path-type &rest subdirs)
The path-type argument should be one of the Windows CSIDL_* constants. These are described in detail in the Windows SDK documentation, but the constants have been defined in the win-utils package and some common ones are described below:
- wu:CSIDL_PERSONAL — current user's "My Documents" folder
- wu:CSIDL_DESKTOP — current user's desktop
- wu:CSIDL_STARTMENU — current user's "Start Menu" folder
- wu:CSIDL_COMMON_STARTMENU — all users' "Start Menu" folder
- wu:CSIDL_APPDATA — current user's "Application Data" folder
- wu:CSIDL_PROGRAM_FILES — "Program Files" folder
Utilities for Inspecting Running Processes
(wu:foreground-app-name)
Returns two values: the name of the current process and its process ID.
(wu:window-image-name hwnd)
Returns the name of the process that started this window.
(wu:window-process-id hwnd)
Returns the process ID of the process that started this window.
(wu:list-process-ids)
Returns a list of the IDs of all the processes currently running.
(wu:process-id-name pid)
Returns the name of the process.
(wu:map-process-modules fn pid)
Iterates over the modules active within a given process.
For each module, fn will be called with two arguments:
1) the handle to the process (which is of type HANDLE)
2) the handle to the module (which is of type HMODULE)
Both of these values are only valid within the scope of the function call,
so don't keep them around to use later.
(wu:get-module-info hProcess hModule)
Returns a module-info object describing the specified module.
(wu:module-basename hProcess hModule)
Returns the base name of the specified module.
(wu:module-filename hProcess hModule)
Returns the full path to the specified module's disk file (usually a DLL).
(wu:mappedfile-name hProcess hModule)
Returns the name of a Windows mapped file (these are file streams mapped into memory and sharable between processes).
Utilities for Examining Memory Allocation
(wu:memory-map process-id &key (strict-merge? t))
Returns an ordered list of mem-block objects detailing the virtual memory space as seen by a specified process (via the process ID pid). If strict-merge? is nil, adjeacent memory blocks will be merged together if they are owned by the same module; if non-nil, adjacent blocks will only be merged if they have the same owner, the same sharing permissions, and the same protection attributes. This function can use a lot of memory and can take some time to run. It's not meant to be called often.
(wu:print-memory-map &key (mem-map nil) (strict-merge? t) (str *standard-output*))
Prints a human-readable description of the current process' virtual memory space. Also returns an ordered list of mem-block objects as via a call to memory-map.
(wu:find-optimal-heap-placement &key (str *standard-output*))
Finds the largest contiguous block of RAM that could be used for your Lisp image's heap. This is quite specific to a given machine, so is not so useful when making executables, but is useful if you want to tweak your own Lisp image to gain the maximum possible heap size. This is probably best used in a freshly started Lisp image, but it can be instructive to use it while you are running your application as well, since your app will most likely cause additional DLLs and such to be loaded. Returns two values: a mem-block object representing the recommended space for your Lisp heap and an ordered list of mem-block objects generated as via the memory-map function.
The following shows an example of the output. (This was generated on a machine running WindowsXP Pro with SP1.)
================================================================================ Memory map: -------------------------------------------------------------------------------- start size prot owner -------------------------------------------------------------------------------- 00010000 1344K P 0100 < *unused* > 00160000 128K S 0001 \Device\HarddiskVolume3\WINDOWS\SYSTEM32\UNICODE.NLS 00180000 256K S 0001 \Device\HarddiskVolume3\WINDOWS\SYSTEM32\LOCALE.NLS 001c0000 320K S 0001 \Device\HarddiskVolume3\WINDOWS\SYSTEM32\SORTKEY.NLS 00210000 64K S 0001 \Device\HarddiskVolume3\WINDOWS\SYSTEM32\SORTTBLS.NLS 00220000 21760K S 0011 < ??? > 01760000 64K S 0001 \Device\HarddiskVolume3\WINDOWS\SYSTEM32\CTYPE.NLS 01770000 2240K P 0100 < *unused* > 019a0000 64K S 0001 tabhook.dll (C:\WINDOWS\System32\tabhook.dll) 019b0000 128K P 0100 < *unused* > 019d0000 192K S 0001 msctfime.ime (C:\WINDOWS\System32\msctfime.ime) 01a00000 1728K S 0100 < ??? > 01bb0000 212K S 0001 \Device\HarddiskVolume3\WINDOWS\Registration\R000000000010.clb 01be5000 1196K P 0100 < *unused* > 01d10000 256K S 0001 ODBC32.dll (C:\WINDOWS\System32\ODBC32.dll) 01d50000 64K S 0001 odbcbcp.dll (C:\WINDOWS\System32\odbcbcp.dll) 01d60000 232064K P 0100 < *unused* > 10000000 254272K S 0001 PGPhk.dll (C:\WINDOWS\system32\PGPhk.dll) 1f850000 5056K S 0001 odbcint.dll (C:\WINDOWS\System32\odbcint.dll) 1fd40000 4096K P 0100 *** YOUR LISP PLL HERE *** 20140000 773952K P 0100 *** YOUR LISP HEAP HERE *** 4f510000 109504K S 0001 SHELL32.dll (C:\WINDOWS\system32\SHELL32.dll) 56000000 79296K P 0100 < *unused* > 5ad70000 127296K S 0001 uxtheme.dll (C:\WINDOWS\System32\uxtheme.dll) 629c0000 14912K S 0001 LPK.DLL (C:\WINDOWS\System32\LPK.DLL) 63850000 215168K S 0001 acl623.dll (C:\_apps\acl620\acl623.dll) 70a70000 10816K S 0001 SHLWAPI.dll (C:\WINDOWS\system32\SHLWAPI.dll) 71500000 2048K S 0001 browseui.dll (C:\WINDOWS\System32\browseui.dll) 71700000 2368K S 0001 shdocvw.dll (C:\WINDOWS\System32\shdocvw.dll) 71950000 1344K S 0001 comctl32.dll (C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.1579_x-ww_7bbf8d08\comctl32.dll) 71aa0000 64K S 0001 WS2HELP.dll (C:\WINDOWS\system32\WS2HELP.dll) 71ab0000 128K S 0001 WS2_32.dll (C:\WINDOWS\system32\WS2_32.dll) 71ad0000 1344K S 0001 WSOCK32.dll (C:\WINDOWS\system32\WSOCK32.dll) 71c20000 9408K S 0001 NETAPI32.dll (C:\WINDOWS\System32\NETAPI32.dll) 72550000 10560K S 0001 pdh.dll (C:\WINDOWS\System32\pdh.dll) 72fa0000 23872K S 0001 USP10.dll (C:\WINDOWS\System32\USP10.dll) 746f0000 192K S 0001 Msimtf.dll (C:\WINDOWS\System32\Msimtf.dll) 74720000 9216K S 0001 MSCTF.dll (C:\WINDOWS\System32\MSCTF.dll) 75020000 10560K S 0001 aclre32.dll (C:\_apps\acl620\cg\aclre32.dll) 75a70000 4928K S 0001 USERENV.dll (C:\WINDOWS\system32\USERENV.dll) 75f40000 3456K S 0001 appHelp.dll (C:\WINDOWS\system32\appHelp.dll) 762a0000 128K S 0001 MSASN1.dll (C:\WINDOWS\system32\MSASN1.dll) 762c0000 832K S 0001 CRYPT32.dll (C:\WINDOWS\system32\CRYPT32.dll) 76390000 128K S 0001 IMM32.DLL (C:\WINDOWS\System32\IMM32.DLL) 763b0000 2368K S 0001 comdlg32.dll (C:\WINDOWS\system32\comdlg32.dll) 76600000 128K S 0001 CSCDLL.dll (C:\WINDOWS\System32\CSCDLL.dll) 76620000 320K S 0001 cscui.dll (C:\WINDOWS\System32\cscui.dll) 76670000 3200K S 0001 SETUPAPI.dll (C:\WINDOWS\System32\SETUPAPI.dll) 76990000 1600K S 0001 ntshrui.dll (C:\WINDOWS\System32\ntshrui.dll) 76b20000 128K S 0001 ATL.DLL (C:\WINDOWS\System32\ATL.DLL) 76b40000 704K S 0001 WINMM.dll (C:\WINDOWS\system32\WINMM.dll) 76bf0000 3712K S 0001 psapi.dll (C:\WINDOWS\System32\psapi.dll) 76f90000 768K S 0001 Secur32.dll (C:\WINDOWS\System32\Secur32.dll) 77050000 832K S 0001 COMRes.dll (C:\WINDOWS\System32\COMRes.dll) 77120000 576K S 0001 OLEAUT32.dll (C:\WINDOWS\system32\OLEAUT32.dll) 771b0000 1600K S 0001 ole32.dll (C:\WINDOWS\System32\ole32.dll) 77340000 8960K S 0001 comctl32.dll (C:\WINDOWS\system32\comctl32.dll) 77c00000 64K S 0001 VERSION.dll (C:\WINDOWS\system32\VERSION.dll) 77c10000 1216K S 0001 MSVCRT.dll (C:\WINDOWS\system32\MSVCRT.dll) 77d40000 576K S 0001 USER32.dll (C:\WINDOWS\system32\USER32.dll) 77dd0000 576K S 0001 ADVAPI32.dll (C:\WINDOWS\system32\ADVAPI32.dll) 77e60000 960K S 0001 kernel32.dll (C:\WINDOWS\system32\kernel32.dll) 77f50000 704K S 0001 ntdll.dll (C:\WINDOWS\System32\ntdll.dll) 78000000 74304K S 0001 RPCRT4.dll (C:\WINDOWS\system32\RPCRT4.dll) 7c890000 40384K S 0001 CLBCATQ.DLL (C:\WINDOWS\System32\CLBCATQ.DLL) 7f000000 7104K S 0001 GDI32.dll (C:\WINDOWS\system32\GDI32.dll) 7f6f0000 9280K S 0011 < ??? > ================================================================================ For maximum size on this machine, your heap should start at 0x20140000. This will allow it to expand to 755 MB. The first module preventing further expansion is SHELL32.dll. ================================================================================
Notes on Upgrading from Win-Utils.lsp
The file qrg\code-library\list\win-utils.lsp has now been deprecated. It was always awkward to use since it didn't have a normal defsys file for loading and thus forced developers to write special code to ensure it was compiled. Furthermore, over time Franz Allegro has built much of its functionality directly into ACL, thus eliminating the need for us to maintain these functions ourselves. This section describes which functions have been obsoleted and what you should call instead.
load-dll-if-needed
You should now use cl:load (yep, the regular Common Lisp load function) to load your DLLs. It's now smart enough to avoid loading duplicate copies of a DLL and furthermore allows the executable-building functions to know what DLLs your application depends upon. Of special note in this regard is the :system-library keyword argument which is used to tell Allegro that the DLL is a system-wide DLL and should not be included in the executable distribution. (If the DLL is under /windows/system32/, then it is most likely a system-wide DLL and not an application-specific DLL. Including these in your distribution may violate copyrights and furthermore might not even work under a different version of the operating system.)
show-url-in-default-html-browser
Use cg:invoke-html-browser instead. It used to be the case that this function would only work with Internet Explorer and Netscape, but now can use whatever the user has set as their default browser (though it still works faster with IE and Netscape/Mozilla browsers). Furthermore, Franz's function seems more reliable than our function ever was.
shell-execute
This function still exists but note that the arguments have been changed dramatically. The old argument list was cumbersome because almost all uses of this function used the same values for many of the arguments and it was a pain to fill out all the arguments just to get default behavior. Now, most of the arguments are keyword arguments and the default values for these are just fine for most uses.