PUGE 1 mēnesi atpakaļ
revīzija
c5a67cc620
5 mainītis faili ar 438 papildinājumiem un 0 dzēšanām
  1. 2 0
      .gitattributes
  2. 1 0
      .gitignore
  3. 35 0
      go.mod
  4. 67 0
      go.sum
  5. 333 0
      main.go

+ 2 - 0
.gitattributes

@@ -0,0 +1,2 @@
+# Auto detect text files and perform LF normalization
+* text=auto

+ 1 - 0
.gitignore

@@ -0,0 +1 @@
+*.exe

+ 35 - 0
go.mod

@@ -0,0 +1,35 @@
+module autoSelectFile
+
+go 1.25.6
+
+require (
+	github.com/dblohm7/wingoes v0.0.0-20250822163801-6d8e6105c62d // indirect
+	github.com/ebitengine/purego v0.9.1 // indirect
+	github.com/gen2brain/shm v0.1.1 // indirect
+	github.com/go-ole/go-ole v1.3.0 // indirect
+	github.com/go-vgo/robotgo v1.0.0 // indirect
+	github.com/godbus/dbus/v5 v5.2.0 // indirect
+	github.com/jezek/xgb v1.2.0 // indirect
+	github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 // indirect
+	github.com/lxn/walk v0.0.0-20210112085537-c389da54e794 // indirect
+	github.com/lxn/win v0.0.0-20210218163916-a377121e959e // indirect
+	github.com/micmonay/keybd_event v1.1.2 // indirect
+	github.com/otiai10/gosseract/v2 v2.4.1 // indirect
+	github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
+	github.com/robotn/xgb v0.10.0 // indirect
+	github.com/robotn/xgbutil v0.10.0 // indirect
+	github.com/shirou/gopsutil/v4 v4.25.10 // indirect
+	github.com/tailscale/win v0.0.0-20250627215312-f4da2b8ee071 // indirect
+	github.com/tklauser/go-sysconf v0.3.16 // indirect
+	github.com/tklauser/numcpus v0.11.0 // indirect
+	github.com/vcaesar/gops v0.41.0 // indirect
+	github.com/vcaesar/imgo v0.41.0 // indirect
+	github.com/vcaesar/keycode v0.10.1 // indirect
+	github.com/vcaesar/screenshot v0.11.1 // indirect
+	github.com/vcaesar/tt v0.20.1 // indirect
+	github.com/yusufpapurcu/wmi v1.2.4 // indirect
+	golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39 // indirect
+	golang.org/x/image v0.33.0 // indirect
+	golang.org/x/sys v0.38.0 // indirect
+	gopkg.in/Knetic/govaluate.v3 v3.0.0 // indirect
+)

+ 67 - 0
go.sum

