我想创建一个Windows快捷方式(.lnk)到桌面和Golang的startmenu。在Go中创建一个Windows快捷方式(.lnk)
我实际上是通过gowin模块拿到桌面&开始菜单文件夹,我想创建一个快捷方式放入系统的位置。
我搜索了但我没有找到任何golang项目。我应该创建它吗?还有其他漂亮的方法吗?
我想创建一个Windows快捷方式(.lnk)到桌面和Golang的startmenu。在Go中创建一个Windows快捷方式(.lnk)
我实际上是通过gowin模块拿到桌面&开始菜单文件夹,我想创建一个快捷方式放入系统的位置。
我搜索了但我没有找到任何golang项目。我应该创建它吗?还有其他漂亮的方法吗?
使用https://github.com/go-ole/go-ole:
ole.CoInitializeEx(0, ole.COINIT_APARTMENTTHREADED|ole.COINIT_SPEED_OVER_MEMORY)
oleShellObject, err := oleutil.CreateObject("WScript.Shell")
if err != nil {
return err
}
defer oleShellObject.Release()
wshell, err := oleShellObject.QueryInterface(ole.IID_IDispatch)
if err != nil {
return err
}
defer wshell.Release()
cs, err := oleutil.CallMethod(wshell, "CreateShortcut", dst)
idispatch := cs.ToIDispatch()
oleutil.PutProperty(idispatch, "TargetPath", src)
oleutil.CallMethod(idispatch, "Save")
一年后,我终于有了一个真正的解决方案!感谢:D –
在生产中运行了好几个月之后,我注意到了一些罕见的错误消息“CoInitialize尚未被调用。”。要解决这个问题,您需要确保调用runtime.LockOSThread(),或者使用https://github.com/go-ole/go-ole/issues/124中概述的comshim库 – tmm1
不,没有任何漂亮的方法可以在golang中创建.lnk文件。
主要原因是,.lnk文件是特定于Windows的文件。
在Windows中,即使是本机程序也需要使用OLE(对象链接和嵌入)和COM(组件对象模型)来创建快捷方式文件,如this answer中所述。
在我看来,在golang中解决这个问题的一种方法是使用gowin,并尝试与OLE COM进行通信。
OR
编写本机Windows组件不会创建.lnk文件的实际工作,并通过你们走程序派生它的进程。
谢谢!如果我成功的话,我会尝试它(显然)在Github上发布它! c: –
@AlexisPaques当你这样做的时候,请告诉我。 – desaiparth
首先,我将只使用外部解决方案,然后可能会尝试在golang中执行 –
经由外部程序从this subject解决方案:从Optimumx
Shortcut.exe /f:"%USERPROFILE%\Desktop\sc.lnk" /a:c /t:%USERPROFILE%\Desktop\scrum.pdf
.VBS
快捷可执行从NirSoft
shortcut "f:\winnt\system32\calc.exe" "~$folder.desktop$" "Windows Calculator"
shortcut "f:\winnt\system32\calc.exe" "~$folder.programs$\Calculators" "Windows Calculator"
shortcut "f:\Program Files\KaZaA\Kazaa.exe" "c:\temp\MyShortcuts" "Kazaa"
shortcut "f:\Program Files" "c:\temp\MyShortcuts" "Program Files Folder" "" "f:\winnt\system32\shell32.dll" 45
shortcut "f:\Program Files" "c:\temp\MyShortcuts" "Program Files Folder" "" "" "" "max"
快捷可执行
Set oWS = WScript.CreateObject("WScript.Shell")
sLinkFile = "C:\MyShortcut.LNK"
Set oLink = oWS.CreateShortcut(sLinkFile)
oLink.TargetPath = "C:\Program Files\MyApp\MyProgram.EXE"
' oLink.Arguments = ""
' oLink.Description = "MyProgram"
' oLink.HotKey = "ALT+CTRL+F"
' oLink.IconLocation = "C:\Program Files\MyApp\MyProgram.EXE, 2"
' oLink.WindowStyle = "1"
' oLink.WorkingDirectory = "C:\Program Files\MyApp"
oLink.Save
Powershell的脚本
set TARGET='D:\Temp'
set SHORTCUT='C:\Temp\test.lnk'
set PWS=powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile
%PWS% -Command "$ws = New-Object -ComObject WScript.Shell; $s = $ws.CreateShortcut(%SHORTCUT%); $S.TargetPath = %TARGET%; $S.Save()"
的AWFUL工作 golang溶液使用VBS;
package main
import(
"bytes"
"fmt"
"io/ioutil"
"os"
"os/exec"
)
func createShortcut(linkName string, target string, arguments string, directory string, description string, destination string) {
var scriptTxt bytes.Buffer
scriptTxt.WriteString("option explicit\n\n")
scriptTxt.WriteString("sub CreateShortCut()\n")
scriptTxt.WriteString("dim objShell, strDesktopPath, objLink\n")
scriptTxt.WriteString("set objShell = CreateObject(\"WScript.Shell\")\n")
scriptTxt.WriteString("strDesktopPath = objShell.SpecialFolders(\"")
scriptTxt.WriteString(destination)
scriptTxt.WriteString("\")\n")
scriptTxt.WriteString("set objLink = objShell.CreateShortcut(strDesktopPath & \"\\")
scriptTxt.WriteString(linkName)
scriptTxt.WriteString(".lnk\")\n")
scriptTxt.WriteString("objLink.Arguments = \"")
scriptTxt.WriteString(arguments)
scriptTxt.WriteString("\"\n")
scriptTxt.WriteString("objLink.Description = \"")
scriptTxt.WriteString(description)
scriptTxt.WriteString("\"\n")
scriptTxt.WriteString("objLink.TargetPath = \"")
scriptTxt.WriteString(target)
scriptTxt.WriteString("\"\n")
scriptTxt.WriteString("objLink.WindowStyle = 1\n")
scriptTxt.WriteString("objLink.WorkingDirectory = \"")
scriptTxt.WriteString(directory)
scriptTxt.WriteString("\"\n")
scriptTxt.WriteString("objLink.Save\nend sub\n\n")
scriptTxt.WriteString("call CreateShortCut()")
fmt.Print(scriptTxt.String())
filename := fmt.Sprintf("lnkTo%s.vbs", destination)
ioutil.WriteFile(filename, scriptTxt.Bytes(), 0777)
cmd := exec.Command("wscript", filename)
err := cmd.Run()
if err != nil {
fmt.Println(err)
}
cmd.Wait()
os.Remove(filename)
return
}
您可以使用反引号的Go字符串文字来避免需要转义引号(\“)。也可以使用这些文字来创建可读多行字符串文字可以减少您所做的WriteString调用次数。你也可以在单个字符串文字中使用像'text/template'这样的模板,使它更易读(并且很容易将变量的内容放入脚本中)。 –
表演怎么样?我用一个简单的字符串连接(+ =),它是可读的,然后我读这个:[Stackoverflow](http://stackoverflow.com/a/23857998/3540247),它是缓冲区的4,000倍复制速度比缓冲区快3倍,但我认为可读性差) –
看完文本/模板之后,这正是我需要的! :o –
我不知道Windows和没有获得它来测试。但是,AFAIU lnk相当于* nix上的符号链接。所以我会尝试[os.Symlink](https://golang.org/pkg/os/#Symlink),因为我希望跨平台的工作除非另有说明。 _(我可能会混淆符号链接和快捷方式)_。 – reedobrien