batch-filevbscriptwindows-scriptingicolnk

how do you set the icon of a shortcut through a batch file?


I'm trying to create a script that will create shortcuts of the target batch files and set the icon to a .ico or .dll icon file:

@echo off
@echo Writing CreateShortcut script
@echo Set oWS = WScript.CreateObject("WScript.Shell") >> CreateShortcut.vbs

@echo sLinkFile = "C:\rustserver\Batch Files\rustserver\launcher\Test1.lnk" >> CreateShortcut.vbs
@echo Set oLink = oWS.CreateShortcut(sLinkFile) >> CreateShortcut.vbs
@echo oLink.TargetPath = "C:\rustserver\Batch Files\Test1.bat" >> CreateShortcut.vbs
@echo oLink.Save >> CreateShortcut.vbs
pause

@echo Writing EditShortcut script
@echo Set iWS = WScript.CreateObject("Shell.Application") >> EditShortcut.vbs

@echo sIconFile.IconLocation "C:\rustserver\Batch Files\rustserver\launcher\Icons\CompilerIcon.ico",0 >> EditShortcut.vbs
@echo Set oIcon = iWS.EditShortcut(sIconFile) >> EditShortcut.vbs
@echo oIcon.TargetPath = "C:\rustserver\Batch Files\rustserver\launcher\Test1.lnk" >> EditShortcut.vbs
@echo oIcon.Save >> EditShortcut.vbs
pause

@echo Running .vbs scripts...
cscript CreateShortcut.vbs
cscript EditShortcut.vbs
pause

@echo Deleting .vbs scripts...
del CreateShortcut.vbs
del EditShortcut.vbs
pause

@echo Deleting test shortcuts...
del Test1.lnk
pause

Converting the .bat files to .exe isn't an option because there are a few values that need to be reconfigured between each batch file.

Like I can get the script to create the shortcuts of the batch files just fine but no matter what I try I can't get the script to set the icon of the shortcut...


Solution

  • Given your self-posted solution, you could have done that in a much simpler way from your batch file.

    The following opens your file for writing only once, before closing it, whereas yours did that for each individual line. You only need one vbscript, to create the shortcut, you don't need to create one, then edit it later.

    ::https://stackoverflow.com/q/68502166
    @(  Echo Set WshShell = WScript.CreateObject("WScript.Shell"^)
        Echo Set oShellLink = WshShell.CreateShortcut("C:\rustserver\Batch Files\rustserver\launcher\Test1.lnk"^)
        Echo oShellLink.TargetPath = """C:\rustserver\Batch Files\Test1.bat"""
        Echo oShellLink.WindowStyle = 1
        Echo oShellLink.Hotkey = "CTRL+SHIFT+B"
        Echo oShellLink.IconLocation = "C:\rustserver\Batch Files\rustserver\launcher\Icons\SMIcons.dll, 0"
        Echo oShellLink.Description = "Run Windows Command Script"
        Echo oShellLink.WorkingDirectory = "C:\rustserver\Batch Files"
        Echo oShellLink.Save) 1>"CreateShortcut.vbs"
    @%SystemRoot%\System32\cscript.exe //NoLogo "CreateShortcut.vbs" && Del "CreateShortcut.vbs"
    

    The main thing to remember with the above method, is because the redirected write block is parenthesized, you'd need to escape any nested closing parentheses, (with a caret), to prevent the outer block being closed prematurely.


    However there is a much simpler way of doing this, which does not require you to escape anything, or dynamically write, run, then delete another file. You could use a batch/WSH polyglot:

    <!-- ::https://stackoverflow.com/q/68502166
    @%SystemRoot%\System32\cscript.exe //NoLogo "%~f0?.wsf"
    @Exit /B
    -->
    <Job><Script Language="VBScript">
    Set WshShell = WScript.CreateObject("WScript.Shell")
    Set oShellLink = WshShell.CreateShortcut("C:\rustserver\Batch Files\rustserver\launcher\Test1.lnk")
    oShellLink.TargetPath = """C:\rustserver\Batch Files\Test1.bat"""
    oShellLink.WindowStyle = 1
    oShellLink.Hotkey = "CTRL+SHIFT+B"
    oShellLink.IconLocation = "C:\rustserver\Batch Files\rustserver\launcher\Icons\SMIcons.dll, 0"
    oShellLink.Description = "Run Windows Command Script"
    oShellLink.WorkingDirectory = "C:\rustserver\Batch Files"
    oShellLink.Save
    </Script></Job>