@@ -0,0 +1,67 @@
+github.com/BurntSushi/freetype-go v0.0.0-20160129220410-b763ddbfe298/go.mod h1:D+QujdIlUNfa0igpNMk6UIvlb6C252URs4yupRUV4lQ=
+github.com/BurntSushi/graphics-go v0.0.0-20160129215708-b43f31a4a966/go.mod h1:Mid70uvE93zn9wgF92A/r5ixgnvX8Lh68fxp9KQBaI0=
+github.com/dblohm7/wingoes v0.0.0-20250822163801-6d8e6105c62d h1:QRKpU+9ZBDs62LyBfwhZkJdB5DJX2Sm3p4kUh7l1aA0=
+github.com/dblohm7/wingoes v0.0.0-20250822163801-6d8e6105c62d/go.mod h1:SUxUaAK/0UG5lYyZR1L1nC4AaYYvSSYTWQSH3FPcxKU=
+github.com/ebitengine/purego v0.9.1 h1:a/k2f2HQU3Pi399RPW1MOaZyhKJL9w/xFpKAg4q1s0A=
+github.com/ebitengine/purego v0.9.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
+github.com/gen2brain/shm v0.1.1 h1:1cTVA5qcsUFixnDHl14TmRoxgfWEEZlTezpUj1vm5uQ=
+github.com/gen2brain/shm v0.1.1/go.mod h1:UgIcVtvmOu+aCJpqJX7GOtiN7X2ct+TKLg4RTxwPIUA=
+github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
+github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
+github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
+github.com/go-vgo/robotgo v1.0.0 h1:LTzPB8cQsP0E/iMMrh3sPhH9LgywyuuJHGPHk70UA74=
+github.com/go-vgo/robotgo v1.0.0/go.mod h1:NcSL/tqNqkpWJ3rmT6YSDUVhQKZwyRsaanDMO4qkT5I=
+github.com/godbus/dbus/v5 v5.2.0 h1:3WexO+U+yg9T70v9FdHr9kCxYlazaAXUhx2VMkbfax8=
+github.com/godbus/dbus/v5 v5.2.0/go.mod h1:3AAv2+hPq5rdnr5txxxRwiGjPXamgoIHgz9FPBfOp3c=
+github.com/jezek/xgb v1.2.0 h1:LzgkD11wOrPnxXEqo588cnjUt4NwMHrFh/tgajo50Q0=
+github.com/jezek/xgb v1.2.0/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk=
+github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 h1:PwQumkgq4/acIiZhtifTV5OUqqiP82UAl0h87xj/l9k=
+github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg=
+github.com/lxn/walk v0.0.0-20210112085537-c389da54e794 h1:NVRJ0Uy0SOFcXSKLsS65OmI1sgCCfiDUPj+cwnH7GZw=
+github.com/lxn/walk v0.0.0-20210112085537-c389da54e794/go.mod h1:E23UucZGqpuUANJooIbHWCufXvOcT6E7Stq81gU+CSQ=
+github.com/lxn/win v0.0.0-20210218163916-a377121e959e h1:H+t6A/QJMbhCSEH5rAuRxh+CtW96g0Or0Fxa9IKr4uc=
+github.com/lxn/win v0.0.0-20210218163916-a377121e959e/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk=
+github.com/micmonay/keybd_event v1.1.2 h1:RpgvPJKOh4Jc+ZYe0OrVzGd2eNMCfuVg3dFTCsuSah4=
+github.com/micmonay/keybd_event v1.1.2/go.mod h1:CGMWMDNgsfPljzrAWoybUOSKafQPZpv+rLigt2LzNGI=
+github.com/otiai10/gosseract/v2 v2.4.1 h1:G8AyBpXEeSlcq8TI85LH/pM5SXk8Djy2GEXisgyblRw=
+github.com/otiai10/gosseract/v2 v2.4.1/go.mod h1:1gNWP4Hgr2o7yqWfs6r5bZxAatjOIdqWxJLWsTsembk=
+github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
+github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
+github.com/robotn/xgb v0.0.0-20190912153532-2cb92d044934/go.mod h1:SxQhJskUJ4rleVU44YvnrdvxQr0tKy5SRSigBrCgyyQ=
+github.com/robotn/xgb v0.10.0 h1:O3kFbIwtwZ3pgLbp1h5slCQ4OpY8BdwugJLrUe6GPIM=
+github.com/robotn/xgb v0.10.0/go.mod h1:SxQhJskUJ4rleVU44YvnrdvxQr0tKy5SRSigBrCgyyQ=
+github.com/robotn/xgbutil v0.10.0 h1:gvf7mGQqCWQ68aHRtCxgdewRk+/KAJui6l3MJQQRCKw=
+github.com/robotn/xgbutil v0.10.0/go.mod h1:svkDXUDQjUiWzLrA0OZgHc4lbOts3C+uRfP6/yjwYnU=
+github.com/shirou/gopsutil/v4 v4.25.10 h1:at8lk/5T1OgtuCp+AwrDofFRjnvosn0nkN2OLQ6g8tA=
+github.com/shirou/gopsutil/v4 v4.25.10/go.mod h1:+kSwyC8DRUD9XXEHCAFjK+0nuArFJM0lva+StQAcskM=
+github.com/tailscale/win v0.0.0-20250627215312-f4da2b8ee071 h1:qo7kOhoN5DHioXNlFytBzIoA5glW6lsb8YqV0lP3IyE=
+github.com/tailscale/win v0.0.0-20250627215312-f4da2b8ee071/go.mod h1:aMd4yDHLjbOuYP6fMxj1d9ACDQlSWwYztcpybGHCQc8=
+github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA=
+github.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI=
+github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw=
+github.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ=
+github.com/vcaesar/gops v0.41.0 h1:FG748Jyw3FOuZnbzSgB+CQSx2e5LbLCPWV2JU1brFdc=
+github.com/vcaesar/gops v0.41.0/go.mod h1:/3048L7Rj7QjQKTSB+kKc7hDm63YhTWy5QJ10TCP37A=
+github.com/vcaesar/imgo v0.41.0 h1:kNLYGrThXhB9Dd6IwFmfPnxq9P6yat2g7dpPjr7OWO8=
+github.com/vcaesar/imgo v0.41.0/go.mod h1:/LGOge8etlzaVu/7l+UfhJxR6QqaoX5yeuzGIMfWb4I=
+github.com/vcaesar/keycode v0.10.1 h1:0DesGmMAPWpYTCYddOFiCMKCDKgNnwiQa2QXindVUHw=
+github.com/vcaesar/keycode v0.10.1/go.mod h1:JNlY7xbKsh+LAGfY2j4M3znVrGEm5W1R8s/Uv6BJcfQ=
+github.com/vcaesar/screenshot v0.11.1 h1:GgPuN89XC4Yh38dLx4quPlSo3YiWWhwIria/j3LtrqU=
+github.com/vcaesar/screenshot v0.11.1/go.mod h1:gJNwHBiP1v1v7i8TQ4yV1XJtcyn2I/OJL7OziVQkwjs=
+github.com/vcaesar/tt v0.20.1 h1:D/jUeeVCNbq3ad8M7hhtB3J9x5RZ6I1n1eZ0BJp7M+4=
+github.com/vcaesar/tt v0.20.1/go.mod h1:cH2+AwGAJm19Wa6xvEa+0r+sXDJBT0QgNQey6mwqLeU=
+github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
+github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
+golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39 h1:DHNhtq3sNNzrvduZZIiFyXWOL9IWaDPHqTnLJp+rCBY=
+golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39/go.mod h1:46edojNIoXTNOhySWIWdix628clX9ODXwPsQuG6hsK0=
+golang.org/x/image v0.33.0 h1:LXRZRnv1+zGd5XBUVRFmYEphyyKJjQjCRiOuAP3sZfQ=
+golang.org/x/image v0.33.0/go.mod h1:DD3OsTYT9chzuzTQt+zMcOlBHgfoKQb1gry8p76Y1sc=
+golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13 h1:5jaG59Zhd+8ZXe8C+lgiAGqkOaZBruqrWclLkgAww34=
+golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
+golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
+gopkg.in/Knetic/govaluate.v3 v3.0.0 h1:18mUyIt4ZlRlFZAAfVetz4/rzlJs9yhN+U02F4u1AOc=
+gopkg.in/Knetic/govaluate.v3 v3.0.0/go.mod h1:csKLBORsPbafmSCGTEh3U7Ozmsuq8ZSIlKk1bcqph0E=

