• 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这个库来尝试,没成功.

    在这里做个分享,呵呵
  • 相关阅读:
    机器学习的分类与主要算法对比
    关于在JSP页面中为什么一定要用${pageContext.request.contextPath}来获取项目路径,而不能用${request.contextPath}?
    Spring Boot静态资源处理
    Tomcat关闭后,重新启动,session中保存的对象为什么还存在解决方法
    Tomcat 7源码学习笔记 -9 tomcat重启后session仍然保留
    mysql-sql语句中变量的使用
    js检测对象中是否存在某个属性
    mysql :=和=的区别
    sql面试题(学生表_课程表_成绩表_教师表)
    ddd
  • 原文地址:https://www.cnblogs.com/zhujiechang/p/9998233.html
Copyright © 2020-2023  润新知