2015-09-07 602 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 –