Winutils extension DLL v0.8 for Tcl

written by David Gravereaux


Just a random collection of stuff for Win32 Tcl. 4:39 PM 4/6/2003


Simple BSD.

Don't sue me if it doesn't work.  Copy and modify it as much as you like.
There's no requirement to give me credit for it.  Fly away little bird,
be free.  I understand full well that because I have released this
software openly on the internet, I lose control over it.  Therefore, I'll
relinquish all control now in contrast to other type of licenses that try,
but fail to retain a minimum of control with empty threats.

Be nice and send me patches for bugs fixed or, at least, reports.

Table Of Contents

winutils::hotkey
winutils::shell
winutils::winhelp
winutils::keylock
winutils::sendmessage
winutils::volinfo
winutils::launch
winutils::exetype
winutils::reg9Xservice
winutils::uptime
winutils::duration

winutils::hotkey

    Creates a system-wide hot key with an event handler.  This is an Itcl class.

    Usage: winutils::hotkey <#auto|name> <keyString> <script>
           winutils::hotkey delete <token>

    Returns: The Itcl oject name or an error describing what went wrong.

    <keyString>
        Describes the key sequence with the following modifiers:
            Alt
            Shift
            Ctrl
            Win

        Use a '+' to separate them with the virtual key name as the last.
        Such as:
            Ctrl+Alt+f1
            Alt+Win+B
            Shift+num:*

        The virtual key names are in flux as I write this, but this is the
        big list as I have it now.  It may not seem to make sense, and I would
        have to agree, but I don't know what else to say, except VK_ macro
        these associate to are in the source, and a tool to display (or create)
        the proper keyString would be a welcome addition some day.

	break,backspace,tab,clear,return,pause,capslock,ime:kana,ime:hangul,
        ime:junja,ime:final,ime:hanja,ime:kanji,escape,ime:convert,
        ime:nonconvert,ime:accept,ime:mode,spacebar,prior,next,end,home,left,
        up,right,down,select,print,execute,prntscr,insert,delete,help,0,1,2,
        3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,
        sleep,num:0,num:1,num:2,num:3,num:4,num:5,num:6,num:7,num:8,num:9,
        num:*,num:plus,num:-,num:.,num:/,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,
        f12,f13,f14,f15,f16,f17,f18,f19,f20,f21,f22,f23,f24,numlock,scrollock,
        browse:back,browse:forward,browse:refresh,browse:stop,browse:search,
        browse:fav,browse:home,volume:mute,volume:down,volume:up,media:next,
        media:prev,media:stop,media:play,launch:mail,launch:select,launch:app1,
        launch:app2,oem:1,oem:plus,oem:,,oem:-,oem:.,oem:2,oem:3,oem:4,oem:5,
        oem:6,oem:7,oem:8,ax,oem:102,ico:help,ico:oo,ime:process,nokia:reset,
        nokia:jump,nokia:pa1,nokia:pa2,nokia:pa3,nokia:wsctrl,nokia:cusel,
        nokia:attn,nokia:finish,nokia:copy,nokia:auto,nokia:enlw,nokia:backtab,
        attn,crsel,exsel,ereof,play,zoom,reserved,pa1,oem:clear

    <script>
        The reference is maintained, thus re-use of bytecode is supported.
        The script is run as a proc and from the ::winutils namespace.
        When the hot key is fired, the script is posted through Tcl's event
        loop.  tclsh users should be aware that the event loop needs manual
        'churning' for this to work.

    Example:

        % set hk [winutils::hotkey #auto Ctrl+Shift+Alt+A {global a; puts "hello there:[incr a]"}]
        hotkey0
        % set a 5
        5
        hello there:6       <-- pressing the combo from another app in foreground
        hello there:7
        hello there:8
        hello there:9
        hello there:10
        hello there:11
        hello there:12
        % $hk destroy

winutils::shell

   winutils::shell is a direct connection to the ShellExecuteEx() Win32 API
   function. Like [exec], it starts programs, but the exec command is blocking 
   and waits for the started app to exit before Tcl regains control. To me,
   this is not what windows is all about.  The shell command returns 
   immediatly and Tcl is free to process.  winutils::shell can also start
   documents using the proper application as found in the registry, as well as,
   launch URLs.  The behavior is idendical to the "Run..." dialog off the start
   menu.

   Usage: winutils::shell [-verb <verb>] [-directory <DefDirectory>]
                          [-show <ShowStyle>] [-wait] <file>
                          [<params> ...]

   NOTES: Options may be in any order, but the <file> must be the last 
          argument.  Use the "/" instead of the "\" as a directory 
          seperator in the <file> and <DefDirectory>.

   Returns: nothing, the exitcode when waiting, or an error describing what
            happened wrong.  $errorCode is not set as the POSIX codes are not
            descriptive enough for the types of errors that happen and have
            no POSIX mirrors.

    [-verb <verb>]
      Valid verbs are:

       open     Opens the file specified by <file>.  The file can be an 
                 executable file or a document file.  The file can be a 
                 Windows 95 folder to open. "open" *might be* the default, if  
                 <verb> is missing.  Depends on which OS.
       print    Prints the file specified by <file>.  The file should  
                 be a document file.  If the file is an executable 
                 file, the function opens the file, as if "open" had 
                 been specified.
       explore  The function explores the folder specified by <file>.
       *any*    Any action name located in the associate section of the 
                 registry for the filetype specified by <file>.
 
    [-show <ShowStyle>]
       Valid showstyles are:

       hide     Hides the window. Be careful with this; it truely hides it.
       maximum  Maximizes the window.
       minimum  Minimizes the window to start.
       normal   Activates and displays a window normally. This is the default,
                 if <ShowStyle> is missing.

    [-wait]  Will cause the command to wait until the launched process (if any)
           has completed.  It's possible that an existing instance of an
           application may use DDE to start <file>.  When this happens,
           an application can not be waited on for exit and will return
           immediately instead.  When waiting, the exitcode will be returned.

winutils::winhelp

     Opens winhlp32.exe to a file with options that you specify.

     Usage: winutils::winhelp <filename> <optionname> ...


     <filename>
        string containing the path, if necessary, and the name of the Help 
        file that the Help application is to display.

        The filename may be followed by an angle bracket (>) and the name of 
        a secondary window if the topic is to be displayed in a secondary 
        window rather than in the primary window. The name of the secondary 
        window must have been defined in the [WINDOWS] section of the Help 
        project (.HPJ) file.


     <optionname>
       Valid option names and associated parameter are:

       command <macro>
         Executes a Help macro or macro string command.
       
       contents
         Displays the topic specified by the Contents option in the [OPTIONS] 
         section of the Help project (.HPJ) file.  This is for backward 
         compatibility.  New applications should provide a .CNT file and use 
         the finder command.

       context <index>
         Displays the topic identified by the specified context identifier 
         defined in the [MAP] section of the .HPJ file.

       contextpopup <index>
         Displays, in a pop-up window, the topic identified by the specified 
         context identifier defined in the [MAP] section of the .HPJ file.

       finder
         Displays the Help Topics dialog box. The Help Topics dialog box lets 
         the user select topics to display by viewing the titles of the 
         topics, the keywords associated with the topics, or the words and 
         phrases found in the topics. Applications typically display the Help 
         Topics dialog box when the user chooses a command, such as Help 
         Topics, from the Help menu. An application may also display this 
         dialog box if the user presses the F1 key when no specific window, 
         control, or menu in the application has the focus or is active.

       forcefile
         Ensures that WinHelp is displaying the correct help file. If the 
         incorrect help file is being displayed, WinHelp opens the correct 
         one; otherwise, there is no action.

       helponhelp
         Displays help on how to use Windows Help, if the WINHELP.HLP file 
         is available.

       index
         Displays the Index in the Help Topics dialog box. This command 
         is for backward compatibility. New applications should use the 
         finder command.

       key <keyword>
         Displays the topic in the keyword table that matches the specified 
         keyword, if there is an exact match. If there is more than one match, 
         displays the Index with the topics listed in the Topics Found list 
         box.

       partialkey <keyword>
         Displays the topic in the keyword table that matches the specified 
         keyword, if there is an exact match. If there is more than one match, 
         displays the Index tab. To display the Index without passing a 
         keyword, you should use an empty string ("").

       quit
         Informs the Help application that it is no longer needed. If 
         no other applications have asked for Help, Windows closes the 
         Help application.

       setcontents <index>
         Specifies the Contents topic. The Help application displays 
         this topic when the user clicks the Contents button.

       setindex <index>
         Specifies a keyword table to be displayed in the Index of the 
         Help Topics dialog box.

winutils::keylock

     Gets or sets the scroll, num, or caps lock attribute of the keyboard.

     Usage: winutils::keylock caps|num|scroll [boolean]

winutils::sendmessage

  Documentation will go here... sometime in the future as opposed to now.

winutils::volinfo

  Returns a 3 part list about the volume.  First is the volume name, then the
  serial number, then the file system type.

  Usage: winutils::volinfo <drive>

  Example:
    % winutils::volinfo e:/
    {Audio CD} 16190012 CDFS
    % winutils::volinfo c:/
    {} -1998926753 NTFS

winutils::launch

  Launches a new process.  This is a direct shot into CreateProcess().  It
  doesn't setup pipes to communicate with, never uses the same console
  window, nor does it wait (unless asked) for the exit code the way [exec]
  does.  A true fire-and-forget with loads of win-specific startup options.

  Usage:  winutils::launch [options] <exe> [<param> ...]

  Returns: The PID of the new process (or exitcode when waiting) or an error
           describing why it went boom.

  Notes:
    <exe> may be prepended with //?/ to over-come the MAX_PATH limitation
    on NT and raise the limit to 32K, but no part may be greater than MAX_PATH
    (260 chars) itself.  Commandline parameters support unicode on NT, but this
    doesn't guarentee the app launched will either get the unicode commandline
    or that there's a valid codepage conversion.

  Examples:
    % winutils::launch -cfill 0x1F -cfull -ctitle "merry christmas" telnet
    1084

    Launch Win2K's character-mode telnet.exe with no pipes and in a separate
    console, full-screen, with blue background and bright white text and with
    the titlebar text of "merry christmas" when restored with Alt+Enter.


    % winutils::launch -show hide -wait find "qwerty" c:\\somefile.txt
    2

    Runs the find.exe utility and waits for the exitcode.


    % winutils::launch find "qwerty" c:\\somefile.txt
    1424

    Runs the find.exe utility (again, as above), but doesn't wait and has a
    momentary flash of a new command prompt window.


    % array set myenv [list abc 123 def 456]
    % winutils::launch -env myenv tclsh84
    1424

    Other tclsh->
    % parray env
    env(COMSPEC) = cmd.exe
    env(HOME)    = c:\
    env(abc)     = 123
    env(def)     = 456
    %

    Runs a new tclsh with a custom environment.


The following options are valid:

  [-desktop <value>]
	<value> specifies either the name of the desktop only or the name
        of both the desktop and window station for this process.  Only valid on
	Win2K.  I have no clue what this really does, yet.

  [-ctitle <value>]
	<value> specifies the titlebar text used by default in the
        console window.  Only valid for a console process.

  [-cdims <Xchars> <Ychars>]
	Sets the default screen buffer size in characters.  This happens to be
        different than the window size.  Only valid with a console process.
        Window size overrides when larger.  This is a strange option to get
        right.  Best used with a small -size and -show max, but then -origin
        isn't respected...   Hmmph..

  [-cfill <value>]
	Sets the color attributes used by the console process.
        An or'ed combo of the following from wincon.h:

        #define FOREGROUND_BLUE      0x0001 //text color contains blue.
        #define FOREGROUND_GREEN     0x0002 //text color contains green.
        #define FOREGROUND_RED       0x0004 //text color contains red.
        #define FOREGROUND_INTENSITY 0x0008 //text color is intensified.
        #define BACKGROUND_BLUE      0x0010 //background color contains blue.
        #define BACKGROUND_GREEN     0x0020 //background color contains green.
        #define BACKGROUND_RED       0x0040 //background color contains red.
        #define BACKGROUND_INTENSITY 0x0080 //background color is intensified.

  [-cfull]
	Launches the console process in full-screen mode.  Same as Alt+Enter.

  [-chide]
	Hides the console window from the user.  This might be a dangerous
	option to use.  Doesn't seem to work on Win2K as described.

  [-origin <X> <Y>]
	Sets the origin point where the window will be created when the new
	process uses CW_USEDEFAULT for the ShowWindow() dimensions.

  [-size <Xspan> <Yspan>]
	Sets the height and width of the process's window should it respect and
	use CW_USEDEFAULT in the first ShowWindow() call.

  [-show <ShowStyle>]
	<ShowStyle> must be one of "hide", "maximum", "minimum" or "normal".
        Same as winutils::shell.

  [-priority <PriorityClass>]
	<PriorityClass> must be one of "realtime", "high", "above",
        "normal", "below" or "idle".  Sets the main thread's priority class of
        the newly created process.

  [-wait]
        Will wait until the process completes before returning.  The PID is not
        returned in this case, but is the exitcode instead.

  [-directory <dir>]
        Sets the starting directory.  Use "/" instead of "\" as directory
	seperators in the normal Tcl style.

  [-env <arrayName>]
        Set the environment the process will use from the named Tcl array.
        Unicode characters are supported under NT, but this doesn't guarentee
        the app to be launched understands unicode.  This allows you to copy
        `env` to a different array and modify it, then hand it the launch
        command without ever changing `env` itself and needing to undo the
        changes later.

winutils::exetype

  Reads the PE header in an executable file and returns the type it is and the
  fullpath in a two element Tcl list.  This does a simplified PEDUMP.  When an
  error happens and the exe is not determined a valid executable, 'None' is
  returned as the type and a useful system error message is returned in the
  third list element.

  Usage: winutils::exetype <exe>

  Examples:
    % winutils::exetype notepad
    {Win32 GUI} C:/WINNT/System32/notepad.exe
    % winutils::exetype edlin
    MS-DOS C:/WINNT/System32/edlin.exe
    % winutils::exetype ntoskrnl.exe
    {Win32 Driver} C:/WINNT/System32/ntoskrnl.exe
    % winutils::exetype tcl84.dll
    {Win32 DLL} {C:/Program Files/Tcl/bin/tcl84.dll}
    % winutils::exetype c:/games/doom2/doom2.exe
    MS-DOS c:/games/doom2/doom2.exe
    % winutils::exetype C:/WINNT/System32/os2/dll/netapi.dll
    {OS/2 Driver} C:/WINNT/System32/os2/dll/netapi.dll
    % winutils::exetype a:/aspils_o.sys
    {OS/2 Driver} a:/aspils_o.sys               <- Old Adaptec SCSI driver
    % winutils::exetype c:/dev/msvc/pharlap/bin/gorun286.exe
    MS-DOS c:/dev/msvc/pharlap/bin/gorun286.exe <- Old PharLap DOS Extender
    % winutils::exetype more.com
    {Win32 CUI} C:/WINNT/system32/more.com      <- This .com is really Win32!
    % winutils::exetype d:/tcl_ws/tcl/win/release/tcl84.dll
    {Win64 DLL} d:/tcl_ws/tcl/win/release/tcl84.dll  <- compiled for 64-bit.

  Types returned will be one of the following:
        None
        Batch
        MS-DOS
        Win16 GUI
        Win16 Driver
        OS/2
        OS/2 Driver
        Win32 CUI
        Win32 GUI
        Win32 DLL
        Win32 Driver
        Win64 CUI
        Win64 GUI
        Win64 DLL
        Win64 Driver

winutils::reg9Xservice

  Register a running process ID with the Windows 95/98/ME Service
  Control Manager (SCM). This enables a process to continue running
  when the current user logs out of the desktop. Normally processes
  are terminated when the user logs out. This command is useful for
  network daemons running under Win95/98/ME although consideration
  should be given to using NT for this sort of software.

  Usage: winutils::reg9Xservice ?-process PID? boolean

  A true argument (the default) registers the process with the SCM. A
  false argument unregisters the process.

  The following options are valid:

  [-process <PID>]
	<PID> specifies the ID of the process to register as a
	service. A PID of 0 means the current process.

  Examples:
    % winutils::reg9Xservice -process 0 true
    % winutils::reg9Xservice -process 203 false

winutils::uptime

  Returns the number of seconds since boot.

  Usage: winutils::uptime

winutils::duration

  A script procedure to turn seconds into a formatted elapsed time.

  Usage: winutils::duration <seconds>

  Examples:
    % winutils::duration [winutils::uptime]
    19 days 14 hrs 11 mins 2 secs
    % namespace eval ::winutils {duration [uptime]}
    19 days 14 hrs 11 mins 22 secs

Valid HTML 4.01!