Cách tạo ứng dụng theo dõi thời gian trên Windows với AutoHotKey

Bạn bắt đầu công việc mỗi ngày từ sớm để có thể giải quyết hết mọi thứ trong ngày. Sau đó, bạn kiểm tra đồng hồ đã 3 giờ sáng mà công việc vẫn chưa làm hết. Vậy thời gian đã trôi đi đâu?

Bạn có thể sử dụng một ứng dụng theo dõi thời gian chuyên dụng, nhưng những ứng dụng này có thể phức tạp và gây khó chịu. Thay vào đó, tại sao không tạo một ứng dụng nhỏ đơn giản của riêng bạn nhỉ? Ứng dụng này có thể theo dõi tất cả các cửa sổ bạn đã sử dụng trong ngày. Bạn chỉ cần AutoHotKey, một trình xử lý văn bản cơ bản như Notepad và khoảng nửa giờ. Hãy bắt đầu nào!

Tạo script ghi nhật ký cửa sổ của riêng bạn với AutoHotKey

Trước khi bắt đầu, bạn nên cài đặt AHK trên máy tính của mình vì nó sẽ hoạt động như "trình phân tích cú pháp" cho script. Đó là công cụ sẽ cho phép script của bạn "chạy".

Lưu ý: Bạn cũng có thể biên dịch script sau khi hoàn tất để biến nó thành một chương trình thực thi thực sự. Tuy nhiên, điều đó nằm ngoài phạm vi của bài viết này.

Tải AutoHotKey từ trang web chính thức và cài đặt nó.

Chọn New > AutoHotKey Script
Chọn New > AutoHotKey Script

Kích hoạt trình quản lý file yêu thích và truy cập thư mục mà bạn muốn lưu trữ script. Sau đó, nhấp chuột phải vào một vị trí trống và chọn New > AutoHotKey Script.

Sau khi hoàn thành, đã đến lúc viết script thực tế.

1. Xác định các biến cần thiết

Mở script trong trình chỉnh sửa yêu thích. Bạn có thể sử dụng một cái gì đó đơn giản như Notepad đi kèm với Windows, còn bài viết sẽ sử dụng Notepad++ cho hướng dẫn này. Notepad++ miễn phí và được điều chỉnh tốt hơn cho mục đích này, vì vậy bạn nên dùng thử.

Lưu ý rằng bạn không nên sử dụng bất kỳ ứng dụng nào như Word hoặc Google Documents, điều này có thể ảnh hưởng đến định dạng của script. Hãy sử dụng trình soạn thảo văn bản hoặc code.

Script sẽ chứa một số thông tin cơ bản được khuyến nghị về khả năng tương thích và hiệu suất. Giữ nguyên chúng và bắt đầu script bên dưới.

Bắt đầu với:

AppLoggingRate = 10 ; Time interval (in seconds) between active window title captures.
SleepTime := AppLoggingRate * 1000
LogPath = %A_ScriptDir%
LastActiveWindow =

Bắt đầu bằng cách gán giá trị "10" cho AppLoggingRate, giá trị này sẽ được sử dụng để tính toán thời gian giữa các lần ghi nhật ký cửa sổ.

Khi được sử dụng với chức năng Sleep của AHK, 1000 gần bằng một giây. Vì vậy, bằng cách nhân nó với AppLogingRate, bạn sẽ làm cho biến SleepTime "bằng 10 giây".

LogPath là đường dẫn dùng để lưu trữ các bản ghi. Ví dụ đang sử dụng giá trị %A_ScriptDir%, giá trị này được dịch thành "thư mục từ nơi bạn chạy script". Bạn có thể sử dụng đường dẫn đầy đủ đến thư mục khác nếu muốn.

Cuối cùng, đặt LastActiveWindow thành trống và sử dụng sau để kiểm tra xem cửa sổ đang hoạt động có thay đổi hay không.

2. Giám sát các cửa sổ đang hoạt động

Vì ta muốn liên tục theo dõi cửa sổ nào đang hoạt động và nếu nó thay đổi, thì ghi lại tiêu đề và thời gian, nên sẽ phải sử dụng một “loop" (vòng lặp).

Như tên gọi cho thấy, một vòng lặp chạy liên tục, lặp lại (các) chức năng giống nhau. Nhờ cú pháp đơn giản của AHK, "code" sau đây tương đối dễ hiểu:

Loop
{
    Sleep %SleepTime%
    Msgbox, It Works!
}

Xác định một vòng lặp bằng cách chỉ cần gõ từ "loop" và sau đó đánh dấu phần đầu của nó bằng "{" và kết thúc bằng "}". Mọi thứ ở các dòng giữa "{""}" sẽ chạy vĩnh viễn cho đến khi bạn thoát khỏi script.

