Jump to content
Sign in to follow this  
FatherTed

Displaying Tooltips for all users logged on

Recommended Posts

FatherTed

Hi,

Bit of a newbie question here.

I have an application than monitors USB activity. The application works fine, detects USB key insertion and displays tooltip messages.

The issue I have is that I will be using this application on multiple machines, and running it with elevated privilages. When I do this, the application is working fine, everything happens exactly how it should but I do not get any Tooltips showing.

I am assuming that this is because the application is not running as the currently logged on user.

Is there a way to get tooltips to display no matter which user is logged on??

Thanks

Share this post


Link to post
Share on other sites
Melba23

FatherTed,

Welcome to the AutoIt forum. :)

First lesson - always post the code with which you are having difficulty (or a small reproducer). It greatly increases the chances of you getting sensible help quickly. ;)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites
FatherTed

Hi,

Here's a small snipit of my code.

For $Key In $oSourceFiles

If Not $oDestinationFiles.Exists($Key) Then

AutoItWinSetTitle($_SingleTonKeyTrayTip) ; set the TrayTip AutoIt Window Title

AutoItSetOption("TrayIconHide", 0) ;0=show, 1=hide tray icon

TrayTip("MEDIAKEY Update","Transfering " & $Key,10,1)

;GUICtrlSetData ($Detail,"Transfering " & $Key )

