What is winutils? winutils is a collection of useful Tcl commands that access some part of the Win32 API. This enables the user to use Windows specific services. Who wrote it? [David Gravereaux] ---- Example : [David Gravereaux] mailto:davygrvy@pobox.com recently wrote in news:comp.lang.tcl Message-ID: <7enq0u4h5t4hkcrb564rco60okvh5fcttf@4ax.com> You can simplify that down a whole lot with my winutils extension and it's winutils::shell command. It's like `eval exec [auto_execok start] $file &`, but without the momentary command prompt flashing up on the screen. http://sf.net/projects/tomasoft package require winutils proc LaunchEditor {myfile} { # try the "edit" command first. if {[catch {winutils::shell -v edit $myfile}]} { winutils::shell -v open $myfile } } proc Launch {args} { eval winutils::shell -v open $args } This makes use of associations and even does full URLs in the exact manner and behavior of the "Run..." dialog off the Start menu. % Launch mailto:davygrvy@pobox.com?subject=hi%20there&body=was%20up? % Launch http://tcl.activestate.com % Launch somefile.txt % Launch netstat -a 2 I forget if I added the "edit" command to my .tcl association or whether the [ActiveTcl] installer did it for me.. % LaunchEditor c:/progra~1/tcl/lib/tcl8.4/init.tcl ---- [Pat Thoyts] has suggested the GetLocaleInfo() API [http://msdn.microsoft.com/library/en-us/intl/nls_34rz.asp] join winutils. What other pieces of win32 make a nice fit here? * The special folders stuff - SHGetFolderPath() for retrieving the official path to application data user profile etc. This can be important for NT/XP systems where we may have reduced rights to write files elsewhere. ---- http://sourceforge.net/project/showfiles.php?group_id=1616&release_id=89891 http://prdownloads.sourceforge.net/tomasoft/winutils-0.6.zip ---- As the "directory watching" ability of winutils appears to undocumented, here is some info straight from David: set w [winutils::dirwatch new c:/somedir { puts gotcha! }] close the watch with: winutils::dirwatch delete $w or if I left the [incr Tcl] class for it, it would be: set w [winutils::dirwatch #auto c:/somedir { puts gotcha! }] $w delete When a file is modified or created in the directory, the script fires. It saves the script as a persistent Tcl_Obj*, so the bytecode rep is maintained. It runs essentially as a proc in that any temp variables are cleared. Use [global] to link to any globals. I run it also from the scope of the ::winutils namespace, which might not be useful. I can fire multiple times for the same event. I think because of the flags used with FindFirstChangeNotification(). Some experiments with changing the flags could improve it. ---- [Scott Nichols] I recommend adding this C++ code to the WinUtils library for creating unique global identifiers (GUIDs). I had a customer that required a GUID be generated with each SOAP transaction so I wrote the Tcl method call in C++ (below) for this, and thought it might be a good candidate for the WinUtils library. The C++ code below is using two dependent libs: tclstub83.lib and rpcrt4.lib. Rpcrt4.lib is part of the Windows OS, and should come with Visual Studio or .net. The source code is so short I went ahead and posted both source files below: ""TclGUID.h:" /* * TclGUID.h v1.0 12-11-2003 Scott Nichols * */ /* TCL Function prototype declarations */ #ifndef TclGUID_H #define TclGUID_H #define USE_NON_CONST #define TCL_USE_STUBS /* Not sure if all the includes are needed */ #include #include #include #include #include "StdAfx.h" extern "C" { __declspec(dllexport) int Tclguid_Init(Tcl_Interp* interp); } static int GetGUID_ObjCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); #endif ""TclGUID.cpp:"" /* * TclGUID.cpp, v1.0 12/11/2003, Scott J. Nichols * scott.nichols4@comcast.net * * The GetGUID Tcl method returns a 128 bit unique identifier * to the Tcl interpeter. Microsoft calls it a globally unique identifier. * The application I am using for is the transaction ID for SOAP messages. This was a customer * requirment of mine. * */ #include "TclGUID.h" static int GetGUID_ObjCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])) { GUID guid; // create random GUID guid = GUID_NULL; ::CoCreateGuid(&guid); if (guid == GUID_NULL) { Tcl_Obj *obj_result = Tcl_NewStringObj((const char *)"Unable to create GUID.", strlen((const char *) "Unable to create GUID.")); Tcl_SetObjResult(interp,obj_result); return TCL_ERROR; } else { BYTE * str; UuidToString((UUID*)&guid, &str); CString unique((LPTSTR)str); unique.MakeUpper(); RpcStringFree(&str); // Return the GUID to the Tcl Interpreter Tcl_Obj *obj_result = Tcl_NewStringObj((const char *)unique, strlen((const char *)unique)); Tcl_SetObjResult(interp,obj_result); return TCL_OK; } } /* Main Routine in the TCL Extension DLL */ int Tclguid_Init(Tcl_Interp *interp) { #if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION >= 1 // Does the TCL interpreter support version 8.3 of TCL? if (Tcl_InitStubs(interp,"8.3",0) == NULL) return TCL_ERROR; #endif Tcl_CreateObjCommand(interp, "GetGUID", GetGUID_ObjCmd, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); return (Tcl_PkgProvide(interp,"TclGUID","1.0") == TCL_ERROR ? TCL_ERROR : TCL_OK); } Each time the GetGUID method is called from Tcl a different 128 bit number is returned that looks similar to this: DE4ED408-5200-46E5-8AD1-EEF7351A7C07 ---- [[ [Category Package] ]]