• golang 调用windows API 中文的处理


    Go语言发展势头很猛,其实缺点也很多,好在有广大爱好者提供了无数的库,把优点表现得太好了,搞得什么都是拿来就使用,基本完全不理会指针,性能还不错。

    最近在windows下使用遇到一个中文的问题,首先要了解的是Golang的编码是utf-8的,而中文windows的API返回时多字节的GBK编码。

    下面是利用API 获得进程的示例,代码是网上的,但是使用时出现了,当进程名是中文时出现的乱码问题。

    先贴代码。

    package utilities
    
    import (
    	"bytes"
    	"io"
    	"log"
    	"net/http"
    	"sort"
    	"strconv"
    	"strings"
    	"syscall"
    
    	//	"unicode/utf8"
    	"unsafe"
    
    	"github.com/axgle/mahonia"
    )
    
    type ulong int32
    type ulong_ptr uintptr
    
    type PROCESSENTRY32 struct {
    	dwSize              ulong
    	cntUsage            ulong
    	th32ProcessID       ulong
    	th32DefaultHeapID   ulong_ptr
    	th32ModuleID        ulong
    	cntThreads          ulong
    	th32ParentProcessID ulong
    	pcPriClassBase      ulong
    	dwFlags             ulong
    	szExeFile           [260]byte
    }
    
    type ProcessStruct struct {
    	processName string // 进程名称
    	processID   int    // 进程id
    }
    
    type ProcessStructSlice []ProcessStruct
    
    func (a ProcessStructSlice) Len() int { // 重写 Len() 方法
    	return len(a)
    }
    func (a ProcessStructSlice) Swap(i, j int) { // 重写 Swap() 方法
    	a[i], a[j] = a[j], a[i]
    }
    func (a ProcessStructSlice) Less(i, j int) bool { // 重写 Less() 方法, 从大到小排序
    	if strings.Compare(a[j].processName, a[i].processName) < 0 {
    		return true
    	} else {
    		return false
    	}
    }
    
    func Upayin_process(w http.ResponseWriter, r *http.Request) {
    	r.ParseForm()
    	_, err := r.Form["callsys"]
    	if !err {
    		io.WriteString(w, "err")
    		return
    	}
    
    	kernel32 := syscall.NewLazyDLL("kernel32.dll")
    	CreateToolhelp32Snapshot := kernel32.NewProc("CreateToolhelp32Snapshot")
    	pHandle, _, _ := CreateToolhelp32Snapshot.Call(uintptr(0x2), uintptr(0x0))
    	if int(pHandle) == -1 {
    		io.WriteString(w, "get process err")
    		return
    	}
    	var data []ProcessStruct
    	var buffer bytes.Buffer
    
    	decoder := mahonia.NewDecoder("gbk")
    
    	Process32Next := kernel32.NewProc("Process32Next")
    	for {
    		var proc PROCESSENTRY32
    		proc.dwSize = ulong(unsafe.Sizeof(proc))
    		if rt, _, _ := Process32Next.Call(uintptr(pHandle), uintptr(unsafe.Pointer(&proc))); int(rt) == 1 {
    
    			len_szExeFile := 0
    			for _, b := range proc.szExeFile {
    				if b == 0 {
    					break
    				}
    				len_szExeFile++
    			}
    			var bytetest []byte = []byte(proc.szExeFile[:len_szExeFile])
    			_, newdata, newerr := decoder.Translate(bytetest, true)
    			if newerr != nil {
    				log.Println(newerr)
    
    			}
    
    			data = append(data, ProcessStruct{
    				processName: string(newdata),
    				processID:   int(proc.th32ProcessID),
    			})
    
    		} else {
    			break
    		}
    	}
    
    	CloseHandle := kernel32.NewProc("CloseHandle")
    	_, _, _ = CloseHandle.Call(pHandle)
    
    	sort.Sort(ProcessStructSlice(data))
    	for _, v := range data {
    		log.Println(v.processName)
    
    		buffer.WriteString("ProcessName : ")
    		buffer.WriteString(v.processName)
    		buffer.WriteString(" ProcessID : ")
    		buffer.WriteString(strconv.Itoa(v.processID))
    		buffer.WriteString("
    ")
    	}
    
    	io.WriteString(w, buffer.String())
    
    }
    

    重要的是

    "github.com/axgle/mahonia"  //这个库
    decoder := mahonia.NewDecoder("gbk") 
    //gbk转utf8
    var bytetest []byte = []byte(proc.szExeFile[:len_szExeFile]) _, newdata, newerr := decoder.Translate(bytetest, true)

    其实里面做了判断,并不是单纯的使用utf8.EncodeRune来解决,刚开始我也是直接使用utf8这个库来尝试,没成功.

    在这里做个分享,呵呵
  • 相关阅读:
    项目管理之代码合并
    C#判断操作系统的位数
    年初离职潮的思考
    线上系统问题的紧急处理案例(一)
    [六、页面跳转]8通过PresentationMode实现导航的后退
    [六、页面跳转]12使用@ObervedObject监听实例对象二
    [六、页面跳转]13使用@StateObject实现简单的购物车功能
    [六、页面跳转]4在导航栏添加一些功能按钮
    [六、页面跳转]5在导航栏视图的底部放置一排工具栏
    [六、页面跳转]7实现导航页面的自定义后退
  • 原文地址:https://www.cnblogs.com/zhujiechang/p/9998233.html
Copyright © 2020-2023  润新知