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转utf8
var bytetest []byte = []byte(proc.szExeFile[:len_szExeFile])
_, newdata, newerr := decoder.Translate(bytetest, true) 其实里面做了判断,并不是单纯的使用utf8.EncodeRune来解决,刚开始我也是直接使用utf8这个库来尝试,没成功. 在这里做个分享,呵呵

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

  1. C#调用windows API的一些方法

    使用C#调用windows API(从其它地方总结来的,以备查询) C#调用windows API也可以叫做C#如何直接调用非托管代码,通常有2种方法: 1.  直接调用从 DLL 导出的函数. 2. ...

  2. C#调用Windows API函数截图

    界面如下: 下面放了一个PictureBox 首先是声明函数: //这里是调用 Windows API函数来进行截图 //首先导入库文件 [System.Runtime.InteropServices ...

  3. 【转】用C#调用Windows API向指定窗口发送

    一.调用Windows API. C#下调用Windows API方法如下: 1.引入命名空间:using System.Runtime.InteropServices; 2.引用需要使用的方法,格式 ...

  4. C#中调用Windows API的要点 .

    介绍 API(Application Programming Interface),我想大家不会陌生,它是我们Windows编程的常客,虽然基于.Net平台的C#有了强大的类库,但是,我们还是不能否认 ...

  5. c# 判断窗体是否永在最前(TopMost),调用windows API

    许多程序都可以把自身的窗体设为最前显示状态,这个可以参考博客c#让窗体永在最前 调用windows api 将窗体设为topmost.那么如何判断桌面上的一个窗体是否为最前显示状态呢,不光是自己的程序 ...

  6. c#让窗体永在最前 调用windows api 将窗体设为topmost

    有时候应用程序需要将一个窗体始终位于屏幕的最前面,即使切换到其它窗体也能看到该窗体,这样的窗体就叫做TopMost窗体. 用C#制作TopMost窗体之前,首先要了解如何声明SetWindowPos函 ...

  7. 善于 调用Windows API

    前一段时间看见别人做的一个自动填写信息并且点击登录的程序,觉得很有意思. 其实就是在程序中调用Windows的API,那么如何调用,下面就做个简单的介绍. 写的简单粗暴, 不喜轻喷. 0.首先引入名称 ...

  8. C#中调用Windows API时的数据类型对应关系

    原文 C#中调用Windows API时的数据类型对应关系 BOOL=System.Int32 BOOLEAN=System.Int32 BYTE=System.UInt16 CHAR=System. ...

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

    用C#调用Windows API向指定窗口发送 一.调用Windows API. C#下调用Windows API方法如下: 1.引入命名空间:using System.Runtime.Interop ...

随机推荐

  1. 2018-12-25 VS Code英汉词典v0.0.8: 批量翻译文件部分命名

    续前文: VS Code英汉词典进化效果演示: 翻译文件所有命名 vscode"英汉词典"插件地址: 官方链接 现在实现的效果比之前的演示差很多, 因为executeDocumen ...

  2. 记一次DDOS攻击防御实录

    前言     笔者所在单位是一家小型创业公司,目前产品正在成长阶段,日活跃用户只有区区几万人次,并发只有日均 85/QPS,自建机房,带宽 100MB.在这样的背景下,完全没想过一个小产品会招来黑客的 ...

  3. 理解Device Tree Usage

    英语原文地址: htttp://devicetree.org/Device_Tree_Usage 本文介绍如何为新的机器或板卡编写设备树(Device Tree), 它旨在概要性的介绍设备树概念,以及 ...

  4. Windows10文件目录下添加 Shift+右键打开管理员Powershell窗口

    背景(可略过) 目前在调试 Python 程序,遇到了一个问题:当程序中包含多线程时,使用 IDLE 运行是不会执行多线程的语句的,在网上一顿搜罗了解到这种情况可以换成在命令行下执行.好像用 PyCh ...

  5. Chrome内核浏览器打开网页报 错误代码: ERR_TIMED_OUT

    升级win10之后如果出现chrome内核的浏览器网页总是打不开 打开很慢  而ie和edge是可以正常访问的 用这个方法可以  我弄了几天终于 搞好了我直接转载过来了近期,工程师收到大量反馈360浏 ...

  6. 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之十一 || AOP自定义筛选,Redis入门 11.1

    代码已上传Github+Gitee,文末有地址 书说上文<从壹开始前后端分离[ .NET Core2.0 Api + Vue 2.0 + AOP + 分布式]框架之十 || AOP面向切面编程浅 ...

  7. 用ASP.NET Core 2.1 建立规范的 REST API -- 缓存和并发

    本文所需的一些预备知识可以看这里: http://www.cnblogs.com/cgzl/p/9010978.html 和 http://www.cnblogs.com/cgzl/p/9019314 ...

  8. 远程window服务器,无法复制粘贴了

    1.先检查本机 2.检查服务器 win+R打开输入taskmgr 找到这个进程,结束进程 3.在win+r打开输入rdpclip确认启动,发现可以复制粘贴了.

  9. 【Android Studio安装部署系列】三十七、从Android Studio3.2升级到Android Studio3.4【以及创建Android Q模拟器】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 保持Android Studio开发环境的最新版本. 下载Android Studio3.4 使用Android Studio自带的 ...

  10. JavaScript一看就懂(2)闭包

    认识闭包之前需要先了解作用域,如果你对作用域还没有足够了解,请移步JavaScript一看就懂(1)作用域 什么是闭包? 我们可以先简单认为:一个函数a定义在另一个函数b里面,这个函数a就是闭包: f ...