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("\n")
	}

	io.WriteString(w, buffer.String())

}

重要的是

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

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

在这里做个分享,呵呵

原文地址:https://www.cnblogs.com/zhujiechang/p/9998233.html

时间: 2024-10-10 13:30:15

golang 调用windows API 中文的处理的相关文章

C#调用windows API的一些方法

使用C#调用windows API(从其它地方总结来的,以备查询) C#调用windows API也可以叫做C#如何直接调用非托管代码,通常有2种方法: 1.  直接调用从 DLL 导出的函数. 2.  调用 COM 对象上的接口方法 我主要讨论从dll中导出函数,基本步骤如下: 1.使用 C# 关键字 static 和 extern 声明方法. 2.将 DllImport 属性附加到该方法.DllImport 属性允许您指定包含该方法的 DLL 的名称. 3.如果需要,为方法的参数和返回值指定

VBS调用windows api函数(postmessage)实现后台发送按键脚本

'=========================================================================='' VBScript Source File -- Created with SAPIEN Technologies PrimalScript 4.0'' NAME: '' AUTHOR: Microsoft , Microsoft' DATE : 2014/8/10'' COMMENT: ''===================定义变量,注册

用C#调用Windows API向指定窗口发送按键消息

一.调用Windows API. C#下调用Windows API方法如下: 1.引入命名空间:using System.Runtime.InteropServices; 2.引用需要使用的方法,格式:[DllImport("DLL文件")]方法的声明; [DllImport("user32.dll")]private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); [DllImport("

C#调用WINDOWS API 示例

一.调用Windows API. C#下调用Windows API方法如下: 1.引入命名空间:using System.Runtime.InteropServices; 2.引用需要使用的方法,格式:[DllImport("DLL文件")]方法的声明; [DllImport("user32.dll")]private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); [DllImport("

善于 调用Windows API

前一段时间看见别人做的一个自动填写信息并且点击登录的程序,觉得很有意思. 其实就是在程序中调用Windows的API,那么如何调用,下面就做个简单的介绍. 写的简单粗暴, 不喜轻喷. 0.首先引入名称空间System.Runtime.InteropServices用来导入Windows DLL. 1.下面是函数原型: 1.1.这是模拟鼠标按下的方法 [DllImport("user32.dll", EntryPoint = "mouse_event")] publi

使用C#调用windows API(从其它地方总结来的,以备查询) -转

使用C#调用windows API(从其它地方总结来的,以备查询) C#调用windows API也可以叫做C#如何直接调用非托管代码,通常有2种方法: 1.  直接调用从 DLL 导出的函数. 2.  调用 COM 对象上的接口方法 我主要讨论从dll中导出函数,基本步骤如下: 1.使用 C# 关键字 static 和 extern 声明方法. 2.将 DllImport 属性附加到该方法.DllImport 属性允许您指定包含该方法的 DLL 的名称. 3.如果需要,为方法的参数和返回值指定

Python调用Windows API函数编写录音机和音乐播放器

功能描述: 1)使用tkinter设计程序界面: 2)调用Windows API函数实现录音机和音乐播放器. . 参考代码: ? 运行界面: ? 原文地址:https://www.cnblogs.com/7758520lzy/p/12149931.html

Golang调用windows下的dll动态库中的函数

Golang调用windows下的dll动态库中的函数 https://blog.csdn.net/xuduorui/article/details/78943331 原文地址:https://www.cnblogs.com/yuanjiangw/p/12196004.html

C#调用Windows API详解(上)

以前我写过通过WMI来获取有关系统信息的系列文章,确实通过WMI能够恨轻易地实现很多我们想实现的功能,不过有些情况下我们很难利用WMI来实现一些 复杂的功能,比如最近我做的一个项目,其中有一个功能就是要更改系统当前时间,利用WMI就很难实现(我没有找到相关的方法),还有一些其它方面的功能, 也比较难以通过WMI来实现,也许是WMI需要较高的权限才能执行的原因吧.所以,尽管我们不愿意,但是又不得不通过调用Windows 的API来实现.本文的目的就是讲述如何在C#中调用Windows的系统API.