Automating/Controlling Kindle for PC

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
tester
Posts: 84
Joined: 10 Jun 2021, 23:03

Automating/Controlling Kindle for PC

Post by tester » 20 Aug 2022, 09:53

Hi there,

I'm looking for a good way to automate/control the program, Kindle for PC, which can be downloaded from this page (by clicking on the button, "Download for PC & Mac"), by not using PixcelSearch or ImageSearch as there will be users with different DPI, light/dark modes, and languages.

By inspecting the app windows with Window Spy, there isn't any control information. I guess the app uses web-based UI or something. Also, I've inspected where they store user settings with the Watch Folder script but strangely it seems they don't store any user preferences with a file on the local machine. Maybe, they store them on their server.

What I'd like to achieve is to make Kindle for PC download certain ebooks newly added by the user and send downloaded .azw files to Calibre. Adding books to the library is done separately on the Amazon web page and it is not talked about here for now. It seems the added books can be detected by parsing the KindleSyncMetadataCache.xml file (%APPDATA%/Local/Amazon/Kindle/Cache/KindleSyncMetadataCache.xml). The problem is how to make Kindle For PC download them programmatically.

I'm guessing that monitoring how the app sends HTTP requests and simulating them might do the job but I need to see some examples.

Any insights would be appreciated.
BoBo
Posts: 6564
Joined: 13 May 2014, 17:15

Re: Automating/Controlling Kindle for PC

Post by BoBo » 21 Aug 2022, 02:05

Have you already checked the forum for "UIA"?
tester
Posts: 84
Joined: 10 Jun 2021, 23:03

Re: Automating/Controlling Kindle for PC

Post by tester » 21 Aug 2022, 23:15

I haven't. I'll check. Thanks for the information.
tester
Posts: 84
Joined: 10 Jun 2021, 23:03

Re: Automating/Controlling Kindle for PC

Post by tester » 24 Aug 2022, 22:32

Using UIA_Interface, I could make it download books by title on an activated window. But not for an inactive window. For some reasons, the UIA_Interface.ControlClick() method doesn't seem to work. In the below code, press F2 to test with Click() and F3 for ControlClick().

Does anybody have any any ideas?

Code: Select all

#SingleInstance, Force
#NoEnv

#include %A_ScriptDir%\..\Lib\UIA_Interface.ahk

if ( ! hWnd := KindleWindowExist() ) {
    Tooltip, %A_NOW%: Waiting for Kindle for PC to start.
    Run, C:\Users\%A_UserName%\AppData\Local\Amazon\Kindle\application\Kindle.exe,,, iPIDKindleForPC
    While ( ! hWnd := KindleWindowExist() ) {
        Sleep 500
    }    
}
While( ! elementUIAKindle := getUIAKindleWindow(hWnd) ) {
    Tooltip, %A_NOW%: Waiting for the Kindlw window to be ready.
    Sleep 500
}
While( ! hWnd := getKindleLibraryWindow() ) {    
    Sleep 500
    if ( A_Index != 1 ) {
        continue
    }
    WinActivate, % "ahk_id " hWnd
    Tooltip, %A_NOW%: Waiting for the user to log in.
    Msgbox, Please log in.    
}

elementUIAKindle := getUIAKindleWindow(hWnd)
Tooltip, % A_NOW ": Ready.`n"
    . "F2: Download a book by Click().`n"
    . "F3: Download a book by ControlClick()`n"
    . "Esc: Exit"

F2::    
    InputBox, sBookTitle, Download a Kindle Book, Enter the book title to download
    if ( ! sBookTitle ) {
        Msgbox, Enter a book title.
        Return
    }
    WinActivate, % "ahk_id " hWnd    
    elementUIAKindle.FindFirstBy("AutomationId=ReaderMainWindow.centralWidget.ToolbarReading.homeButton").Click() ; show the libray
    elementUIAKindle.WaitElementExist("ControlType=DataItem AND Name='" sBookTitle "'",,2).Click("left", 2)
Return

F3::    
    InputBox, sBookTitle, Download a Kindle Book, Enter the book title to download
    if ( ! sBookTitle ) {
        Msgbox, Enter a book title.
        Return
    }
    WinMinimize, % "ahk_id " hWnd
    elementUIAKindle.FindFirstBy("AutomationId=ReaderMainWindow.centralWidget.ToolbarReading.homeButton").Click() ; show the libray
    SetControlDelay, -1
    elementUIAKindle.WaitElementExist("ControlType=DataItem AND Name='" sBookTitle "'",,2).ControlClick("ahk_id " hWnd, "", "left", 2)
~Esc::ExitApp

KindleWindowExist() {
    if ( ! hWnd := WinExist("ahk_class Qt5QWindowIcon") ) {
        return false
    }
    WinGetTitle, sWindowTitle, ahk_id %hWnd%
    return InStr(sWindowTitle, "Kindle") ? hWnd : false
}
getUIAKindleWindow(hWnd) {
    oUIAInterfaceKindle := UIA_Interface()
    if ( ! IsObject(oUIAInterfaceKindle) ) {
        return false
    }
    elementUIAKindle := oUIAInterfaceKindle.ElementFromHandle(hWnd)
    elementUIAKindle.WaitElementExist("Type=RadioButton AND AutomationId=ReaderMainWindow.centralWidget.ToolbarLibrary.itemViewModeButtonFrame.listViewButtonFrame.listViewButton")
    if ( ! IsObject(elementUIAKindle) ) {
        return false
    }
    return elementUIAKindle
}
getKindleLibraryWindow() {
    if ( ! hWnd := KindleWindowExist() ) {
        return false
    }
    WinGetTitle, sWindowTitle, ahk_id %hWnd%
    return InStr(sWindowTitle, "Kindle for PC") ? hWnd : false
}
Post Reply

Return to “Ask for Help (v1)”