2015-09-07 106 views
1

我想创建一个Windows快捷方式(.lnk)到桌面和Golang的startmenu。在Go中创建一个Windows快捷方式(.lnk)

我实际上是通过gowin模块拿到桌面&开始菜单文件夹,我想创建一个快捷方式放入系统的位置。

我搜索了但我没有找到任何golang项目。我应该创建它吗?还有其他漂亮的方法吗?

+0

我不知道Windows和没有获得它来测试。但是,AFAIU lnk相当于* nix上的符号链接。所以我会尝试[os.Symlink](https://golang.org/pkg/os/#Symlink),因为我希望跨平台的工作除非另有说明。 _(我可能会混淆符号链接和快捷方式)_。 – reedobrien

回答

3

使用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") 
+0

一年后,我终于有了一个真正的解决方案!感谢:D –

+1

在生产中运行了好几个月之后,我注意到了一些罕见的错误消息“CoInitialize尚未被调用。”。要解决这个问题,您需要确保调用runtime.LockOSThread(),或者使用https://github.com/go-ole/go-ole/issues/124中概述的comshim库 – tmm1

1

不,没有任何漂亮的方法可以在golang中创建.lnk文件。

主要原因是,.lnk文件是特定于Windows的文件。

在Windows中,即使是本机程序也需要使用OLE(对象链接和嵌入)和COM(组件对象模型)来创建快捷方式文件,如this answer中所述。

在我看来,在golang中解决这个问题的一种方法是使用gowin,并尝试与OLE COM进行通信。

OR

编写本机Windows组件不会创建.lnk文件的实际工作,并通过你们走程序派生它的进程。

+0

谢谢!如果我成功的话,我会尝试它(显然)在Github上发布它! c: –

+0

@AlexisPaques当你这样做的时候,请告诉我。 – desaiparth

+0

首先,我将只使用外部解决方案,然后可能会尝试在golang中执行 –

0

经由外部程序从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()" 
0

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 
} 
+1

您可以使用反引号的Go字符串文字来避免需要转义引号(\“)。也可以使用这些文字来创建可读多行字符串文字可以减少您所做的WriteString调用次数。你也可以在单个字符串文字中使用像'text/template'这样的模板,使它更易读(并且很容易将变量的内容放入脚本中)。 –

+0

表演怎么样?我用一个简单的字符串连接(+ =),它是可读的,然后我读这个:[Stackoverflow](http://stackoverflow.com/a/23857998/3540247),它是缓冲区的4,000倍复制速度比缓冲区快3倍,但我认为可读性差) –

+0

看完文本/模板之后,这正是我需要的! :o –

相关问题