2015-09-07 1 views
1

Je souhaite créer un raccourci Windows (.lnk) sur le bureau et le menu Démarrer dans Golang.Création d'un raccourci Windows (.lnk) dans Go

J'ai effectivement eu les dossiers de bureau & Startmenu via le module gowin et je voudrais créer un raccourci vers ces emplacements.

J'ai cherché mais je n'ai trouvé aucun projet de golang pour cela. Devrais-je le créer? Y a-t-il une autre jolie méthode?

+0

Je ne sais pas de fenêtres et n'ont pas accès à tester. Cependant, AFAIU lnk est l'équivalent d'un lien symbolique sur * nix. Donc, je voudrais essayer [os.Symlink] (https://golang.org/pkg/os/#Symlink) comme je m'attendrais à ce que cela fonctionne multi-plateforme, sauf indication contraire. _ (Je suis peut-être en train de confondre des liens symboliques et des raccourcis) _. – reedobrien

Répondre

3

En utilisant 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

Un an plus tard, j'ai enfin une vraie solution! Merci: D –

+1

Après avoir exécuté cela en production pendant plusieurs mois, j'ai remarqué quelques rares échecs avec le message "CoInitialize n'a pas été appelé.". Pour résoudre ce problème, vous devez vous assurer que runtime.LockOSThread() est appelé ou utiliser la bibliothèque comshim comme indiqué dans https://github.com/go-ole/go-ole/issues/124 – tmm1

1

Non, il n'y a pas de méthode simple pour créer un fichier .lnk, en golang.

La raison principale est que les fichiers .lnk sont spécifiques à Windows. Dans Windows, même un programme natif doit utiliser OLE (Object linking and embedding) et COM (Component Object Model) pour créer un fichier de raccourci, comme décrit dans this answer. À mon avis, Une façon d'aborder ce problème dans golang est d'utiliser gowin, et essayer de communiquer avec COM OLE.

OU

Ecrivez une fenêtre native composant qui fait le travail réel de la création du fichier .lnk, et juste frayer son processus dans votre programme de go.

+0

Merci! Je vais l'essayer et (évidemment) l'afficher sur Github si je réussis! c: –

+0

@AlexisPaques Faites-moi savoir, quand vous faites cela. – desaiparth

+0

D'abord, je vais juste utiliser la solution externe, puis, peut-être, va essayer de le faire dans golang –

0

Solution via programme externe de this subject:

raccourci exécutable à partir 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" 

raccourci exécutable à partir Optimumx

Shortcut.exe /f:"%USERPROFILE%\Desktop\sc.lnk" /a:c /t:%USERPROFILE%\Desktop\scrum.pdf 

vbs

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 

scripts 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

Les AWFULtravail solution golang utilisant 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

Vous pouvez utiliser des chaînes de caractères Go retour arrière cité pour éviter d'avoir besoin d'échapper les guillemets (\ "). Vous pouvez également les utiliser pour rendre lisible littéraux de chaînes multilignes pour diminuer le nombre d'appels 'WriteString' que vous faites.Vous pouvez également utiliser quelque chose comme 'text/template' avec le modèle dans un seul littéral pour le rendre beaucoup plus lisible (et encore facilement mettre le contenu de vos variables dans le script). –

+0

Et les performances? J'ai utilisé la concaténation (+ =) avec une chaîne simple, c'était lisible puis j'ai lu ceci: [Stackoverflow] (http://stackoverflow.com/a/23857998/3540247) et c'était 4 mille fois plus rapide avec le buffer (la copie est 3 fois plus rapide que le buffer mais moins lisible je pense) –

+0

Après avoir regardé du texte/template, c'est exactement ce dont j'ai besoin! : o –