Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

GMail Commander - Command your PC using GMail


  • Please log in to reply
2 replies to this topic
..:: Free Radical ::..
  • Members
  • 74 posts
  • Last active: May 30 2015 12:13 PM
  • Joined: 20 Sep 2006
GMail Commander aka GCMD

Here's a simple script with which you can control your PC using GMail.

Make a fresh GMail account for use with this app to avoid conflicts and spam.

Enter the username (without @gmail.com) and password for the account

In the Accept IDs box, add your email ids which you may use to send an email to the app. You may add any number of email ids from any host and separate them with commas. Remember, there is no other security check in the app other than your email ids. So in order to prevent unauthorized access to your pc, add only the ones you will be using.

In the Refresh UpDown box, you can change the refresh interval for the app from 1 to 1000 minutes.
This is the time interval between detection of new emails. The app reads rss feeds from GMail and would typically use ~10 kB per refresh. Adjust it according to your bandwidth and data limits.

Don't add any subject to the email to avoid grouping of emails!
Don't send the exact same command more than once in succession as the app would think its the same and not interpret it.

It takes a finite amount of time for the email to reach GMail plus the refresh interval.
The app typically runs within a minute of your sending out the email if your refresh interval is 1 minute, even if you are on the moon. Fast enough I guess.

Keep in mind that the app would not interpret any old emails.
Make sure the app is running before you send out an email command and that the app has access to the internet and your firewall is not blocking it.

Even if you disconnect while the app is running, it would remember the last email before the disconnection and would sleep till you reconnect.
This would help in further bandwidth savings eg. you can schedule a disconnect and reconnect via Task Scheduler and thereby limit the time period within which the app works.

#Persistent
#NoEnv
#SingleInstance force

/*
#Include COM.ahk
#Include cdomessage.ahk
#Include XMLRead.ahk
#Include UnHTM.ahk
#Include gdip.ahk
#Include sc.ahk
*/

SetBatchLines, -1
StringCaseSense, Off
DetectHiddenWindows, On
SetTitleMatchMode, 2
SetTitleMatchMode, slow
Process, Priority, , High

COM_Init()

App := "GMail Commander"
File := A_Temp . "\GMail.XML"

;Menu, Tray, Icon, D:\My Documents\My Icons\GMail.ico
Menu, Tray, Tip, % App
Menu, Tray, NoStandard
Menu, Tray, Add, &Configure, Config
Menu, Tray, Add
Menu, Tray, Add, E&xit, Exit

RegRead, Favorites, HKEY_CURRENT_USER, Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders, Favorites
If Not Favorites
	RegRead, Favorites, HKEY_CURRENT_USER, Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders, Favorites

RegRead, Recent, HKEY_CURRENT_USER, Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders, Recent
If Not Recent
	RegRead, Recent, HKEY_CURRENT_USER, Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders, Recent
	
IniRead, User, % A_ScriptDir . "\gCMD.INI", Settings, User, % A_Space
IniRead, Password, % A_ScriptDir . "\gCMD.INI", Settings, Password, % A_Space
IniRead, Id, % A_ScriptDir . "\gCMD.INI", Settings, Id, % A_Space
IniRead, Refresh, % A_ScriptDir . "\gCMD.INI", Settings, Refresh, % A_Space

If (!User or !Password or !Id or Refresh < 0.1)
	Goto, Config
else Goto, Check

Config:

Menu, Tray, Disable, &Configure

Gui, Font, s11 cBlack, Segoe UI SemiBold
Gui, Add, Text, x10 y10, Username
Gui, Font, cBlue
Gui, Add, Edit, x100 y10 w200 vUser, % User
Gui, Font, cBlack
Gui, Add, Text, x+8, @gmail.com
Gui, Font, cRed
Gui, Add, Edit, x+8 w200 vPassword Password, % Password
Gui, Font, cBlack
Gui, Add, Text, x+8 y10, Password
Gui, Add, Text, x10 y50, Accept IDs
Gui, Font, cGreen
Gui, Add, Edit, x100 y50 h30 w600 vId, % Id
Gui, Font, cBlack
Gui, Add, Text, x10 y90, Refresh
Gui, Add, Edit, x100 y90 w80
Gui, Add, UpDown, x+ Range 1-1000 vRefresh, 3
Gui, Add, Text, x+8, minutes
Gui, Add, Button, x+8 w450 h30 Default, Done
Gui, Show, AutoSize Center, % App
return

ButtonDone:

Gui, Submit
Gui, Destroy

If (!User or !Password or !Id or Refresh < 1)
	Goto, Config