Bắt đầu vòng lặp bằng cách đợi (Sleep) trong một khoảng thời gian bằng với biến SleepTime. Biến này làm cho việc kiểm soát thời gian trở nên đơn giản hơn. Thay vì tự chỉnh sửa script, bạn có thể "cho" nó biết, thông qua biến này, mỗi vòng lặp sẽ kéo dài bao nhiêu giây.

Cuối cùng, sử dụng Message Box để kiểm tra script. Hãy thử lưu và chạy nó (nhấp đúp vào file script). Bạn sẽ thấy một hộp thông báo cho biết "It Works!” (script đang hoạt động) sau 10 giây.

Nhấp chuột phải vào biểu tượng của AHK trong khay Windows và thoát khỏi script khi bạn đã có đủ hộp thông báo. Sau đó, quay lại trình soạn thảo và thay thế dòng MsgBox bằng:

WinGetActiveTitle, ActiveWindow

Đây là lệnh để lấy tiêu đề của cửa sổ đang hoạt động. Bỏ qua dòng "StoreActiveWindow" bổ sung mà ví dụ đã sử dụng trong khi viết script để thử nghiệm.

Lấy tiêu đề của cửa sổ đang hoạt động và lưu trữ nó trong một biến
Lấy tiêu đề của cửa sổ đang hoạt động và lưu trữ nó trong một biến

3. Lấy thời gian và tên hiện tại

Bây giờ đến phần cốt lõi của logic script. So sánh tên của cửa sổ đang hoạt động với tên trước đó và nếu chúng khác nhau, hãy "làm gì đó". Mọi thứ đơn giản như sau:

If ActiveWindow != %LastActiveWindow%
{
}

Với những điều trên, kiểm tra xem ActiveWindow hiện tại có khác (!=) với giá trị được lưu trữ trong biến LastActiveWindow (mà ban đầu được đặt thành trống) hay không. Nếu đúng như vậy, AHK sẽ thực thi code giữa {}, hiện đang trống.

Thiết lập chức năng so sánh tiêu đề của cửa sổ đang hoạt động và cửa sổ trước đó
Thiết lập chức năng so sánh tiêu đề của cửa sổ đang hoạt động và cửa sổ trước đó

Cần theo dõi cả ngày và giờ để đo thời gian hoạt động của một cửa sổ. Các nhật ký khác nhau cho mỗi ngày, sử dụng ngày trong tên của chúng sẽ được giữ lại. Không chỉ mọi thay đổi mà thời điểm nó xảy ra cũng sẽ được ghi lại. Để làm điều đó, hãy gán những định dạng thời gian khác nhau cho các biến LogTimeLogFilename, với:

FormatTime, LogTime,, HH:mm:ss
FormatTime, LogFilename,, yyyy-MMM-dd

Thêm các dòng đó vào giữa các dấu ngoặc nhọn trong "If ActiveWindow...", để AHK chạy chúng khi phát hiện thay đổi cửa sổ.

Lấy thời gian hiện tại và gán nó trong hai biến có định dạng khác nhau
Lấy thời gian hiện tại và gán nó trong hai biến có định dạng khác nhau

4. Định dạng dữ liệu

Hiện ta đã nắm bắt thời gian trong hai biến được định dạng khác nhau, cũng như tiêu đề của cửa sổ đang hoạt động. Tuy nhiên, có một vấn đề nhỏ: Tiêu đề của cửa sổ cũng có thể chứa các ký tự không mong muốn. Có thể xóa tất cả các ký tự không phải chữ và số bằng cách sử dụng hỗ trợ của AHK cho RegEx, với:

LogWindow := Regexreplace(ActiveWindow, "[^a-zA-Z0-9]", " ")

Với điều này, hãy "yêu cầu" AHK xóa tất cả các ký tự khỏi biến ActiveWindow không khớp với những gì trong dấu ngoặc:

  • Chữ viết thường
  • Chữ viết hoa
  • Con số

Sau đó, gán kết quả cho biến LogWindow.

Dọn dẹp tiêu đề của cửa sổ đang hoạt động với RegEx
Dọn dẹp tiêu đề của cửa sổ đang hoạt động với RegEx

Với tất cả các biến được đặt và tất cả dữ liệu có giá trị được thu thập, hiện bạn đã sẵn sàng định dạng file nhật ký và nội dung của nó.

LogFilename = %LogFilename%_AppLog.md
LogFile = %LogPath%\%LogFilename%

Trước đây, ta đã gán ngày hiện tại cho biến LogFilename. Do đó, với dòng đầu tiên, hãy thêm "_AppLog.md" vào ngày để sử dụng nó làm tên file.

Thiết lập tên file nhật ký
Thiết lập tên file nhật ký

Trong dòng thứ hai, kết hợp biến LogPath, đã xác định ở đầu làm đích cho file nhật ký đi kèm với tên file. Sự kết hợp của chúng là tên đường dẫn đầy đủ của file nhật ký, được gán cho biến LogFile.

