Creating internet shortcuts

From NSIS Wiki
Jump to navigationJump to search
Author: Anders (talk, contrib)


Introduction

Internet shortcuts cannot be created with the CreateShortcut NSIS instruction because they are a different file type (.URL, not .LNK).

.URL files are actually just .INI files and can be created/edited with the NSIS INI instructions.


Writing .URL files directly as a .INI file

While technically not the correct way to create .URL files, you can write them directly with the WriteINIStr instruction or use simple helper macros:

!macro CreateInternetShortcut FILEPATH URL
WriteINIStr "${FILEPATH}" "InternetShortcut" "URL" "${URL}"
!macroend
 
!macro CreateInternetShortcutWithIcon FILEPATH URL ICONPATH ICONINDEX
WriteINIStr "${FILEPATH}" "InternetShortcut" "URL" "${URL}"
WriteINIStr "${FILEPATH}" "InternetShortcut" "IconIndex" "${ICONINDEX}"
WriteINIStr "${FILEPATH}" "InternetShortcut" "IconFile" "${ICONPATH}"
!macroend
Section
 
!insertmacro CreateInternetShortcut "$Desktop\Example1.URL" "http://example.net/path?query#frag"
!insertmacro CreateInternetShortcutWithIcon "$Desktop\Example2.URL" "http://example.com" "$windir\explorer.exe" 13
 
SectionEnd


The .URL file format

The .URL file format is not officially documented. Only the URL value in the InternetShortcut section is required, everything else is optional.

[InternetShortcut]
URL=
HotKey=
IconFile=
IconIndex=
ShowCommand=
Modified=
Roamed=
IDList=
Author=
WhatsNew=
Comment=
Desc=

[InternetShortcut.A]
; CP_ACP stuff?

[InternetShortcut.W]
; UTF-7 stuff?

[DEFAULT] ; HTML frameset
BASEURL=

[DOC<NestedFramesetInfo>]
BASEURL=
ORIGURL=

[Bookmarklet] ; JavaScript bookmarklet
ExtendedURL=

[MonitoredItem]
FeedUrl=
IsLivePreview=
PreviewSize=

[{000214A0-0000-0000-C000-000000000046}] ; FMTID_Intshcut property storage
Prop<2..2147483647>=
  • Bookmarklet:ExtendedURL allows bookmarklets up to 5119 characters while the normal InternetShortcut:URL field is limited to 2083 characters.

Using the IUniformResourceLocator interface

Using the IUniformResourceLocator interface is the documented way to create/read/write .URL files.

IUniformResourceLocator helper macros were added in NSIS v3.05.

!include LogicLib.nsh
!include Win\COM.nsh
!include Win\PropKey.nsh
 
Section
 
!insertmacro ComHlpr_CreateInProcInstance ${CLSID_InternetShortcut} ${IID_IUniformResourceLocator} r1 ""
${If} $1 P<> 0
  ${IUniformResourceLocator::SetURL} $1 '("http://example.com?simple")'
  ${IUnknown::QueryInterface} $1 '("${IID_IPersistFile}",.r2)'
  ${If} $2 P<> 0
    ${IPersistFile::Save} $2 '("$Desktop\Example4.URL",1)'
    ${IUnknown::Release} $2 ""
  ${EndIf}
  ${IUnknown::Release} $1 ""
${EndIf}
 
!insertmacro ComHlpr_CreateInProcInstance ${CLSID_InternetShortcut} ${IID_IUniformResourceLocator} r1 ""
${If} $1 P<> 0
  ${IUniformResourceLocator::SetURL} $1 '("http://example.com?propstorage")'
  ${IUnknown::QueryInterface} $1 '("${IID_IPropertySetStorage}",.r2)'
  ${If} $2 P<> 0
      ${IPropertySetStorage::Open} $2 '("${FMTID_Intshcut}", ${STGM_READWRITE}, .r3)'
      ${If} $3 P<> 0
        System::Call '*${SYSSTRUCT_PROPVARIANT}(${VT_LPWSTR},,,&w${NSIS_MAX_STRLEN} "$windir\explorer.exe")p.r5' ; Allocate PROPVARIANT + string buffer
        IntPtrOp $6 $5 + ${SYSSIZEOF_PROPVARIANT} ; Calculate string address
        ${V_SetPointer} $5 "" $6
        !insertmacro IPropertyStorage_WritePropById $3 ${PID_IS_ICONFILE} $5 ""
        ${V_SetInt32} $5 ${VT_I4} 8
        !insertmacro IPropertyStorage_WritePropById $3 ${PID_IS_ICONINDEX} $5 ""
        System::Free $5 ; Free PROPVARIANT
        ${IPropertyStorage::Commit} $3 '(${STGC_DEFAULT})'
      ${IUnknown::Release} $3 ""
    ${EndIf}
    ${IUnknown::Release} $2 ""
  ${EndIf}
  ${IUnknown::QueryInterface} $1 '("${IID_IPersistFile}",.r2)'
  ${If} $2 P<> 0
    ${IPersistFile::Save} $2 '("$Desktop\Example5.URL",1)'
    ${IUnknown::Release} $2 ""
  ${EndIf}
  ${IUnknown::Release} $1 ""
${EndIf}
 
SectionEnd


URLs in .LNK shortcuts

Most Windows versions can parse and store URLs in the shell namespace. Because .LNK shortcut files can contain a PIDL you can put a PIDL URL in a .LNK shortcut. The result is not ideal because not all Windows versions display the default URL icon correctly. The URL PIDL format is not documented nor stable across all Windows versions.

  • NT4 (IE2) cannot handle URL PIDLs?
  • 95.OSR2 (IE3) stores URLs as ANSI PIDLs: [?] [,61h,00h,http:...#frag]
  • 98 (IE4) stores URLs as ANSI PIDLs: [INTERNET] [,61h:00h:00000000h,http:...] [61h:01h:00000000h,#frag]
  • 98.SE (IE5) stores URLs as Unicode PIDLs: [INTERNET] [,61h:80h:00000000h,h t t p : ...,BEEF...,# f r a g]


URLs in .HTM shortcuts

Using URL redirection in a .htm[l] file has no advantage on Windows (the file is larger and more complicated) but it is the only format that is supported in all operating systems.

<!DOCTYPE html><!-- saved from url=(0014)about:internet -->
<html><head>
<meta id="r" http-equiv="refresh" content="1; url=http://example.net/path/?q#f">
<script><!--
if((d=document).all&&!d.getElementById)d.getElementById=function(n){return d.all[n]};
if((d=document).getElementById){u=d.getElementById("r").content;window.location.replace(u.slice(u.indexOf("=")+1))}
//--></script>
</head></html>