IniWrite, % User, % A_ScriptDir . "\gCMD.INI", Settings, User
IniWrite, % Password, % A_ScriptDir . "\gCMD.INI", Settings, Password
IniWrite, % Id, % A_ScriptDir . "\gCMD.INI", Settings, Id
IniWrite, % Refresh, % A_ScriptDir . "\gCMD.INI", Settings, Refresh

Check:

Menu, Tray, Enable, &Configure
SetTimer, Check, % Refresh*60000

FileDelete, % File
URLDownloadToFile, % "https://" . User . ":" . Password . "@mail.google.com/mail/feed/atom", % File
Sleep, 5000
If !ErrorLevel
{
	gOld := gNew
	gFrom := XMLRead(File, "feed.entry.author.email")
	;gTitle := XMLRead(File, "feed.entry.title")
	gNew := XMLRead(File, "feed.entry.summary")
	If !init
	{
		init=1
		return
	}
	If gNew != %gOld%
	{
		If Id contains %gFrom%
		{
			GoSub, Exec
			SoundBeep, 4000, 4000
		}
	}
}
return

Exec:

If InStr(gNew,"run ") == 1
{
	RegExMatch(gNew,"i)run (.*)",s)
	gCMD := UnHTM(s1)
	Goto, RunProgram
}
else If InStr(gNew,"kill ") == 1
{
	RegExMatch(gNew,"i)kill (.*)",s)
	gCMD := UnHTM(s1)
	Goto, KillProgram
}
else If InStr(gNew,"cmd ") == 1
{
	RegExMatch(gNew,"i)cmd (.*)",s)
	gCMD := UnHTM(s1)
	Goto, Command
}
else If InStr(gNew,"screen") == 1
{
	Goto, Capture
}
else If InStr(gNew,"set ") == 1
{
	RegExMatch(gNew,"i)set (.*)",s)
	gCMD := UnHTM(s1)
	Goto, Settings
}
else If InStr(gNew,"win ") == 1
{
	RegExMatch(gNew,"i)win (.*)",s)
	gCMD := UnHTM(s1)
	Goto, Window
}
return

RunProgram:

If gCMD<>
{	
	Loop, %Favorites%\%gCMD%*, 0
	{
		GoSub, Shortcut
	}
	Loop, %Recent%\%gCMD%*, 0
	{
		GoSub, Shortcut
	}
	Loop, %A_AppData%\Microsoft\Internet Explorer\Quick Launch\%gCMD%*, 0, 1
	{
		GoSub, Shortcut
	}
	Loop, %A_AppData%\Microsoft\Windows\Recent\%gCMD%*, 0
	{
		GoSub, Shortcut
	}
	Loop, %A_StartMenu%\%gCMD%*, 0, 1
	{
		GoSub, Shortcut
	}
	Loop, %A_StartMenuCommon%\%gCMD%*, 0, 1
	{
		GoSub, Shortcut
	}
	Loop, HKEY_CURRENT_USER, Software\Quizo\QTTabBar\RecentFiles
	{
		RegRead, Path
		IfInString, Path, %gCMD%, GoSub, File	
	}

	;StringTrimRight, List, List, 1
	StringSplit, Program, List, `,
	Run, % Program1

	Out := "Running `n" . Program1
	TrayTip,, % Out, 5, 1
	GoSub, Mail

}

return

KillProgram:

If gCMD<>
{

	Process, Exist
	h := DllCall("OpenProcess", "UInt", 0x0400, "Int", false, "UInt", ErrorLevel)
	DllCall("Advapi32.dll\OpenProcessToken", "UInt", h, "UInt", 32, "UIntP", t)
	VarSetCapacity(ti, 16, 0)
	NumPut(1, ti, 0)
	DllCall("Advapi32.dll\LookupPrivilegeValueA", "UInt", 0, "Str", "SeDebugPrivilege", "Int64P", luid)
	NumPut(luid, ti, 4, "int64")
	NumPut(2, ti, 12)
	DllCall("Advapi32.dll\AdjustTokenPrivileges", "UInt", t, "Int", false, "UInt", &ti, "UInt", 0, "UInt", 0, "UInt", 0)
	DllCall("CloseHandle", "UInt", h)
	hModule := DllCall("LoadLibrary", "Str", "Psapi.dll")
	s := VarSetCapacity(a, 4096)
	c := 0
	DllCall("Psapi.dll\EnumProcesses", "UInt", &a, "UInt", s, "UIntP", r)
	Loop, % r // 4
	{
		pid := NumGet(a, A_Index * 4)
		h := DllCall("OpenProcess", "UInt", 0x0010 | 0x0400, "Int", false, "UInt", pid)
		VarSetCapacity(n, s, 0)
		e := DllCall("Psapi.dll\GetModuleBaseNameA", "UInt", h, "UInt", 0, "Str", n, "UInt", s)
		DllCall("CloseHandle", "UInt", h)
		If (n && e)
		{
			If n contains %gCMD%
				Process, Close, % n		
		}
	}
	n := ""
	DllCall("FreeLibrary", "UInt", hModule)
	
	Out := % "Terminated programs with name `n" . gCMD
	TrayTip,, % Out, 5, 1
	GoSub, Mail
	
}