Hãy gán giá trị tương đương của "empty line, Time - Window's Name, two more empty lines, a divider, and another empty line, for good measure" cho biến FileContent.

FileContent = `n%LogTime% - %LogWindow%`n`n- - -`n
  • Chữ "n" yêu cầu AHK nhập một dòng mới (tương đương với việc nhấn Enter một lần).
  • Ba dấu gạch ngang sẽ xuất hiện như một dải phân cách khi được hiển thị trong trình xem tương thích với dấu xuống.
  • "% LogTime%" và "% LogWindow%" là các biến đã lưu trữ tên của cửa sổ đang hoạt động và thời gian nó được phát hiện.
Xác định nội dung của file nhật ký
Xác định nội dung của file nhật ký

5. Cập nhật file

Bạn đã xác định những gì chúng tôi muốn ghi vào file, cũng như đường dẫn và tên file của nó. Tất cả những gì còn lại là văn bản thực tế, đơn giản như sau:

FileAppend, %FileContent%, %LogFile%

Nối mọi thứ trong biến "FileContent" vào file "LogFile".

Sử dụng chức năng Append (nối) của AHK để cập nhật file nhật ký hoặc tạo một file từ đầu
Sử dụng chức năng Append (nối) của AHK để cập nhật file nhật ký hoặc tạo một file từ đầu

Hàm "append" sẽ thêm "FileContent" vào file nếu nó tồn tại, nhưng cũng sẽ tạo từ đầu nếu file không tồn tại.

Có một tinh chỉnh cuối cùng: thay thế nội dung của biến LastActiveWindow bằng cửa sổ hiện đang hoạt động.

Chèn tiêu đề của cửa sổ hoạt động hiện tại vào biến LastActiveWindow để kiểm tra trong tương lai
Chèn tiêu đề của cửa sổ hoạt động hiện tại vào biến LastActiveWindow để kiểm tra trong tương lai

Để làm điều này, script sẽ có thể phát hiện thay đổi cửa sổ tiếp theo.

LastActiveWindow = %ActiveWindow%

Và với lần bổ sung cuối cùng đó, trình ghi nhật ký cửa sổ đã sẵn sàng! Lưu lại script và chạy nó. Sau đó, kiểm tra file markdown, file này sẽ xuất hiện trong thư mục file script sau 10 giây.

File nhật ký cửa sổ được tạo trong cùng thư mục với script
File nhật ký cửa sổ được tạo trong cùng thư mục với script

Tự mình làm chủ thời gian

Bạn có thể mở file nhật ký bằng bất kỳ trình soạn thảo văn bản nào. Tuy nhiên, nó sẽ trông đẹp hơn nếu bạn mở trong một trình chỉnh sửa tương thích với markdown. Trong ảnh chụp màn hình, bạn có thể thấy nhật ký trong trình chỉnh sửa Typora phổ biến.

File markdown tạo ra bởi script được load trong Typora
File markdown tạo ra bởi script được load trong Typora

Đó là một cách dễ dàng để kiểm tra ứng dụng nào bạn đã sử dụng nhiều thời gian nhất và chỉ cần một công cụ đó như Notepad để sử dụng.

Nếu bạn muốn thứ gì đó "đặc biệt hơn", bạn luôn có thể "tạo phong cách" cho đầu ra của trình ghi nhật ký để tạo file CSV thay thế. Dễ dàng như điều chỉnh biến FileContent và phần mở rộng của file đã tạo. Sau đó, bạn có thể nhập các file như vậy vào các ứng dụng như Excel, Google Calc hoặc thậm chí là trình theo dõi thời gian của bên thứ ba.

Script hoàn chỉnh

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
; Variables
; ---------
AppLoggingRate = 10 ; Time interval (in seconds) between active window title captures.
SleepTime := AppLoggingRate * 1000
LogPath = %A_ScriptDir%
LastActiveWindow = 
; Logic
; -----
Loop
{
	Sleep %SleepTime%
	
	WinGetActiveTitle, ActiveWindow
	StoreActiveWindow = %ActiveWindow%
	
	If ActiveWindow != %LastActiveWindow%
	{
		FormatTime, LogTime,, HH:mm:ss
		FormatTime, LogFilename, , yyyy-MM-dd
		
		LogWindow := Regexreplace(ActiveWindow, "[^a-zA-Z0-9]", " ")
		
		LogFilename = %LogFilename%_AppLog.md
		LogFile = %LogPath%\%LogFilename%
		
		FileContent = `n%LogTime% - %LogWindow%`n`n- - -`n
		
		sleep 50
		
		FileAppend, %FileContent%, %LogFile%
		LastActiveWindow = %ActiveWindow%
	}
}
Exit
Thứ Tư, 01/12/2021 08:07
55 👨 180
0 Bình luận
Sắp xếp theo