$SyncRet = FileCopy($sSource & "\" & $Key, $sDestination & "\" & $Key, 9)

If $SyncRet = 0 Then $SyncSuccess = False

Else

The tooltip displays fine if i run it as the logged on user, I want to run it from a scheduled task as a system process and show the tooltip no matter who is logged on.

Thanks

Share this post


Link to post
Share on other sites
JLogan3o13

The only way I know of to run as System and interact with the desktop of whomever is logged in would be to run the application as a Service. You might check out SrvAny, though I believe it is buggy in Win7. There was also a thread in the Examples section regarding running your script as a service, I'll see if I can dig up the link.

Edit:

Edited by JLogan3o13

√-1 2^3 ∑ π, and it was delicious!

Share this post


Link to post
Share on other sites
FatherTed

Hi J,

Tried that unfortunately, with the same results. Script does all the work fine but won't display tooltips or GUIs, as I've tried both.

Thanks

Share this post


Link to post
Share on other sites
Artisan

Can you get it to show MsgBox alerts?  Not pretty, but it would at least be something.

My second idea is vague and a bit of a stretch.  Is there any way to hook it into the Windows COM+ system and use that to send user alerts?  I don't know if you can make a tooltip that way, however.  I have very little knowledge of COM stuff, but it should be possible.

My third idea is to create a separate application/script that is in a location accessible to all users.  You then use your system script to call the accessible script which in turn creates the tooltip.

Edited by Artisan

Share this post


Link to post
Share on other sites
FatherTed

Hi,

Tried that too, with no success.

I think it's got something to do with the Session 0 Issolation built into Window 7,

Grrrr.

Trying to get some information on WTSSendMessage but with no success. :(

Share this post


Link to post
Share on other sites
Artisan

FatherTed,

I looked into WTSSendMessage a bit on MSDN.  I'm sure you're aware it's a Remote Desktop function.  I have only a little experience with C and with AutoIt's DllCall(), and I put together what I could.  The base functions are "there", but it doesn't work yet.  I've taken it as far as I can.  I'm posting this for you or anyone else to look at and hopefully make some progress with.

Best of luck!

EDIT:

For those who just want to peak, here's the code

;   WTSSendMessage Function
;   Displays a message box on the client desktop of a specified Remote Desktop Services session.
;   See MSDN information on WTSSendMessage:
;   http://msdn.microsoft.com/en-us/library/windows/desktop/aa383842(v=vs.85).aspx

Global Const $WTS_CURRENT_SERVER_HANDLE = 0         ; "#define WTS_CURRENT_SERVER_HANDLE  ((HANDLE)NULL)"

; ====================== $Style Values (for message) ======================
Global Const $MB_OK = 0x00000000                    ; Has button: OK
Global Const $MB_OKCANCEL = 0x00000001              ; Has buttons: OK and Cancel
Global Const $MB_RETRYCANCEL = 0x00000005           ; Has buttons: Retry and Cancel
Global Const $MB_YESNO = 0x00000004                 ; Has buttons: Yes and No
Global Const $MB_YESNOCANCEL = 0x00000003           ; Has buttons: Yes, No, and Cancel
Global Const $MB_ABORTRETRYIGNORE = 0x00000002      ; Has buttons: Abort, Retry, and Ignore
Global Const $MB_CANCELTRYCONTINUE = 0x00000006     ; Has buttons: Cancel, Try Again, Continue
Global Const $MB_HELP = 0x00004000                  ; Adds a Help button to the message box (sends WM_HELP to owner)
Global Const $MB_ICONEXCLAMATION = 0x00000030       ; Icon: Exclamation point
Global Const $MB_ICONWARNING = 0x00000030           ; Icon: Exclamation point
Global Const $MB_ICONINFORMATION = 0x00000040       ; Icon: Blue circled i
Global Const $MB_ICONASTERISK = 0x00000040          ; Icon: Blue circled i
Global Const $MB_ICONQUESTION = 0x00000020          ; Icon: Question-mark (no longer recommended for use)
Global Const $MB_ICONSTOP = 0x00000010              ; Icon: Stop sign
Global Const $MB_ICONERROR = 0x00000010             ; Icon: Stop sign
Global Const $MB_ICONHAND = 0x00000010              ; Icon: Stop sign
Global Const $MB_DEFBUTTON1 = 0x00000000            ; (default) 1st button is Default
Global Const $MB_DEFBUTTON2 = 0x00000100            ; 2nd button is Default
Global Const $MB_DEFBUTTON3 = 0x00000200            ; 3rd button is Default
Global Const $MB_DEFBUTTON4 = 0x00000300            ; 4th button is Default
Global Const $MB_APPLMODAL = 0x00000000             ; (default) application-modal
Global Const $MB_SYSTEMMODAL = 0x00001000           ; Sets WS_EX_TOPMOST (blocks all application GUI's until responded to)
Global Const $MB_TASKMODAL = 0x00002000             ; Like $MB_APPLMODAL, but used when hwnd is NULL (irrelevant for WTSSendMessage?)
Global Const $MB_DEFAULT_DESKTOP_ONLY = 0x00020000  ; "If the current input desktop is not the default desktop, MessageBox does not return until the user switches to the default desktop."
Global Const $MB_RIGHT = 0x00080000                 ; Right-justify message
Global Const $MB_RTLREADING = 0x00100000            ; Used to set right-to-left reading order (Hebrew & Arabic systems)
Global Const $MB_SETFOREGROUND = 0x00010000         ; Sets the message box as the foreground window
Global Const $MB_TOPMOST = 0x00040000               ; Creates the message box with WS_EX_TOPMOST style
Global Const $MB_SERVICE_NOTIFICATION = 0x00200000  ; Indicates that _WinAPI_WTSSendMessage is being called from a system service (hwnd must be NULL)
; ====================== // $Style Values ======================


; ====================== $pResponse Values (User clicked...) ======================
Global Const $IDABORT = 3           ; Abort button
Global Const $IDCANCEL = 2          ; Cancel button
Global Const $IDCONTINUE = 11       ; Continue button
Global Const $IDIGNORE = 5          ; Ignore button
Global Const $IDNO = 7              ; No button
Global Const $IDOK = 1              ; OK button
Global Const $IDRETRY = 4           ; Retry button
Global Const $IDTRYAGAIN = 10       ; Try Again button
Global Const $IDYES = 6             ; Yes button
Global Const $IDASYNC = 0x7D01      ; Nothing - $bWait was False so the function returned right away
Global Const $IDTIMEOUT = 0x7D00    ; Nothing - $bWait was True and the user did nothing
; ====================== // $pResponse Values ======================


; Displays a message box on the client desktop of a specified Remote Desktop Services session.
Func _WinAPI_WTSSendMessage( $hServer, $SessionId, $pTitle, $pMessage, $Style, $Timeout, ByRef $pResponse, $bWait = True )
    Local $aResult = DllCall("Wtsapi32.dll", "BOOL", "WTSSendMessage", _
    "handle", $hServer, _               ; Handle to RD Session Host server (from WTSOpenServer) or $WTS_CURRENT_SERVER_HANDLE ("RD Session Host server on which your application is running")
    "DWORD", $SessionId, _              ; Remote Desktop Services session identifier. Can be WTS_CURRENT_SESSION.
    "str*", $pTitle, _                  ; Title for message box
    "DWORD", StringLen($pTitle), _      ; Title length
    "str*", $pMessage, _                ; Message for message box
    "DWORD", StringLen($pMessage), _    ; Message length
    "DWORD", $Style, _                  ; Style for the message box, similar to AutoIt's MsgBox styles (see above)
    "DWORD", $Timeout, _                ; Time in seconds until timeout occurs.  0 = wait for user.
    "DWORD*", $pResponse, _             ; This variable will contain the user's response (see above)
    "BOOL", $bWait)                     ; True = Wait for user (blocking function)
                                        ; False = Asynchronous use? ($pResponse = IDASYNC)
    Return $aResult     ; 0 = Failure, Non-zero = Success
EndFunc

; Opens a handle to a Remote Desktop Server
Func _WinAPI_WTSOpenServer( $pServerName )
    Local $aResult = DllCall("Wtsapi32.dll", "handle", "WTSOpenServer", _
    "str*", $pServerName)               ; The NetBIOS name of the RD server
    Return $aResult
            ; Seriously, Microsoft??
            ; "If the function fails, it returns a handle that is not valid.
            ; You can test the validity of the handle by using it in another function call."
EndFunc

; Closes a handle to a Remote Desktop Server
Func _WinAPI_WTSCloseServer( $hServer )
    DllCall("Wtsapi32.dll", "none", "WTSCloseServer", _
    "handle", $hServer)             ; The handle returned by _WinAPI_WTSOpenServer
    ; This function has no return value
EndFunc

; List the Session ID's
Func _WinAPI_WTSEnumerateSessions( $hServer, $ppSessionInfo, ByRef $pCount)
    DllCall("Wtsapi32.dll", "BOOL", "WTSEnumerateSessions", _
        "handle", $hServer, _       ; Handle to RD hose as returned by _WinAPI_WTSOpenServer
        "DWORD", 0, _               ; Reserved.  Always 0.
        "DWORD", 1, _               ; Enumeration version.  Always 1.
        "ptr*", $ppSessionInfo, _   ; A point to a pointer to an array.  Good job, MS.  Contains WTS_SESSION_INFO structures.
        "DWORD*", $pCount)          ; The number of $ppSessionInfo structures returned
    Return 0 ; *** hehe!
EndFunc

; ============== TEST ==============

Func _WinAPI_GetComputerName()
    Local $lpBuffer, $lpnSize = 32
    $aResult = DllCall("Kernel32.dll", "BOOL", "GetComputerName", _
        "str*", $lpBuffer, _    ; This will contain the computer's NetBIOS name
        "DWORD*", $lpnSize)     ; On input, MAX_COMPUTERNAME_LENGTH + 1.  On output, StringLen() of $lpBuffer
    ; $aResult ==>  0 = Failure, Non-zero = Success
    Return $lpBuffer
EndFunc


;ConsoleWrite("Contacting RD Server..." & @LF)
;Dim $hRD = _WinAPI_WTSOpenServer("AwesomePC")
;ConsoleWrite('>>' & $hRD & '<<' & @LF)
;_WinAPI_WTSCloseServer($hRD)
;ConsoleWrite("Finished test." & @LF)

ConsoleWrite(_WinAPI_GetComputerName() & @LF)

Remote Desktop.au3

Edited by Artisan

Share this post


Link to post
Share on other sites
Artisan

I just learned something cool.  If you're on Windows 7, you can use the command line program "msg" to send a message.  Just run "msg" from a Win7 console and it'll show you how to use it.  It would be quite simple to call it from AutoIt.

If that doesn't work, then I agree with Melba - post (a working sample of) your code and we'll see what we can do from there.

Share this post


Link to post
Share on other sites
kylomas

I just learned something cool. If you're on Windows 7, you can use the command line program "msg" to send a message. Just run "msg" from a Win7 console and it'll show you how to use it. It would be quite simple to call it from AutoIt

 

For business and pro versions only...

kylomas


Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Share this post


Link to post
Share on other sites
FatherTed

o/ Success ......
 
Thanks for your help guys, I did a bit more searching and found some Autoit code on the forums.
 
After a little bit of editing I have a working solution.
 
here's the final code
 
Func _TSSendConsoleMessage($TitleText, $MessageText, $ButtonSet = 0, $Timeout = 10, $Wait = False)
    $pTitle = DllStructCreate("char Title[32]")
    $pMessage = DllStructCreate("char Message[128]")
    $pResponse = DllStructCreate("DWORD Response")
    $SessionId = WTSGetActiveConsoleSessionId()
    DllStructSetData($pTitle, "Title", $TitleText)
    DllStructSetData($pMessage, "Message", $MessageText)
    $wtsapiCall = DllOpen("Wtsapi32.dll")
    $SendMessageResult = DllCall($wtsapiCall,"BOOL","WTSSendMessage","HANDLE","WTS_CURRENT_SERVER_HANDLE","DWORD",$SessionId,"str",DllStructGetData($pTitle, "Title"),"DWORD",DllStructGetSize($pTitle),"str",DllStructGetData($pMessage, "Message"),"DWORD",DllStructGetSize($pMessage),"DWORD",$ButtonSet,"DWORD",$Timeout,"DWORD",DllStructGetPtr($pResponse),"BOOL",$Wait)
    DllClose($wtsapiCall)
EndFunc

Func WTSGetActiveConsoleSessionId()
    $Ret = DllCall('Kernel32.dll', 'dword', 'WTSGetActiveConsoleSessionId')
    Return $Ret[0]
EndFunc

To test i call it like this

_TSSendConsoleMessage("TITLE","MESSAGE","0","10","FALSE")

 

Thanks again guys.

FT

Share this post


Link to post
Share on other sites
Artisan

Great job, FatherTed! I'm glad you got it figured out.  I'm going to compare it to what I came up with and see what I can learn / where I went wrong.  :) 

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×