- System functions including OS and processor information, shutdown, message formatting
- User and group management
- Security and resource access control
- Window management - window attributes, position, size etc.
- User input: generation of key/mouse input and hotkey support
- Basic sound playback functions
- Windows services
- Windows event log access
- Process and thread management
- Directory change monitoring
- Windows file and print network shares
- Drive information, file system types etc.
- Network configuration and statistics
- Connection control and name lookups
- Clipboard access and monitoring
- Console mode functions for changing attributes, titles, screen buffers etc.
- System performance data
- Window stations and desktops
- Internationalization
- Task scheduling
- Printer management
- Shell property dialogs, shortcuts and themes
- TWAPI COM support
- Device notifications (e.g. USB device insertion)
- Crypto/SSPI interfaces
- Windows Installer interfaces
- Power management
Ffidl also provides access to the Win32 API along with other platforms. Comparing TWAPI and Ffidl on Windows compares it with TWAPI.
JMN 2004-05-22 Installation of twapi-0.3 as described on http://twapi.sf.net appears straightforward, but I'm so far unable to get it working on my NT4 machine. (RLH: corrected URL only)
% package require twapi Could not load dll twapi.dllAPN Could you also check for PDH.DLL? I just found this does not exist by default on NT 4.0 as it does on Win2K and later. You can download it (*NT 4.0 only*) from Microsoft [3]. Similarly, the PSAPI DLL (for those who do not have it on their NT 4.0 systems) can be downloaded from Microsoft [4] as well. Note these must not be installed on Win2K and up which come with their own versions out of the boxJMN There was a pdh.dll dated 1996-07-27 in the system32 directory. Removing this file made it work! I don't know if there is another pdh.dll somewhere else on my path... strange.
RT Just wondering if there's a Win32 call available to learn the cluster size of an NTFS volume. This would let a Tcl program calculate a more accurate space usage for a given set of files. The volume info available in 0.5 doesn't seem to cover that. BTW, thanks for removing external package dependencies in 0.5 :^) - Roy 25Jan2005APN Could not find where the cluster size info is available. I'm not sure it would even help you estimate the true size since NTFS supports sparse files.RT I just found on XP that the new native command fsutil can give this (and many more answers). Usage is like:
fsutil fsinfo ntfsinfo c:and that yields a nice size chunk of informative information easily parsed. Don't know if this tool can be found on w2000, it's not on my 2k.
Any idea how TWAPI compares with http://zazu.maxwell.syr.edu/nt-tcl/ ?I would definitely favor TWAPI as it is much newer and in active development. I have used a few parts of the nt-tcl package and it worked fine for me at the time (4 years ago). So I would use TWAPI exclusively and fall back to nt-tcl if there was no alternative. RT 11Apr2005
To construct twapi arguments programmatically, use eval.For example, the windows command "netstat -a -o 5" will display network status update every 5 secondsThe twapi create_process command can also launch this process.
# twapi requires full path for program files
set nsfile [file join $::env(windir) system32 netstat.exe]
set opts [list -cmdline "-a -o 5"]
set e [catch {eval twapi::create_process $nsfile $opts} result]Lars H: Won't that break if $nsfile contains spaces? The following should be more quoting safe:set cmd twapi::create_process lappend cmd [file join $::env(windir) system32 netstat.exe] lappend cmd -cmdline "-a -o 5" set e [catch $cmd result]RLH; You may be right but I have not had any problems doing it set nsfile [file join $::env(windir) system32 netstat.exe] and I definitely had spaces in my path names.Lars H: Yes, the "set nsfile" part should be OK. I'd expect problems though when such an $nsfile is subjected to eval. Since that eval is the point that is stressed in the advice, it would be extra severe if it is wrong. Is there a reason for constructing the twapi::create_process options programmatically? Isn't it more likely that the options for the process need to be constructed programmatically?
escargo 20 May 2005 - I was looking at how to access functions that seem to be part of Windows Server 2003. I don't know if they are not part of the TWAPI range or not (I suspect not), but I thought I would ask. The particular functions have to do with "rescan disks," which is part of the Disk Manager. If TWAPI won't allow me to access those functions, is there another Tcl way to do it?RLH: I did not see anything related to that in the TWAPI docs. However, you have direct access to the Windows API via TWAPI and if you want to see if you can do what you want try this: twapi::list_raw_apiescargo 23 May 2005 - Digging around on MSDN, I think the functions I need are FindFirstVolumn, FindNextVolumn, and FindVolumnClose. My particular application requires that I find volumns that are new, that are not even formatted yet. Since they are not formatted, I'm not sure that the TWAPI function get_logical_drives will find the new volumn (since it might not be a logical drive yet). Part of what I need to do is develop a scriptable function that works with a storage area network (SAN) so that I can use the SAN manager to create a new volumn and then use Windows to detect and format that new volumn. Right now the detection and formatting are interactive applications; it is highly desirable to make those steps scriptable. If I can't do it on the Windows server itself (with a scripting interface), then I might have to find an alternative mechanism. (escargo 25 May 2005 - I discovered by accident today that DiskPart has a RESCAN command in it. That might be a useful base to build on for a tool that uses a Windows command line.)''RT comments: So how about using Ffidl or Yet another dll caller? Seems like either one would get you to the API functions you want.escargo responds: Thanks for the hints. The Yet another dll caller page looks promising. Apparently the functions I want are in Kernel32.dll (according to an API reference), but the HANDLE type that gets returned is not a basic type. I'm still going to have to do some digging, but at least I'm going in the right direction.RLH encourages: I would work with the TWAPI author to get your functionality wrapped into the TWAPI package. TWAPI is a really good Windows extension and it would nice to have it extended more. : )APN 28 May 2005 - Support for the Volume management functions is part of V0.7. However, I'm not sure these functions will actually do what you want - returning unformatted partitions. They seem to only return what Windows sees as (formatted) volumes.escargo 7 Jun 2005 - Looking for unformatted partitions is exactly what I want. I'm working with some programs that do device I/O, not file I/O, so raw devices are exactly what I must find. Let me know if I can help with testing.APN 2008-06-25 - Finally, only three years later, TWAPI has device io support. In 2.0.10 you can use get_physical_disk_info and find_physical_disks in combination to do the above. The whole device management stuff on Win32 is rather arcane (to me anyways), and it took a while to get motivated enough to get it done.
escargo 9 Jun 2005 - I have now used twapi to create_process something (diskpart) that generates output. The output is coming back to my tclsh console. Is there any way to make output directed to the console go to a file instead? I could speculate that this is to be done using the -stdhandles argument. First you create file handles for input and output and then pass them to the process, but maybe there's another way.APN You could do it that way but unless you have any special need to use create_process, it is much easier to use Tcl's open command as in "set fd [open "| diskpart options"] and read back the data from the file dscriptor or do a "exec diskpart options > filename". create_process should only be used in special cases like when you need to run as a different account etc.escargo 10 Jun 2005 - After I was unsuccessful with create_process, I did try both open and exec. Open did allow me to read back what was output; exec allowed me to direct output to a file. Both might be viable alternatives. (I would still like to verify what I should do with create_process, since that might be handy in the future.)male 2007-11-20 - May I ask APN how you use create_process to start a process with a different user? (kind of runas) APN 2008-06-25 - Sorry for the late response! But did not notice the question before. See [5] for an example but there are other samples you could google as well. I believe TWAPI has all the requisite raw Win32 calls (as of 2.0.10) but have not put together a complete ready-to-go implementation yet.
escargo 21 Sep 2005 - Can TWAPI be used to inspect the Running Object Table (ROT)?APN No, I don't think so. There aren't any COM interfaces in TWAPI since I assumed you would be much better off using the TCOM extension for COM-related stuff.escargo - From what I read about ROT, it identifies objects, not their COM interfaces. So you need to know what the objects are before you can use tcom on them. Since the ROT is part of system state, it seemed like TWAPI would an appropriate way to access it. (See the sample code at the link on the ROT page.)
escargo 10 Mar 2006 - Can TWAPI be used to read and write to raw disk devices (unformatted disks without partitions)?APN No. Looking at the SDK, it looks like a job for DeviceIOControl but seems non-trivial, particularly for testing. Possibly one could also just call WriteFile after opening the raw device \\.\PhysicalDriveN using CreateFile. I'm afraid of trying something like this on my single development machine and trashing it!
Alastair Davies asks if there is an API to configure wireless networking? For example, I would like to obtain a list of available wireless networks, and to connect to one. I would not be surprised if this were quite straight-forward, in Windows XP at least.APN You might want to look at WRAPI [6] but you would have to write a Tcl binding for that.
MHo 2006/05/17 just tried source twapi-0.8.kit - ok, no error. namespace exist twapi gives 1. But no commands are available. Oh lord, I'm to stupid to load a starkit or what? (Do a package require, perhaps? jcw) As jcw says, you need to do a package require twapi after doing the source. MHo Tried that, but have another Twapi-Version in my auto_path... that yields to
conflicting versions provided for package "twapi": 0.8, then 0.7The whole thing:
set auto_path [linsert $auto_path 0 ./]; source twapi-0.8.kit package require -exact twapi 0.8 puts [twapi::get_system_uptime]Result:
D:\PGM\TCL\usr\Tst\twapi0.8>tclsh test01.tcl
conflicting versions provided for package "twapi": 0.8, then 0.7
while executing
"package provide twapi $twapi::version"
(file "D:/PGM/tcl/usr/Tst/twapi0.8/twapi-0.8.kit/lib/twapi/twapi.tcl" line 1292)
invoked from within
"source D:/PGM/tcl/usr/Tst/twapi0.8/twapi-0.8.kit/lib/twapi/twapi.tcl"
("package ifneeded" script)
invoked from within
"package require -exact twapi 0.8"
(file "test01.tcl" line 3)APN Could you try the same exact sequence above but using tclkitsh instead of tclsh ? It appears to me that you have an older version of twapi (0.7) as part of your tcl install. When the 0.8 twapi tcl code tries to load the twapi binary dll, it lands up loading the 0.7 dll resulting in a version conflict. The twapi Tcl startup code checks for whether it is a starkit by checking ::starkit::topdir and then either loads from the standard Tcl load path (if this variable does not exist) or from the twapi.kit (if the variable exists). My guess is because you are running tclsh, it loads the dll from the standard Tcl lib path and lands up with a version mismatch. If the above code does not generate the error, that would confirm this is what is happening. Then I can look at making the DLL locating code more robust.MHo: Yes, with tclkitsh it works!LV June 05, 2006: sure would be useful if this extension became a part of ActiveTcl!RLH June 05, 2006: I think that has been suggested more than once on the ActiveTcl mailing list. : )APN I had sent email to ActiveTcl. They had responded (quite reasonably) that they needed it to build with the standard TEA build environment. I on the other hand am not sufficiently motivated to do this as at first glance it appears to be a non-trivial amount of work.
APN July 21, 2006: Took the liberty of cleaning up stale stuff from this page.
Nightbreed: July 24, 2006: When using a variable to grab the get_mouse_location function, it's all fine and good but this value is useless when you want to apply it to the move_mouse command. What's needed is to grab the mouse location, store that value, then move it 'back' to it's original place. Is there a way to isolate the Xpos and Ypos to make this possible?MG That's exactly what get_mouse_location does. You just need to break the value it returns (which is a list of the x and y positions) into two separate values, which can be done in any number of ways, a few of which include:
set full [get_mouse_location] ; set x [lindex $full 0] ; set y [lindex $full 1] ; unset full
# or
foreach {x y} [get_mouse_location] {break}
# or even
scan [get_mouse_location] "%d %d" x y
# then
move_mouse $x $yThe foreach version seems to be the fastest, taking a whole 4 microseconds, as opposed to 5 microseconds for the set/lindex version, and a whopping 6 microseconds for the scan version.Nightbreed: Yeah, my apologies on saying it was useless. That was out of frustration. I tried both the foreach and scan methods and ended up settling on the scan which, both worked great, thanks MG. I use Tcl with BBLean, the Blackbox project for windows. There's a plugin called tcl4bb which powers the scripting part in the shell. Here's a brief screenshot of Tcl and Twapi in action. http://boxshots.org./style/3862.
Nightbreed: What type of message does Twapi give off that informs it when a drive isn't ready? I know it throws a message, but is there a way to use that? Something like a CDRom drive that doesn't have a disk in it.MG I'm not sure how TWAPI does it, but you can use pure Tcl to check to see if a drive is ready or not:
foreach x [file volumes] {
if { [catch {file attributes $x}] {
puts "No disk in drive $x"
} else {
puts "Drive $x is ready"
}
}Nightbreed: So it's Tcl that throws the error and not Twapi, correct? One other thing, the above example, shows the drives are in ready state no matter what. When doing this in pure Twapi however, I get this error: "could not read "cdrom": no such file or directory". So that would suggest that something is returning some kind of error code, least that's what I would think.APN Could you post the exact code snippet that is generating the "could not read cdrom" error?Nightbreed: As soon as I am able to reproduce that error, I will post it. However, I did find a solution using file exists with this. foreach x [twapi::find_logical_drives] {
set drive_state [file exists $x]
if { $drive_state !=0 } {
puts "$x is ready"
} else {
puts "x is not ready"
}
}I did a small edit to show my final code for checking device status. The code that was shown before my edit was not descriptive enough. I know it's a little crude, but it works.Nightbreed: Hello all. I know Twapi can get the current theme info from the windows environment, but can it be used to set a theme? APN No, as of 0.9 it cannot.
MHo: It would be nice if there where some way to register an event source to avoid such stupid error messages within eventvwr.exe. APN Yes it would be nice but I'm not sure how. AFAIK, to register an event source requires a resource in a DLL or other file. So the messages would have to be "bound" to the resource. You could do this with a resource compiler but then you would not need TWAPI. Or am I missing something? MHo That's right. Perhaps the necessary minimal resources/definitions could be build right into twapi.dll. I don't know exactly how to do event source registration by myself (with ms api's this is not uncommon.... smile ;-). No, it can't be built into twapi. Let's say your application wants to log a message "Danger, Danger! Resource do-hickey running low!". That message has to be in some resource, but obviously it can't be in twapi.dll which knows nothing about the application errors. The only way would be to create a resource file on the fly on the target system and that's just too much work. MHo Hm.... The actually message itself sure comes from the caller at runtime; what's missing is the registration of twapi as a valid event source... sure twapi cannot conatin application specific things... As an example, me as a tcl programmer can write generic messages to the eventlog through means of Winserv or tclsvc...APN It's not enough to register twapi.dll as a valid event source. It has to actually contain a valid resource string for the message logged as well. Just registering it will not make the message go away.
For an example of how to use TWAPI to 'draw' in MS Paint, see Using TWAPI with MS Paint.
MHo 2007-10-25: Just a thought: often I only need one or two API-Calls in my tools, which are typically delivered as starpacks. But because TWAPI has become such a big package, my .EXEs grow accordingly. Perhaps it would be better to split up or group the APIs into several separate DLLs...? (We have no intelligent link step which removes unused code...). APN I have often thought of doing this, but the burden of testing separate packages, test suites etc. is more work than I have time for. Currently, twapi.kit is under 300K so it is not a huge bloat for distribution. One alternative you might consider if size is an issue and you only use a few functions is either ffidl or winapi which is layered on top of it. APN As of the 2.1.6 release, TWAPI can be built as a server-only or desktop-only subset. The savings are marginal (server kit is around 100K v/s 300K for the full version) but if you really want, you can build it.
MHo 2008-09-23: Where's the .CHM help file gone? APN See the README. Basically, the MS Help compiler is crashing. Reinstalling did not help. I don't think it is a size issue as the crash goes away if a few lines are added or removed, but then comes back when more documentation is added. I basically got tired of getting the docs to fit the "non-crash" window! MHo I understand. But can we download the html files as one .ZIP file etc.? APN Done. MHo Thanks a lot!
male 2008-10-01: Here one sample of manipulating a Windows message box using TWAPI ... countdownMsgBox
MHo 2008-11-20: Experience or known problems or incompatibilities in using TWAPI on Windows Server 2003 64bit anybody? APN I have no experience with the 64 bit versions of Windows but I do know there will be some issues - for example, some of the 32 bit API's that deal with getting system information (processes, memory etc.) will not work as they all implicitly assume 32 bit address space. Much of TWAPI should still work though, you'll probably have to just try specific commands you need to see if they work.
MHo 2009-02-20: I noticed that get_global_group_members does not give back members if that group only contains other groups (that is, no "direct members"). So which way I could perform a recursive resolution of all computers downwards from a given OU? That's the same behaviour as with NET GROUP, indeed. With some complicated combinations of DSQUERY and DSGET I'm not satisfied after hours and thought tcl and twapi could help... APN Do the ADSI COM interfaces not provide any help here?