Application's Managed Installer (AMI)

Releases, guides, changelogs, support and discussion of The ScriptPack. User created scripts and utilities.

Moderators: Waldo2k2, RogueSpear

AMI Part 4 {HTA/HTC Details} [ProgressLineItem.htc]

Postby TofuBug » Tue Jun 24, 2008 6:13 pm

ProgressLineItem.htc

Welcome Back Everyone!

Sorry the post is so late in the evening it has been a more hectic day than usual

We're now jumping into our Composite Level 1 HTC

So without further adieu the code

Code: Select all
<html xmlns:Ryan>
   <?import namespace="Ryan" implementation="ProgressBar.htc">
   <public:component tagname="ProgressLineItem">
      <Public:method name="Install" />
      <public:event name="onInstalled" id="InstalledEventID" />
      <public:property name="InstallTitle" put="PutTitle" get="GetTitle" />
      <public:property name="InstallValue" put="PutValue" get="GetValue"/>
      <public:property name="InstallPath" Put="PutPath" get="GetPath"/>
      <public:property name="ProgressLineItemWidth" />
   </public:component>
   <script language="vbscript" type="text/vbscript">
      '----------------------Component HTML objects----------------------
      On Error Resume Next
      Dim CheckBoxElement
      Dim AnimationElement
      Dim TextElement
      
      '----------------------Component variables-------------------------
      Dim path
      Dim CheckInstallationTimerID
      Dim Killed

      '-----------------------Component "Constructor"-----------------------
      Sub InitializeComponent()
         Set CheckBoxElement = document.CreateElement("<input type=""checkbox"" id=""CheckBoxElement"" style="" position: absolute; Left: 5px; top: 0px;font-family: verdana; "">")
         Set TextElement = document.CreateElement("<input type=""text"" id=""TextElement"" readonly=""readonly"" style="" position : absolute; Left : 25px; top: 1px; width : " + ProgressLineItemWidth + "px" + "; font-size : 9pt; font-family: verdana; border-top-style: none; border-Right-style: none; border-Left-style: none; border-bottom-style: none; color : black"">")
         Set AnimationElement = document.CreateElement("<Ryan:ProgressBar id=""AnimationElement"" style=""position: absolute; Left : 25px; top : 1px; width : " + ProgressLineItemWidth + "px" + "; visibility : hidden;""></Ryan:ProgressBar>")
         Element.AppendChild(AnimationElement)
         Element.AppendChild(CheckBoxElement)
         Element.AppendChild(TextElement)
         AnimationElement.Speed = 50
         CheckBoxElement.AttachEvent "onclick", GetRef("SuppressClicks")
         CheckBoxElement.AttachEvent "ondblclick", GetRef("ForceEnd")
         Killed = False
      End Sub
   
      '---------------Exposed Methods---------------
      Sub Install()
         If RegistryItemExists("HKLM\SOFTWARE\LM_AMI\" + Split(path,"\")(UBound(Split(path,"\")) - 1) + "\") Then CreateObject("WScript.Shell").RegDelete("HKLM\SOFTWARE\LM_AMI\" + Split(path,"\")(UBound(Split(path,"\")) - 1) + "\")                                                                        'If there is already info In the applications hive delete the hive
         TextElement.style.pixelleft = TextElement.style.pixelleft + TextElement.style.pixelwidth
         AnimationElement.style.visibility = "visible"
         SwapTextColors()
         AnimationElement.Animate()
         StartInstallationMonitor()
         CheckAndLaunchScript(Path)
      End Sub

      '----------------Internal Methods----------------
      Function RegistryItemExists(RegistryItem)
         On Error Resume Next                                                       'Disable Error handling
         CreateObject("WScript.Shell").RegRead RegistryItem                                  'Try And read In the value
         RegistryItemExists = (Err = 0)                                                'The key exists If we get back a 0
         If ((Err = &H80070002) And (Right(RegistryItem, 1) = "\")) Then                        'Check To see If we get a specific Error back And the value passed In was a key Not a value
            TheErrDescription = Replace(Err.description, RegistryItem, "")                     'Get the description
            Err.Clear()                                                            'Clear the old Error
            CreateObject("WScript.Shell").RegRead "HKEY_ERROR\"                            'Read In from the Error key
            RegistryItemExists = (TheErrDescription <> Replace(Err.description, "HKEY_ERROR\", ""))   'Check against the Error key And our original errpr description
         End If
      End Function 'Function RegistryItemExists(RegistryItem)

      Function Shr(Num, X)
         If X >= 32 Then Exit Function                                                   'If we try To shift Right more than 32 Exit the Function
         If X = 0 Then Shr = Num : Exit Function                                             'If we try To shift Right 0 times return the Num passed In And Exit the Function
         Shr = (((Num And &H7FFFFFFF) And (Not (Pwr2(X) - 1))) \ Pwr2(X)) Or (Num < 0) And Pwr2(31 - X)   
      End Function 'Function Shr(Num, X)

      Function Pwr2(Exponent)
         Dim Res(31)                                 'Local variable declarations
         Dim Counter
         If Exponent < 0 Or Exponent > 31 Then Err.Raise 5   'If we don't have an acceptable range of exponent raise an Error
         If Res(0) = 0 Then                           'If we are starting With zero
            Res(0) = 1                              'Set the first number To 1
            For Counter = 1 To 30                     'Count To 30
               Res(Counter) = Res(Counter - 1) * 2         'Set up the numbers
            Next
            Res(31) = &H80000000                     'Create the final binary value
         End If
         Pwr2 = Res(Exponent)                        'Return the value of the exponent
      End Function ' Function Power2(Exponent)

      Sub CheckAndLaunchScript(Script)
         Dim CRCTable
         Dim CaculatedCRC
         Dim Temp
         Dim fso
         Dim File
         Dim FileName
         Dim Character
 
         CRCTable = _
           Split("&h0,&h77073096,&hEE0E612C,&h990951BA,&h076DC419,&h706AF48F,&hE963A535,&h9E6495A3,&h0EDB8832,&h79DCB8A4," + _
           "&hE0D5E91E,&h97D2D988,&h09B64C2B,&h7EB17CBD,&hE7B82D07,&h90BF1D91,&h1DB71064,&h6AB020F2,&hF3B97148," + _
            "&h84BE41DE,&h1ADAD47D,&h6DDDE4EB,&hF4D4B551,&h83D385C7,&h136C9856,&h646BA8C0,&hFD62F97A,&h8A65C9EC," + _
           "&h14015C4F,&h63066CD9,&hFA0F3D63,&h8D080DF5,&h3B6E20C8,&h4C69105E,&hD56041E4,&hA2677172,&h3C03E4D1," + _
           "&h4B04D447,&hD20D85FD,&hA50AB56B,&h35B5A8FA,&h42B2986C,&hDBBBC9D6,&hACBCF940,&h32D86CE3,&h45DF5C75," + _
           "&hDCD60DCF,&hABD13D59,&h26D930AC,&h51DE003A,&hC8D75180,&hBFD06116,&h21B4F4B5,&h56B3C423,&hCFBA9599," + _
            "&hB8BDA50F,&h2802B89E,&h5F058808,&hC60CD9B2,&hB10BE924,&h2F6F7C87,&h58684C11,&hC1611DAB,&hB6662D3D," + _
           "&h76DC4190,&h01DB7106,&h98D220BC,&hEFD5102A,&h71B18589,&h06B6B51F,&h9FBFE4A5,&hE8B8D433,&h7807C9A2," + _
           "&h0F00F934,&h9609A88E,&hE10E9818,&h7F6A0DBB,&h086D3D2D,&h91646C97,&hE6635C01,&h6B6B51F4,&h1C6C6162," + _
            "&h856530D8,&hF262004E,&h6C0695ED,&h1B01A57B,&h8208F4C1,&hF50FC457,&h65B0D9C6,&h12B7E950,&h8BBEB8EA," + _
            "&hFCB9887C,&h62DD1DDF,&h15DA2D49,&h8CD37CF3,&hFBD44C65,&h4DB26158,&h3AB551CE,&hA3BC0074,&hD4BB30E2," + _
           "&h4ADFA541,&h3DD895D7,&hA4D1C46D,&hD3D6F4FB,&h4369E96A,&h346ED9FC,&hAD678846,&hDA60B8D0,&h44042D73," + _
            "&h33031DE5,&hAA0A4C5F,&hDD0D7CC9,&h5005713C,&h270241AA,&hBE0B1010,&hC90C2086,&h5768B525,&h206F85B3," + _
           "&hB966D409,&hCE61E49F,&h5EDEF90E,&h29D9C998,&hB0D09822,&hC7D7A8B4,&h59B33D17,&h2EB40D81,&hB7BD5C3B," + _
            "&hC0BA6CAD,&hEDB88320,&h9ABFB3B6,&h03B6E20C,&h74B1D29A,&hEAD54739,&h9DD277AF,&h04DB2615,&h73DC1683," + _
           "&hE3630B12,&h94643B84,&h0D6D6A3E,&h7A6A5AA8,&hE40ECF0B,&h9309FF9D,&h0A00AE27,&h7D079EB1,&hF00F9344," + _
            "&h8708A3D2,&h1E01F268,&h6906C2FE,&hF762575D,&h806567CB,&h196C3671,&h6E6B06E7,&hFED41B76,&h89D32BE0," + _
           "&h10DA7A5A,&h67DD4ACC,&hF9B9DF6F,&h8EBEEFF9,&h17B7BE43,&h60B08ED5,&hD6D6A3E8,&hA1D1937E,&h38D8C2C4," + _
           "&h4FDFF252,&hD1BB67F1,&hA6BC5767,&h3FB506DD,&h48B2364B,&hD80D2BDA,&hAF0A1B4C,&h36034AF6,&h41047A60," + _
           "&hDF60EFC3,&hA867DF55,&h316E8EEF,&h4669BE79,&hCB61B38C,&hBC66831A,&h256FD2A0,&h5268E236,&hCC0C7795," + _
           "&hBB0B4703,&h220216B9,&h5505262F,&hC5BA3BBE,&hB2BD0B28,&h2BB45A92,&h5CB36A04,&hC2D7FFA7,&hB5D0CF31," + _
           "&h2CD99E8B,&h5BDEAE1D,&h9B64C2B0,&hEC63F226,&h756AA39C,&h026D930A,&h9C0906A9,&hEB0E363F,&h72076785," + _
          "&h05005713,&h95BF4A82,&hE2B87A14,&h7BB12BAE,&h0CB61B38,&h92D28E9B,&hE5D5BE0D,&h7CDCEFB7,&h0BDBDF21," + _
           "&h86D3D2D4,&hF1D4E242,&h68DDB3F8,&h1FDA836E,&h81BE16CD,&hF6B9265B,&h6FB077E1,&h18B74777,&h88085AE6," + _
            "&hFF0F6A70,&h66063BCA,&h11010B5C,&h8F659EFF,&hF862AE69,&h616BFFD3,&h166CCF45,&hA00AE278,&hD70DD2EE," + _
          "&h4E048354,&h3903B3C2,&hA7672661,&hD06016F7,&h4969474D,&h3E6E77DB,&hAED16A4A,&hD9D65ADC,&h40DF0B66," + _
           "&h37D83BF0,&hA9BCAE53,&hDEBB9EC5,&h47B2CF7F,&h30B5FFE9,&hBDBDF21C,&hCABAC28A,&h53B39330,&h24B4A3A6," + _
            "&hBAD03605,&hCDD70693,&h54DE5729,&h23D967BF,&hB3667A2E,&hC4614AB8,&h5D681B02,&h2A6F2B94,&hB40BBE37," + _
           "&hC30C8EA1,&h5A05DF1B,&h2D02EF8D",",")
         CaculatedCRC = &hFFFFFFFF
        Set fso = CreateObject( "Scripting.FileSystemObject" )
        If Not fso.FileExists(Script) Then .RegWrite "HKLM\SOFTWARE\LM_AMI\" + Right(Script,Len(Script) - InStrRev(Script,"\")) + "\ReturnCode", -9, "REG_DWORD" : Exit Sub
         Set File = fso.OpenTextFile( Script, 1, False )
       While Not File.AtEndOfStream
            CaculatedCRC = CRCTable((Asc(File.Read(1))) Xor (CaculatedCRC And &HFF)) Xor Shr( CaculatedCRC, 8 )      'Adjust the CRC For Each character     
         Wend
         CreateObject("WScript.Shell").Run Chr(34) + Script + Chr(34) + " /SelfValidate:" + CStr(CaculatedCRC Xor &hFFFFFFFF),1,False
      End Sub

      Sub SwapTextColors() : If TextElement.style.Color = "black" Then : TextElement.style.color = "red" : Else : TextElement.style.color = "black" : End If : End Sub
   
      Sub StartInstallationMonitor() : CheckInstallationTimerID = window.setinterval(GetRef("CheckInstallation"),50) : End Sub
   
      Sub StopInstallationMonitor() : window.clearInterval(CheckInstallationTimerID) : End Sub
   
      Sub CheckInstallation() : If RegistryItemExists("HKLM\SOFTWARE\LM_AMI\" + Split(path,"\")(UBound(Split(path,"\")) - 1) + "\ReturnCode") Then FireInstalled(CreateObject("WScript.Shell").RegRead("HKLM\SOFTWARE\LM_AMI\" + Split(path,"\")(UBound(Split(path,"\")) - 1) + "\ReturnCode")) : End If : End Sub
   
      Sub KillProcess(ProcessName)
         On Error Resume Next
         For Each objProcess In GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2").ExecQuery("Select * FROM Win32_Process WHERE CommandLine LIKE '%" + processName + "%'")
            objProcess.Terminate()
         Next
      End Sub
      
      '-----------------------Internal Event Handlers-----------------------
      Sub SuppressClicks() : CheckBoxElement.checked = Not CheckBoxElement.checked : End Sub      
      
      Sub ForceEnd()
         If Not Killed then
            KillProcess("setup.vbs""  /SelfValidate:")   
            FireInstalled(-99)
         End If
      End Sub

      '--------------------Event Firing Methods--------------------
      Sub FireInstalled(OutReturnCode)
         StopInstallationMonitor()
         If OutReturnCode = 3010 Or OutReturnCode = 0 Then CheckBoxElement.Checked = True
         AnimationElement.StopAnimation()
         TextElement.style.pixelleft = TextElement.style.pixelleft - TextElement.style.pixelwidth
         AnimationElement.style.visibility = "hidden"
         If OutReturnCode = 3010 or OutReturnCode = 0 Then SwapTextColors()
         Dim InstalledEventObject
         Set InstalledEventObject = window.document.CreateEventObject()
         InstalledEventObject.ReturnValue = OutReturnCode
         Killed = True
         InstalledEventID.Fire(InstalledEventObject)
      End Sub

      '----------------------Property Put's & Get's-----------------------
      Sub PutTitle(InTitle) : TextElement.title = InTitle : End Sub

      Function GetTitle() : GetTitle = TextElement.title : End Function

      Sub PutValue(InValue) : TextElement.value = InValue : End Sub

      Function GetValue() : GetValue = TextElement.Value : End Function
   
      Sub PutPath(InPath) : Path = InPath : End Sub
   
      Function GetPath() : GetPath = Path : End Function

      InitializeComponent()
   </script>
</html>


185 lines for us to analyze this evening

So let’s start with our Declaration Section

Code: Select all
<html xmlns:Ryan>
   <?import namespace="Ryan" implementation="ProgressBar.htc">
   <public:component tagname="ProgressLineItem">
      <Public:method name="Install" />
      <public:event name="onInstalled" id="InstalledEventID" />
      <public:property name="InstallTitle" put="PutTitle" get="GetTitle" />
      <public:property name="InstallValue" put="PutValue" get="GetValue"/>
      <public:property name="InstallPath" Put="PutPath" get="GetPath"/>
      <public:property name="ProgressLineItemWidth" />
   </public:component>


Ok we're back to using Composite HTCs so we have our standard xmlns being set we are importing our required HTC(s) and we have several properties and 1 method and 1 event being exposed to the parent element by this HTC

Next up we have our variables, objects and constants sections

Code: Select all
      '----------------------Component HTML objects----------------------
      On Error Resume Next
      Dim CheckBoxElement
      Dim AnimationElement
      Dim TextElement
      
      '----------------------Component variables-------------------------
      Dim path
      Dim CheckInstallationTimerID
      Dim Killed


We will be using a checkbox element a Textbox element and an Animation element (our ProgressBar HTC) in addition we have a variable for the Path a timer ID and a Killed variable

On to the Component Constructor

Code: Select all
      '-----------------------Component "Constructor"-----------------------
      Sub InitializeComponent()
         Set CheckBoxElement = document.CreateElement("<input type=""checkbox"" id=""CheckBoxElement"" style="" position: absolute; Left: 5px; top: 0px;font-family: verdana; "">")
         Set TextElement = document.CreateElement("<input type=""text"" id=""TextElement"" readonly=""readonly"" style="" position : absolute; Left : 25px; top: 1px; width : " + ProgressLineItemWidth + "px" + "; font-size : 9pt; font-family: verdana; border-top-style: none; border-Right-style: none; border-Left-style: none; border-bottom-style: none; color : black"">")
         Set AnimationElement = document.CreateElement("<Ryan:ProgressBar id=""AnimationElement"" style=""position: absolute; Left : 25px; top : 1px; width : " + ProgressLineItemWidth + "px" + "; visibility : hidden;""></Ryan:ProgressBar>")
         Element.AppendChild(AnimationElement)
         Element.AppendChild(CheckBoxElement)
         Element.AppendChild(TextElement)
         AnimationElement.Speed = 50
         CheckBoxElement.AttachEvent "onclick", GetRef("SuppressClicks")
         CheckBoxElement.AttachEvent "ondblclick", GetRef("ForceEnd")
         Killed = False
      End Sub


Fairly standard fan-fare so far we are creating 3 elements and appending them to the HTC you will notice that box the TextElement and AnimationElement have their width property of their style set to the ProgressLineItemWidth property of the HTC also the Animation Element’s visibility is set to hidden to begin. In addition the Checkbox element has both an onclick and ondblclick events wired to two internal event handlers.

Lastly we are setting the Animation Element’s speed property to 50 milliseconds and setting Killed to false

Over to the Exposed Methods Section for our only Exposed Method

Code: Select all
      Sub Install()
         If RegistryItemExists("HKLM\SOFTWARE\LM_AMI\" + Split(path,"\")(UBound(Split(path,"\")) - 1) + "\") Then CreateObject("WScript.Shell").RegDelete("HKLM\SOFTWARE\LM_AMI\" + Split(path,"\")(UBound(Split(path,"\")) - 1) + "\")                                                                        'If there is already info In the applications hive delete the hive
         TextElement.style.pixelleft = TextElement.style.pixelleft + TextElement.style.pixelwidth
         AnimationElement.style.visibility = "visible"
         SwapTextColors()
         AnimationElement.Animate()
         StartInstallationMonitor()
         CheckAndLaunchScript(Path)
      End Sub


The AMI controls its logging and installations through the registry in a common Hive the system first checks to see if the packages hive currently exists and if so it deletes it to start fresh

Then we move the TextElement over so the left side now begins where the right side used to end

Then we turn on the Animation Element’s visibility and call SwapTextColors()

Finally we Call the ProgressBar HTC's Animate() method followed with a call to StartInstallationMonitor() Finally CheckAndLaunchScript()

Now we come to the Internal Methods Section

Quite a lot going on in here for this post

Code: Select all
      Function RegistryItemExists(RegistryItem)
         On Error Resume Next                                                       'Disable Error handling
         CreateObject("WScript.Shell").RegRead RegistryItem                                  'Try And read In the value
         RegistryItemExists = (Err = 0)                                                'The key exists If we get back a 0
         If ((Err = &H80070002) And (Right(RegistryItem, 1) = "\")) Then                        'Check To see If we get a specific Error back And the value passed In was a key Not a value
            TheErrDescription = Replace(Err.description, RegistryItem, "")                     'Get the description
            Err.Clear()                                                            'Clear the old Error
            CreateObject("WScript.Shell").RegRead "HKEY_ERROR\"                            'Read In from the Error key
            RegistryItemExists = (TheErrDescription <> Replace(Err.description, "HKEY_ERROR\", ""))   'Check against the Error key And our original errpr description
         End If
      End Function 'Function RegistryItemExists(RegistryItem)


This method if you have been following along from a year ago when I first posted about the AMI back when it was in version 1.0 will recognize it from the Package Template VBScript file

Basically this method allows you to verify if a registry key OR value exists in the registry (to search for key end string with \ omit \ to search for a value)

Code: Select all
      Function Shr(Num, X)
         If X >= 32 Then Exit Function                                                   'If we try To shift Right more than 32 Exit the Function
         If X = 0 Then Shr = Num : Exit Function                                             'If we try To shift Right 0 times return the Num passed In And Exit the Function
         Shr = (((Num And &H7FFFFFFF) And (Not (Pwr2(X) - 1))) \ Pwr2(X)) Or (Num < 0) And Pwr2(31 - X)   
      End Function 'Function Shr(Num, X)


This little method emulates the >> (Shift Right) operator of languages like C++

Code: Select all
      Function Pwr2(Exponent)
         Dim Res(31)                                 'Local variable declarations
         Dim Counter
         If Exponent < 0 Or Exponent > 31 Then Err.Raise 5   'If we don't have an acceptable range of exponent raise an Error
         If Res(0) = 0 Then                           'If we are starting With zero
            Res(0) = 1                              'Set the first number To 1
            For Counter = 1 To 30                     'Count To 30
               Res(Counter) = Res(Counter - 1) * 2         'Set up the numbers
            Next
            Res(31) = &H80000000                     'Create the final binary value
         End If
         Pwr2 = Res(Exponent)                        'Return the value of the exponent
      End Function ' Function Power2(Exponent)


This method raises an Exponent by the Power of 2

Code: Select all
      Sub CheckAndLaunchScript(Script)
         Dim CRCTable
         Dim CaculatedCRC
         Dim Temp
         Dim fso
         Dim File
         Dim FileName
         Dim Character
 
         CRCTable = _
           Split("&h0,&h77073096,&hEE0E612C,&h990951BA,&h076DC419,&h706AF48F,&hE963A535,&h9E6495A3,&h0EDB8832,&h79DCB8A4," + _
           "&hE0D5E91E,&h97D2D988,&h09B64C2B,&h7EB17CBD,&hE7B82D07,&h90BF1D91,&h1DB71064,&h6AB020F2,&hF3B97148," + _
            "&h84BE41DE,&h1ADAD47D,&h6DDDE4EB,&hF4D4B551,&h83D385C7,&h136C9856,&h646BA8C0,&hFD62F97A,&h8A65C9EC," + _
           "&h14015C4F,&h63066CD9,&hFA0F3D63,&h8D080DF5,&h3B6E20C8,&h4C69105E,&hD56041E4,&hA2677172,&h3C03E4D1," + _
           "&h4B04D447,&hD20D85FD,&hA50AB56B,&h35B5A8FA,&h42B2986C,&hDBBBC9D6,&hACBCF940,&h32D86CE3,&h45DF5C75," + _
           "&hDCD60DCF,&hABD13D59,&h26D930AC,&h51DE003A,&hC8D75180,&hBFD06116,&h21B4F4B5,&h56B3C423,&hCFBA9599," + _
            "&hB8BDA50F,&h2802B89E,&h5F058808,&hC60CD9B2,&hB10BE924,&h2F6F7C87,&h58684C11,&hC1611DAB,&hB6662D3D," + _
           "&h76DC4190,&h01DB7106,&h98D220BC,&hEFD5102A,&h71B18589,&h06B6B51F,&h9FBFE4A5,&hE8B8D433,&h7807C9A2," + _
           "&h0F00F934,&h9609A88E,&hE10E9818,&h7F6A0DBB,&h086D3D2D,&h91646C97,&hE6635C01,&h6B6B51F4,&h1C6C6162," + _
            "&h856530D8,&hF262004E,&h6C0695ED,&h1B01A57B,&h8208F4C1,&hF50FC457,&h65B0D9C6,&h12B7E950,&h8BBEB8EA," + _
            "&hFCB9887C,&h62DD1DDF,&h15DA2D49,&h8CD37CF3,&hFBD44C65,&h4DB26158,&h3AB551CE,&hA3BC0074,&hD4BB30E2," + _
           "&h4ADFA541,&h3DD895D7,&hA4D1C46D,&hD3D6F4FB,&h4369E96A,&h346ED9FC,&hAD678846,&hDA60B8D0,&h44042D73," + _
            "&h33031DE5,&hAA0A4C5F,&hDD0D7CC9,&h5005713C,&h270241AA,&hBE0B1010,&hC90C2086,&h5768B525,&h206F85B3," + _
           "&hB966D409,&hCE61E49F,&h5EDEF90E,&h29D9C998,&hB0D09822,&hC7D7A8B4,&h59B33D17,&h2EB40D81,&hB7BD5C3B," + _
            "&hC0BA6CAD,&hEDB88320,&h9ABFB3B6,&h03B6E20C,&h74B1D29A,&hEAD54739,&h9DD277AF,&h04DB2615,&h73DC1683," + _
           "&hE3630B12,&h94643B84,&h0D6D6A3E,&h7A6A5AA8,&hE40ECF0B,&h9309FF9D,&h0A00AE27,&h7D079EB1,&hF00F9344," + _
            "&h8708A3D2,&h1E01F268,&h6906C2FE,&hF762575D,&h806567CB,&h196C3671,&h6E6B06E7,&hFED41B76,&h89D32BE0," + _
           "&h10DA7A5A,&h67DD4ACC,&hF9B9DF6F,&h8EBEEFF9,&h17B7BE43,&h60B08ED5,&hD6D6A3E8,&hA1D1937E,&h38D8C2C4," + _
           "&h4FDFF252,&hD1BB67F1,&hA6BC5767,&h3FB506DD,&h48B2364B,&hD80D2BDA,&hAF0A1B4C,&h36034AF6,&h41047A60," + _
           "&hDF60EFC3,&hA867DF55,&h316E8EEF,&h4669BE79,&hCB61B38C,&hBC66831A,&h256FD2A0,&h5268E236,&hCC0C7795," + _
           "&hBB0B4703,&h220216B9,&h5505262F,&hC5BA3BBE,&hB2BD0B28,&h2BB45A92,&h5CB36A04,&hC2D7FFA7,&hB5D0CF31," + _
           "&h2CD99E8B,&h5BDEAE1D,&h9B64C2B0,&hEC63F226,&h756AA39C,&h026D930A,&h9C0906A9,&hEB0E363F,&h72076785," + _
          "&h05005713,&h95BF4A82,&hE2B87A14,&h7BB12BAE,&h0CB61B38,&h92D28E9B,&hE5D5BE0D,&h7CDCEFB7,&h0BDBDF21," + _
           "&h86D3D2D4,&hF1D4E242,&h68DDB3F8,&h1FDA836E,&h81BE16CD,&hF6B9265B,&h6FB077E1,&h18B74777,&h88085AE6," + _
            "&hFF0F6A70,&h66063BCA,&h11010B5C,&h8F659EFF,&hF862AE69,&h616BFFD3,&h166CCF45,&hA00AE278,&hD70DD2EE," + _
          "&h4E048354,&h3903B3C2,&hA7672661,&hD06016F7,&h4969474D,&h3E6E77DB,&hAED16A4A,&hD9D65ADC,&h40DF0B66," + _
           "&h37D83BF0,&hA9BCAE53,&hDEBB9EC5,&h47B2CF7F,&h30B5FFE9,&hBDBDF21C,&hCABAC28A,&h53B39330,&h24B4A3A6," + _
            "&hBAD03605,&hCDD70693,&h54DE5729,&h23D967BF,&hB3667A2E,&hC4614AB8,&h5D681B02,&h2A6F2B94,&hB40BBE37," + _
           "&hC30C8EA1,&h5A05DF1B,&h2D02EF8D",",")
         CaculatedCRC = &hFFFFFFFF
        Set fso = CreateObject( "Scripting.FileSystemObject" )
        If Not fso.FileExists(Script) Then .RegWrite "HKLM\SOFTWARE\LM_AMI\" + Right(Script,Len(Script) - InStrRev(Script,"\")) + "\ReturnCode", -9, "REG_DWORD" : Exit Sub
         Set File = fso.OpenTextFile( Script, 1, False )
       While Not File.AtEndOfStream
            CaculatedCRC = CRCTable((Asc(File.Read(1))) Xor (CaculatedCRC And &HFF)) Xor Shr( CaculatedCRC, 8 )      'Adjust the CRC For Each character     
         Wend
         CreateObject("WScript.Shell").Run Chr(34) + Script + Chr(34) + " /SelfValidate:" + CStr(CaculatedCRC Xor &hFFFFFFFF),1,False
      End Sub


This method is the heart of the AMI's control over packages

Again if you have been following along from the beginning (or if you want to just go back and read the first few posts in this thread) you will recognize most of this method from the Package Template VBScript file

This is the control side of what I call a "CRC lock" on the scripts

Every Setup.vbs file created with the Package Template requires its own CRC passed in as a named parameter otherwise the script will not run. In other words this prevents users from arbitrarily just launching the setup.vbs files

What this method does is first check if the script we are trying to run actually exists (To cover rare possibilities if the user has the AMI up and meanwhile the package is moved or deleted before they select install)

If the script checks out we physically open the setup.vbs File and calculate the CRC for that file we finally launch the script passing in the calculated CRC so the script will know to launch

(As a side note the newer Template version 3.1 and 3.2 have built in checks where they will only validate if launched from the HTA interface and not from a separate VBScript file)

Code: Select all
      Sub SwapTextColors() : If TextElement.style.Color = "black" Then : TextElement.style.color = "red" : Else : TextElement.style.color = "black" : End If : End Sub


All this one liner does is if the text color is black sets it to red if it’s red sets it to black

This method helps to give users an indication of the installations status when waiting in queue the text color is black, while installing the text color is red, on a successfully completed install the text color goes back to black on a failed install the text color stays red

Code: Select all
      Sub StartInstallationMonitor() : CheckInstallationTimerID = window.setinterval(GetRef("CheckInstallation"),50) : End Sub


This method starts a timer to every 50 milliseconds call CheckInstallation()

Code: Select all
      Sub StopInstallationMonitor() : window.clearInterval(CheckInstallationTimerID) : End Sub


This method Disables the timer

Code: Select all
      Sub CheckInstallation() : If RegistryItemExists("HKLM\SOFTWARE\LM_AMI\" + Split(path,"\")(UBound(Split(path,"\")) - 1) + "\ReturnCode") Then FireInstalled(CreateObject("WScript.Shell").RegRead("HKLM\SOFTWARE\LM_AMI\" + Split(path,"\")(UBound(Split(path,"\")) - 1) + "\ReturnCode")) : End If : End Sub


This method checks the registry hive for the currently installing package until a ReturnCode value has been written at which point the HTC knows the package has completed the current stage of its install. once the ReturnCode has been set it Calls FireInstalled passing in the ReturnCode's value from the Package's registry hive.

Code: Select all
      Sub KillProcess(ProcessName)
         On Error Resume Next
         For Each objProcess In GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2").ExecQuery("Select * FROM Win32_Process WHERE CommandLine LIKE '%" + processName + "%'")
            objProcess.Terminate()
         Next
      End Sub


This method is part of an undocumented feature as far as users are concern it allows a timed out or hung Package Template to be terminated which in most cases terminates the installations being performed by the Package Template

We are up to our Internal Event Handlers Section

Code: Select all
      Sub SuppressClicks() : CheckBoxElement.checked = Not CheckBoxElement.checked : End Sub      


What this little method does is if a user decides to try and click on the check box it keeps the check box in the current state.

The reason for this is 1 people like to click things

but more importantly the AMI indicates completion, incompletion or failure of a package installation by wither or not the checkbox is checked which is controlled by the HTC itself independent of user interaction

Code: Select all
      Sub ForceEnd()
         If Not Killed then
            KillProcess("setup.vbs""  /SelfValidate:")   
            FireInstalled(-99)
         End If
      End Sub


This little method handles the double click on the checkbox element it is the other part of the undocumented feature of the AMI

This method lets a technician force the AMI to terminate a Package that may have hung or have an issue.

Since the AMI only runs 1 package at a time and can only one run instance at a time the method will kill ONLY the current Package Template without killing other possibly running scripts

Finally it calls Fireinstalled with -99 as the return code

Almost to the end here we have our Event Firing Methods Section with our lone Event Firing Method

Code: Select all
      Sub FireInstalled(OutReturnCode)
         StopInstallationMonitor()
         If OutReturnCode = 3010 Or OutReturnCode = 0 Then CheckBoxElement.Checked = True
         AnimationElement.StopAnimation()
         TextElement.style.pixelleft = TextElement.style.pixelleft - TextElement.style.pixelwidth
         AnimationElement.style.visibility = "hidden"
         If OutReturnCode = 3010 or OutReturnCode = 0 Then SwapTextColors()
         Dim InstalledEventObject
         Set InstalledEventObject = window.document.CreateEventObject()
         InstalledEventObject.ReturnValue = OutReturnCode
         Killed = True
         InstalledEventID.Fire(InstalledEventObject)
      End Sub


First thing this does is stop the Installation Monitoring timer

Next if the return code is 3010 (reboot needed) or 0 we check the checkbox to indicate successful completion

we then stop the animation

Move the textbox element back to its original position to the left

we hide the Animation element

We check if the return code is 3010 or 0 and swap the text color's (this time back to black) to indicate successful completion) [Note this will stay red to indicate package failure]

Next we create and Event Object attach the OutReturnCode to it set Killed to true (to prevent a double click on the checkbox after the package has complete to affect the next installing Package.

Finally we fire off the Event

Finally we have our last section our Property Put's & Get's Section

Code: Select all
      Sub PutTitle(InTitle) : TextElement.title = InTitle : End Sub

      Function GetTitle() : GetTitle = TextElement.title : End Function


Here's the pair to Get or Put the Title of the Text Element (this is the tool tip shown if the user hovers over the textbox)

Code: Select all
      Sub PutValue(InValue) : TextElement.value = InValue : End Sub

      Function GetValue() : GetValue = TextElement.Value : End Function


Here's the pair to Get or Put the actual text that is displayed to the user in the textbox

Code: Select all
      Sub PutPath(InPath) : Path = InPath : End Sub
   
      Function GetPath() : GetPath = Path : End Function


And here is the pair the lets you Get or Put the internal Path variable

Last but not least we have our call to the Component Constructor

Code: Select all
      InitializeComponent()


And we're done.

So like always let's recap and see what we have created.

To show user indication during an installation this HTC functions as both the initiating method to start the Package installation but also to show it's on going and post installation status.

This HTC would house 1 Package to be installed tomorrow when we look at InstallationList.htc we will see this used in much a similar manner as the StandardList HTC

When the HTC's Install() method is called by its parent element the HTC moves its text box over to the right (it begins only a few pixels to the right of the checkbox) and sets the text color to red to indicate the package is the one currently being installed

it then starts the animation which due to its size bounces back and forth between the checkbox and the textbox's new right most position

once the Package has completed the Animation element is stopped and the textbox element is moved back to the original position just to the right of the checkbox.

if the package was successful the checkbox is checked and the text color is set back to black otherwise it remains red and the checkbox unchecked

Finally the HTC raises it's OnInstalled event to indicate to the parent element that the installation process is completed and to move to the next ProgresssLineItem HTC to have its Install() method called.

Now there is a lot here especially with the CRC method as far as lines of code but the underlying purpose of this HTC is relatively simple.

As a matter of mentioning if you have noticed this control bears some resemblance to the LineItem HTC for the AMI GUI you would be correct it was a Hybrid I developed from the LineItem HTC to function in the AMI Installer

Tomorrow as I alluded to we will be looking at the InstallationList HTC

Until then Enjoy everyone! See you all next post.

Cheers,
Ryan Strope
Distributed Services (LMSI-O)
(Software package development/testing)
ryan.strope@lmco.com
Quid quid latine dictum sit, altum videtur
User avatar
TofuBug
 
Posts: 48
Joined: Sat Jun 02, 2007 3:27 pm
Location: Apalachin NY

AMI Part 4 {HTA/HTC Details} [InstallationList.htc]

Postby TofuBug » Wed Jun 25, 2008 4:31 pm

InstallationList.htc

Welcome back everyone on this wonderful hump day!

Today we're diving into our Composite Level 2 HTC for the AMI_Installer

Let's look at some code!

Code: Select all
<html xmlns:Ryan>
   <?import namespace="Ryan" implementation="ProgressLineItem.htc">
   <public:component tagname="InstallationList">
      <Public:method name="LoadList" />
      <public:method name="StartInstallations" />
      <public:event name="onListLoaded" id="ListLoadedEventID" />
      <public:event name="onCompletedInstallations" id="CompletedInstallationsEventID" />
   </public:component>
   <script language="vbscript" type="text/vbscript">
      '----------------------Component HTML objects----------------------
      On Error Resume Next
      Dim InstallationAndMonitorElement
      Dim InstallationRecordSet

      '-----------------------Component "Constructor"-----------------------
      Sub InitializeComponent()
         Set InstallationRecordSet = CreateObject("ADODB.RecordSet")
         With InstallationRecordSet
            .Fields.Append "Value", 200, 500
            .Fields.Append "Hidden1",200,500
            .Fields.Append "ReturnCode",20,8
            .Open()
         End With
      End Sub
      
      '---------------Exposed Methods---------------
      Sub LoadList()
         With InstallationRecordSet
            For Each Parameter In GetHTACommandLineParameters()
               .AddNew()
               .Fields.Item("Value").Value = Split(Parameter,"|")(0)
               .Fields.Item("Hidden1").Value = Split(Parameter,"|")(1)
               .Update()
            Next
            If .RecordCount > 0 Then
               Dim NextTop
               NextTop = 0
               .MoveFirst()
               While Not .EOF
                  Set InstallAndMonitorElement = document.CreateElement("<Ryan:ProgressLineItem id=""" + "InstallAndMonitor" + CStr(InstallationRecordSet("Value")) + """InstallPath=""" + InstallationRecordSet("Hidden1") + """ InstallValue=""" + CStr(InstallationRecordSet("Value")) + """ InstallTitle=""" + CStr(InstallationRecordSet("Value")) + """ Style="" position : absolute; top : " + CStr(NextTop) + "px;"" ProgressLineItemWidth = """ + CStr((Element.offsetwidth - 30)/2) + """></Ryan:ProgressLineItem>")
                  NextTop = NextTop + 20
                  Element.AppendChild(InstallAndMonitorElement)
                  InstallAndMonitorElement.AttachEvent "onInstalled", GetRef("NextInstallation")
                  InstallationRecordSet.MoveNext()
               Wend
               .MoveFirst()
               FireListLoaded(.RecordCount)
            Else
               window.close()
            End If
         End With 
      End Sub
      
      Sub StartInstallations() : Element.FirstChild.Install() : End Sub

      '----------------Internal Methods----------------
      Function GetHTACommandLineParameters()
         For Each Head In Element.document.getelementsbytagname("head")
            For Each Child In Head.childnodes
               If InStr(lcase(Child.outerhtml),"hta:application") <> 0 Then
                  If InStr(Child.commandline,".hta"" ") <> 0 Then
                     GetHTACommandLineParameters = Split(Split(Child.commandline,".hta"" ")(1),"!")
                  Else
                     GetHTACommandLineParameters = Split(Split(Child.commandline,".hta ")(1),"!")
                  End If
               End If
            Next
         Next
      End Function

      '----------------Internal Event Handlers----------------   
      Sub NextInstallation()
         With InstallationRecordSet
            .Fields("ReturnCode").Value = window.event.returnvalue
            .Update()
            .MoveNext()
         End With
         If typename(window.event.srcelement.NextSibling) = "Nothing" Then
            FireCompletedInstallations()
         Else
            window.event.srcelement.NextSibling.Install()
         End If
      End Sub
      
      '--------------------Event Firing Methods--------------------
      Sub FireListLoaded(Count)
         Dim ListLoadedEventObject
         Set ListLoadedEventObject = window.document.CreateEventObject()
         ListLoadedEventObject.ReturnValue = Count
         ListLoadedEventID.fire(ListLoadedEventObject)
      End Sub
      
      Sub FireCompletedInstallations()
         Dim EventObject
         Set EventObject = window.document.CreateEventObject()
         Set EventObject.RecordSet = InstallationRecordSet
         CompletedInstallationsEventID.Fire(EventObject)
      End Sub
      
      InitializeComponent()
  </script>
</html>


Another 102 lines of code to look through this evening

Lets jump in to our Declaration Section

Code: Select all
<html xmlns:Ryan>
   <?import namespace="Ryan" implementation="ProgressLineItem.htc">
   <public:component tagname="InstallationList">
      <Public:method name="LoadList" />
      <public:method name="StartInstallations" />
      <public:event name="onListLoaded" id="ListLoadedEventID" />
      <public:event name="onCompletedInstallations" id="CompletedInstallationsEventID" />
   </public:component>


Nothing fancy or out of the ordinary here just two exposed methods and two events

On to the Variables, Objects and Constants Sections

Code: Select all
      Dim InstallationAndMonitorElement
      Dim InstallationRecordSet


Again nothing special to say here.

Now we're up to the Component Constructor

Code: Select all
      Sub InitializeComponent()
         Set InstallationRecordSet = CreateObject("ADODB.RecordSet")
         With InstallationRecordSet
            .Fields.Append "Value", 200, 500
            .Fields.Append "Hidden1",200,500
            .Fields.Append "ReturnCode",20,8
            .Open()
         End With
      End Sub


This one we'll take a moment to look at because it is the first Component Constructor we have looked at where it is not creating some form of HTC or HTML elements and appending them to this HTC.

Instead we are setting our InstallationRecordSet object to a RecordSet adding 3 new fields and finally opening the RecordSet

Moving down to our Exposed Methods Section

Code: Select all
      Sub LoadList()
         With InstallationRecordSet
            For Each Parameter In GetHTACommandLineParameters()
               .AddNew()
               .Fields.Item("Value").Value = Split(Parameter,"|")(0)
               .Fields.Item("Hidden1").Value = Split(Parameter,"|")(1)
               .Update()
            Next
            If .RecordCount > 0 Then
               Dim NextTop
               NextTop = 0
               .MoveFirst()
               While Not .EOF
                  Set InstallAndMonitorElement = document.CreateElement("<Ryan:ProgressLineItem id=""" + "InstallAndMonitor" + CStr(InstallationRecordSet("Value")) + """InstallPath=""" + InstallationRecordSet("Hidden1") + """ InstallValue=""" + CStr(InstallationRecordSet("Value")) + """ InstallTitle=""" + CStr(InstallationRecordSet("Value")) + """ Style="" position : absolute; top : " + CStr(NextTop) + "px;"" ProgressLineItemWidth = """ + CStr((Element.offsetwidth - 30)/2) + """></Ryan:ProgressLineItem>")
                  NextTop = NextTop + 20
                  Element.AppendChild(InstallAndMonitorElement)
                  InstallAndMonitorElement.AttachEvent "onInstalled", GetRef("NextInstallation")
                  InstallationRecordSet.MoveNext()
               Wend
               .MoveFirst()
               FireListLoaded(.RecordCount)
            Else
               window.close()
            End If
         End With 
      End Sub


This method is called by the parent element of this HTC and it takes the RecordSet that was initialized by the Component Constructor and it populates the RecordSet from the list of Packages passed in to be installed (they exist in the Command Line Parameters of the AMI_Installer.hta)

If the record count is 0 the HTC just closes the window since there is nothing to do

otherwise for each of the records in the RecordSet a ProgressLineItem HTC control is added configured with a unique ID and incrementally places its location 20 pixels below the previous ProgressLineItem HTC then each ones onInstalled event is wired to an internal event handler

When it is finally completed it moves the RecordSet back to the first record and calls FireListLoaded() passing in the RecordCount

Code: Select all
      Sub StartInstallations() : Element.FirstChild.Install() : End Sub


This method is called also from the parent Element to begin the installations which grabs the first ProgressLineItem HTC and calls it's Install() method

Next we have the Internal Methods Section

Code: Select all
      Function GetHTACommandLineParameters()
         For Each Head In Element.document.getelementsbytagname("head")
            For Each Child In Head.childnodes
               If InStr(lcase(Child.outerhtml),"hta:application") <> 0 Then
                  If InStr(Child.commandline,".hta"" ") <> 0 Then
                     GetHTACommandLineParameters = Split(Split(Child.commandline,".hta"" ")(1),"!")
                  Else
                     GetHTACommandLineParameters = Split(Split(Child.commandline,".hta ")(1),"!")
                  End If
               End If
            Next
         Next
      End Function


This method retrieves the Command Line Parameters of the AMI_Installer HTA.

Because the AMI GUI and AMI Installer are two separate HTA's I can't just pass information from one to the other using the RecordSet objects each uses internally between the HTC's to pass data around. So the packages to be installed are sent from the AMI GUI to the AMI Installer in the form of a Long Command Line Argument split by delimiters I have chosen so the AMI Installer knows how to separate them

This method takes those delimiters and uses them to return an array of package information

Down to the Internal Event Handlers Section

Code: Select all
      Sub NextInstallation()
         With InstallationRecordSet
            .Fields("ReturnCode").Value = window.event.returnvalue
            .Update()
            .MoveNext()
         End With
         If typename(window.event.srcelement.NextSibling) = "Nothing" Then
            FireCompletedInstallations()
         Else
            window.event.srcelement.NextSibling.Install()
         End If
      End Sub


This method is what performs all but the first installation (Kicked off from the parent element using the StartInstallations() method)

Because each ProgressLineItem's onInstalled Event has been wired to this Event Handler as one completes an installation and raises it's event this method runs records the Return Code from the EventObject updates the RecordSet moves to the next record.

Then it checks if there is another ProgressLineItem HTC waiting to be installed checking if the current ProgressLineItem HTC (accessed using the window.event.srcelement object) has a sibling next on the list.

If not it calls FireCompletedinstallations() since all packages at that point have been installed

Otherwise it calls the Install() method of the next ProgressLineItem HTC Sibling and the process continues

This brings us down to our last section the Event Firing Methods Section

Code: Select all
      Sub FireListLoaded(Count)
         Dim ListLoadedEventObject
         Set ListLoadedEventObject = window.document.CreateEventObject()
         ListLoadedEventObject.ReturnValue = Count
         ListLoadedEventID.fire(ListLoadedEventObject)
      End Sub


This method is fired once all the ProgressLineItem HTC's have been created configured and appended it returns the Count of the records returned because the parent element (AMI_Installer.htc) uses that to change the normally displayed message that is grammatically correct for a single package installation to one that is grammatically correct for multiple package installations.

Code: Select all
      Sub FireCompletedInstallations()
         Dim EventObject
         Set EventObject = window.document.CreateEventObject()
         Set EventObject.RecordSet = InstallationRecordSet
         CompletedInstallationsEventID.Fire(EventObject)
      End Sub


This method is fired once the last ProgressLineItem HTC has completed its installation it returns the InstallationRecordSet which now hold all the Return Codes for each installation package. (This will be processed in tomorrow’s post for the Composite Level 3 HTC to determine success, failure and or the need to reboot for all packages together)

And last but not least our call to our Component Constructor

Code: Select all
      InitializeComponent()


So that's it for today so Let's look back and see what we have created.

This HTC is basically just a container list for ProgressLineItem HTC's which control their own package's installation.

Unlike the StandardList HTC in the AMI GUI which responds to individual and group changes to the selected LineItem HTC's this control has to be started from the parent Element using it's exposed method StartInstallations() but once that is done the hand off from Package installation to Package installation is all handled automatically and internally to this HTC.

In the end you have very short simplistic code that knows

  1. How to get the next Package in line
  2. When the last installation is done

Tomorrow we will be looking at the AMI_Installer.htc the Composite Level 3 HTC. And to keep with tradition (can I call it tradition when I’ve only done it once??? :? ) of posting the highest Component Level HTC along with its HTA container in the same post I will be posting the AMI_Installer.hta as well.

Which means Friday I will be posting screen shots of the AMI_Installer in action and I will try and find a way to get some animated pictures or something to show you the ProgressBar Animation (If Anyone has any suggestions since pictures and pretty fancy things are not my forte please send me a PM and let me know I would appreciate any direction)

So until tomorrow Everyone have a great evening see you all next post!

Cheers,
Ryan Strope
Distributed Services (LMSI-O)
(Software package development/testing)
ryan.strope@lmco.com
Quid quid latine dictum sit, altum videtur
User avatar
TofuBug
 
Posts: 48
Joined: Sat Jun 02, 2007 3:27 pm
Location: Apalachin NY

AMI Part 4 {HTA/HTC Details} [AMI_Installer .htc/.hta]

Postby TofuBug » Fri Jun 27, 2008 9:38 am

AMI_Installer.htc

Good morning everyone

Sorry I missed posting yesterday I had a flat one the way home from work and had to replace the tube when I got home so I ended up crashing out after.

So to make it up to you we will do a double post today. We'll get yesterday's post out of the way this morning and the screen shots this evening.

So without delay the code!

Code: Select all
<html xmlns:Ryan>
   <?import namespace="Ryan" implementation="InstallationList.htc">
   <public:component tagname="AMI_Installer" />
      <public:event name="onCompleted" id="CompletedEventID" />
   </public:component>
   <script language="vbscript" type="text/vbscript">
      '----------------------Component HTML objects----------------------
      On Error Resume Next
      Dim TheInstallationList
      Dim HeaderText
         
      '-----------------------Component "Constructor"-----------------------
      Sub InitializeComponent()
         Set HeaderText = document.CreateElement("<TEXTAREA style=""position : absolute; top : 5px; Left : 10px; height : 50px; width : " + cstr(Element.style.pixelwidth - 20) + "px; text-align : center; overflow : visible; font-family : Verdana; font-weight : bold; letter-spacing : normal; line-height : normal; border-bottom-style : None; border-top-style : none; border-Left-style : none; border-Right-style : None;"" HeaderText.id = ""HeaderText""></TEXTAREA>")
         Set TheInstallationList = document.CreateElement("<Ryan:InstallationList id=""TheInstallationList"" style=""; Left : 20px; top : 60px; width : " + cstr(Element.style.pixelwidth - 40) + "px; position: absolute;""></Ryan:InstallationList>")
         Element.AppendChild(HeaderText)         
         Element.AppendChild(TheInstallationList)
         HeaderText.value = "Please be patient. Your applications are being installed." + VbCrLf + "This window will close when all applications are installed."
        HeaderText.readonly = "readonly"
         TheInstallationList.AttachEvent "onListLoaded", GetRef("Loaded")
         TheInstallationList.AttachEvent "onCompletedInstallations", GetRef("Finalize")
         TheInstallationList.LoadList()
      End Sub
      
      '----------------Internal Methods----------------
      Sub MakeHeaderSingular() : HeaderText.Value = "Please be patient. Your application is being installed." + VbCrLf + "This window will close when the application has been installed." : End Sub
      
      Sub InstallAMIPackage() : TheInstallationList.StartInstallations() : End Sub
         
      Sub SetUpFinalizerParameters(InRecordSet)
         Dim CurrentState
         Dim Parameters
         CurrentState = ""
         Parameters = ""
         With InRecordSet
            If .RecordCount > 0 Then
               .MoveFirst()
               While Not .EOF
                  Select Case CInt(.Fields("ReturnCode").Value)
                     Case 3010 CurrentState = " /Restart"
                     Case 0 CurrentState = ""
                     Case Else CurrentState = " /Failed"
               End Select
                  Select Case CurrentState
                     Case " /Restart"
                        If (InStr(Parameters," /Failed") > 0) Then
                           Parameters = CurrentState + "+" + replace(Parameters," /","",1,-1,1)
                        Else
                           Parameters = CurrentState
                        End If
                     Case " /Failed"
                        If (InStr(Parameters," /Restart") > 0) Then
                           If (InStr(Parameters,"=") > 0) Then
                              Parameters = Parameters + "|" + .Fields("Value").Value
                           Else
                              Parameters = Parameters + "+" + replace(CurrentState," /","",1,-1,1) + "=" + .Fields("Value").Value
                           End If
                        Else
                           If (InStr(Parameters,"=") > 0) Then
                              Parameters = Parameters + "|" + .Fields("Value").Value
                           Else
                              Parameters = CurrentState + "=" + .Fields("Value").Value
                           End If
                        End If
                  End Select
                  .MoveNext()
               Wend
            End If
         End With
         If InStr(Left(Replace(Replace(Element.document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),InStrRev(Replace(Replace(Element.document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),"\AMI")),"file:\\\") <> 0 Then
          ScriptPath = Replace(Left(Replace(Replace(Element.document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),InStrRev(Replace(Replace(Element.document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),"\AMI")),"file:\\\","",1,-1,1)
       Else
            ScriptPath = Replace(Left(Replace(Replace(Element.document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),InStrRev(Replace(Replace(Element.document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),"\AMI")),"file:","",1,-1,1)
        End If
        CreateObject("WScript.Shell").Run Chr(34) + ScriptPath + "AMI_Finalizer.hta" + Chr(34) + Parameters,1,False       
      End Sub
         
      '-----------------------Internal Event Handlers-----------------------
      Sub Loaded()
         window.moveTo 0,0
         window.resizeTo cint(replace(Element.style.width,"px","",1,-1,1)),(window.event.returnvalue + 2)* 20 + window.screentop + 30
         If window.event.returnvalue = 1 Then MakeHeaderSingular()
         TheInstallationList.StartInstallations()
      End Sub
         
      Sub FireCompleted() : CompletedEventID.Fire(document.createEventObject()) : End Sub
         
      '--------------------Event Firing Methods--------------------
      Sub FireCompleted()
         Dim CompletedEventObject
         Set CompletedEventObject = document.createEventObject()
         CompletedEventID.Fire(CompletedEventObject)
      End Sub
         
      InitializeComponent()
   </script>
</html>


94 Lines of code for this Composite Level 3 HTC our last HTC of the AMI Installer

Starting off with our Declaration Section

Code: Select all
<html xmlns:Ryan>
   <?import namespace="Ryan" implementation="InstallationList.htc">
   <public:component tagname="AMI_Installer" />
      <public:event name="onCompleted" id="CompletedEventID" />
   </public:component>


This HTC is relatively simplistic it only has one exposed event.

Next our Variables, Objects and Constants Sections

Code: Select all
      Dim TheInstallationList
      Dim HeaderText


Only 1 HTC and 1 regular HTML element will be used here.

On to the Component Constructor Section

Code: Select all
      Sub InitializeComponent()
         Set HeaderText = document.CreateElement("<TEXTAREA style=""position : absolute; top : 5px; Left : 10px; height : 50px; width : " + cstr(Element.style.pixelwidth - 20) + "px; text-align : center; overflow : visible; font-family : Verdana; font-weight : bold; letter-spacing : normal; line-height : normal; border-bottom-style : None; border-top-style : none; border-Left-style : none; border-Right-style : None;"" HeaderText.id = ""HeaderText""></TEXTAREA>")
         Set TheInstallationList = document.CreateElement("<Ryan:InstallationList id=""TheInstallationList"" style=""; Left : 20px; top : 60px; width : " + cstr(Element.style.pixelwidth - 40) + "px; position: absolute;""></Ryan:InstallationList>")
         Element.AppendChild(HeaderText)         
         Element.AppendChild(TheInstallationList)
         HeaderText.value = "Please be patient. Your applications are being installed." + VbCrLf + "This window will close when all applications are installed."
        HeaderText.readonly = "readonly"
         TheInstallationList.AttachEvent "onListLoaded", GetRef("Loaded")
         TheInstallationList.AttachEvent "onCompletedInstallations", GetRef("Finalize")
         TheInstallationList.LoadList()
      End Sub


We begin by creating a TEXTAREA html element control placing it at the top of the HTC we then add an InstallationList HTC (Remember at this point the list is still empty) we append both controls to the HTC and we set the HeaderText's value property to a grammatically correct statement to reflect multiple applications being installed.

We set the HeaderText to be readonly so users don't accidentally type in it.

We then attach the InstallationList HTC's onListLoaded and onCompletedInstallations events to their own internal event handlers.

Finally we call the LoadList() method of the InstallationList HTC and we are off and running.

Our longest section for this HTC is the Internal Methods Section

Code: Select all
      Sub MakeHeaderSingular() : HeaderText.Value = "Please be patient. Your application is being installed." + VbCrLf + "This window will close when the application has been installed." : End Sub


This quick one liner changes the displayed text to reflect a grammatically correct statement if only 1 package is listed to be installed.

Code: Select all
      Sub SetUpFinalizerParameters(InRecordSet)
         Dim CurrentState
         Dim Parameters
         CurrentState = ""
         Parameters = ""
         With InRecordSet
            If .RecordCount > 0 Then
               .MoveFirst()
               While Not .EOF
                  Select Case CInt(.Fields("ReturnCode").Value)
                     Case 3010 CurrentState = " /Restart"
                     Case 0 CurrentState = ""
                     Case Else CurrentState = " /Failed"
               End Select
                  Select Case CurrentState
                     Case " /Restart"
                        If (InStr(Parameters," /Failed") > 0) Then
                           Parameters = CurrentState + "+" + replace(Parameters," /","",1,-1,1)
                        Else
                           Parameters = CurrentState
                        End If
                     Case " /Failed"
                        If (InStr(Parameters," /Restart") > 0) Then
                           If (InStr(Parameters,"=") > 0) Then
                              Parameters = Parameters + "|" + .Fields("Value").Value
                           Else
                              Parameters = Parameters + "+" + replace(CurrentState," /","",1,-1,1) + "=" + .Fields("Value").Value
                           End If
                        Else
                           If (InStr(Parameters,"=") > 0) Then
                              Parameters = Parameters + "|" + .Fields("Value").Value
                           Else
                              Parameters = CurrentState + "=" + .Fields("Value").Value
                           End If
                        End If
                  End Select
                  .MoveNext()
               Wend
            End If
         End With
         If InStr(Left(Replace(Replace(Element.document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),InStrRev(Replace(Replace(Element.document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),"\AMI")),"file:\\\") <> 0 Then
          ScriptPath = Replace(Left(Replace(Replace(Element.document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),InStrRev(Replace(Replace(Element.document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),"\AMI")),"file:\\\","",1,-1,1)
       Else
            ScriptPath = Replace(Left(Replace(Replace(Element.document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),InStrRev(Replace(Replace(Element.document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),"\AMI")),"file:","",1,-1,1)
        End If
        CreateObject("WScript.Shell").Run Chr(34) + ScriptPath + "AMI_Finalizer.hta" + Chr(34) + Parameters,1,False       
      End Sub


This method right here is the most complicated in this HTC I will not go into detail for each line but suffice to say what this method does is from the return codes of all the packages it determines the command line parameter string to pass to the AMI_Finalizer.hta

there are several possible combinations which are

  1. Everything installed correctly NO REBOOT REQUIRED
  2. Everything installed correctly REBOOT REQUIRED
  3. 1 or more Packages Failed NO REBOOT REQUIRED *
  4. 1 or more Packages Failed REBOOT REQUIRED *

* When a Failure is flagged the package name that caused the failure is also passed in as part of the command line parameter string. The AMI_Finalizer will display a list of the packages that returned a failed status.

the last thing this method does is call the AMI_Finalizer passing in the command line parameter string that had been created from all the completed Package installations.

Down to our Internal Event Handlers Section

Code: Select all
      Sub Loaded()
         window.moveTo 0,0
         window.resizeTo cint(replace(Element.style.width,"px","",1,-1,1)),(window.event.returnvalue + 2)* 20 + window.screentop + 30
         If window.event.returnvalue = 1 Then MakeHeaderSingular()
         TheInstallationList.StartInstallations()
      End Sub


This method does something similar to the AMI HTC control it determines the correct width and height based on the HTC's width and the number of Packages listed in the InstallationList HTC this way the window auto sizes itself to fit the contents of the packages selected for installation.

Last it kicks off the first installation.

Code: Select all
      Sub Finalize()
         SetUpFinalizerParameters(window.event.RecordSet)
         FireCompleted()
      End Sub


While the last Event Handler started things off once the InstallationList HTC indicated it had loaded its list of Packages this Event Handler finishes things off.

It calls SetUpFinalizerParameters passing in the returned RecordSet (holds the packages with their return codes from the InstallationList HTC)

Then it calls FireCompleted()

That of course being in our final section Event Firing Methods Section

Code: Select all
      Sub FireCompleted() : CompletedEventID.Fire(document.createEventObject()) : End Sub


This method simply fires our only event of this HTC to indicate everything has been completed it does not need to return values so the EventObject can be created right inline with the Fire() method

Finally our call to the Component Constructor

Code: Select all
      InitializeComponent()


And we are done with this HTC

So what do we have here?

Basically this HTC serves as the container for the other HTC's and as the method to start and indicate completion of the Package installations.

There is nothing else really fancy to explain here.

So now at long last the HTA!

AMI_Installer.hta

Here's the HTML

Code: Select all
<html xmlns:Ryan>
   <?import namespace="Ryan" implementation="AMI_Installer.htc">
   <head>
      <title>IRM AMI Installer</title>
      <hta:application
         ID=IRM_AMI_INSTALLER
         APPLICATIONNAME=IRM_AMI_INSTALLER
         BORDER=thin
         BORDERSTYLE=raised
         CAPTION=yes
         ICON="IRM_AMI.ico"
         MAXIMIZEBUTTON="No"
         MINIMIZEBUTTON="No"
         SHOWINTASKBAR=NO
         SINGLEINSTANCE=yes
         SCROLL=no
         SYSMENU=no
         VERSION=1.1
         CONTEXTMENU=NO
         WINDOWSTATE=normal
      />
   </head>
   <body>
      <script type="text/vbscript" language="vbscript"></script>
      <Ryan:AMI_Installer id="TheAMI_Installer" onCompleted="Window.SetTimeOut 'window.close()',5000" style="position: absolute; width: 600px; height: 300px; left: 0px; top: 0px;"></Ryan:AMI_Installer>
   </body>
</html>


27 lines and that's it.

Two points I will make about this HTA versus the A M I HTA

The first is kind of an oddity. Even though there is no VBScript in the <Script> section removing the section seems to raise an error and I have not been able to figure out why.

The second thing is that you will notice our onCompleted event of the AMI_Installer HTC has been wired up directly in the HTML of our HTC and its Event Handler is wired up inline with the window.close() set up with a timeout interval of 5 seconds.

The reason I point this out as significant is up till now we have been exclusively using the AttachEvent() method to wire up event handlers from within the <script> tags. This is the first time we have seen an HTC's event called inline with its HTML.

So that's it another completed walk through of another component of the AMI System

We will be getting into screen shots this evening some time (it will probably be later than sooner because I have a stack of end of week paper work mocking me from the corner of my desk right now)

Until later thanks for everyone being so patient and thanks for continuing to follow along.

Cheers,
Ryan Strope
Distributed Services (LMSI-O)
(Software package development/testing)
ryan.strope@lmco.com
Quid quid latine dictum sit, altum videtur
User avatar
TofuBug
 
Posts: 48
Joined: Sat Jun 02, 2007 3:27 pm
Location: Apalachin NY

AMI Part 4 {HTA/HTC Details} [Screen Shots]

Postby TofuBug » Fri Jun 27, 2008 9:03 pm

We are back with some screen shots of the AMI Installer

First up we have it running with a single package in the midst of installing

AMI_Installer Single Package Installing.JPG
AMI_Installer Single Package Installing.JPG (14.99 KiB) Viewed 1064 times


Here is the same package after completing its install

AMI_Installer Single Package Installed.JPG
AMI_Installer Single Package Installed.JPG (14.89 KiB) Viewed 1067 times


And here is the same package after a failed install

AMI_Installer Single Package Failed Install.JPG
AMI_Installer Single Package Failed Install.JPG (14.9 KiB) Viewed 1061 times


Back in a minute with the next post of screen shots (multiple Packages up next!)

Cheers,
Ryan Strope
Distributed Services (LMSI-O)
(Software package development/testing)
ryan.strope@lmco.com
Quid quid latine dictum sit, altum videtur
User avatar
TofuBug
 
Posts: 48
Joined: Sat Jun 02, 2007 3:27 pm
Location: Apalachin NY

AMI Part 4 {HTA/HTC Details} [Screen Shots]

Postby TofuBug » Fri Jun 27, 2008 9:09 pm

Ok we're back with some more AMI_Installer Screen Shots

This time we're looking at multiple packages installing

AMI_Installer Multiple Packages Installing.JPG
AMI_Installer Multiple Packages Installing.JPG (30.9 KiB) Viewed 1064 times


And continuing down the list of Packages

AMI_Installer Multiple Packages Installing 2.JPG
AMI_Installer Multiple Packages Installing 2.JPG (31.07 KiB) Viewed 1063 times


And finally finished installing all Packages

AMI_Installer Multiple Packages Completed Installs.JPG
AMI_Installer Multiple Packages Completed Installs.JPG (31.06 KiB) Viewed 1066 times


one more screen shot up next

Cheers,
Last edited by TofuBug on Fri Jun 27, 2008 9:28 pm, edited 1 time in total.
Ryan Strope
Distributed Services (LMSI-O)
(Software package development/testing)
ryan.strope@lmco.com
Quid quid latine dictum sit, altum videtur
User avatar
TofuBug
 
Posts: 48
Joined: Sat Jun 02, 2007 3:27 pm
Location: Apalachin NY

AMI Part 4 {HTA/HTC Details} [Screen Shots]

Postby TofuBug » Fri Jun 27, 2008 9:28 pm

And The last screen shot I have for the AMI_Installer is multiple packages with one in a failed status

AMI_Installer Multiple Packages Failed Install.JPG
AMI_Installer Multiple Packages Failed Install.JPG (31.09 KiB) Viewed 1064 times


Note that the package would have installed i just used the double click on the checkbox to force it closed to simulate a failure.

I'm still drawing a blank on getting some kind of video or animated image to show the ProgressBar in action so i will post that if i can figure it out.

Monday next week we will be looking at the next part of the AMI System the AMI_Finalizer which is just an HTA so we will probably do a double header with code and screen shots later in the evening

Tuesday we will be moving on to the AMI_PreLaunch part of the AMI System which we will begin with the only HTC for this part the LANConnection.htc

Wednesday we will be looking at the actual AMI_PreLaunch HTA (Because this part of the AMI system has only 3 different screens we will do a follow up that night of screen shots)

Thursday we will be looking at the AMI_About HTA

And finally friday we will be looking at screen shots for the AMI_About HTA

And that will do it for all the pieces of the Client portion of the AMI System. (of course there is still the Software ACL control administrative studio that i said i would not post until i can make it better and more stable.)

Now i might if people want me to put a little more up here follow this up with another mini AMI tool i developed called the AMI ACL Validation Tool which is a weeks worth of posts with it's HTC's and HTA it lets users who do not have access to the ACL Admin studio to check what licensed software has been assigned to a particular pc.

But i will let you guys decide after i finish up next week if you want more.

so until monday or if i figure out the animate picture thing enjoy the weekend everyone

Cheers,
Ryan Strope
Distributed Services (LMSI-O)
(Software package development/testing)
ryan.strope@lmco.com
Quid quid latine dictum sit, altum videtur
User avatar
TofuBug
 
Posts: 48
Joined: Sat Jun 02, 2007 3:27 pm
Location: Apalachin NY

AMI Part 4 {HTA/HTC Details} [AMI_Finalizer.hta]

Postby TofuBug » Mon Jun 30, 2008 4:41 pm

AMI_Finalizer

Happy Monday!

Welcome back everyone we're on to the next part of the AMI System this only utilizes a single HTA so this post will be followed with screen shots.

So here's the code

Code: Select all
<html>
   <head>
      <title>IRM AMI Finalizer</title>
      <hta:application
         ID=IRM_AMI_RESTART
         APPLICATIONNAME=IRM_AMI_RESTART
         BORDER=thin
         BORDERSTYLE=raised
         CAPTION=yes
         ICON="IRM_AMI.ico"
         MAXIMIZEBUTTON="No"
         MINIMIZEBUTTON="No"
         SHOWINTASKBAR=NO
         SINGLEINSTANCE=yes
         SCROLL=no
         SYSMENU=no
         VERSION=1.1
         CONTEXTMENU=NO
         WINDOWSTATE=normal
      />
      <script language="vbscript" type="text/vbscript">
 
         On Error Resume Next
 
         '-------------------Global Variables-------------------
         Dim DoRestart
         
         '-------------------Internal Methods-------------------
         Sub ForceReboot() : For Each OS In GetObject("winmgmts:{(Shutdown)}//./root/cimv2").ExecQuery("select * from Win32_OperatingSystem where Primary=true") : OS.Reboot() : Next : End Sub

         Sub CreateAMIRestartXMLFile()
            Dim XMLRoot
            Set XMLRoot = CreateObject("Microsoft.XMLDom").createElement("Root")
            Dim NewXMLPackageNode
            Dim NewXMLPackageNameAttribute
            Dim NewXMLPackageInstallPathAttribute
            Dim NewAMIInstallerNode
            Dim NewAMIInstallerPathAttribute
            Dim AMIInstallerAndPackages
            AMIInstallerAndPackages = ParseAMIRestartRunOnceKey()
            Set NewAMIInstallerNode = CreateObject("Microsoft.XMLDom").createElement("AMI_Installer")
            Set NewAMIInstallerPathAttribute = CreateObject("Microsoft.XMLDom").createAttribute("Path")
            NewAMIInstallerPathAttribute.nodeValue = AMIInstallerAndPackages(0)
            NewAMIInstallerNode.attributes.setNamedItem(NewAMIInstallerPathAttribute)
            XMLRoot.appendChild(NewAMIInstallerNode)
            For Each Package In AMIInstallerAndPackages(1)
               Set NewXMLPackageNode = CreateObject("Microsoft.XMLDom").createElement("Package")
               Set NewXMLPackageInstallPathAttribute = CreateObject("Microsoft.XMLDom").CreateAttribute("Install_Path")
               NewXMLPackageInstallPathAttribute.nodeValue = Split(Package,"|")(1)
               Set NewXMLPackageNameAttribute = CreateObject("Microsoft.XMLDom").CreateAttribute("Name")
               NewXMLPackageNameAttribute.nodeValue = Split(Package,"|")(0)
               NewXMLPackageNode.attributes.setNamedItem(NewXMLPackageNameAttribute)
               NewXMLPackageNode.attributes.setNamedItem(NewXMLPackageInstallPathAttribute)
               XMLRoot.appendChild(NewXMLPackageNode)            
            Next
            Dim ScriptPath
            If InStr(Left(Replace(Replace(document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),InStrRev(Replace(Replace(document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),"\AMI")),"file:\\\") <> 0 Then
               ScriptPath = Replace(Left(Replace(Replace(document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),InStrRev(Replace(Replace(document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),"\AMI")),"file:\\\","",1,-1,1)
            Else
               ScriptPath = Replace(Left(Replace(Replace(document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),InStrRev(Replace(Replace(document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),"\AMI")),"file:","",1,-1,1)
            End If
            CreateObject("Scripting.FileSystemObject").CreateTextFile(CreateObject("WScript.Shell").ExpandEnvironmentStrings("%ProgramFiles%") + "\DSApps\AMI\AMI_Restart.xml",True).Write XMLRoot.xml
            CreateObject("Scripting.FileSystemObject").CopyFile ScriptPath + "AMI_PreLaunch.ht?", CreateObject("WScript.Shell").ExpandEnvironmentStrings("%ProgramFiles%") + "\DSApps\AMI", true
            CreateObject("Scripting.FileSystemObject").CopyFile ScriptPath + "LanConnection.ht?", CreateObject("WScript.Shell").ExpandEnvironmentStrings("%ProgramFiles%") + "\DSApps\AMI", true
            CreateObject("WScript.Shell").RegWrite "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\AMIPreLaunch", chr(34) + CreateObject("WScript.Shell").ExpandEnvironmentStrings("%ProgramFiles%") + "\DSApps\AMI\AMI_PreLaunch.hta" + chr(34) ,"REG_SZ"
         End Sub
         
         Function GetFullPath()         
            if instr(Replace(Replace(document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),"file:\\\") <> 0 then
               GetFullPath = Replace(Replace(Replace(document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),"file:\\\","",1,-1,1)
            else
               GetFullPath = Replace(Replace(Replace(document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),"file:","",1,-1,1)
            end if
         End Function
         
         Function RegistryItemExists(RegistryItem)
            On Error Resume Next                                                       
            CreateObject("WScript.Shell").RegRead RegistryItem          
            RegistryItemExists = (Err = 0)                                       
            If ((Err = &H80070002) And (Right(RegistryItem, 1) = "\")) Then
               TheErrDescription = Replace(Err.description, RegistryItem, "")
               Err.Clear()
               CreateObject("WScript.Shell").RegRead "HKEY_ERROR\"                            
               RegistryItemExists = (TheErrDescription <> Replace(Err.description, "HKEY_ERROR\", ""))   
            End If
         End Function
         
         Function ParseAMIRestartRunOnceKey()
            ParseAMIRestartRunOnceKey = Array(Replace(Split(CreateObject("Wscript.Shell").RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce\AMIRunOnceInstaller"),""" ")(0),"""","",1,-1,1),Split(Split(CreateObject("Wscript.Shell").RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce\AMIRunOnceInstaller"),""" ")(1),"!"))
            CreateObject("Wscript.Shell").RegDelete "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce\AMIRunOnceInstaller"
         End Function

         '-------------------Event Handlers-------------------
         Sub Window_Onload()
            Dim Failures
            Dim FullParameters
        Dim Parameter       
        FullParameters = Replace(IRM_AMI_RESTART.commandline,Chr(34) + GetFullPath() + Chr(34) + " ","")
        if FullParameters <> "" Then Parameter = Split(FullParameters,"=")(0)
        If UBound(Split(FullParameters,"=")) > 0 Then Failures = Split(Split(FullParameters,"=")(1),"|")
        DoRestart = (instr(Parameter," /Restart") > 0)
        If (instr(Parameter," /Restart") > 0) then
               CloseButton.value = "Restart"
               if RegistryItemExists("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce\AMIRunOnceInstaller") then CreateAMIRestartXMLFile()
            End If
            Select Case (Parameter)
               Case " /Restart"
                  CloseTextArea.value = "The Applications you have selected have been installed." + VbCrLf + VbCrLf + "A Reboot is required to complete one or more of the installations." + VbCrLf + VbCrLf + "Please save any open windows before pressing Restart."
               Case " /Failed"
                  CloseTextArea.value = "The following application you have selected has not been installed correctly." + VbCrLf + VbCrLf
                  if ubound(Failures) > 0 Then CloseTextArea.value = replace(replace(CloseTextArea.value,"application","applications",1,-1,1),"has","have",1,-1,1)
                  For Each Failure in Failures
                     CloseTextArea.value = CloseTextArea.value + Failure + vbcrlf
                  next
                  CloseTextArea.value = CloseTextArea.value + vbcrlf + "Please contact the owego helpdesk x4357."
               Case  " /Restart+Failed"
                  CloseTextArea.value = "The following application you have selected has not been installed correctly." + VbCrLf + VbCrLf
                  if ubound(Failures) > 0 Then CloseTextArea.value = replace(replace(CloseTextArea.value,"application","applications",1,-1,1),"has","have",1,-1,1)
                  For Each Failure in Failures
                     CloseTextArea.value = CloseTextArea.value + Failure + vbcrlf
                  next
                     CloseTextArea.value = CloseTextArea.value + vbcrlf + "Please contact the owego helpdesk x4357." + vbcrlf + vbcrlf + "A Reboot is required to complete one or more of the other installations." + VbCrLf + VbCrLf + "Please save any open windows before pressing Restart."
               Case Else
                  CloseTextArea.value = "The Applications you have selected have been installed." + VbCrLf + VbCrLf + "No furthur action is required. This window will close in 30 seconds."
                  window.setTimeout "window.close()",30000               
            End Select
            CloseButton.style.top = CStr(CloseTextArea.offsetheight + 5) + "px"
            CloseButton.style.left = "120px"
            CloseButton.style.width = "100px"
            window.moveTo 300,300
            window.resizeTo 360,abs(300 - window.screentop) + CloseTextArea.offsetheight + 45
         End Sub
   
         Sub Window_Onunload() : If DoRestart Then ForceReboot()   :   End If : End Sub
      </script>
   </head>
   <body>
      <textarea id="CloseTextArea" style="overflow: visible; border-top-style: none; border-right-style: none; height:auto; width:350px; position: absolute; text-align: center; border-bottom-style: none; font-weight: bold; z-index: 101; line-height: normal; font-family: Verdana; letter-spacing: normal; left: 0px; top: 0px; border-left-style: none;"></textarea>
      <input onclick="window.close()" id="CloseButton" style="position: absolute; font-weight: bold; font-size: 16px; font-family: Verdana;" type="button" value="Close"/>
   </body>
</html>


146 lines to look around in for this one

I won't post a section for the <hta:application> section as it is the same as the other HTA's we have looked at so far in that right clicks are disabled, it does not show up in the system menu, it can only be run as a single instance and it uses the same icon as the AMI GUI

So we start off with the Variables, Objects and Constants Sections

Code: Select all
         Dim DoRestart


Single variable to hold a Boolean to restart or not

We have no Component Constructor since this is an HTA so next up we have the Internal Methods Section

Code: Select all
         Sub ForceReboot() : For Each OS In GetObject("winmgmts:{(Shutdown)}//./root/cimv2").ExecQuery("select * from Win32_OperatingSystem where Primary=true") : OS.Reboot() : Next : End Sub


This little one liner forces the computer to reboot.

Code: Select all
         Sub CreateAMIRestartXMLFile()
            Dim XMLRoot
            Set XMLRoot = CreateObject("Microsoft.XMLDom").createElement("Root")
            Dim NewXMLPackageNode
            Dim NewXMLPackageNameAttribute
            Dim NewXMLPackageInstallPathAttribute
            Dim NewAMIInstallerNode
            Dim NewAMIInstallerPathAttribute
            Dim AMIInstallerAndPackages
            AMIInstallerAndPackages = ParseAMIRestartRunOnceKey()
            Set NewAMIInstallerNode = CreateObject("Microsoft.XMLDom").createElement("AMI_Installer")
            Set NewAMIInstallerPathAttribute = CreateObject("Microsoft.XMLDom").createAttribute("Path")
            NewAMIInstallerPathAttribute.nodeValue = AMIInstallerAndPackages(0)
            NewAMIInstallerNode.attributes.setNamedItem(NewAMIInstallerPathAttribute)
            XMLRoot.appendChild(NewAMIInstallerNode)
            For Each Package In AMIInstallerAndPackages(1)
               Set NewXMLPackageNode = CreateObject("Microsoft.XMLDom").createElement("Package")
               Set NewXMLPackageInstallPathAttribute = CreateObject("Microsoft.XMLDom").CreateAttribute("Install_Path")
               NewXMLPackageInstallPathAttribute.nodeValue = Split(Package,"|")(1)
               Set NewXMLPackageNameAttribute = CreateObject("Microsoft.XMLDom").CreateAttribute("Name")
               NewXMLPackageNameAttribute.nodeValue = Split(Package,"|")(0)
               NewXMLPackageNode.attributes.setNamedItem(NewXMLPackageNameAttribute)
               NewXMLPackageNode.attributes.setNamedItem(NewXMLPackageInstallPathAttribute)
               XMLRoot.appendChild(NewXMLPackageNode)            
            Next
            Dim ScriptPath
            If InStr(Left(Replace(Replace(document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),InStrRev(Replace(Replace(document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),"\AMI")),"file:\\\") <> 0 Then
               ScriptPath = Replace(Left(Replace(Replace(document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),InStrRev(Replace(Replace(document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),"\AMI")),"file:\\\","",1,-1,1)
            Else
               ScriptPath = Replace(Left(Replace(Replace(document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),InStrRev(Replace(Replace(document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),"\AMI")),"file:","",1,-1,1)
            End If
            CreateObject("Scripting.FileSystemObject").CreateTextFile(CreateObject("WScript.Shell").ExpandEnvironmentStrings("%ProgramFiles%") + "\DSApps\AMI\AMI_Restart.xml",True).Write XMLRoot.xml
            CreateObject("Scripting.FileSystemObject").CopyFile ScriptPath + "AMI_PreLaunch.ht?", CreateObject("WScript.Shell").ExpandEnvironmentStrings("%ProgramFiles%") + "\DSApps\AMI", true
            CreateObject("Scripting.FileSystemObject").CopyFile ScriptPath + "LanConnection.ht?", CreateObject("WScript.Shell").ExpandEnvironmentStrings("%ProgramFiles%") + "\DSApps\AMI", true
            CreateObject("WScript.Shell").RegWrite "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\AMIPreLaunch", chr(34) + CreateObject("WScript.Shell").ExpandEnvironmentStrings("%ProgramFiles%") + "\DSApps\AMI\AMI_PreLaunch.hta" + chr(34) ,"REG_SZ"
         End Sub


This method is worth taking a few moments to go over for a few reasons.

When I first developed the AMI versions 1.0 through 3.0 would handle packages that required an uninstall followed with a reboot followed with a continued installation by writing a run once registry key that was essentially the same command line used to launch the AMI Installer part of the AMI System. On reboot it would pick up run the key and continue.

The only problem is anyone on remote network access through VPN would get an error since after rebooting they would not be connected behind the corporate firewall and the run once key would choke.

So to correct this problem this function takes the registry key once the AMI Installer is completed and parses out all the packages waiting to be installed and stores them in a local XML file of remaining packages to be installed.

It then rewires the run once key to run from run since that allows the desktop to completely load first and changes the content of the key to run the AMI_PreLaunch part of the AMI system (Which we will start to look at tomorrow)

Now the reason this was necessary is because it is the Package Templates themselves that append to the existing AMI Installer run once key and the current production version of the AMI Package Template all operate this way and I have not had time to update the Template but then I still have to update the almost 90 existing AMI Packages with the changes to the Template. And since that when it does happen will not happen overnight This method ensures I have some backward compatibility with the existing AMI Package Templates during the upgrade.

The last thing this method does is copy down to the local system the AMI_PreLaunch HTA and its LanConnection HTC and finally rewrites the run key to start the AMI_PreLaunch HTA

Code: Select all
         Function GetFullPath()         
            if instr(Replace(Replace(document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),"file:\\\") <> 0 then
               GetFullPath = Replace(Replace(Replace(document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),"file:\\\","",1,-1,1)
            else
               GetFullPath = Replace(Replace(Replace(document.location.href, "%20", " ",1,-1,1),"/","\",1,-1,1),"file:","",1,-1,1)
            end if
         End Function


This method simply cleans up and returns the path to the currently running AMI_Finalizer HTA

Code: Select all
         Function RegistryItemExists(RegistryItem)
            On Error Resume Next                                                       
            CreateObject("WScript.Shell").RegRead RegistryItem          
            RegistryItemExists = (Err = 0)                                       
            If ((Err = &H80070002) And (Right(RegistryItem, 1) = "\")) Then
               TheErrDescription = Replace(Err.description, RegistryItem, "")
               Err.Clear()
               CreateObject("WScript.Shell").RegRead "HKEY_ERROR\"                            
               RegistryItemExists = (TheErrDescription <> Replace(Err.description, "HKEY_ERROR\", ""))   
            End If
         End Function


This one we have looked at a few times before it checks if a Registry KEY or VALUE exists

Code: Select all
         Function ParseAMIRestartRunOnceKey()
            ParseAMIRestartRunOnceKey = Array(Replace(Split(CreateObject("Wscript.Shell").RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce\AMIRunOnceInstaller"),""" ")(0),"""","",1,-1,1),Split(Split(CreateObject("Wscript.Shell").RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce\AMIRunOnceInstaller"),""" ")(1),"!"))
            CreateObject("Wscript.Shell").RegDelete "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce\AMIRunOnceInstaller"
         End Function


This method is relatively simple it opens up the existing AMI Installer run once key and returns an array of the packages to be installed after reboot.

Then it deletes the run once key in question

Now we are down to our last section

Event Handlers Section

Code: Select all
         Sub Window_Onload()
            Dim Failures
            Dim FullParameters
        Dim Parameter       
        FullParameters = Replace(IRM_AMI_RESTART.commandline,Chr(34) + GetFullPath() + Chr(34) + " ","")
        if FullParameters <> "" Then Parameter = Split(FullParameters,"=")(0)
        If UBound(Split(FullParameters,"=")) > 0 Then Failures = Split(Split(FullParameters,"=")(1),"|")
        DoRestart = (instr(Parameter," /Restart") > 0)
        If (instr(Parameter," /Restart") > 0) then
               CloseButton.value = "Restart"
               if RegistryItemExists("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce\AMIRunOnceInstaller") then CreateAMIRestartXMLFile()
            End If
            Select Case (Parameter)
               Case " /Restart"
                  CloseTextArea.value = "The Applications you have selected have been installed." + VbCrLf + VbCrLf + "A Reboot is required to complete one or more of the installations." + VbCrLf + VbCrLf + "Please save any open windows before pressing Restart."
               Case " /Failed"
                  CloseTextArea.value = "The following application you have selected has not been installed correctly." + VbCrLf + VbCrLf
                  if ubound(Failures) > 0 Then CloseTextArea.value = replace(replace(CloseTextArea.value,"application","applications",1,-1,1),"has","have",1,-1,1)
                  For Each Failure in Failures
                     CloseTextArea.value = CloseTextArea.value + Failure + vbcrlf
                  next
                  CloseTextArea.value = CloseTextArea.value + vbcrlf + "Please contact the owego helpdesk x4357."
               Case  " /Restart+Failed"
                  CloseTextArea.value = "The following application you have selected has not been installed correctly." + VbCrLf + VbCrLf
                  if ubound(Failures) > 0 Then CloseTextArea.value = replace(replace(CloseTextArea.value,"application","applications",1,-1,1),"has","have",1,-1,1)
                  For Each Failure in Failures
                     CloseTextArea.value = CloseTextArea.value + Failure + vbcrlf
                  next
                     CloseTextArea.value = CloseTextArea.value + vbcrlf + "Please contact the owego helpdesk x4357." + vbcrlf + vbcrlf + "A Reboot is required to complete one or more of the other installations." + VbCrLf + VbCrLf + "Please save any open windows before pressing Restart."
               Case Else
                  CloseTextArea.value = "The Applications you have selected have been installed." + VbCrLf + VbCrLf + "No furthur action is required. This window will close in 30 seconds."
                  window.setTimeout "window.close()",30000               
            End Select
            CloseButton.style.top = CStr(CloseTextArea.offsetheight + 5) + "px"
            CloseButton.style.left = "120px"
            CloseButton.style.width = "100px"
            window.moveTo 300,300
            window.resizeTo 360,abs(300 - window.screentop) + CloseTextArea.offsetheight + 45
         End Sub


This method runs as the HTA window loads.

In a nutshell it chops out the path + AMI_Finalizer.hta part leaving the command line parameters

then it checks if there is a /Restart flag anywhere in the parameters and set our DoRestart variable accordingly.

Following that up if we have to restart then we change the button's text from Close to Restart and we check if there is an AMIRunOnceInstaller key and if so we call the CreateAMIRestartXMLFile() method we looked at above.

It then checks the first part of the parameter which houses only 4 distinct items

  1. /Restart
  2. /Failed
  3. /Restart+Failed

The last one is blank because nothing is returned

If it's number one it sets up the TextArea to indicate a reboot is required

if its number two it tells the user something failed and it appends the names of the packages that failed along with the message

if its number three a combination of the first two happen

it lets the user know most packages completed and need reboots but some packages failed.

For all of these the AMI_Finalizer will not close until the Button has been pushed this leaves the helpdesk phone number up for the user to call to report the problem

if its number for it simply changes the TextArea to say everything installed correctly and the window will self close in 30 seconds and then sets the timer to do so

Finally it readjusts the size of the window to accommodate the potentially multiple package failures listed.

Code: Select all
         Sub Window_Onunload() : If DoRestart Then ForceReboot()   :   End If : End Sub


This one is launched whenever the window is closed (Even including ALT+F4 and closing the window using the X) all it does is check if we have set DoRestart to true and if so we force a reboot.

This is nice this way because I can keep the onclick event of the button to be window.close() even though it's mode changes from normal close to restart its content does not need to change this Event Handler deals with it all.

So that's really it for that one.

Tomorrow we will be looking at the next part of the AMI System in the chain of events the AMI PreLaunch of which we will be looking at the LanConnection HTC which is so short it will be short posting tomorrow.

So I will be back in a few minutes with screen shots

Cheers,
Ryan Strope
Distributed Services (LMSI-O)
(Software package development/testing)
ryan.strope@lmco.com
Quid quid latine dictum sit, altum videtur
User avatar
TofuBug
 
Posts: 48
Joined: Sat Jun 02, 2007 3:27 pm
Location: Apalachin NY

AMI Part 4 {HTA/HTC Details} [Screen Shots]

Postby TofuBug » Mon Jun 30, 2008 4:58 pm

Ok Here we are with the first 3 of the 4 possible AMI Finalizer screens

First up we have the All's good no reboot

AMI Finalizer All Installed NO REBOOT.JPG
AMI Finalizer All Installed NO REBOOT.JPG (13.68 KiB) Viewed 1043 times


Next up we have the All's still good but we need to reboot

AMI Finalizer All Installed REBOOT REQUIRED.JPG
AMI Finalizer All Installed REBOOT REQUIRED.JPG (17.96 KiB) Viewed 1056 times


And next we have some Failed Packages but no Reboot

AMI Finalizer Failed Packages NO REBOOT.JPG
AMI Finalizer Failed Packages NO REBOOT.JPG (17.47 KiB) Viewed 1036 times


We'll be back with the last screen shot

Cheers,
Ryan Strope
Distributed Services (LMSI-O)
(Software package development/testing)
ryan.strope@lmco.com
Quid quid latine dictum sit, altum videtur
User avatar
TofuBug
 
Posts: 48
Joined: Sat Jun 02, 2007 3:27 pm
Location: Apalachin NY

AMI Part 4 {HTA/HTC Details} [Screen Shots]

Postby TofuBug » Mon Jun 30, 2008 5:01 pm

Ok last one

Here's Failed Packages with a reboot required

AMI Finalizer Failed Packages REBOOT REQUIRED.JPG
AMI Finalizer Failed Packages REBOOT REQUIRED.JPG (29.28 KiB) Viewed 1040 times


That's it for this Part of the AMI system

See everyone tomorrow when we jump into the LanConnection HTC

Cheers,
Ryan Strope
Distributed Services (LMSI-O)
(Software package development/testing)
ryan.strope@lmco.com
Quid quid latine dictum sit, altum videtur
User avatar
TofuBug
 
Posts: 48
Joined: Sat Jun 02, 2007 3:27 pm
Location: Apalachin NY

AMI Part 4 {HTA/HTC Details} [LanConnection.htc]

Postby TofuBug » Tue Jul 01, 2008 1:32 pm

LanConnection.htc

Hello Again everyone.

We're about to embark on the shortest HTC review EVER!

So lets jump into the code

Code: Select all
<public:component ID="LANConnection" tagname="LANConnection">
   <public:event name="onConnected"   id="ConnectedEventID" />
   <public:event name="onTimeOut"      id="TimeOutEventID" />
   <public:method name="TestConnection" />
</public:component>
<script language="vbscript" type="text/vbscript">
   '----------------Internal Methods----------------
   Function IsLANConnected() : On Error Resume Next : IsLANConnected = IsObject(GetObject("LDAP://RootDSE")) : End Function
   
   '---------------Exposed Methods---------------
   Sub TestConnection() : If Not IsLANConnected() Then : FireTimeOut() : Else : FireConnected() : End If :   End Sub
   
   '--------------------Event Firing Methods--------------------
   Sub FireConnected() : ConnectedEventID.Fire(element.document.CreateEventObject()) :   End Sub

   Sub FireTimeOut() : TimeOutEventID.Fire(element.document.CreateEventObject()) :   End Sub
</script>


17 lines that's it.

So lets look at our Declaration Section

Code: Select all
<public:component ID="LANConnection" tagname="LANConnection">
   <public:event name="onConnected"   id="ConnectedEventID" />
   <public:event name="onTimeOut"      id="TimeOutEventID" />
   <public:method name="TestConnection" />
</public:component>


We have two exposed Events and one exposed Method

On to the Internal Methods Section

Code: Select all
   Function IsLANConnected() : On Error Resume Next : IsLANConnected = IsObject(GetObject("LDAP://RootDSE")) : End Function


If we can get to the RootDSE using LDAP we have been authenticated back onto the domain and we are connected.

Next up is our Exposed Methods Section

Code: Select all
   Sub TestConnection() : If Not IsLANConnected() Then : FireTimeOut() : Else : FireConnected() : End If : End Sub


Run IsLanConnected() if true call one Event Firing Method if false call the other

Which brings us to our final section

Event Firing Methods Section

Code: Select all
   Sub FireConnected() : ConnectedEventID.Fire(element.document.CreateEventObject()) :   End Sub


Fires the onConnected Event

Code: Select all
   Sub FireTimeOut() : TimeOutEventID.Fire(element.document.CreateEventObject()) :   End Sub


Fires the onTimeOut Event

And that's it.

So what do we get out of 17 lines?

While this HTC does not do anything automatically on its own when it launches it performs a very important task when it's TestConnection() method is called it returns if it's connected or not.

Which means as we will see tomorrow that the AMI_PreLaunch simply sets up a 1 second timer to retry the TestConnection() method until it returns the onConnected Event.

Other than that not a lot to say

So I will see everyone back here for the AMI_PreLaunch HTA and screen shots tomorrow

Cheers,
Ryan Strope
Distributed Services (LMSI-O)
(Software package development/testing)
ryan.strope@lmco.com
Quid quid latine dictum sit, altum videtur
User avatar
TofuBug
 
Posts: 48
Joined: Sat Jun 02, 2007 3:27 pm
Location: Apalachin NY

AMI Part 4 {HTA/HTC Details} [AMI_PreLaunch.hta]

Postby TofuBug » Mon Jul 21, 2008 10:52 am

AMI_PreLaunch.hta

Hello again everyone.

My apologize for the lag in posts it's been a very distracting bunch of weeks lately and in most cases not the good kind of distracting.

We're jumping in today with the next part of the AMI system the AMI_PreLaunch HTA

So let’s get back to the code

Code: Select all
<HTML xmlns:Ryan>
   <?import namespace="Ryan" implementation="LANConnection.htc">
   <head>
      <title>AMI Connection Monitor</title>
      <hta:application
         ID=IRM_AMI_PRELAUNCH
         APPLICATIONNAME=IRM_AMI_PRELAUNCH
         BORDER=thin
         BORDERSTYLE=raised
         CAPTION=yes
         ICON="IRM_AMI.ico"
         MAXIMIZEBUTTON="No"
         MINIMIZEBUTTON="No"
         SHOWINTASKBAR=NO
         SINGLEINSTANCE=yes
         SCROLL=no
         SYSMENU=no
         VERSION=2.1
         CONTEXTMENU=NO
         WINDOWSTATE=normal
      />
   </head>
   <body>
      <script type="text/vbscript" language="vbscript">
         On Error Resume Next

         '-------------------Global Variables-------------------
         Dim RestartRS
         Dim AMIInstallerPath
         
         '-------------------Internal Methods-------------------
         Sub RelaunchAMIInstaller()
            Dim InstallParameters
            With RestartRS
               .MoveFirst()
               InstallParameters = " " + .Fields("Value").Value + "|" + .Fields("Hidden1").Value
               .MoveNext()
               While Not .EOF
                  InstallParameters = InstallParameters + "!" + .Fields("Value").Value + "|" + .Fields("Hidden1").Value
                  .MoveNext()
               Wend
            End With
            CreateObject("WScript.Shell").Run Chr(34) + AMIInstallerPath + Chr(34) + InstallParameters,1,False
            window.settimeout "window.close",1000
         End Sub
         
         Function RegistryItemExists(RegistryItem)
            On Error Resume Next             
            CreateObject("WScript.Shell").RegRead RegistryItem
            RegistryItemExists = (Err = 0)                              
            If ((Err = &H80070002) And (Right(RegistryItem, 1) = "\")) Then   
               TheErrDescription = Replace(Err.description, RegistryItem, "")
               Err.Clear()                  
               CreateObject("WScript.Shell").RegRead "HKEY_ERROR\"
               RegistryItemExists = (TheErrDescription <> Replace(Err.description, "HKEY_ERROR\", ""))
            End If
         End Function
                  
         Sub DeleteFiles()
            If CreateObject("Scripting.FileSystemObject").FileExists(CreateObject("WScript.Shell").ExpandEnvironmentStrings("%ProgramFiles%") + "\DSApps\AMI\AMI_Restart.xml") Then CreateObject("Scripting.FileSystemObject").DeleteFile CreateObject("WScript.Shell").ExpandEnvironmentStrings("%ProgramFiles%") + "\DSApps\AMI\AMI_Restart.xml",True
            If CreateObject("Scripting.FileSystemObject").FileExists(CreateObject("WScript.Shell").ExpandEnvironmentStrings("%ProgramFiles%") + "\DSApps\AMI\AMI_PreLaunch.hta") Then CreateObject("Scripting.FileSystemObject").DeleteFile CreateObject("WScript.Shell").ExpandEnvironmentStrings("%ProgramFiles%") + "\DSApps\AMI\AMI_PreLaunch.hta",True
            If CreateObject("Scripting.FileSystemObject").FileExists(CreateObject("WScript.Shell").ExpandEnvironmentStrings("%ProgramFiles%") + "\DSApps\AMI\LANConnection.htc") Then CreateObject("Scripting.FileSystemObject").DeleteFile CreateObject("WScript.Shell").ExpandEnvironmentStrings("%ProgramFiles%") + "\DSApps\AMI\LANConnection.htc",True
            If RegistryItemExists("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\AMIPreLaunch") Then CreateObject("Wscript.Shell").RegDelete "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\AMIPreLaunch"
         End Sub
                  
         Function GetPackagesFromRebootXML()
            Dim XMLRoot
            Set XMLRoot = CreateObject("Microsoft.XMLDOM")
            Set RestartRS = CreateObject("ADODB.Recordset")
            XMLRoot.Load("AMI_Restart.xml")
            With RestartRS
               .Fields.Append "Value", 200, 500
               .Fields.Append "Hidden1",200,500
               .Open
               .Sort = "Value"
               For Each PackageElement In XMLRoot.GetElementsByTagName("Package")
                  .AddNew()
                  .Fields.Item("Value").Value = PackageElement.Attributes.getNamedItem("Name").nodevalue
                  .Fields.Item("Hidden1").Value = PackageElement.Attributes.getNamedItem("Install_Path").nodevalue
                  .Update()
               Next            
            End With
            For Each AMIInstaller In XMLRoot.GetElementsByTagName("AMI_Installer")
               AMIInstallerPath = AMIInstaller.attributes.getnameditem("Path").nodeValue
            next
            DeleteFiles()
         End Function
         
         Sub SetupNotConnectedMessage()
            NotConnectedMessageTextArea.value = "The following application"
            If RestartRS.RecordCount > 1 Then
               TitleText.value = "ATTENTION: Installations are pending"
               NotConnectedMessageTextArea.value = NotConnectedMessageTextArea.value + "s have"
            Else
               TitleText.value = "ATTENTION: An installation is pending"
               NotConnectedMessageTextArea.value = NotConnectedMessageTextArea.value + " has an"
            End If
               NotConnectedMessageTextArea.value = NotConnectedMessageTextArea.value + " incomplete installation"
            If RestartRS.RecordCount > 1 Then
               NotConnectedMessageTextArea.value = NotConnectedMessageTextArea.value + "s:" + vbCrLf + vbCrLf
            Else
               NotConnectedMessageTextArea.value = NotConnectedMessageTextArea.value + ":" + vbCrLf + vbCrLf
            End If
            With RestartRS
               .MoveFirst()
               While Not .EOF
                  NotConnectedMessageTextArea.value = NotConnectedMessageTextArea.value + .Fields("Value").Value + vbCrLf
                  .MoveNext()
               WEnd
            End With
            NotConnectedMessageTextArea.value = NotConnectedMessageTextArea.value + vbCrLf
            NotConnectedMessageTextArea.value = NotConnectedMessageTextArea.value + "Please reconnect to the Lockheed Martin Network to continue" + vbcrlf + vbcrlf
            NotConnectedMessageTextArea.value = NotConnectedMessageTextArea.value + "NOTE: No other action is required this program will continue automatically once a connection has been established and verified."
         End Sub
         
         '-------------------Event Handlers-------------------
         Sub ShowConnected()
            NotConnectedMessageTextArea.style.visibility = "hidden"
            TitleText.value = "Connection Established, Continuing Installation"
            If RestartRS.RecordCount > 1 Then TitleText.value = TitleText.value + "s"
            TitleText.value = TitleText.value + "..."
            window.settimeout "RelaunchAMIInstaller",5000            
            window.resizeTo TitleText.offsetWidth + 10,TitleText.offsetHeight + window.screentop' + document.body.bottommargin - 10         
         End Sub
         
         Sub ShowTimeOut()
            On Error Resume Next
            NotConnectedMessageTextArea.style.visibility = ""
            window.resizeTo TitleText.offsetWidth + 10,TitleText.offsetheight + NotConnectedMessageTextArea.offsetHeight + window.screenTop + document.body.bottommargin
            window.settimeout "LANConnection1.TestConnection",1000
         End Sub

         Sub Window_OnLoad()
            If CreateObject("Scripting.FileSystemObject").FileExists(CreateObject("WScript.Shell").ExpandEnvironmentStrings("%ProgramFiles%") + "\DSApps\AMI\AMI_Restart.xml") then
               window.moveTo 0,0
               GetPackagesFromRebootXML()
               SetupNotConnectedMessage()
               LanConnection1.TestConnection()
            Else
               DeleteFiles()
               window.close()
            End If
         End Sub
      </script>
      <input id="TitleText" style="font-weight: bold; font-size: 16pt; border-top-style: none; font-family: verdana; border-right-style: none; border-left-style: none; position: absolute; border-bottom-style: none; width: 522px; left: 0px; top: 0px; color: red; overflow: visible; height: 38px; vertical-align: middle;" type="text" readonly="readOnly" />
      <textarea id="NotConnectedMessageTextArea" style="font-size: 10pt; overflow: visible; width: 522px; border-top-style: none; font-family: verdana; border-right-style: none; border-left-style: none; position: absolute; text-align: center; border-bottom-style: none; left: 0px; top: 38px; visibility: hidden; font-weight: bold; vertical-align: top;"></textarea>
      <Ryan:LANConnection ID="LANConnection1" onTimeOut="ShowTimeOut()" onConnected="ShowConnected()" />
   </body>
</html>


149 lines to look through so

Starting with our Variables, Objects and Constants Sections

Code: Select all
         Dim RestartRS
         Dim AMIInstallerPath


First one will hold a RecordSet of Packages waiting to continue installing

Second one will hold the location of the AMI_Installer HTA (since there is a separate production and development AMI it needs to know which one to go back to)

On to the Internal Methods Section

Code: Select all
         Sub RelaunchAMIInstaller()
            Dim InstallParameters
            With RestartRS
               .MoveFirst()
               InstallParameters = " " + .Fields("Value").Value + "|" + .Fields("Hidden1").Value
               .MoveNext()
               While Not .EOF
                  InstallParameters = InstallParameters + "!" + .Fields("Value").Value + "|" + .Fields("Hidden1").Value
                  .MoveNext()
               Wend
            End With
            CreateObject("WScript.Shell").Run Chr(34) + AMIInstallerPath + Chr(34) + InstallParameters,1,False
            window.settimeout "window.close",1000
         End Sub


This method just like the Details HTC control sets up a command line parameter list of packages to install from the RestartRS RecordSet it then passes that to the appropriate AMI_Installer and self closes itself.

Code: Select all
         Function RegistryItemExists(RegistryItem)
            On Error Resume Next             
            CreateObject("WScript.Shell").RegRead RegistryItem
            RegistryItemExists = (Err = 0)                              
            If ((Err = &H80070002) And (Right(RegistryItem, 1) = "\")) Then   
               TheErrDescription = Replace(Err.description, RegistryItem, "")
               Err.Clear()                  
               CreateObject("WScript.Shell").RegRead "HKEY_ERROR\"
               RegistryItemExists = (TheErrDescription <> Replace(Err.description, "HKEY_ERROR\", ""))
            End If
         End Function


We've looked at this one a few times it is used to check for the existence of a registry key or value

Code: Select all
         Sub DeleteFiles()
            If CreateObject("Scripting.FileSystemObject").FileExists(CreateObject("WScript.Shell").ExpandEnvironmentStrings("%ProgramFiles%") + "\DSApps\AMI\AMI_Restart.xml") Then CreateObject("Scripting.FileSystemObject").DeleteFile CreateObject("WScript.Shell").ExpandEnvironmentStrings("%ProgramFiles%") + "\DSApps\AMI\AMI_Restart.xml",True
            If CreateObject("Scripting.FileSystemObject").FileExists(CreateObject("WScript.Shell").ExpandEnvironmentStrings("%ProgramFiles%") + "\DSApps\AMI\AMI_PreLaunch.hta") Then CreateObject("Scripting.FileSystemObject").DeleteFile CreateObject("WScript.Shell").ExpandEnvironmentStrings("%ProgramFiles%") + "\DSApps\AMI\AMI_PreLaunch.hta",True
            If CreateObject("Scripting.FileSystemObject").FileExists(CreateObject("WScript.Shell").ExpandEnvironmentStrings("%ProgramFiles%") + "\DSApps\AMI\LANConnection.htc") Then CreateObject("Scripting.FileSystemObject").DeleteFile CreateObject("WScript.Shell").ExpandEnvironmentStrings("%ProgramFiles%") + "\DSApps\AMI\LANConnection.htc",True
            If RegistryItemExists("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\AMIPreLaunch") Then CreateObject("Wscript.Shell").RegDelete "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\AMIPreLaunch"
         End Sub


This is our cleanup method it checks for the existence of AMI_PreLaunch.hta, LANConnection.htc and AMI_Restart.xml and deletes them if found it also checks the run key to ensure the AMIPreLaunch value is removed.

Code: Select all
         Function GetPackagesFromRebootXML()
            Dim XMLRoot
            Set XMLRoot = CreateObject("Microsoft.XMLDOM")
            Set RestartRS = CreateObject("ADODB.Recordset")
            XMLRoot.Load("AMI_Restart.xml")
            With RestartRS
               .Fields.Append "Value", 200, 500
               .Fields.Append "Hidden1",200,500
               .Open
               .Sort = "Value"
               For Each PackageElement In XMLRoot.GetElementsByTagName("Package")
                  .AddNew()
                  .Fields.Item("Value").Value = PackageElement.Attributes.getNamedItem("Name").nodevalue
                  .Fields.Item("Hidden1").Value = PackageElement.Attributes.getNamedItem("Install_Path").nodevalue
                  .Update()
               Next            
            End With
            For Each AMIInstaller In XMLRoot.GetElementsByTagName("AMI_Installer")
               AMIInstallerPath = AMIInstaller.attributes.getnameditem("Path").nodeValue
            next
            DeleteFiles()
         End Function


This method is what we use to extract the information left on the hard drive prior to the restart in the AMI_Restart.xml

In a similar fashion of the XMLPackageFilter HTC we create our own RecordSet assign some Fields to it open it and then we loop through all the Package XML Elements and add a new record for each XML Element pulling the applicable information to populate the fields from the XML Attributes.

Once done we grab the path to the AMI that needs to be recalled (Development or Production) from the AMI_Installer XML Element's Path XML Attribute.

Finally we Call DeleteFiles to clean up

Code: Select all
         Sub SetupNotConnectedMessage()
            NotConnectedMessageTextArea.value = "The following application"
            If RestartRS.RecordCount > 1 Then
               TitleText.value = "ATTENTION: Installations are pending"
               NotConnectedMessageTextArea.value = NotConnectedMessageTextArea.value + "s have"
            Else
               TitleText.value = "ATTENTION: An installation is pending"
               NotConnectedMessageTextArea.value = NotConnectedMessageTextArea.value + " has an"
            End If
               NotConnectedMessageTextArea.value = NotConnectedMessageTextArea.value + " incomplete installation"
            If RestartRS.RecordCount > 1 Then
               NotConnectedMessageTextArea.value = NotConnectedMessageTextArea.value + "s:" + vbCrLf + vbCrLf
            Else
               NotConnectedMessageTextArea.value = NotConnectedMessageTextArea.value + ":" + vbCrLf + vbCrLf
            End If
            With RestartRS
               .MoveFirst()
               While Not .EOF
                  NotConnectedMessageTextArea.value = NotConnectedMessageTextArea.value + .Fields("Value").Value + vbCrLf
                  .MoveNext()
               WEnd
            End With
            NotConnectedMessageTextArea.value = NotConnectedMessageTextArea.value + vbCrLf
            NotConnectedMessageTextArea.value = NotConnectedMessageTextArea.value + "Please reconnect to the Lockheed Martin Network to continue" + vbcrlf + vbcrlf
            NotConnectedMessageTextArea.value = NotConnectedMessageTextArea.value + "NOTE: No other action is required this program will continue automatically once a connection has been established and verified."
         End Sub


This method sets up what the user sees when the LANConnection HTC determines it does not have a connection.

We begin by setting up the first part of our message to the user and the general title to say an installation or installations are pending

I have it split up like that to keep the message grammatically correct for single and multiple installs pending

Then it Lists the AMI Packages that are pending a continued install

It finally finishes up by adding a generic note to reconnect to the Network to continue.

We are now down to the Event Handlers Section

Code: Select all
         Sub ShowConnected()
            NotConnectedMessageTextArea.style.visibility = "hidden"
            TitleText.value = "Connection Established, Continuing Installation"
            If RestartRS.RecordCount > 1 Then TitleText.value = TitleText.value + "s"
            TitleText.value = TitleText.value + "..."
            window.settimeout "RelaunchAMIInstaller",5000            
            window.resizeTo TitleText.offsetWidth + 10,TitleText.offsetHeight + window.screentop' + document.body.bottommargin - 10         
         End Sub


This event handler is called when the LANConnection HTC fires its onConnected Event signaling the system has reconnected to the network.

It hides the section of text listing the AMI Packages awaiting to continue installing, then changes the generic title to state the connection was established and the installations are continuing It then sets up a 5 second time to call RelaunchHTAInstaller and finally changes the width and height of the AMI_PreLaunch HTA to fit

Code: Select all
         Sub ShowTimeOut()
            On Error Resume Next
            NotConnectedMessageTextArea.style.visibility = ""
            window.resizeTo TitleText.offsetWidth + 10,TitleText.offsetheight + NotConnectedMessageTextArea.offsetHeight + window.screenTop + document.body.bottommargin
            window.settimeout "LANConnection1.TestConnection",1000
         End Sub


This is ShowConnected's counterpart it is called when the LANConnection HTC fires its onTimeOut Event signaling the system cannot establish a connection with the network.

It makes the TextArea containing the list of AMI Packages to be installed visible and resizes the window to accommodate the size of the now visible element.

Finally it sets up a 1 second time to retry the LANConnection HTC's TestConnection() Method

Code: Select all
         Sub Window_OnLoad()
            If CreateObject("Scripting.FileSystemObject").FileExists(CreateObject("WScript.Shell").ExpandEnvironmentStrings("%ProgramFiles%") + "\DSApps\AMI\AMI_Restart.xml") then
               window.moveTo 0,0
               GetPackagesFromRebootXML()
               SetupNotConnectedMessage()
               LanConnection1.TestConnection()
            Else
               DeleteFiles()
               window.close()
            End If
         End Sub


Our last Event Handler is called when the physical window first loads

It first checks to make sure it has the appropriate XML file to load if it does it moves the window to the upper left corner, calls GetPackagesFromRebootXML() to populate the RecordSet then calls SetupNotConnectedMessage() to prepare the prompt supplied to the user for information. And finally it calls LanConnection1.TestConnection() to do its first determination of the systems connection to the LAN

If the XML file does not exist then it calls DeleteFiles() to clear any leftover items and it then self closes.

So that does it for this part of the AMI system.

So let’s recap what we have here.

This Light HTA with only one HTC used is set up from the AMI_Finalizer to launch on the Run key when windows loads (did this because RunOnce and RunOnceEx do not let the desktop load until they complete and I need the user to be able to launch the VPN Client software)

It Extracts the AMI Packages awaiting a continued installation checks the connection and when it is good re-launches the AMI_Installer.

I will be back this evening or tomorrow morning with screen shots of the AMI_PreLaunch HTA in action.

Until then thanks everyone for your patience.

Cheers,
Ryan Strope
Distributed Services (LMSI-O)
(Software package development/testing)
ryan.strope@lmco.com
Quid quid latine dictum sit, altum videtur
User avatar
TofuBug
 
Posts: 48
Joined: Sat Jun 02, 2007 3:27 pm
Location: Apalachin NY

AMI Part 4 {HTA/HTC Details} [Screen Shots]

Postby TofuBug » Thu Jul 24, 2008 5:40 pm

Hello again everyone,

Sorry for the touch and go lately things still haven't calmed down

We're here for a quick look at the AMI_PreLaunch HTA Screen shots

AMI Connection Monitor NO CONNECTION.JPG
AMI Connection Monitor NO CONNECTION.JPG (30.06 KiB) Viewed 979 times


First up we have the screen that is displayed when a connection cannot be established this will remain up until a connection is reestablished

AMI Connection Monitor CONNECTION ESTABLISHED.JPG
AMI Connection Monitor CONNECTION ESTABLISHED.JPG (12.15 KiB) Viewed 975 times


Once a connection is established either through connecting to a VPN connection or plugging the LAN cable back in (that's how I test and capture screen shots from my office PC) the window automatically changes to the second screen shot

It then automatically launches the AMI_Installer HTA and auto closes itself after a preset time limit

That's it for this piece of the AMI

I can't promise the way things have been going that i will get to the AMI_About HTA tomorrow but I'm hoping i can.

Thanks again for everyone's patience and interest in this topic.

Cheers,
Ryan Strope
Distributed Services (LMSI-O)
(Software package development/testing)
ryan.strope@lmco.com
Quid quid latine dictum sit, altum videtur
User avatar
TofuBug
 
Posts: 48
Joined: Sat Jun 02, 2007 3:27 pm
Location: Apalachin NY

AMI Part 4 {HTA/HTC} Details [AMI_About.hta]

Postby TofuBug » Fri Jan 23, 2009 9:04 am

Hello again everyone.

I'm back after another hiatus. My apologies for being gone so long especially with only a little left to finish up. Well I'm going to do my best to make it up to those of you who were following along.

Today we're going to take a look (finally) at the last part of AMI's main system the AMI_About.hta so lets jump right into the code

Code: Select all
<html>
   <head>
      <title>About AMI</title>
      <hta:application
         id="AMI_ABOUT"
         applicationname="AMI_ABOUT"
         border="thin"
         borderstyle="raised"
         caption="yes" icon=""
         maximizebutton="No"
         minimizebutton="No"
         showintaskbar="No"
         singleinstance="Yes"
         scroll="No"
         sysmenu="No"
         version="1.1"
         contextmenu="No"
         windowstate="Normal" />
   </head>
   <body>
      <script language="vbscript" type="text/vbscript">
         Function GetAMIVersion()
            With CreateObject("Scripting.FileSystemObject").OpenTextFile("IRM_AMI.HTA",1)
               While Not .AtEndOfStream
                  Line = .ReadLine()
                  If InStr(UCase(Line),"VERSION=") <> 0 Then GetAMIVersion = Split(Line,"=")(1) : Exit Function
               Wend
            End With
         End Function

         Sub window_onload() : window.resizeTo 630,340 : VersionText.value = GetAMIVersion() : End Sub
      </script>
      <textarea id="TextArea1" style="z-index: 100; left: 4px; width: 614px; position: absolute; top: 129px; height: 156px; font-size: 10pt; overflow: hidden; font-family: verdana;" readonly="readOnly">The AMI is a lightweight, portable, controlled LAN based application installation interface.
         
Available applications may be different for each PC. Available Applications are based on:

   The manufacturer of the PC
            
   The type of PC
            
   Any licensed application connections currently assigned in the AMI to the PC.</textarea>
   <img src="IRM_AMI.ico" style="z-index: 101; left: 4px; width: 100px; border-top-style: none; border-right-style: none; border-left-style: none; position: absolute; top: 4px; height: 100px; border-bottom-style: none" />
   <input id="Text1" readonly="readonly" style="font-weight: bold; font-size: 20pt; z-index: 102; left: 108px; width: 509px; border-top-style: none; font-family: Verdana; border-right-style: none; border-left-style: none; position: absolute; top: 64px; border-bottom-style: none" type="text" value="(Applications' Managed Installer)" />
   <input id="Text2" readonly="readonly" style="font-weight: bold; font-size: 30pt; z-index: 103; left: 318px; width: 93px; border-top-style: none; font-family: Verdana; border-right-style: none; border-left-style: none; position: absolute; top: 15px; border-bottom-style: none" type="text" value="AMI" />
   <input id="Text3" readonly="readonly" style="font-size: 10pt; z-index: 104; left: 4px; width: 50px; border-top-style: none; font-family: verdana; border-right-style: none; border-left-style: none; position: absolute; top: 111px; border-bottom-style: none; font-weight: bold;" type="text" value="About:" />
   <input id="Text4" readonly="readonly" style="font-size: 10pt; z-index: 105; left: 4px; width: 63px; border-top-style: none; font-family: verdana; border-right-style: none; border-left-style: none; position: absolute; top: 290px; border-bottom-style: none; font-weight: bold;" type="text" value="Version:" />
   <input id="VersionText" readonly="readonly" style="font-size: 10pt; z-index: 106; left: 69px; border-top-style: none; font-family: verdana; border-right-style: none; border-left-style: none; position: absolute; top: 290px; border-bottom-style: none" type="text" />
   <input onclick="Window.Close()" id="CloseButton" style="font-size: 10pt; z-index: 107; left: 564px; font-family: Verdana; position: absolute; top: 285px" type="button" value="Close" />
</body>
</html>


This one is pretty straight forward only 50 lines total. we have a few static elements most of them are just static values only VersionText is dynamic.

We only have a short script section this time the first thing called is just our normal window_onload event

Code: Select all
         Sub window_onload() : window.resizeTo 630,340 : VersionText.value = GetAMIVersion() : End Sub


which resizes the screen and calls the only other method GetAMIVersion

Code: Select all
         Function GetAMIVersion()
            With CreateObject("Scripting.FileSystemObject").OpenTextFile("IRM_AMI.HTA",1)
               While Not .AtEndOfStream
                  Line = .ReadLine()
                  If InStr(UCase(Line),"VERSION=") <> 0 Then GetAMIVersion = Split(Line,"=")(1) : Exit Function
               Wend
            End With
         End Function


All this does is loads the AMI's main HTA and pulls the current version from the hta:application tag

That's really it you get the following little pop up when the user presses F1 from the main GUI's window.

AMI_About.JPG
AMI_About.JPG (39.33 KiB) Viewed 850 times


And we are after almost a year and a half done posting :-)

Thanks for coming along for the ride.

Now to make it up to everyone for my being busy and distracted Some of you might remember I mentioned that I had developed a tool to manage the licensed software connections in AMI but I would not post it because it was a thrown together piece of junk that only had to function (and did poorly if I do say so).

Well I just finished implementing it's replacement into our production system. I finally got to do a complete rewrite of the tool and it turned out Phenomenal so I will probably Monday be starting to cover the Files that make up this new tool along with all the screen shots and what not.

Some new developments since this thread started:

What started out as an essentially single program with one very well defined purpose has developed into a fairly useful suite of tools.

AMI now comprises 5 separate tools for different tasks

  • AMI GUI
    • This is the interface we've covered over the last year and a half it's the main user interface used for software installs It's the most commonly used part of AMI outside of our support technicians
  • AMI Software ACL Admin Tool
    • This allows our authorized support technicians with R/W access to the actual software control database to assign or remove licensed software from computers in AMI
      • NOTE: This was just rewritten
  • AMI ACL Verification Tool
    • This light weight tool lets a non authorized user like the help desk look up quickly what licensed software is assigned to a particular Computer
  • AMI ACL GUI
    • This is a modified version of the AMI GUI it has no Administrative sections and does not do any actual installations what it does do is dump an XML file of the selected applications if any It is used in our computer imaging process to.
      • Has special permissions to ALL software only for our imaging account this lets our imaging technicians install any software to a new computer
      • When a system is in the process of being imaged when the imaging tech selects software or does not select any it generates two XML files
        • The first goes on the computer being imaged and is used in the rest of the imaging process to pull and install the correct packages from AMI's repository.
        • The second is created on a common logging LAN share and consists only of the computer and the chosen software. These XML files are used to import/update the software assignments using the Software ACL Admin Studio in the ACL Database for the AMI GUI
  • AMI DVD
    • This last item has actually been around from the beginning its a stripped down version the GUI much like the ACL GUI that is designed to be burned onto a CD or DVD along with any packages needed. it implements the same filtering and folder tree structure as the full blown GUI so the CD/DVD will still filter based on machine and maker. it does not employ the ACL control for obvious reasons but we don't hand out CD's all that often

So that's pretty much how the system has expanded out to what it is now.

If anyone gets to this before Monday I'd like to know if you would like me to continue about the Software ACL Admin Studio in this thread or If I should start a fresh thread for this part of AMI.

Let me know and thanks again for following along for so long.

Cheers,
Ryan Strope
Distributed Services (LMSI-O)
(Software package development/testing)
ryan.strope@lmco.com
Quid quid latine dictum sit, altum videtur
User avatar
TofuBug
 
Posts: 48
Joined: Sat Jun 02, 2007 3:27 pm
Location: Apalachin NY

Re: AMI Part 4 {HTA/HTC} Details [AMI_About.hta]

Postby dumpydooby » Wed Oct 14, 2009 12:01 pm

TofuBug wrote:I will probably Monday be starting to cover the Files that make up this new tool along with all the screen shots and what not.

Long weekend? :mrgreen:
Love Always,
Dumpy Dooby
User avatar
dumpydooby
 
Posts: 280
Joined: Fri Sep 01, 2006 8:22 pm

Re: Application's Managed Installer (AMI)

Postby dumpydooby » Fri Jan 29, 2010 6:53 am

Happy birthday! :cheers:
Love Always,
Dumpy Dooby
User avatar
dumpydooby
 
Posts: 280
Joined: Fri Sep 01, 2006 8:22 pm

PreviousNext

Return to Scripts and Utilities

Who is online

Users browsing this forum: No registered users and 1 guest

cron