+ 333 - 0
main.go

@@ -0,0 +1,333 @@
+package main
+
+import (
+	"encoding/json"
+	"fmt"
+	"log"
+	"net/http"
+	"os/exec"
+	"syscall"
+	"time"
+	"unsafe"
+)
+
+type RequestData struct {
+	Type     string `json:"type"`
+	Path     string `json:"path"`
+	FileName string `json:"fileName"`
+}
+
+// 常量
+const (
+	VK_CONTROL = 0x11
+	VK_V       = 0x56
+)
+
+var (
+	user32 = syscall.NewLazyDLL("user32.dll")
+
+	findWindowW         = user32.NewProc("FindWindowW")
+	moveWindow          = user32.NewProc("MoveWindow")
+	setForegroundWindow = user32.NewProc("SetForegroundWindow")
+	getWindowRect       = user32.NewProc("GetWindowRect")
+	setCursorPos        = user32.NewProc("SetCursorPos")
+	mouse_event         = user32.NewProc("mouse_event")
+	keybd_event         = user32.NewProc("keybd_event")
+)
+
+type RECT struct {
+	Left   int32
+	Top    int32
+	Right  int32
+	Bottom int32
+}
+
+// 回车键的虚拟键码
+const VK_RETURN = 0x0D
+const KEYEVENTF_KEYUP = 0x0002
+
+// 简化函数
+func FindWindow(title string) (uintptr, error) {
+	titlePtr, err := syscall.UTF16PtrFromString(title)
+	if err != nil {
+		return 0, err
+	}
+
+	hwnd, _, err := findWindowW.Call(0, uintptr(unsafe.Pointer(titlePtr)))
+	if hwnd == 0 {
+		return 0, fmt.Errorf("窗口未找到: %v", err)
+	}
+	return hwnd, nil
+}
+
+func MoveWindow(hwnd uintptr, x, y, w, h int32) error {
+	ret, _, err := moveWindow.Call(hwnd, uintptr(x), uintptr(y), uintptr(w), uintptr(h), 1)
+	if ret == 0 {
+		return fmt.Errorf("移动窗口失败: %v", err)
+	}
+	return nil
+}
+
+func SetForegroundWindow(hwnd uintptr) error {
+	ret, _, err := setForegroundWindow.Call(hwnd)
+	if ret == 0 {
+		return fmt.Errorf("设置前台窗口失败: %v", err)
+	}
+	return nil
+}
+
+func GetWindowRect(hwnd uintptr) (RECT, error) {
+	var rect RECT
+	ret, _, err := getWindowRect.Call(hwnd, uintptr(unsafe.Pointer(&rect)))
+	if ret == 0 {
+		return rect, fmt.Errorf("获取窗口矩形失败: %v", err)
+	}
+	return rect, nil
+}
+
+func SetCursorPos(x, y int32) error {
+	ret, _, err := setCursorPos.Call(uintptr(x), uintptr(y))
+	if ret == 0 {
+		return fmt.Errorf("设置光标位置失败: %v", err)
+	}
+	return nil
+}
+
+func MouseClick(x, y int32) error {
+	// 移动鼠标
+	if err := SetCursorPos(x, y); err != nil {
+		return err
+	}
+
+	time.Sleep(100 * time.Millisecond)
+
+	// 左键按下 (0x0002 = MOUSEEVENTF_LEFTDOWN)
+	mouse_event.Call(2, 0, 0, 0, 0)
+	time.Sleep(50 * time.Millisecond)
+
+	// 左键释放 (0x0004 = MOUSEEVENTF_LEFTUP)
+	mouse_event.Call(4, 0, 0, 0, 0)
+
+	return nil
+}
+
+func Paste() {
+	// Ctrl 按下
+	keybd_event.Call(uintptr(VK_CONTROL), 0, 0, 0)
+	time.Sleep(50 * time.Millisecond)
+
+	// V 按下
+	keybd_event.Call(uintptr(VK_V), 0, 0, 0)
+	time.Sleep(50 * time.Millisecond)
+
+	// V 释放 (0x0002 = KEYEVENTF_KEYUP)
+	keybd_event.Call(uintptr(VK_V), 0, 2, 0)
+	time.Sleep(50 * time.Millisecond)
+
+	// Ctrl 释放
+	keybd_event.Call(uintptr(VK_CONTROL), 0, 2, 0)
+}
+
+func PressEnter() {
+	// 按下回车键
+	keybd_event.Call(
+		uintptr(VK_RETURN), // bVk
+		0,                  // bScan
+		0,                  // dwFlags (按下)
+		0,                  // dwExtraInfo
+	)
+
+	time.Sleep(5 * time.Millisecond)
+
+	// 释放回车键
+	keybd_event.Call(
+		uintptr(VK_RETURN),       // bVk
+		0,                        // bScan
+		uintptr(KEYEVENTF_KEYUP), // dwFlags (释放)
+		0,                        // dwExtraInfo
+	)
+}
+
+// 使用系统命令设置剪贴板(更可靠)
+func SetClipboard(text string) error {
+	// 方法1:使用 clip 命令
+	cmd := exec.Command("cmd", "/c", fmt.Sprintf("echo %s | clip", text))
+	if err := cmd.Run(); err == nil {
+		return nil
+	}
+
+	// 方法2:使用 PowerShell
+	cmd2 := exec.Command("powershell", "-Command", fmt.Sprintf("Set-Clipboard -Value '%s'", text))
+	return cmd2.Run()
+}
+
+func findAndOperateWindow(title string, filePath string, fileName string) {
+	fmt.Printf("开始查找窗口: %s\n", title)
+
+	var hwnd uintptr
+	var err error
+	found := false
+
+	// 10秒内每秒尝试查找窗口
+	for i := 0; i < 10; i++ {
+		fmt.Printf("尝试第 %d 次查找...\n", i+1)
+
+		hwnd, err = FindWindow(title)
+		if err == nil && hwnd != 0 {
+			found = true
+			fmt.Printf("找到窗口: %s (句柄: 0x%X)\n", title, hwnd)
+			break
+		}
+
+		time.Sleep(1 * time.Second)
+	}
+
+	if !found {
+		log.Printf("在10秒内未找到窗口: %s", title)
+		log.Println("请确保:")
+		log.Println("1. 窗口已经打开")
+		log.Println("2. 窗口标题完全匹配: " + title)
+		log.Println("3. 可能需要以管理员身份运行此程序")
+		return
+	}
+
+	// 激活窗口
+	if err := SetForegroundWindow(hwnd); err != nil {
+		log.Printf("激活窗口失败: %v", err)
+	}
+	time.Sleep(500 * time.Millisecond)
+
+	// 调整窗口大小到800x600
+	fmt.Println("正在修改窗口大小为800x600...")
+	if err := MoveWindow(hwnd, 100, 100, 800, 600); err != nil {
+		log.Printf("调整窗口大小失败: %v", err)
+	} else {
+		fmt.Println("窗口大小修改成功")
+	}
+
+	// 获取窗口位置
+	rect, err := GetWindowRect(hwnd)
+	if err != nil {
+		log.Printf("获取窗口位置失败: %v", err)
+	} else {
+		fmt.Printf("窗口位置: X=%d, Y=%d\n", rect.Left, rect.Top)
+	}
+
+	// 等待窗口调整完成
+	time.Sleep(500 * time.Millisecond)
+
+	MouseClick(rect.Left+450, rect.Top+60)
+
+	SetClipboard(filePath)
+
+	time.Sleep(500 * time.Millisecond)
+
+	// 粘贴剪贴板内容
+	fmt.Println("正在粘贴剪贴板内容...")
+	Paste()
+	fmt.Println("粘贴完成")
+	time.Sleep(500 * time.Millisecond)
+	fmt.Println("按回车键")
+	PressEnter()
+	fmt.Println("操作完成")
+	MouseClick(rect.Left+450, rect.Top+530)
+	time.Sleep(2 * time.Second)
+	SetClipboard(fileName)
+	time.Sleep(500 * time.Millisecond)
+	Paste()
+	time.Sleep(500 * time.Millisecond)
+	PressEnter()
+}
+
+func handlePostRequest(w http.ResponseWriter, r *http.Request) {
+	// 只处理POST请求
+	if r.Method != http.MethodPost {
+		http.Error(w, "只支持POST请求", http.StatusMethodNotAllowed)
+		return
+	}
+
+	// 解析JSON数据
+	var data RequestData
+	decoder := json.NewDecoder(r.Body)
+	if err := decoder.Decode(&data); err != nil {
+		http.Error(w, "JSON解析错误: "+err.Error(), http.StatusBadRequest)
+		return
+	}
+	defer r.Body.Close()
+
+	// 输出接收到的数据
+	fmt.Println("=== 接收到POST请求数据 ===")
+	fmt.Printf("类型 (type): %s\n", data.Type)
+	fmt.Printf("路径 (path): %s\n", data.Path)
+	fmt.Printf("文件名 (fileName): %s\n", data.FileName)
+	fmt.Println("==========================")
+
+	// 根据type执行不同操作
+	if data.Type == "openFile" {
+		// 在新goroutine中执行窗口操作,避免阻塞HTTP响应
+		go func() {
+			findAndOperateWindow("打开", data.Path, data.FileName)
+		}()
+
+		// 返回响应
+		w.Header().Set("Content-Type", "application/json")
+		response := map[string]interface{}{
+			"status":  "processing",
+			"message": "正在执行窗口操作",
+			"data":    data,
+		}
+		json.NewEncoder(w).Encode(response)
+		return
+	}
+
+	// 返回成功响应
+	w.Header().Set("Content-Type", "application/json")
+	response := map[string]interface{}{
+		"status":  "success",
+		"message": "数据接收成功",
+		"data":    data,
+	}
+	json.NewEncoder(w).Encode(response)
+}
+
+func main() {
+	fmt.Println("窗口操作服务启动...")
+	fmt.Println("注意:某些窗口操作可能需要管理员权限")
+	fmt.Println("如果需要,请以管理员身份运行此程序")
+	fmt.Println()
+
+	// 设置处理POST请求的路由
+	http.HandleFunc("/", handlePostRequest)
+
+	// 设置服务器监听8866端口
+	port := ":8866"
+	fmt.Printf("服务器正在监听端口 %s ...\n", port)
+	fmt.Println("等待POST请求...")
+	fmt.Println()
+
+	// 启动HTTP服务器
+	if err := http.ListenAndServe(port, nil); err != nil {
+		log.Fatal("服务器启动失败:", err)
+	}
+}
+
+// 前端JS请求示例
+// const myHeaders = new Headers();
+// myHeaders.append("Content-Type", "application/json");
+
+// const raw = JSON.stringify({
+//   "type": "openFile",
+//   "path": "C:\\Users\\mail\\Downloads",
+//   "fileName": "128.png"
+// });
+
+// const requestOptions = {
+//   method: "POST",
+//   headers: myHeaders,
+//   body: raw,
+// };
+
+// fetch("http://127.0.0.1:8866/", requestOptions)
+//   .then((response) => response.text())
+//   .then((result) => console.log(result))
+//   .catch((error) => console.error(error));