Automate Skype Login using AutoIt

Since Microsoft laucnhed Skype ver8.23.0.10, it was not appreciated by the community, primarily due to its user-interface and do not respect what Skype user want. Some of these people criticize Microsoft when they acquired GitHub, because they suspect Microsoft will do the same with GitHub as what they did to Skype.

Major Changes in Skype 8

  • From AutoIt automation point of view, previously we were logging into Skype using _IEAttach() function while now we login using _UIA_getFirstObjectOfElement found within a user-defined AutoIt Library IUIAutomation MS framework
  • Another significant difference is that now there is no way to export your contacts, nor they are stored in c:\Users\WIN_USERNAME\AppData\Roaming\Skype\SKYPE_USERNAME\main.db any longer. However you can export your contacts only if you login to their web-interface.
  • The third change is that now Skype program contian within Microoft directory instead of Skype’s own directory, like C:\Program Files (x86)\Microsoft\Skype for Desktop\Skype.exe

Pre-requisites to automate Skype Login

Skype Login Automation AutoIt Script

#include "UIAWrappers.au3"
 
; #INDEX# =======================================================================================================================
; Title .........: Skype Login Automation
; AutoIt Version : 1.0
; Language ......: English
; Description ...: Login to Skype ver 8.23.0.10
; Author ........: Ahmed Shaikh Memon 
; Requirements...: AutoIt v3.3.12, Developed/Tested on Windows 7 Ultimate SP 1
; ===============================================================================================================================
 
; #CONSTANTS# ===================================================================================================================
Global Const $cDocument ="controltype:=Document"
; ===============================================================================================================================
 
; #LOCAL VARIABLES# ============================================================================================================
Local $Username	= "YOUR_SKYPE_USERNAME"
Local $Password	= "YOUR_SKYPE_PASSWORD"
; ===============================================================================================================================
 
;
; Start Skype
;
Local $ProgramFileDir
Switch @OSArch
	Case "X32"
		$ProgramFileDir = "Program Files"
	Case "X64"
		$ProgramFileDir = "Program Files (x86)"
EndSwitch
$ProgramFileDir = @HomeDrive & "\" & $ProgramFileDir
Run($ProgramFileDir & "\Microsoft\Skype for Desktop\Skype.exe")
Sleep(5000)
 
 
Local $bIsLoggedIn = False
 
; Is Skype running?
If Not WinExists("[Class:Chrome_WidgetWin_1]") Then
	ConsoleWrite("Unable to find Skype")
	Exit
EndIf
 
;
; Get Skype window object
;
Local $oChrome = _UIA_getFirstObjectOfElement($UIA_oDesktop,"class:=Chrome_WidgetWin_1", $treescope_children)
$oChrome.setfocus()
Sleep(1000)
 
;
; Click Proceed to login form
;
Local $oDocument = _UIA_getFirstObjectOfElement($oChrome, "controltype:=" & $UIA_DocumentControlTypeId, $treescope_subtree)
 
Local $oAnotherUser = _UIA_getObjectByFindAll($oDocument, "name:=Use another", $treescope_subtree)
If IsObj($oAnotherUser) Then
	_UIA_action($oAnotherUser,"leftclick")
	$bIsLoggedIn = True
Else
	Local $oSignInWithMS = _UIA_getObjectByFindAll($oDocument, "name:=Sign", $treescope_subtree)
	If IsObj($oSignInWithMS) Then
		_UIA_action($oSignInWithMS,"leftclick")
		$bIsLoggedIn = True
	EndIf
EndIf
 
If Not $bIsLoggedIn Then
	ConsoleWrite("Unable to login")
	Exit
Else
	Sleep(10000)
EndIf
 
;
; Write Username
;
Local $oDocument = _UIA_action($cDocument, "object")
Local $oElement = _UIA_getObjectByFindAll($oDocument, "controltype:=UIA_EditControlTypeId", $treescope_subtree)
 
If Not IsObj($oElement) Then
	ConsoleWrite("Unable to get Username element")
	Exit
EndIf
 
_UIA_action($oElement, "leftclick")
Send("^a")
Send($Username & "{ENTER}")
 
Sleep(5500)
 
;
; Write Password
;
Local $oDocument = _UIA_action($cDocument, "object")
Local $oElement = _UIA_getObjectByFindAll($oDocument, "controltype:=UIA_EditControlTypeId", $treescope_subtree)
 
If Not IsObj($oElement) Then
	ConsoleWrite("Unable to get Username element")
	Exit
EndIf
 
_UIA_action($oElement, "leftclick")
Send("^a")
Send($Password & "{ENTER}")
Sleep(5500)

Checkout all scripts and compile into your AutoIt.

Debuging
We can use _UIA_DumpThemAll($oChrome, $treescope_subtree) to find the name or element type id associated with particular control over Skype screen. Download examples zip on IUIAutomation MS framework.

Explanation

  • controltype:=Document in Global Const $cDocument will be used to get access to document object of Skype’s screens change during login process.
  • $ProgramFileDir points to right 32-bit Program Files on this script host computer.
  • _UIA_getFirstObjectOfElement will give access to Skype screen and will try to find it using UI_Automation class name Chrome_WidgetWin_1. We will find this name using Inspect tool
  • $oDocument will be used to find particular elements on Skype app. We can get list of all available elements UI Automation control-type, name, index etc using _UIA_DumpThemAll($oChrome, $treescope_subtree) or _UIA_DumpThemAll($oDocument, $treescope_subtree)
  • _UIA_getObjectByFindAll($oDocument, "name:=Use another", $treescope_subtree) will return element object (if exist) that has text “Use another account”. This will be displayed on Skype login screen if and only if you’ve previously logged in to Skype and logout. Otherwise it will display Sign in
    Skype 8 Automation - Use Another Account
    Skype 8 Automation – Use Another Account
    Skype 8 Automation - Sign in with Microsoft
    Skype 8 Automation – Sign in with Microsoft
  • _UIA_action($oAnotherUser,"leftclick") will trigger leftclick event on Skype screen, this particular line will click “Use another account” link
  • _UIA_getObjectByFindAll($oDocument, "name:=Sign", $treescope_subtree) is added as fail-safe. This piece of code will work when there is no “Use another account” link is visible on Skype login screen.
  • _UIA_getObjectByFindAll($oDocument, "controltype:=UIA_EditControlTypeId", $treescope_subtree) will return Username text-field element.
  • _UIA_action($oElement, "leftclick")
    Send("^a")
    Send($Username & "{ENTER}")

    In a perfect world, we could have used just single line;

    _UIA_action($oElement,"setvalue using keys", $Username & "{ENTER}")

    But setvalue using keys work in following sequence;

    1. put element into focus
    2. select all text within element
    3. send text to control using Send()

    setvalue using keys is not working as expected on Skype screen. Because as soon as Send() is called, it looses the focus, thus no text is written to the element in question

    While my 3 lines code above, always work, as I am triggering left-click on element instead of focus

    Personally I dont like using Send(), as it require window to be active, which might disturb control being sent to incorrect window, however it seems like the need until we get better solution.

Best practises implemented

  • Well commented code
  • Use of @OSArch & @HomeDrive to build system architecture specific directory
  • Saved two interactions and instead passed [ENTER] keystroke while writing username & password
  • Used generic condition controltype:=UIA_EditControlTypeId for _UIA_getObjectByFindAll to find username & password elements. Deliberately did not used the name or title to find them