{"id":233,"date":"2008-12-03T22:28:59","date_gmt":"2008-12-03T14:28:59","guid":{"rendered":"http:\/\/www.jhouseconsulting.com\/?p=233"},"modified":"2014-03-12T22:53:58","modified_gmt":"2014-03-12T14:53:58","slug":"the-challenges-of-using-vbscript-to-create-shortcuts","status":"publish","type":"post","link":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/2008\/12\/03\/the-challenges-of-using-vbscript-to-create-shortcuts-233","title":{"rendered":"The Challenges of Using VBScript to Create Shortcuts"},"content":{"rendered":"<p>Updated 8th December 2008&#8230;<\/p>\n<p>Today I was finalising the application deployment for a new XenApp farm. One of the final scripts to create was to place 9\u00a0shortcuts on the Desktop of the All Users profile. That&#8217;s quite a simple task, and for the most part some would probably just end up copying a bunch of previously created ones into place. But that would be too easy. I wanted to create them on the fly!<\/p>\n<p>So whilst I was writing the script I was faced with three challenges:<!--more--><\/p>\n<ol>\n<ol>\n<li>As per Microsoft KB article Q263324, when you create shortcuts and specify a long file name in the target path, the path is truncated if the hard disk (or drive mapping) for the target path does not exist.<\/li>\n<\/ol>\n<\/ol>\n<p style=\"padding-left: 30px;\">For example, create a shortcut with the following target:<\/p>\n<p style=\"padding-left: 60px;\">J:\\Mydirectory\\Myapplication.exe<\/p>\n<p style=\"padding-left: 30px;\">If drive J does not exist, the path is truncated to:<\/p>\n<p style=\"padding-left: 60px;\">J:\\Mydirect\\Mypplica.exe<\/p>\n<p style=\"padding-left: 30px;\">This problem can occur because the shell cannot determine whether the hard disk supports long file names, so the path is truncated to be acceptable to all file systems. Amazing that this is still a problem in this day and age!<\/p>\n<p style=\"padding-left: 30px;\">To work around this problem, you can use the subst command to point drive J to a local hard disk.<\/p>\n<p style=\"padding-left: 60px;\">To subst a drive to make the mapping work&#8230;<\/p>\n<p style=\"padding-left: 90px;\">ret = WshShell.Run (&#8220;cmd \/c subst j: %SystemDrive%\\&#8221;, 0, TRUE)<\/p>\n<p style=\"padding-left: 60px;\">To remove the subst&#8230;<\/p>\n<p style=\"padding-left: 90px;\">ret = WshShell.Run (&#8220;cmd \/c subst j: \/d&#8221;, 0, TRUE)<\/p>\n<p>So to work around this problem I created a function called CreateSubstDrive that will create a virtual drive, and then delete it when finished.<\/p>\n<ol>\n<li>The IconLocation property that assigns an icon to a shortcut does not work for URL shortcuts. Only LNK shortcuts work with this property, so I had create a subroutine that opens the .URL file and appends the IconFile and IconIndex. However, if run after the deployment of IE7, the make up of the contents of the URL file is different. IE7 adds some more properties, including a GUID section. Since the origninal script was simply just appending the IconFile and IconIndex lines, and because IE6 only created URL shortcuts with one section called &#8220;[InternetShortcut]&#8221;, it was now being placed in the wrong &#8220;section&#8221;. So now we need to treat the URL file as an ini file. Therefore I have replaced the original AddURLIcon subroutine with a standard WriteINIString subroutine from <a href=\"http:\/\/www.motobit.com\/tips\/detpg_asp-vbs-read-write-ini-files\/\" target=\"_blank\">Motobit Software<\/a>.<\/li>\n<li>This script will error with a &#8220;Catastrophic failure&#8221; when creating any URL shortcuts if run after the deployment of IE7 and before a reboot. Even using &#8220;On Error Resume Next&#8221; to force the script to continue, fails to create the shortcuts correctly. Therefore, this script must either be run before the deployment of IE7, or after a reboot.<\/li>\n<\/ol>\n<pre class=\"brush: vb; auto-links: false; title: ; toolbar: false; notranslate\" title=\"\">\r\n' This script will create the required Shortcuts\r\n'\r\n' Revision 1.1 released on 8th December 2008.\r\n' Written by Jeremy@jhouseconsulting.com on 3rd December 2008.\r\n\r\nOption Explicit\r\n\r\nDim objfso, objFolder, wshShell, oShellLink, strAUPrograms, strAUStartup, strAUDesktop\r\nDim strProgramFiles, strTargetPath, strScriptPath, strSystemRoot, strSystemDrive\r\nDim strProcessorArchitecture, blnActiveSubst, strIconFile, intIconIndex\r\n\r\nset WshShell = WScript.CreateObject(&quot;WScript.Shell&quot;)\r\nset objfso = CreateObject(&quot;Scripting.FileSystemObject&quot;)\r\n\r\nstrSystemDrive = WshShell.ExpandEnvironmentStrings(&quot;%SystemDrive%&quot;)\r\nstrSystemRoot = WshShell.ExpandEnvironmentStrings(&quot;%SystemRoot%&quot;)\r\nstrProcessorArchitecture = WshShell.ExpandEnvironmentStrings(&quot;%PROCESSOR_ARCHITECTURE%&quot;)\r\nIf strProcessorArchitecture = &quot;x86&quot; Then\r\n  strProgramFiles = WshShell.ExpandEnvironmentStrings(&quot;%ProgramFiles%&quot;)\r\nElse\r\n  strProgramFiles = WshShell.ExpandEnvironmentStrings(&quot;%ProgramFiles(86)%&quot;)\r\nEnd If\r\nstrAUPrograms = WshShell.SpecialFolders(&quot;AllUsersPrograms&quot;)\r\nstrAUStartup = WshShell.SpecialFolders(&quot;AllUsersStartup&quot;)\r\nstrAUDesktop = WshShell.SpecialFolders(&quot;AllUsersDesktop&quot;)\r\nstrScriptPath = GetCurrentPath\r\n\r\n' ********************************************************************************\r\n\r\nblnActiveSubst=False\r\nIf CreateSubstDrive(&quot;i&quot;,&quot;create&quot;) Then blnActiveSubst=True\r\nSet oShellLink = WshShell.CreateShortcut(strAUDesktop &amp; &quot;\\APM Springboard.lnk&quot;)\r\noShellLink.TargetPath = &quot;I:\\springboard\\index.html&quot;\r\noShellLink.WorkingDirectory = &quot;I:\\springboard&quot;\r\noShellLink.IconLocation = &quot;%SystemRoot%\\system32\\SHELL32.dll&quot; &amp; &quot;,93&quot;\r\noShellLink.Save\r\nIf blnActiveSubst then Call CreateSubstDrive(&quot;i&quot;,&quot;delete&quot;)\r\n\r\n' ********************************************************************************\r\n\r\nblnActiveSubst=False\r\nIf CreateSubstDrive(&quot;q&quot;,&quot;create&quot;) Then blnActiveSubst=True\r\nSet oShellLink = WshShell.CreateShortcut(strAUDesktop &amp; &quot;\\Case Manager.lnk&quot;)\r\noShellLink.TargetPath = chr(34) &amp; &quot;Q:\\Case Manager\\CaseManagerLoader.exe&quot; &amp; chr(34)\r\noShellLink.Arguments = &quot;\/DB:ODBC;DSN=CaseManager \/nosplash&quot;\r\noShellLink.WorkingDirectory = chr(34) &amp; &quot;Q:\\CASEMA~1&quot; &amp; chr(34)\r\noShellLink.IconLocation = &quot;Q:\\Case Manager\\CaseMan.exe&quot; &amp; &quot;,0&quot;\r\noShellLink.Save\r\nIf blnActiveSubst then Call CreateSubstDrive(&quot;q&quot;,&quot;delete&quot;)\r\n\r\n' ********************************************************************************\r\n\r\nSet oShellLink = WshShell.CreateShortcut(strAUDesktop &amp; &quot;\\\\ConnX.url&quot;)\r\noShellLink.TargetPath = &quot;http:\/\/apm-wp-db001\/connx\/&quot;\r\noShellLink.Save\r\nIf objFSO.FileExists(strScriptPath &amp; &quot;connx.ico&quot;) Then\r\n  If NOT objFSO.FolderExists(strSystemDrive &amp; &quot;\\Connx&quot;) Then\r\n    Set objFolder = objFSO.CreateFolder(strSystemDrive &amp; &quot;\\Connx&quot;)\r\n  End If\r\n  objFSO.CopyFile strScriptPath &amp; &quot;connx.ico&quot;, strSystemDrive &amp; &quot;\\Connx\\&quot;, True\r\n  strIconFile=strSystemDrive &amp; &quot;\\Connx\\connx.ico&quot;\r\n  intIconIndex=0\r\n  WriteINIString &quot;InternetShortcut&quot;, &quot;IconIndex&quot;, intIconIndex, strAUDesktop &amp; &quot;\\\\ConnX.url&quot;\r\n  WriteINIString &quot;InternetShortcut&quot;, &quot;IconFile&quot;, strIconFile, strAUDesktop &amp; &quot;\\\\ConnX.url&quot;\r\nEnd If\r\n\r\n' ********************************************************************************\r\n\r\nSet oShellLink = WshShell.CreateShortcut(strAUDesktop &amp; &quot;\\\\Crystal Reports Infoview.url&quot;)\r\noShellLink.TargetPath = &quot;http:\/\/apm-wp-crystal2\/businessobjects\/enterprise115\/InfoView\/logon.aspx&quot;\r\noShellLink.Save\r\n\r\n' ********************************************************************************\r\n\r\nblnActiveSubst=False\r\nIf CreateSubstDrive(&quot;j&quot;,&quot;create&quot;) Then blnActiveSubst=True\r\nSet oShellLink = WshShell.CreateShortcut(strAUDesktop &amp; &quot;\\Daily Update.lnk&quot;)\r\noShellLink.TargetPath = &quot;J:\\DailyUpdate\\dailyupdate.html&quot;\r\noShellLink.WorkingDirectory = &quot;J:\\DailyUpdate&quot;\r\noShellLink.IconLocation = &quot;%SystemRoot%\\system32\\SHELL32.dll&quot; &amp; &quot;,13&quot;\r\noShellLink.Save\r\nIf blnActiveSubst then Call CreateSubstDrive(&quot;j&quot;,&quot;delete&quot;)\r\n\r\n' ********************************************************************************\r\n\r\nSet oShellLink = WshShell.CreateShortcut(strAUDesktop &amp; &quot;\\Desktop eForms.lnk&quot;)\r\noShellLink.TargetPath = chr(34) &amp; strProgramFiles &amp; &quot;\\Shana\\Informed\\Filler.exe&quot; &amp; chr(34)\r\noShellLink.IconLocation = strProgramFiles &amp; &quot;\\Shana\\Informed\\Filler.exe&quot; &amp; &quot;,0&quot;\r\noShellLink.Save\r\n\r\n' ********************************************************************************\r\n\r\nSet oShellLink = WshShell.CreateShortcut(strAUDesktop &amp; &quot;\\\\HelpDesk Portal.url&quot;)\r\noShellLink.TargetPath = &quot;http:\/\/helpdesk\/Versacat&quot;\r\noShellLink.Save\r\n\r\n' ********************************************************************************\r\n\r\nblnActiveSubst=False\r\nIf CreateSubstDrive(&quot;h&quot;,&quot;create&quot;) Then blnActiveSubst=True\r\nSet oShellLink = WshShell.CreateShortcut(strAUDesktop &amp; &quot;\\JobReady+ v8.lnk&quot;)\r\noShellLink.TargetPath = &quot;H:\\JobReady\\JobReady_logon.fp7&quot;\r\noShellLink.WorkingDirectory = &quot;H:\\JobReady&quot;\r\noShellLink.IconLocation = &quot;%ProgramFiles%\\FileMaker\\FileMaker Pro 8.5\\FileMaker Pro.exe&quot; &amp; &quot;,0&quot;\r\noShellLink.Save\r\nIf blnActiveSubst then Call CreateSubstDrive(&quot;h&quot;,&quot;delete&quot;)\r\n\r\n' ********************************************************************************\r\n\r\nblnActiveSubst=False\r\nIf CreateSubstDrive(&quot;i&quot;,&quot;create&quot;) Then blnActiveSubst=True\r\nSet oShellLink = WshShell.CreateShortcut(strAUDesktop &amp; &quot;\\Resources.lnk&quot;)\r\noShellLink.TargetPath = &quot;I:\\springboard\\onlineresources.htm&quot;\r\noShellLink.WorkingDirectory = &quot;I:\\springboard&quot;\r\noShellLink.IconLocation = &quot;%SystemRoot%\\system32\\SHELL32.dll&quot; &amp; &quot;,98&quot;\r\noShellLink.Save\r\nIf blnActiveSubst then Call CreateSubstDrive(&quot;i&quot;,&quot;delete&quot;)\r\n\r\n' ********************************************************************************\r\n\r\nSet WshShell = Nothing\r\nSet objfso = Nothing\r\nSet objFolder = Nothing\r\n\r\nWScript.Quit(0)\r\n\r\nFunction GetCurrentPath\r\n' Return path to the current script\r\n  DIM path\r\n  path = WScript.ScriptFullName\r\n  GetCurrentPath = Left(path, InstrRev(path, &quot;\\&quot;))\r\nEnd Function\r\n\r\nSub AddURLIcon(strShortCutPath,strIconFile,intIconIndex)\r\n  Dim objfile,ots,line,contents,blnIconNotSet\r\n  set objfile=objfso.getfile(strShortCutPath)\r\n  set ots=objfile.openastextstream(1)\r\n  contents=&quot;&quot;\r\n  do while not ots.atEndofstream\r\n    line=ots.readline\r\n    if instr(1,line,&quot;IconIndex&quot;,1)=0 and instr(1,line,&quot;IconFile&quot;,1)=0 then\r\n      contents=contents &amp; line &amp; vbcrlf\r\n    end if\r\n  loop\r\n  ots.close\r\n  contents=contents &amp; &quot;IconFile=&quot; &amp; strIconFile &amp; vbcrlf\r\n  contents=contents &amp; &quot;IconIndex=&quot; &amp; cstr(intIconIndex)\r\n  set ots=objfile.openastextstream(2)\r\n  ots.write contents\r\n  ots.close\r\n  set ots=nothing\r\n  set objfile=nothing\r\nEnd Sub\r\n\r\nFunction CreateSubstDrive(strLetter,strAction)\r\n  Dim ret, WshShell, objfso\r\n  set WshShell = WScript.CreateObject(&quot;WScript.Shell&quot;)\r\n  set objfso = CreateObject(&quot;Scripting.FileSystemObject&quot;)\r\n  If lcase(strAction)=&quot;create&quot; Then\r\n    If NOT objfso.FolderExists(strLetter &amp; &quot;:\\&quot;) Then\r\n      ret = WshShell.Run (&quot;cmd \/c subst &quot; &amp; strLetter &amp; &quot;: %SystemDrive%\\&quot;, 0, TRUE)\r\n      CreateSubstDrive = True\r\n    Else\r\n      CreateSubstDrive = False\r\n    End If\r\n  End If\r\n  If lcase(strAction)=&quot;delete&quot; Then\r\n    ret = WshShell.Run (&quot;cmd \/c subst &quot; &amp; strLetter &amp; &quot;: \/d&quot;, 0, TRUE)\r\n    CreateSubstDrive = True\r\n  End If\r\n  set WshShell = Nothing\r\n  set objfso = Nothing\r\nEnd Function\r\n\r\nSub WriteINIString(Section, KeyName, Value, FileName)\r\n  Dim INIContents, PosSection, PosEndSection\r\n\r\n' Get contents of the INI file As a string\r\n  INIContents = GetFile(FileName)\r\n\r\n' Find section\r\n  PosSection = InStr(1, INIContents, &quot;&#x5B;&quot; &amp; Section &amp; &quot;]&quot;, vbTextCompare)\r\n  If PosSection&gt;0 Then\r\n'   Section exists. Find end of section\r\n    PosEndSection = InStr(PosSection, INIContents, vbCrLf &amp; &quot;&#x5B;&quot;)\r\n'   ?Is this last section?\r\n    If PosEndSection = 0 Then PosEndSection = Len(INIContents)+1\r\n\r\n'   Separate section contents\r\n    Dim OldsContents, NewsContents, Line\r\n    Dim sKeyName, Found\r\n    OldsContents = Mid(INIContents, PosSection, PosEndSection - PosSection)\r\n    OldsContents = split(OldsContents, vbCrLf)\r\n\r\n'   Temp variable To find a Key\r\n    sKeyName = LCase(KeyName &amp; &quot;=&quot;)\r\n\r\n'   Enumerate section lines\r\n    For Each Line In OldsContents\r\n      If LCase(Left(Line, Len(sKeyName))) = sKeyName Then\r\n        Line = KeyName &amp; &quot;=&quot; &amp; Value\r\n        Found = True\r\n      End If\r\n      NewsContents = NewsContents &amp; Line &amp; vbCrLf\r\n    Next\r\n\r\n    If isempty(Found) Then\r\n'     key Not found - add it at the end of section\r\n      NewsContents = NewsContents &amp; KeyName &amp; &quot;=&quot; &amp; Value\r\n    Else\r\n'     remove last vbCrLf - the vbCrLf is at PosEndSection\r\n      NewsContents = Left(NewsContents, Len(NewsContents) - 2)\r\n    End If\r\n\r\n'   Combine pre-section, new section And post-section data.\r\n    INIContents = Left(INIContents, PosSection-1) &amp; _\r\n    NewsContents &amp; Mid(INIContents, PosEndSection)\r\n  else'if PosSection&gt;0 Then\r\n'   Section Not found. Add section data at the end of file contents.\r\n    If Right(INIContents, 2) &lt;&gt; vbCrLf And Len(INIContents)&gt;0 Then\r\n      INIContents = INIContents &amp; vbCrLf\r\n    End If\r\n    INIContents = INIContents &amp; &quot;&#x5B;&quot; &amp; Section &amp; &quot;]&quot; &amp; vbCrLf &amp; _\r\n    KeyName &amp; &quot;=&quot; &amp; Value\r\n  end if'if PosSection&gt;0 Then\r\n  WriteFile FileName, INIContents\r\nEnd Sub\r\n\r\nFunction GetFile(ByVal FileName)\r\n  Dim FS: Set FS = CreateObject(&quot;Scripting.FileSystemObject&quot;)\r\n' Go To windows folder If full path Not specified.\r\n  If InStr(FileName, &quot;:\\&quot;) = 0 And Left (FileName,2)&lt;&gt;&quot;\\\\&quot; Then\r\n    FileName = FS.GetSpecialFolder(0) &amp; &quot;\\&quot; &amp; FileName\r\n  End If\r\n  On Error Resume Next\r\n\r\n  GetFile = FS.OpenTextFile(FileName).ReadAll\r\nEnd Function\r\n\r\nFunction WriteFile(ByVal FileName, ByVal Contents)\r\n\r\n  Dim FS: Set FS = CreateObject(&quot;Scripting.FileSystemObject&quot;)\r\n' On Error Resume Next\r\n\r\n' Go To windows folder If full path Not specified.\r\n  If InStr(FileName, &quot;:\\&quot;) = 0 And Left (FileName,2)&lt;&gt;&quot;\\\\&quot; Then\r\n    FileName = FS.GetSpecialFolder(0) &amp; &quot;\\&quot; &amp; FileName\r\n  End If\r\n\r\n  Dim OutStream: Set OutStream = FS.OpenTextFile(FileName, 2, True)\r\n  OutStream.Write Contents\r\nEnd Function\r\n<\/pre>\n<p>Enjoy!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Updated 8th December 2008&#8230; Today I was finalising the application deployment for a new XenApp farm. One of the final scripts to create was to place 9\u00a0shortcuts on the Desktop of the All Users profile. That&#8217;s quite a simple task, and for the most part some would probably just end up copying a bunch of &#8230; <a title=\"The Challenges of Using VBScript to Create Shortcuts\" class=\"read-more\" href=\"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/2008\/12\/03\/the-challenges-of-using-vbscript-to-create-shortcuts-233\" aria-label=\"Read more about The Challenges of Using VBScript to Create Shortcuts\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[5],"tags":[117,112,111,114,113,62],"class_list":["post-233","post","type-post","status-publish","format-standard","hentry","category-scripting","tag-catastrophic-failure","tag-iconlocation","tag-shortcut","tag-truncate-target-path","tag-url","tag-vbscript"],"aioseo_notices":[],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/posts\/233","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/comments?post=233"}],"version-history":[{"count":12,"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/posts\/233\/revisions"}],"predecessor-version":[{"id":235,"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/posts\/233\/revisions\/235"}],"wp:attachment":[{"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/media?parent=233"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/categories?post=233"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/tags?post=233"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}