pac相关项目记录

项目

就是获取和设置这个脚本地址, 包括下图"使用设置脚本"的开/关

在这里插入图片描述

pac

在pac-cmd外面用Go语言封装了一层

特点
  1. 只有3个函数/方法可用
	pac.EnsureHelperToolPresent(fullPath, prompt, iconFullPath)
	pac.On(pacUrl string)
	pac.Off()
不足
  1. pac-cmd可以通过重定向获得pacUrl,这个pac好像没有对应的Show方法/函数,就是没办法获得操作系统当前的pacUrl
  2. 把二进制文件直接读出字节写死在Go源码里,应该可以有更好的的方式
  3. 上面一步的字节切片和已有的文件的比较,逐个字节比较
解读
EnsureHelperToolPresent

保证pac-cmd的二进制文件的存在,核心函数

  1. 第二个参数,只在苹果系统上有用, 苹果会弹出提示框
  2. 第一个if判断windows系统上的后缀名是_386.exe还是_amd64.exe
  3. 其中Asset()只是把string转为[]byte,见收获(2)
  4. byteexec.New()就是把第2步生成的文件写入到了filepath.Join(os.Getenv(“APPDATA”), “byteexec”)(如: C:\Users\Administrator\AppData\Roaming\byteexec)下面,这其中,判断了如果文件存在,是否一致的情况,不一致就重新写入,但是他这个判断是否一致,是一个字节一个字节的判断的.感觉应该有更好的方式
  5. ensureElevatedOnDarwin,只是在苹果系统上才会进行条件编译
  6. 总结下: 以windows系统为例,就是在指定的目录下生成了个exe的可执行文件,这个exe的源码以string的形式写死在Go源代码里了
// EnsureHelperToolPresent checks if helper tool exists and extracts it if not.
// On Mac OS, it also checks and set the file's owner to root:wheel and the setuid bit,
// it will request user to input password through a dialog to gain the rights to do so.
// path: absolute or relative path of the file to be checked and generated if
// not exists. Note - relative paths are resolved relative to the system-
// specific folder for aplication resources.
// prompt: the message to be shown on the dialog.
// iconPath: the full path of the icon to be shown on the dialog.
func EnsureHelperToolPresent(path string, prompt string, iconFullPath string) (err error) {
	mu.Lock()
	defer mu.Unlock()
	assertName := "pac"
	// Load different binaries for 32bit and 64bit Windows respectively.
	if runtime.GOOS == "windows" {
		suffix := "_386.exe"
		// https://blogs.msdn.microsoft.com/david.wang/2006/03/27/howto-detect-process-bitness/
		if strings.EqualFold(os.Getenv("PROCESSOR_ARCHITECTURE"), "amd64") ||
			strings.EqualFold(os.Getenv("PROCESSOR_ARCHITEW6432"), "amd64") {
			suffix = "_amd64.exe"
		}
		assertName = assertName + suffix
	}
	pacBytes, err := Asset(assertName)
	if err != nil {
		return fmt.Errorf("Unable to access pac asset: %v", err)
	}
	be, err = byteexec.New(pacBytes, path)
	if err != nil {
		return fmt.Errorf("Unable to extract helper tool: %v", err)
	}
	return ensureElevatedOnDarwin(be, prompt, iconFullPath)
}
pac.On和pac.Off

就是简单的命令行调用,调用EnsureHelperToolPresent生成的二进制文件.在windows下就相当于sysproxy-cmd.exe on xxxx这样

pac-cmd

就是一个C语言写的跨平台的改变操作系统的自动代理设置, 不同的平台有不同的二进制文件

特点

只是个二进制文件,单独执行这个二进制文件是不会在命令行有任何输出的,需要把输出进行重定向

	pac_amd64.exe show > 1.txt
如何做到无控制台输出的

比如show命令,源码里是printf了的:

	if ((options.pOptions[0].Value.dwValue & PROXY_TYPE_AUTO_PROXY_URL) > 0) {
    if (options.pOptions[1].Value.pszValue != NULL) {
      printf("%s\n", options.pOptions[1].Value.pszValue);
    }
  }

是通过编译选项控制的
Makefile里有如下控制:
LDFLAGS += -l rasapi32 -l wininet -Wl,–subsystem,windows
就是 -Wl,–subsystem,windows 做到的无控制台输出

Go语言里如何获取上面的输出

上面的C语言在链接的时候控制了不向命令行输出
可以用如下代码

func show(){
	cmd := exec.Command("pac_amd64.exe", "show")
	b,err:=cmd.CombinedOutput()
	if err!=nil{
		panic(err)
	}
	fmt.Println(string(b))
}

收获

  1. strings.EqualFold()比较的unicode码,而且忽略大小写

  2. string转[]byte更有效率的方式->Feature: provide no-copy conversion from []byte to string

  3. []byte相等比较用bytes.Compare

  4. 文件的Sync When to flush a file in Go?,感觉就如这个回复说的一样,只是为了尽可能的保证文件的写入的完整性,因为有可能在你Close之前程序崩溃了,导致文件没写入

    When you want to ensure data integrity as much as possible. For example, what happens if your program crashes before it comes to closing the file?
    
  5. 在Golang里要借助跨平台的二进制可执行文件,可以把二进制文件都读出来,以string的方式写死在Go源代码里,要用的时候再写为对应平台的二进制文件

  6. C语言控制控制台无输出及Go语言获取这种输出

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值