install

if (!A_IsAdmin) {
	try Run("*RunAs " DllCall("GetCommandLine", "Str"))
	ExitApp
}
g := Gui('OwnDialogs', 'AutoHotkey安装'), g.OnEvent('Escape', (*) => WinClose(g.Hwnd)), g.MarginX := g.MarginY := 10
for ctr in [['GroupBox', 'x10 y10 w460 h50 ', '“打开”关联的 AutoHotkey'], ['Edit', 'x25 y30 w340 h20 vAHK_Path', ''], ['Button', 'x375 y30 w40 h20 vop1', '浏览'], ['GroupBox', 'x10 y70 w460 h50 ', '“编辑”关联的编辑器'], ['Edit', 'x25 y90 w340 h20 vEditor_Path', ''], ['Button', 'x375 y90 w40 h20 vop2', '浏览'], ['Button', 'x420 y90 w40 h20 vdf2', '默认'], ['GroupBox', 'x10 y130 w460 h50 ', '“编译”关联的编译器'], ['Edit', 'x25 y150 w340 h20 vCompile_Path', ''], ['Button', 'x375 y150 w40 h20 vop3', '浏览'], ['Button', 'x420 y150 w40 h20 vdf3', '默认'], ['GroupBox', 'x10 y190 w460 h50', '关联扩展名'], ['Checkbox', 'x25 y210 w80 h20 vahk', '.ahk'], ['Checkbox', 'x120 y210 w80 h20 vah2', '.ah2'], ['Checkbox', 'x215 y210 w80 h20 vahk2', '.ahk2'], ['Checkbox', 'x25 y250 w270 h20 vNew_Script', '右键“新建”菜单中增加“AutoHotkey 脚本”'], ['Checkbox', 'x300 y250 w75 h20 vUIAccess', 'UIAccess'], ['Button', 'x375 y250 w40 h20 vinstall', '设置'], ['Button', 'x420 y250 w40 h20 vuninstall', '卸载']]
	g.Add(ctr[1], ctr[2], ctr[3])
