Reset navicat trial
Reset the Navicat trial time on Mac.
#!/bin/bash
set -uo pipefail
# ==========================================
# 變數定義 / Variables Definition
# ==========================================
readonly APP_NAME="Navicat Premium"
readonly APP_SUPPORT_DIR="$HOME/Library/Application Support/PremiumSoft CyberTech/Navicat CC/Navicat Premium"
readonly PLIST_FILE="$HOME/Library/Preferences/com.navicat.NavicatPremium.plist"
readonly KEYCHAIN_SERVICE="com.navicat.NavicatPremium"
readonly HASH_REGEX="^[0-9A-F]{32}$"
# ==========================================
# 日誌函數 / Logging Functions
# ==========================================
log_info() { echo -e "[\033[34mINFO\033[0m] $1"; }
log_success() { echo -e "[\033[32mSUCCESS\033[0m] $1"; }
log_warn() { echo -e "[\033[33mWARN\033[0m] $1"; }
# ==========================================
# 功能函數 / Functional Modules
# ==========================================
# 1. 終止應用程式 / Terminate Application
terminate_app() {
log_info "正在檢查並終止 $APP_NAME 程序... / Checking and terminating $APP_NAME process..."
if pkill -9 "$APP_NAME" 2>/dev/null; then
log_success "已成功終止正在執行的 $APP_NAME 程序。/ Successfully terminated running process."
else
log_info "$APP_NAME 程序未在執行。/ Process is not running."
fi
}
# 2. 清理應用程式支援目錄的雜湊檔案 / Clean hash files in App Support
clean_support_files() {
log_info "清理應用程式支援目錄的雜湊檔案... / Cleaning hash files in app support directory..."
if [[ ! -d "$APP_SUPPORT_DIR" ]]; then
log_warn "目錄不存在,跳過: $APP_SUPPORT_DIR / Directory not found, skipping."
return
fi
local deleted_count=0
while IFS= read -r file; do
local filename
filename=$(basename "$file")
# 匹配以 . 開頭且後面跟著 32 位大寫十六進位字元的檔案
if echo "${filename#.}" | grep -Eq "$HASH_REGEX"; then
rm -f "$file"
log_info "已刪除雜湊檔案: $filename / Deleted hash file: $filename"
((deleted_count++))
fi
done < <(find "$APP_SUPPORT_DIR" -maxdepth 1 -type f -name '.[0-9A-F]*' 2>/dev/null)
log_success "應用程式支援目錄清理完成,共刪除 $deleted_count 個檔案。/ Cleaned $deleted_count files."
}
# 3. 處理偏好設定檔案 / Clean preferences plist file
clean_plist_keys() {
log_info "處理偏好設定檔案... / Processing preferences plist file..."
if [[ ! -f "$PLIST_FILE" ]]; then
log_warn "偏好設定檔案不存在: $PLIST_FILE / Plist file not found."
return
fi
# 獲取所有符合 32 位元雜湊格式的頂層鍵值
local keys_to_delete
keys_to_delete=$(/usr/libexec/PlistBuddy -c "Print" "$PLIST_FILE" 2>/dev/null | grep -Eoa "^\s{4}[0-9A-F]{32}" | tr -d ' ' || true)
if [[ -z "$keys_to_delete" ]]; then
log_info "未找到需要刪除的 32 位元雜湊鍵值。/ No 32-character hash keys found."
return
fi
local deleted_count=0
while IFS= read -r key; do
if /usr/libexec/PlistBuddy -c "Delete :$key" "$PLIST_FILE" 2>/dev/null; then
log_info "已刪除 Plist 鍵值: $key / Deleted Plist key: $key"
((deleted_count++))
fi
done <<< "$keys_to_delete"
log_success "偏好設定清理完成,共刪除 $deleted_count 個鍵值。/ Cleaned $deleted_count keys."
}
# 4. 清理鑰匙圈中的試用期追蹤項目 / Clean Keychain entries
clean_keychain() {
log_info "清理鑰匙圈中的試用期追蹤項目... / Cleaning trial tracking entries in Keychain..."
local keychain_accounts
keychain_accounts=$(security dump-keychain ~/Library/Keychains/login.keychain-db 2>/dev/null | \
awk '/0x00000007.*'"$KEYCHAIN_SERVICE"'/{found=1} found && /"acct"/{print; found=0}' | \
sed 's/.*<blob>="\([^"]*\)".*/\1/')
if [[ -z "$keychain_accounts" ]]; then
log_info "未找到需要刪除的鑰匙圈項目。/ No keychain entries found."
return
fi
local deleted_count=0
while IFS= read -r account; do
if echo "$account" | grep -Eq "$HASH_REGEX"; then
if security delete-generic-password -s "$KEYCHAIN_SERVICE" -a "$account" >/dev/null 2>&1; then
log_info "已刪除鑰匙圈項目: $account / Deleted keychain entry: $account"
((deleted_count++))
fi
fi
done <<< "$keychain_accounts"
log_success "鑰匙圈清理完成,共刪除 $deleted_count 個項目。/ Deleted $deleted_count keychain entries."
}
# ==========================================
# 主程式執行 / Main Execution
# ==========================================
main() {
echo "=================================================="
echo " Navicat Premium 重設腳本 / Reset Script"
echo "=================================================="
terminate_app
clean_support_files
clean_plist_keys
clean_keychain
echo "=================================================="
log_success "所有清理任務已完成!/ All cleaning tasks completed!"
}
# 執行主程式
main