return

Command:

If gCMD<>
{

	If (InStr(gCMD,"dir ") == 1 && StrLen(gCMD) < 10)
		gCMD .= ":"
	If InStr(gCMD,">")
	{
		RunWait, % comspec . " /c " . gCMD,, min
		Out := gCMD
	}
	else
	{
		FileDelete, % A_Temp . "\gCMD.TXT"
		RunWait, % comspec . " /c " . gCMD . " > " . A_Temp . "\gCMD.TXT",, min
		FileRead, Out, % A_Temp . "\gCMD.TXT"
		FileDelete, % A_Temp . "\gCMD.TXT"
	}
	
	Out := % "Invoked Command Line `n" . gCMD
	TrayTip,, % Out, 5, 1
	GoSub, Mail
	
}

return

Window:

If gCMD<>
{

	If (InStr(gCMD,"act") == 1)
	{
		RegExMatch(gCMD,"i)act*\s(.*)",s)
		Window := UnHTM(s1)
		WinGetTitle, Window, % Window
		If Window<>
		{
			WinActivate, % Window	
			Out := "Window activated `n" . Window
			TrayTip,, % Out, 5, 1
			GoSub, Mail
		}
	}
	else If (InStr(gCMD,"close") == 1)
	{
		RegExMatch(gCMD,"i)close*\s(.*)",s)
		Window := UnHTM(s1)
		WinGetTitle, Window, % Window
		If Window<>
		{
			WinClose, % Window
			Out := "Window closed `n" . Window
			TrayTip,, % Out, 5, 1
			GoSub, Mail
		}
	}
	else If (InStr(gCMD,"kill") == 1)
	{
		RegExMatch(gCMD,"i)kill.*\s(.*)",s)
		Window := UnHTM(s1)
		WinGetTitle, Window, % Window
		If Window<>
		{
			WinKill, % Window
			Out := "Window killed `n" . Window
			TrayTip,, % Out, 5, 1
			GoSub, Mail
		}
	}
	else If (InStr(gCMD,"max") == 1)
	{
		RegExMatch(gCMD,"i)max.*\s(.*)",s)
		Window := UnHTM(s1)
		WinGetTitle, Window, % Window
		If Window<>
		{
			WinMaximize, % Window
			Out := "Window maximized `n" . Window
			TrayTip,, % Out, 5, 1
			GoSub, Mail
		}
	}
	else If (InStr(gCMD,"min") == 1)
	{
		RegExMatch(gCMD,"i)min.*\s(.*)",s)
		Window := UnHTM(s1)
		WinGetTitle, Window, % Window
		If Window<>
		{
			WinMinimize, % Window
			Out := "Window minimized `n" . Window
			TrayTip,, % Out, 5, 1
			GoSub, Mail
		}
	}
	else If (InStr(gCMD,"res") == 1)
	{
		RegExMatch(gCMD,"i)res.*\s(.*)",s)
		Window := UnHTM(s1)
		WinGetTitle, Window, % Window
		If Window<>
		{
			WinRestore, % Window
			Out := "Window restored `n" . Window
			TrayTip,, % Out, 5, 1
			GoSub, Mail
		}
	}
	else If (InStr(gCMD,"hide") == 1)
	{
		RegExMatch(gCMD,"i)hide.*\s(.*)",s)
		Window := UnHTM(s1)
		WinGetTitle, Window, % Window
		If Window<>
		{
			WinHide, % Window
			Out := "Window hidden `n" . Window
			TrayTip,, % Out, 5, 1
			GoSub, Mail
		}
	}	
	else If (InStr(gCMD,"show") == 1)
	{
		RegExMatch(gCMD,"i)show.*\s(.*)",s)
		Window := UnHTM(s1)
		WinGetTitle, Window, % Window
		If Window<>
		{
			WinShow, % Window
			Out := "Window unhidden `n" . Window
			TrayTip,, % Out, 5, 1
			GoSub, Mail
		}
	}	
	
}

return

Settings:

If gCMD<>
{

	If InStr(gCMD,"refresh ")
	{
		RegExMatch(gCMD,"i)refresh (.*)",s)
		Refresh := UnHTM(s1)
		IniWrite, % Refresh, % A_ScriptDir . "\gCMD.INI", Settings, Refresh
		
		Out := "Refresh rate set to `n" . Refresh . " minutes."
		TrayTip,, % Out, 5, 1
		GoSub, Mail
	}
	
}

return

File:

IfExist, % Path
{
	List .= Path . ","
}
return

Shortcut:

FileGetShortcut, % A_LoopFileLongPath, Path
IfExist, % Path
{
	List .= A_LoopFileLongPath . ","
}
return

Capture:

	Name := A_Now . ".JPG"
	sc_CaptureScreen(0,0,"Screen.JPG",50)
	FileMove, Screen.JPG, % A_Temp . "\" . Name
	
	Attach := A_Temp . "\" . Name
	Out := "Screen Captured `n" . Name
	TrayTip,, % Out, 5, 1
	GoSub, Mail
	
Return

Mail:

	gCMD := ""

	pmsg :=   COM_CreateObject("CDO.Message")
	pcfg :=   COM_Invoke(pmsg, "Configuration")
	pfld :=   COM_Invoke(pcfg, "Fields")

	COM_Invoke(pfld, "Item", "http://schemas.microsoft.com/cdo/configuration/sendusing", 2)
	COM_Invoke(pfld, "Item", "http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout", 60)
	COM_Invoke(pfld, "Item", "http://schemas.microsoft.com/cdo/configuration/smtpserver", "smtp.gmail.com")
	COM_Invoke(pfld, "Item", "http://schemas.microsoft.com/cdo/configuration/smtpserverport", 465)
	COM_Invoke(pfld, "Item", "http://schemas.microsoft.com/cdo/configuration/smtpusessl", True)
	COM_Invoke(pfld, "Item", "http://schemas.microsoft.com/cdo/configuration/smtpauthenticate", 1)
	COM_Invoke(pfld, "Item", "http://schemas.microsoft.com/cdo/configuration/sendusername", User . "@gmail.com")
	COM_Invoke(pfld, "Item", "http://schemas.microsoft.com/cdo/configuration/sendpassword", Password)
	COM_Invoke(pfld, "Update")

	COM_Invoke(pmsg, "From", "GMail Commander")
	COM_Invoke(pmsg, "To", gFrom)
	COM_Invoke(pmsg, "Subject", "")
	COM_Invoke(pmsg, "TextBody", Out)
	If Attach<>
		COM_Invoke(pmsg, "AddAttachment", Attach)
		
	COM_Invoke(pmsg, "Send")
	
	COM_Release(pfld)
	COM_Release(pcfg)
	COM_Release(pmsg)
	
	FileDelete, % Attach
	Attach := ""
	Out := ""
		
return

Exit:
	COM_Term()
ExitApp


eg.
Run opera
will search for a shortcut named opera and run it
you will be emailed the path of the shortcut run.

Kill firefox
will kill a process with firefox in its name

cmd tasklist
The cmd command will invoke the command line with any command with switches and email you the output after it terminates

screen
Will email you a jpeg screenshot.

set refresh n
to change the refresh interval on the fly

win <subcommand> <search string>
to activate, maximize, minimize, restore, hide, show, close and kill windows by name.

The subcommands used are:
act, max, min, res, hide, show, close, kill (you can use the full names eg. activate or any string of characters without whitespaces following the subcommand)

Uses CDO_COM, sc_Capture with gdi+, UnHTM() and XML_Read().
You may need to #include these if you don't have it in your \Lib\
Credits to the respective authors for these indispensable functions.

I am not a programmer but I am an avid AHK fan and eager to learn more.
There may be a more elegant way to achieve this than my messy script.

Please help me optimize this for everyone.
Critiques and inputs welcome.

You may download the compiled app here:
GMail Commander - Command Your PC Using GMail - <!-- m -->http://www.erodov.co... ... 38700.html<!-- m -->

:wink:

sumon
  • Moderators
  • 1317 posts
  • Last active: Dec 05 2016 10:14 PM
  • Joined: 18 May 2010
Oh my, this idea seems totally awesome. I don't know exactly what to do with it yet, but I expect it could be used in combination with a few "standard scripts" to allow for pretty nice things.

Gonna try it out later :)

Grendahl
  • Members
  • 416 posts
  • Last active: Jul 07 2014 08:01 PM
  • Joined: 10 Aug 2009
There's not a convenient download link at that site. Can you post a link in this thread too please? (to the full zip, not just the compiled .exe)
Always have your scripts when you need them with Dropbox.
Sign up for free! http://db.tt/9Hrieqj