readPopUps: reading all the network-popup messages which have been received on the local machine out of the eventlog using tcom and wmi:
package require tcom proc readPopUps {{cb ""}} { set res {} if [catch {::tcom::ref getobject "winmgmts:root/CIMV2"} wmi] then { return -code error $wmi; # minimal errorhandling } set wql {select * from Win32_NTLogEvent where LogFile='System' and \ EventType='3' and \ SourceName='Application Popup'} if [catch {$wmi ExecQuery $wql} tmp] then { return -code error $tmp; # minimal errorhandling } # enumerating all 'records' ::tcom::foreach instance $tmp { set propSet [$instance Properties_] # only the property (object) 'Message' is of interest here set msgVal [[$propSet Item Message] Value] if {[string equal $cb ""]} { lappend res $msgVal } else { uplevel [list $cb $msgVal] } } return $res # Returns list }
A view tests/demos:
returning entries as a list, print them one by one in a loop afterwords:
foreach rec [readPopUps] { puts $rec; }
retrieving the entries via a directly coded callback:
readPopUps {puts}
retrieving the entries via a callback proc:
proc callBack {args} { puts $args } readPopUps callBack
More technical infos can be found at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnanchor/html/anch_wmi.asp .
Fragment: Creating Desktop-Shortcuts (Links) using WSH
package require tcom set wsh [::tcom::ref createobject "WScript.Shell"] set fld [$wsh SpecialFolders] set dsk [$fld Item Desktop] set lnk [file join $dsk ThisIsAProgrammaticallyCreatedLink.lnk] set lno [$wsh CreateShortcut $lnk] $lno TargetPath {"notepad.exe"} $lno Save
Of course, this must be encapsulated and taken to a much higher abstraction level (something like wshGetSpecialFolder [folderName] and wshCreateLink args...)
NJG August 8, 2004 See also (as of now) last item in Windows shell links
A simple ADSI-Example using tcom:
proc logEvent {evtType args} { # ohne Fehlernachricht catch { set wsh [::tcom::ref createobject "WScript.Shell"] $wsh LogEvent $evtType "[regsub -all {\n} $args { - }]" } }
One more complicated example: return the available Windows-NT- and ADS-Domains and Workgroups as a list:
proc GetDomains {} { set ret {} if [catch {::tcom::ref getobject "WinNT:"} d] then { return -code error "<getobject 'WinNT:'> failed: $d" } else { ::tcom::foreach domain $d { if ![catch {::tcom::ref getobject [$domain ADsPath],domain}] { set ct (Domain) } else { set ct (Workgroup) } lappend ret [list [$domain Name] $ct] } } return $ret }
And another one: get the groups of a given container (that is, a Domain or Workgroup):
proc GetGroups {container {contype domain}} { set ret {} # get Domain-/Computerobject if [catch {::tcom::ref getobject "WinNT://$container,$contype"} g] then { return -code error "<getobject 'WinNT://$container,$contype'> failed: $g" } ::tcom::foreach m $g { # instead of IF one can use a -filter here... if {[$m Class] == "Group"} { lappend ret [$m Name] } } return $ret }
(contype can be domain or computer)
And finally get the users within such a group:
(...to be done...)
[Category Package???]