package main import ( "fmt" "os" "path/filepath" "syscall" "unsafe" ) var dll *syscall.LazyDLL func main() { dllPath := resolveDLLPath() dll = syscall.NewLazyDLL(dllPath) if err := dll.Load(); err != nil { fmt.Fprintf(os.Stderr, "load %s failed: %v\n", dllPath, err) os.Exit(1) } usbNames := enumPortNames("Port_EnumUSB") fmt.Printf("USB: %v\n", usbNames) prnNames := enumPortNames("Port_EnumPRN") fmt.Printf("PRN: %v\n", prnNames) data := []byte{0x1B, 0x40, 0x1B, 0x7B, 0x00, 'T', 'E', 'S', 'T', '\n', '\n', '\n', 0x1B, 0x69} if len(os.Args) >= 3 { fileData, err := os.ReadFile(os.Args[2]) if err != nil { fmt.Fprintf(os.Stderr, "read %s failed: %v\n", os.Args[2], err) os.Exit(1) } if !tryOpenPrint(os.Args[1], fileData) { os.Exit(1) } return } if len(os.Args) == 2 { if !tryOpenPrint(os.Args[1], data) { os.Exit(1) } return } for _, name := range prnNames { fmt.Printf("Trying PRN: %s\n", name) tryPrint(name, data) } for _, name := range usbNames { fmt.Printf("Trying USB: %s\n", name) tryOpenPrint(name, data) } } func resolveDLLPath() string { if exe, err := os.Executable(); err == nil { localPath := filepath.Join(filepath.Dir(exe), "CsnPrinterLibs.dll") if _, err := os.Stat(localPath); err == nil { return localPath } } return "CsnPrinterLibs.dll" } func enumPortNames(procName string) []string { var buf [256]byte ret, _, _ := dll.NewProc(procName).Call(uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf))) if ret == 0 { return nil } var names []string for start := 0; start < len(buf); { end := start for end < len(buf) && buf[end] != 0 { end++ } if end == start { break } names = append(names, string(buf[start:end])) start = end + 1 } return names } func tryPrint(name string, data []byte) bool { nameB := append([]byte(name), 0) h, _, _ := dll.NewProc("Port_OpenPRNIO").Call(uintptr(unsafe.Pointer(&nameB[0]))) if h == 0 { fmt.Printf(" OpenPRN failed\n") return false } defer dll.NewProc("Port_ClosePort").Call(h) dll.NewProc("Port_SetPort").Call(h) w, _, _ := dll.NewProc("WriteData").Call(uintptr(unsafe.Pointer(&data[0])), uintptr(len(data)), 3000) fmt.Printf(" WriteData: %d bytes\n", w) return int(w) == len(data) } func tryOpenPrint(name string, data []byte) bool { nameB := append([]byte(name), 0) h, _, _ := dll.NewProc("Port_OpenUSBIO").Call(uintptr(unsafe.Pointer(&nameB[0]))) if h == 0 { fmt.Printf(" OpenUSB(%s) failed\n", name) return false } defer dll.NewProc("Port_ClosePort").Call(h) dll.NewProc("Port_SetPort").Call(h) w, _, _ := dll.NewProc("WriteData").Call(uintptr(unsafe.Pointer(&data[0])), uintptr(len(data)), 3000) fmt.Printf(" USB WriteData: %d bytes\n", w) return int(w) == len(data) }