Zaxon Posted February 18, 2005 Share Posted February 18, 2005 I'm writing a script that will run in every profile that is started. So in Windows XP, if two users logon, then there will be an instance of the script running for each user. I want the script running under the active user profile to execute a task. So the script goes: . Is my user profile currently active? . If so, then do something How can I detect whether the current user profile is active or not under Windows XP? Link to comment Share on other sites More sharing options...
tazdev Posted February 18, 2005 Share Posted February 18, 2005 First install it under the All User profile c:\documents and settings\all users\start menu\programs\startup\ This will run it no matter who logs in. Next use the @username to determine who is logged in and now you can assign a var: $curprofile = "C:\Documents and settings\" & @UserName I am not sure what you mean though by detect the current user profile is active or not under Windows XP. Do you mean has a particular profile been used recently? If so then check the date of the ntuser.dat file under the profile in question. Link to comment Share on other sites More sharing options...
SlimShady Posted February 18, 2005 Share Posted February 18, 2005 You can check the username by doing: If @Username = "James" Then ;... ElseIf @Username = "Administrator" Then ;... EndIf Good luck. Link to comment Share on other sites More sharing options...
Zaxon Posted February 18, 2005 Author Share Posted February 18, 2005 I am not sure what you mean though by detect the current user profile is active or not under Windows XP. Do you mean has a particular profile been used recently? If so then check the date of the ntuser.dat file under the profile in question.<{POST_SNAPBACK}>I've written a scheduling program that will file programs off at specific date/times. Think of it as an advanced version of the scheduler that comes with XP.An instance of the scheduler starts up with each person who logs on, and access the some scheduler database.Some fired off programs may require a user input. Take a backup program, for example, that displays prompts such as "please insert the next disk", "that disk isn't blank", etc.Under Windows Task Manager > [users], it will list all usernames along with their status. active - meaning you're currently using that profile. disconnected - meaning the profile is only running in the backgroundIf you windows-L between the two profiles/users, the status of which profile is currently active can be seen reflected in the list of users and their associated statuses.So, I want my scheduling program to fire off tasks in the instance of the scheduler which is currently running as the active profile. Link to comment Share on other sites More sharing options...
Zaxon Posted February 18, 2005 Author Share Posted February 18, 2005 If @Username = "James" Then ;... ElseIf @Username = "Administrator" Then ;... EndIf<{POST_SNAPBACK}>That's right. But let's assume that everyone is eligible to run this program. And all we need to determine is which user is "active" at that moment in time. Link to comment Share on other sites More sharing options...
Zaxon Posted February 18, 2005 Author Share Posted February 18, 2005 I've found some relevant information at http://msdn.microsoft.com/library/default....ml/winxpfus.aspBOOL WINAPIWTSRegisterSessionNotification( HWND hWnd, // Window handle DWORD dwFlags // Flags );The registered HWND receives the message WM_WTSSESSION_CHANGE.In dwFlags you can specify: NOTIFY_FOR_THIS_SESSION. A window is notified only about the session change events that affect the session to which window belongs. NOTIFY_FOR_ALL_SESSIONS. A window is notified for all session change events.Essentially, your process can register to be informed if its session becomes active or loses the active status.So obviously there's some sort of message sending going on, but I'll need someone more familiar with interfacing to the operating system to give me a hand. Link to comment Share on other sites More sharing options...
Zaxon Posted February 20, 2005 Author Share Posted February 20, 2005 Anyone with some skills to help me on this one? Link to comment Share on other sites More sharing options...
DaveF Posted February 20, 2005 Share Posted February 20, 2005 I don't use fast user switching, but it looks like WTSRegisterSessionNotification() is defined in Wtsapi32.dll, so if you:- Learn what the value of the NOTIFY_FOR_ALL_SESSIONS flag is- Likewise learn the value of the WM_WTSSESSION_CHANGE message- and WTS_CONSOLE_CONNECT- and WTS_CONSOLE_DISCONNECT...then you could make a AutoIt3 GUI script that registered itself for session change notification using DllCall() and monitored the changes in its GUI message loop. Yes yes yes, there it was. Youth must go, ah yes. But youth is only being in a way like it might be an animal. No, it is not just being an animal so much as being like one of these malenky toys you viddy being sold in the streets, like little chellovecks made out of tin and with a spring inside and then a winding handle on the outside and you wind it up grrr grrr grrr and off it itties, like walking, O my brothers. But it itties in a straight line and bangs straight into things bang bang and it cannot help what it is doing. Being young is like being like one of these malenky machines. Link to comment Share on other sites More sharing options...
Zaxon Posted February 20, 2005 Author Share Posted February 20, 2005 OK. I've found some more places that talk about this functionality. The best I can do is find discussions about it, but I'll need someone with some skills in calling DLLs to help decipher this.See http://dev.remotenetworktechnology.com/api/wtsapi.htmSee http://support.microsoft.com/kb/310153/EN-US/Although I have no idea on how to even begin with this, I can put forward an attempted bumbly framework. Shows I'm trying.#include <GuiConstants.au3> const $NOTIFY_FOR_THIS_SESSION=1; not really sure of this value $main=guicreate("main") guisetstate() $dll=DllOpen ("Wtsapi32.dll") $result=dllcall($dll,"int","WTSRegisterSessionNotification","hwnd",$main,"int",$NOTIFY_FOR_THIS_SESSION) if @error then msgbox(0,"","Dll call failed") ; currently not returning an error - a good start endif msgbox(0,"",$result) ; this should return 1, but currently returning an empty string. Not good do use either GUICtrlRecvMsg ($main,???) or GUIGetMsg (); not sure which until 0 Link to comment Share on other sites More sharing options...
sugi Posted February 20, 2005 Share Posted February 20, 2005 $curprofile = "C:\Documents and settings\" & @UserNamePlease... forget this buggy way.Just use @UserProfileDir. It saves you a lot of typing and it saves you from the bugs your line can be responsible for. Link to comment Share on other sites More sharing options...
DaveF Posted February 21, 2005 Share Posted February 21, 2005 From the Windows Server 2003 SDK From WtsAPI32.h: #define NOTIFY_FOR_ALL_SESSIONS 1 #define NOTIFY_FOR_THIS_SESSION 0 From WinUser.h: #define WTS_CONSOLE_CONNECT 0x1 #define WTS_CONSOLE_DISCONNECT 0x2 #define WTS_REMOTE_CONNECT 0x3 #define WTS_REMOTE_DISCONNECT 0x4 #define WTS_SESSION_LOGON 0x5 #define WTS_SESSION_LOGOFF 0x6 #define WTS_SESSION_LOCK 0x7 #define WTS_SESSION_UNLOCK 0x8 #define WTS_SESSION_REMOTE_CONTROL 0x9 // ... #define WM_WTSSESSION_CHANGE 0x02B1 Tried this this morning, DllCall() returns success, but WM_WTSSESSION_CHANGE is never a recognizable message at the message loop; as always this may be due to my imperfect understanding... GUI code by CyberSlug's splendid AutoBuilder expandcollapse popup; Script generated by AutoBuilder 0.5 Prototype #include <GuiConstants.au3> If Not IsDeclared('WS_CLIPSIBLINGS') Then Global $WS_CLIPSIBLINGS = 0x04000000 $main = GuiCreate("Session Info", 277, 81,(@DesktopWidth-277)/2, (@DesktopHeight-81)/2 , $WS_OVERLAPPEDWINDOW + $WS_VISIBLE + $WS_CLIPSIBLINGS) $Label_1 = GuiCtrlCreateLabel("Last time we left this window session was: ", 10, 10, 200, 20) $Label_2 = GuiCtrlCreateLabel("Never", 220, 10, 40, 20) $Button_3 = GuiCtrlCreateButton("OK", 90, 40, 90, 30) $NOTIFY_FOR_THIS_SESSION = 0 $WM_WTSSESSION_CHANGE = 0x02B1 GuiSetState() Sleep(1000) $ourCall = DllCall(@SystemDir & "\Wtsapi32.dll", "int", "WTSRegisterSessionNotification", "hwnd", $main, "int", $NOTIFY_FOR_THIS_SESSION) MsgBox(0, "Debug", "DllCall returned: " & $ourCall[0]) While 1 $msg = GuiGetMsg(1) Select Case $msg[0] = $GUI_EVENT_CLOSE ExitLoop Case $msg[0] = $Button_3 ExitLoop Case $msg[0] = $WM_WTSSESSION_CHANGE ; If we're here we got the message Sleep(2000) MsgBox(0, "Debug", "Array[1] = " & $msg[1] & @CRLF & "Array[2] = " & $msg[2] & @CRLF & "Array[3] = " & $msg[3]) GUICtrlSetData($Label_2, @HOUR & ":" & @MIN) Case Else ;;; EndSelect WEnd Exit Yes yes yes, there it was. Youth must go, ah yes. But youth is only being in a way like it might be an animal. No, it is not just being an animal so much as being like one of these malenky toys you viddy being sold in the streets, like little chellovecks made out of tin and with a spring inside and then a winding handle on the outside and you wind it up grrr grrr grrr and off it itties, like walking, O my brothers. But it itties in a straight line and bangs straight into things bang bang and it cannot help what it is doing. Being young is like being like one of these malenky machines. Link to comment Share on other sites More sharing options...
Zaxon Posted February 21, 2005 Author Share Posted February 21, 2005 I can confirm we're not getting back any notification. Even with a modified loop doing "show me virtually anything", we're definately not going anything back.While 1 $msg = GuiGetMsg(1) Select Case $msg[0] = $GUI_EVENT_CLOSE ExitLoop Case $msg[0] = $Button_3 ExitLoop Case $msg[0] = $WM_WTSSESSION_CHANGE ; If we're here we got the message Sleep(2000) MsgBox(0, "Debug", "Array[1] = " & $msg[1] & @CRLF & "Array[2] = " & $msg[2] & @CRLF & "Array[3] = " & $msg[3]) GUICtrlSetData($Label_2, @HOUR & ":" & @MIN) case $msg[0] = -11 ; do nothing case $msg[0] = 0 ; do nothing Case Else msgbox(0,"case else",$msg[0]) EndSelect WEndThe other thing I noticed is that the line: MsgBox(0, "Debug", "DllCall returned: " & $ourCall[0]) lets us know the number of parameters, not the parameter returned itself.If I look at $ourCall[1] I get something like '001507AE', which is weird, considering that the function we're calling is supposed to return a boolean:BOOL WTSRegisterSessionNotification( HWND hWnd, DWORD dwFlags);What's happening with the registration return value? Link to comment Share on other sites More sharing options...
DaveF Posted February 21, 2005 Share Posted February 21, 2005 The other thing I noticed is that the line: MsgBox(0, "Debug", "DllCall returned: " & $ourCall[0]) lets us know the number of parameters, not the parameter returned itself.Are you using the most recent release version of AutoIt? DllCall() returns an array, and index zero of the array is the DLL function return value. Check your version, check your docs... Yes yes yes, there it was. Youth must go, ah yes. But youth is only being in a way like it might be an animal. No, it is not just being an animal so much as being like one of these malenky toys you viddy being sold in the streets, like little chellovecks made out of tin and with a spring inside and then a winding handle on the outside and you wind it up grrr grrr grrr and off it itties, like walking, O my brothers. But it itties in a straight line and bangs straight into things bang bang and it cannot help what it is doing. Being young is like being like one of these malenky machines. Link to comment Share on other sites More sharing options...
Zaxon Posted February 21, 2005 Author Share Posted February 21, 2005 Are you using the most recent release version of AutoIt? DllCall() returns an array, and index zero of the array is the DLL function return value. Check your version, check your docs...<{POST_SNAPBACK}>Well, back to school for me! I'm so used to AutoIt filling $array[0] with the number of elements in the array, that I automatically read "$return[1] = function return value" in my mind from the docs. Link to comment Share on other sites More sharing options...
Valik Posted February 21, 2005 Share Posted February 21, 2005 GUIGetMsg() isn't going to return the message. All you're doing is showing the messages that are allowed through. Search the Support forum for "PeekMessage" by me for a potential work-around to actually see the message. Link to comment Share on other sites More sharing options...
Zaxon Posted February 22, 2005 Author Share Posted February 22, 2005 GUIGetMsg() isn't going to return the message. All you're doing is showing the messages that are allowed through. Search the Support forum for "PeekMessage" by me for a potential work-around to actually see the message.<{POST_SNAPBACK}>Has anyone got PeekMessage to work and give useful results? According to the messages I was reading on PeekMessage, people understood it was a necessary function, but they didn't appear to be getting useful results with it.Nevertheless, I've whipped up a PeekMessage based on the examples in the messages so far, and with some minor tailorings:#include <GUIConstants.au3> #Include <date.au3> Const $PM_NOREMOVE = 0 Const $PM_REMOVE = 1 Const $WM_QUERYENDSESSION = 17 const $NOTIFY_FOR_THIS_SESSION = 0 Dim $dummy[200], $ret[200] $handle=DllOpen("user32.dll") if @error then msgbox(64,"Error!","Didn't open DLL!",2) $window = GUICreate("Main window", 400, 400) $ourCall = DllCall(@SystemDir & "\Wtsapi32.dll", "int", "WTSRegisterSessionNotification", "hwnd", $window, "int", $NOTIFY_FOR_THIS_SESSION) if @error then msgbox(64,"Error!","Didn't open DLL!",2) $edit = GUICtrlCreateEdit("", 10, 10, 380, 380, $ES_READONLY + $ES_AUTOVSCROLL) GUISetState() while 1 ; (lpMsg As MSG, ByVal hwnd As Long, ByVal wMsgFilterMin As Long, ByVal wMsgFilterMax As Long, ByVal wRemoveMsg As Long) As Long $ret=DllCall($handle, "long", "PeekMessage", "str", $dummy, "long" , $window, "long" , 0, "long", 1000, "long", $PM_REMOVE) if @error = 1 Then msgbox(64, "Error!","Error in DllCall",2) else ; If the function succeeds, the return value is nonzero. if $ret[0] <> 0 Then GUICtrlSetData($edit, _NowTime() & ": " & $ret[0]& $ret[1]& $ret[2]& $ret[3]& $ret[4]& $ret[5] & @crlf, 1) EndIf endif WEndCurrently it doesn't produce anything too useful. Valik, can you help refine this? Or anyone? Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now