windows编译Go程序
一、自动UAC管理员权限
本段来自:https://www.codeleading.com/article/19833148230/
在windows上执行有关系统设置命令的时候需要管理员权限才能操作,比如修改网卡的禁用、启用状态。双击执行是不能正确执行命令的,只有右键以管理员身份运行才能成功。
为解决此问题,最终找到一个简单的方法,双击也能执行成功了。过程如下:
1> go get github.com/akavel/rsrc
2> 把nac.manifest 文件拷贝到当前windows项目根目录(这个文件需要直接写,内容在下边)
3> rsrc -manifest nac.manifest -o nac.syso
4> go build (可使用下一段的方式编译)
nac.mainfest的内容为:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="9.0.0.0"
processorArchitecture="x86"
name="myapp.exe"
type="win32"
/>
<description>myapp</description>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
要注意一下,第四步,没错就是golang编译命令是采用无参数编译–go build。如果写成指定文件编译–go build main.go 将无法成功获取UAC。(go build 在编译开始时,会搜索当前目录的 go 源码以及.syso文件,最后将所有资源一起打包到EXE文件。go build main.go 这种指定文件的编译命令,会编译指定文件和指定文件里面的所需要的依赖包,但是不会将.syso 文件打包到EXE。)如果,你的golang程序需要UAC权限或带GUI界面的,一定要注意正确使用编译命令!
二、隐藏控制台窗口
本段来自:https://studygolang.com/articles/9047
隐藏go程序自己的cmd窗口
go build -ldflags -H=windowsgui
隐藏调用的外部程序的cmd窗口
cmd := exec.Command("sth")
if runtime.GOOS == "windows" {
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
}
三、弹出windows窗口
本段来自:https://studygolang.com/articles/5918(有修正)
做为一个WIN的爱好者,不得不说,通常情况下在学习一门新语言之后我会很急于制作一个弹窗来测试一下这个语言在WIN的窗体效果,这里不多说,先上代码。
package main
import (
"github.com/lxn/win"
"syscall"
"strconv"
)
func _TEXT(_str string) *uint16{
return syscall.StringToUTF16Ptr(_str)
}
func _toString(_n int32) string{
return strconv.Itoa(int(_n))
}
func main() {
var hwnd win.HWND
cxScreen := win.GetSystemMetrics(win.SM_CXSCREEN)
cyScreen := win.GetSystemMetrics(win.SM_CYSCREEN)
win.MessageBox(hwnd,_TEXT("大家好,我屏幕的宽度为:" + _toString(cxScreen) + " 高度为:" + _toString(cyScreen)),_TEXT("Golang 窗口测试"),win.MB_OK)
}
备注:github.com/lxn/go-winapi已改为github.com/lxn/win
// 带图标的异常消息
win.MessageBox(hwnd,_TEXT(err.Error()),_TEXT("消 息"),win.MB_ICONERROR)
// 带图标的正常消息
win.MessageBox(hwnd,_TEXT("已成功导入!" ),_TEXT("消 息"),win.MB_ICONINFORMATION)
四、导入证书到windows系统
var (
modcrypt32 = syscall.NewLazyDLL("crypt32.dll")
procCertAddEncodedCertificateToStore = modcrypt32.NewProc("CertAddEncodedCertificateToStore")
procCertCloseStore = modcrypt32.NewProc("CertCloseStore")
procCertDeleteCertificateFromStore = modcrypt32.NewProc("CertDeleteCertificateFromStore")
procCertDuplicateCertificateContext = modcrypt32.NewProc("CertDuplicateCertificateContext")
procCertEnumCertificatesInStore = modcrypt32.NewProc("CertEnumCertificatesInStore")
//procCertOpenSystemStoreW = modcrypt32.NewProc("CertOpenSystemStoreW") //此方法提示 failed adding cert: Access is denied.
procCertOpenSystemStoreW = modcrypt32.NewProc("CertOpenStore")
)
func (w windowsRootStore) addCert(cert []byte) error {
store, err := syscall.CertOpenStore(10, 0, 0,
0x4000|0x20000|0x00000004, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("root"))))
if err != nil {
return err
}
defer syscall.CertCloseStore(store, 0)
_, _, err = procCertAddEncodedCertificateToStore.Call(uintptr(store), 1, uintptr(unsafe.Pointer(&cert[0])), uintptr(uint(len(cert))), 4, 0)
if err.(syscall.Errno) != 0 {
return err
}
return nil
// TODO: ok to always overwrite?
//ret, _, err := procCertAddEncodedCertificateToStore.Call(
// uintptr(w), // HCERTSTORE hCertStore
// uintptr(syscall.X509_ASN_ENCODING|syscall.PKCS_7_ASN_ENCODING), // DWORD dwCertEncodingType
// uintptr(unsafe.Pointer(&cert[0])), // const BYTE *pbCertEncoded
// uintptr(len(cert)), // DWORD cbCertEncoded
// 3, // DWORD dwAddDisposition (CERT_STORE_ADD_REPLACE_EXISTING is 3)
// 0, // PCCERT_CONTEXT *ppCertContext
//)
//if ret != 0 {
// return nil
//}
//return fmt.Errorf("Failed adding cert: %v", err)
}
c语言参考
static int crypto_import_pawdroot()
{
HCERTSTORE hCertStore;
BOOL bRet;
hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A,
0, 0L, CERT_SYSTEM_STORE_LOCAL_MACHINE, "ROOT");
if (hCertStore == NULL) {
return -1;
}
bRet = CertAddEncodedCertificateToStore(hCertStore, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
kPawdRootCert, kPawdRootCertLen, CERT_STORE_ADD_REPLACE_EXISTING, NULL);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
return bRet ? 0 : -2;
}