g.Show(), g['df2'].OnEvent('Click', (*) => g['Editor_Path'].Value := 'notepad.exe'), g['df3'].OnEvent('Click', (*) => (g['Compile_Path'].Value := FileExist(ext := RegExReplace(g['AHK_Path'].Value, '[^\\/]+$', 'Compiler\Ahk2Exe.exe')) ? StrReplace(ext, '/', '\') : ''))
seldir := (name, gobj, *) => (gobj.Gui[name].Value := FileSelect(, , '选择' '路径', '*.exe') || gobj.Gui[name].Value)
g['op1'].OnEvent('Click', seldir.Bind('AHK_Path')), g['op2'].OnEvent('Click', seldir.Bind('Editor_Path')), g['op3'].OnEvent('Click', seldir.Bind('Compile_Path')), g['uninstall'].OnEvent('Click', uninstall), g['install'].OnEvent('Click', install)
init(g)
if (!g['AHK_Path'].Value && FileExist('AutoHotkey32.exe') && MsgBox('未检测到已安装的AutoHotkey,是否自动安装到默认路径?', , 4) = 'Yes') {
	DirCreate(t := StrReplace(A_ProgramFiles, ' (x86)') '\AutoHotkey')
	try FileCopy('AutoHotkey.chm', t)
	try FileCopy('*.exe', t, true)
	try DirCopy('Compiler', t '\Compiler'), g['Compile_Path'].Value := t '\Compiler\Ahk2Exe.exe'
	try FileCopy('AutoHotkey32.exe', t '\AutoHotkey.exe', true), g['AHK_Path'].Value := t '\AutoHotkey.exe'
	g['Editor_Path'].Value := 'notepad.exe'
	g['ahk'].Value := g['New_Script'].Value := 1
	install(g['install'])
}

init(g) {
	t := ''
	for v in ['AHK_Path', 'Editor_Path', 'Compile_Path']
		g[v].Value := ''
	for v in ['ahk', 'ah2', 'ahk2', 'New_Script']
		g[v].Value := 0
	for ext in ['ahk', 'ah2', 'ahk2'] {
		try v := RegRead('HKCR\.' ext), cmd := RegRead('HKCR\' v '\Shell\Open\Command')
		catch
			continue
		g[ext].Value := !t || (t = v)
		if (t)
			continue
		t := t || v, RegExMatch(cmd, '("?)(.+?)\1\s', &m), g['AHK_Path'].Value := m[2]
		try cmp := RegRead('HKCR\' v '\Shell\Compile\Command'), RegExMatch(cmp, '("?)(.+?)\1\s', &m), g['Compile_Path'].Value := m[2]
		try edt := RegRead('HKCR\' v '\Shell\Edit\Command'), RegExMatch(edt, '("?)(.+?)\1\s', &m), g['Editor_Path'].Value := m[2]
		try RegRead('HKCR\.' ext '\ShellNew', 'FileName'), g['New_Script'].Value := 1
	}
	g['UIAccess'].Value := FileExist(RegExReplace(g['AHK_Path'].Value, 'i)\.exe$', '_UIA.exe')) ? 1 : 0
}

uninstall(ctr, *) {
	s := ctr.Gui.Submit(false), un := Map(), ex := Map(), un.CaseSense := ex.CaseSense := false, l := ''
	for ext in ['ahk', 'ah2', 'ahk2'] {
		try v := RegRead('HKCR\.' ext)
		catch
			continue
		if (s.%ext%) {
			un[v] := true, l .= ',' ext
			try RegDeleteKey('HKCR\.' ext)
		} else
			ex[v] := true
	}
	for k in un
		if (!ex.Has(k))
			try RegDeleteKey('HKCR\' k)
	try FileDelete(RegExReplace(s.AHK_Path, 'i)\.exe$', '_UIA.exe'))
	init(ctr.Gui)
	if (l)
		MsgBox('已取消' Trim(l, ',') '文件关联')
}

install(ctr, *) {
	s := ctr.Gui.Submit(false), n := ''
	if (!FileExist(s.AHK_Path))
		return (ctr.Gui['AHK_Path'].Value := '', MsgBox('AutoHotkey.exe文件不存在'))
	if (s.ahk2 || s.ah2) {
		n := 'AutoHotkey2Script', RegWrite('AutoHotkey2 Script', 'REG_SZ', 'HKCR\' n)
	} else if (s.ahk)
		n := 'AutoHotkeyScript', RegWrite('AutoHotkey Script', 'REG_SZ', 'HKCR\' n)
	else
		return
	RegWrite(formatpath(s.AHK_Path) ',1', 'REG_SZ', 'HKCR\' n '\DefaultIcon')
	RegWrite('打开(&O)', 'REG_SZ', 'HKCR\' n '\Shell\Open')
	RegWrite(formatpath(s.AHK_Path) ' "%1" %*', 'REG_SZ', 'HKCR\' n '\Shell\Open\Command')
	RegWrite('', 'REG_SZ', 'HKCR\' n '\Shell\RunAs', 'HasLUAShield')
	RegWrite(formatpath(s.AHK_Path) ' "%1" %*', 'REG_SZ', 'HKCR\' n '\Shell\RunAs\Command')
	RegWrite('{86C86720-42A0-1069-A2E8-08002B30309D}', 'REG_SZ', 'HKCR\' n '\ShellEx\DropHandler')
	if (t := s.Editor_Path)
		RegWrite('编辑(&E)', 'REG_SZ', 'HKCR\' n '\Shell\Edit'), RegWrite(formatpath(t) ' "%1"', 'REG_SZ', 'HKCR\' n '\Shell\Edit\Command')
	else
		try RegDeleteKey('HKCR\' n '\Shell\Edit')
	if (t := ctr.Gui['Compile_Path'].Value := FileExist(s.Compile_Path) ? s.Compile_Path : '')
		RegWrite('编译(&C)', 'REG_SZ', 'HKCR\' n '\Shell\Compile'), RegWrite(formatpath(t) ' /in "%l" %*', 'REG_SZ', 'HKCR\' n '\Shell\Compile\Command')
	else
		try RegDeleteKey('HKCR\' n '\Shell\Compile')
	for ext in ['ahk', 'ah2', 'ahk2']
		if (s.%ext%) {
			RegWrite(n, 'REG_SZ', 'HKCR\.' ext)
			if (s.New_Script)
				RegWrite('', 'REG_SZ', 'HKCR\.' ext '\ShellNew', 'FileName')
			else
				try RegDeleteKey('HKCR\.' ext '\ShellNew')
		}
	if (s.UIAccess) {
		FileCopy(s.AHK_Path, pp := RegExReplace(s.AHK_Path, 'i)\.exe$', '_UIA.exe'), true)
		EnableUIAccess(pp)
	} else if FileExist(pp := RegExReplace(s.AHK_Path, 'i)\.exe$', '_UIA.exe'))
		FileDelete(pp)
	MsgBox('安装完成')
}

formatpath(path) {
	path := Trim(path, ' "')
	return InStr(path, ' ') ? '"' path '"' : path
}

EnableUIAccess(filename){
	hStore := DllCall("Crypt32\CertOpenStore", "ptr", 10 ; STORE_PROV_SYSTEM_W
		, "uint", 0, "ptr", 0, "uint", 0x20000 ; SYSTEM_STORE_LOCAL_MACHINE
		, "wstr", "Root", "ptr")
	if !hStore
		throw
	p := DllCall("Crypt32\CertFindCertificateInStore", "ptr", hStore
		, "uint", 0x10001 ; X509_ASN_ENCODING|PKCS_7_ASN_ENCODING
		, "uint", 0, "uint", 0x80007 ; FIND_SUBJECT_STR
		, "wstr", "AutoHotkey", "ptr", 0, "ptr")
	if p
		cert := CertContext(p)
	else
		cert := EnableUIAccess_CreateCert("AutoHotkey", hStore)
	EnableUIAccess_SetManifest(filename)
	EnableUIAccess_SignFile(filename, cert, "AutoHotkey")
}
EnableUIAccess_SetManifest(file){
	xml := ComObject("Msxml2.DOMDocument")
	xml.async := false
	xml.setProperty("SelectionLanguage", "XPath")
	xml.setProperty("SelectionNamespaces"
		, "xmlns:v1='urn:schemas-microsoft-com:asm.v1' "
		. "xmlns:v3='urn:schemas-microsoft-com:asm.v3'")
	if !xml.load("res://" file "/#24/#1") ; Load current manifest
		throw
	node := xml.selectSingleNode("/v1:assembly/v3:trustInfo/v3:security"
					. "/v3:requestedPrivileges/v3:requestedExecutionLevel")
	if !node ; Not AutoHotkey v1.1?
		throw
	node.setAttribute("uiAccess", "true")
	xml := RTrim(xml.xml, "`r`n")
	data := Buffer(data_size := StrPut(xml, "utf-8") - 1)
	StrPut(xml, data, "utf-8")
	if !(hupd := DllCall("BeginUpdateResource", "str", file, "int", false))
		throw
	r := DllCall("UpdateResource", "ptr", hupd, "ptr", 24, "ptr", 1
					, "ushort", 1033, "ptr", data, "uint", data_size)
	if !DllCall("EndUpdateResource", "ptr", hupd, "int", !r) && r
		throw
}
EnableUIAccess_CreateCert(CertName, hStore){
	if !DllCall("Advapi32\CryptAcquireContext", "ptr*", &hProv := 0
		, "str", CertName, "ptr", 0, "uint", 1, "uint", 0) ; PROV_RSA_FULL=1, open existing=0
	{
		if !DllCall("Advapi32\CryptAcquireContext", "ptr*", &hProv
			, "str", CertName, "ptr", 0, "uint", 1, "uint", 8) ; PROV_RSA_FULL=1, CRYPT_NEWKEYSET=8
			throw
		prov := CryptContext(hProv)
		if !DllCall("Advapi32\CryptGenKey", "ptr", hProv
				, "uint", 2, "uint", 0x4000001, "ptr*", &hKey := 0) ; AT_SIGNATURE=2, EXPORTABLE=..01
			throw
		(CryptKey(hKey)) ; To immediately release it.
	}
	Loop 2
	{
		if A_Index = 1
			pbName := cbName := 0
		else
			bName := Buffer(cbName), pbName := bName.Ptr
		if !DllCall("Crypt32\CertStrToName", "uint", 1, "str", "CN=" CertName
			, "uint", 3, "ptr", 0, "ptr", pbName, "uint*", cbName, "ptr", 0) ; X509_ASN_ENCODING=1, CERT_X500_NAME_STR=3
			throw
	}
	cnb := Buffer(2*A_PtrSize), NumPut("uptr", pbName, NumPut("uptr", cbName, cnb))
	endTime := Buffer(16)
	DllCall("GetSystemTime", "ptr", endTime)
	NumPut("ushort", NumGet(endTime, "ushort") + 10, endTime) ; += 10 years
	if !hCert := DllCall("Crypt32\CertCreateSelfSignCertificate"
		, "ptr", hProv, "ptr", cnb, "uint", 0, "ptr", 0
		, "ptr", 0, "ptr", 0, "ptr", endTime, "ptr", 0, "ptr")
		throw
	cert := CertContext(hCert)
	if !DllCall("Crypt32\CertAddCertificateContextToStore", "ptr", hStore
		, "ptr", hCert, "uint", 1, "ptr", 0) ; STORE_ADD_NEW=1
		throw
	return cert
}
EnableUIAccess_DeleteCertAndKey(CertName){
	DllCall("Advapi32\CryptAcquireContext", "ptr*", &undefined := 0
		, "str", CertName, "ptr", 0, "uint", 1, "uint", 16) ; PROV_RSA_FULL=1, CRYPT_DELETEKEYSET=16
	if !hStore := DllCall("Crypt32\CertOpenStore", "ptr", 10 ; STORE_PROV_SYSTEM_W
		, "uint", 0, "ptr", 0, "uint", 0x20000 ; SYSTEM_STORE_LOCAL_MACHINE
		, "wstr", "Root", "ptr")
		throw
	if !p := DllCall("Crypt32\CertFindCertificateInStore", "ptr", hStore
		, "uint", 0x10001 ; X509_ASN_ENCODING|PKCS_7_ASN_ENCODING
		, "uint", 0, "uint", 0x80007 ; FIND_SUBJECT_STR
		, "wstr", CertName, "ptr", 0, "ptr")
		return 0
	if !DllCall("Crypt32\CertDeleteCertificateFromStore", "ptr", p)
		throw
	return 1
}
class CryptContext {
	__New(p) {
		this.p := p
	}
	__Delete() {
		DllCall("Advapi32\CryptReleaseContext", "ptr", this.p, "uint", 0)
	}
}
class CertContext extends CryptContext {
	__Delete() {
		DllCall("Crypt32\CertFreeCertificateContext", "ptr", this.p)
	}
}
class CryptKey extends CryptContext {
	__Delete() {
		DllCall("Advapi32\CryptDestroyKey", "ptr", this.p)
	}
}
EnableUIAccess_SignFile(File, CertCtx, Name){
	wfile := Buffer(2 * StrPut(File, "utf-16")), StrPut(File, wfile, "utf-16")
	wname := Buffer(2 * StrPut(Name, "utf-16")), StrPut(Name, wname, "utf-16")
	cert_ptr := IsObject(CertCtx) ? CertCtx.p : CertCtx
	EnableUIAccess_Struct(&file_info, "ptr", A_PtrSize*3 ; SIGNER_FILE_INFO
		, "ptr", wfile.Ptr)
	EnableUIAccess_Struct(&subject_info, "ptr", A_PtrSize*4 ; SIGNER_SUBJECT_INFO
		, "ptr", (dwIndex := Buffer(4, 0)).Ptr, "ptr", SIGNER_SUBJECT_FILE:=1, "ptr", file_info.Ptr)
	EnableUIAccess_Struct(&cert_store_info, "ptr", A_PtrSize*4 ; SIGNER_CERT_STORE_INFO
		, "ptr", cert_ptr, "ptr", SIGNER_CERT_POLICY_CHAIN:=2)
	EnableUIAccess_Struct(&cert_info, "uint", 8+A_PtrSize*2 ; SIGNER_CERT
		, "uint", SIGNER_CERT_STORE:=2, "ptr", cert_store_info.Ptr)
	EnableUIAccess_Struct(&authcode_attr, "uint", 8+A_PtrSize*3 ; SIGNER_ATTR_AUTHCODE
		, "int", false, "ptr", true, "ptr", wname.Ptr)
	EnableUIAccess_Struct(&sig_info, "uint", 8+A_PtrSize*4 ; SIGNER_SIGNATURE_INFO
		, "uint", CALG_SHA1:=0x8004, "ptr", SIGNER_AUTHCODE_ATTR:=1
		, "ptr", authcode_attr.Ptr)
	hr := DllCall("MSSign32\SignerSign"
		, "ptr", subject_info, "ptr", cert_info, "ptr", sig_info
		, "ptr", 0, "ptr", 0, "ptr", 0, "ptr", 0, "uint")
	if (hr != 0)
		throw hr
}
EnableUIAccess_Struct(&struct, arg*){
	struct := Buffer(arg[2], 0), p := struct.Ptr
	Loop arg.Length//2
		p := NumPut(arg[1], arg[2], p), arg.RemoveAt(1, 2)
	return struct
}

给TA捐赠
共{{data.count}}人
人已捐赠
其他

HSDisconnect

2021-12-2 15:23:23

其他

light or dark(Ctrl+j一键切换明亮和黑暗模式)

2021-12-2 15:23:35

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索