/build/static/layout/Breadcrumb_cap_w.png

Using Regdacl from Embedded Vbscript

I am using regdacl.exe to set permissions on registry-keys. For this I use a Custom Action "Execute Progra, from Installatie", however during installtion of the MSI, my users see several DOS-boxes splashing.

Using Google I found a vbscript to execute regdacl via an embedded vbscript (to hide the DOS-boxes), however I have had to add regdacl.exe to my msi (system-folder) to be able the use it with the embedded vbscript. But I rather not install extra files with my MSI-package.

I have been told, one can add regdacl.exe to the MSI resources (Wise: Install Expert -> Project Definition part --> Resources [just underneath Path Variables]) and call them from an embedded script, however I don't know how.

Can anyone please tell me how to call a binary resource from a embedded vbscript Custom Action?

0 Comments   [ + ] Show comments

Answers (11)

Posted by: anonymous_9363 16 years ago
Red Belt
2
Here's the function I use to extract stuff from the binary table:

Function ExtractBinary(ByVal strBinaryName, ByVal strOutputFile)
Dim objDatabase
Dim objView
Dim objRecord
Dim objBinaryData
Dim objStream

Const msiReadStreamAnsi = 2

ExtractBinary = False

Set objDatabase = Session.Database

Set objView = objDatabase.OpenView("SELECT * FROM Binary WHERE Name = '" & strBinaryName & "'")
objView.Execute

Set objRecord = objView.Fetch

objBinaryData = objRecord.ReadStream(2, objRecord.DataSize(2), msiReadStreamAnsi)

Set objStream = objFSO.CreateTextFile(strOutputFile, True)
objStream.Write objBinaryData
objStream.Close

If Not objFSO.FileExists(strOutputFile) Then
Exit Function
End If

ExtractBinary = True

Set objStream = Nothing
Set objRecord = Nothing
Set objView = Nothing
Set objDatabase = Nothing

End Function
Posted by: anonymous_9363 16 years ago
Red Belt
0
Since this is unlikely to be the only time you'll need to permission the registry, why not simply add the EXE as a file to the project? Better, add it to a copy of your 'Windows Application' template and use the new template. Better still, use SetACL instead, as this can permission the file system as well as the registry.
Posted by: Jemboy2004 16 years ago
Senior Yellow Belt
0
ORIGINAL: VBScab
Since this is unlikely to be the only time you'll need to permission the registry, why not simply add the EXE as a file to the project? Better, add it to a copy of your 'Windows Application' template and use the new template. Better still, use SetACL instead, as this can permission the file system as well as the registry.

I am NOT allowed to leave thirdparty utilities on the customer's workstation. Nobody is probably checking but you never now...
Posted by: Jemboy2004 16 years ago
Senior Yellow Belt
0
Thanks VBScab, I think I could use this to extract regdacl.exe to the c:\temp, use it and aftwerwards delete it again.
You really are a VB(script) genius...[8|]

This message has been added to my scripting favorites[;)]
Posted by: anonymous_9363 16 years ago
Red Belt
0
I think I could use this to extract regdacl.exe to the c:\temp, use it and aftwerwards delete it again.
The function will extract anything from the Binary table so yes, you could indeed.

I should also have pointed out that the function, as posted, will only work as an embedded script, because the database is loaded from the 'Session' object (line 11, Set objDatabase = Session.Database). To make it work in an external script, one would need to add code to get the path to and name of the MSI.
Posted by: Jemboy2004 16 years ago
Senior Yellow Belt
0
When I run the script I now get error 1720.
VbScab could you please help me out?

This is what I have done:

[hr]

  1. make a test.msi (with one file in it).
  2. add an entry to the Resources: MyRegDacl --> Regdacl.exe
  3. made a bogus Set Property with PropertyName: Action1
  4. create a "Call VBScript from Embedded Code" (Custom Action Name: Action1) in Execute Deffered (before InstallFinalize).
  5. copied your script and added a line at the top: Call ExtractBinary ("MyRegDacl","c:\regdacl.exe")
  6. execute msi


[hr]


Below a transcript of the logging during the error:

[hr]

MSI (s) (78:64) [13:03:57:546]: Executing op: CustomActionSchedule(Action=Action1,ActionType=3110,Source=Call ExtractBinary ("MyRegDacl","c:\regdacl.exe")
Function ExtractBinary(Byval strBinaryName, Byval strOutputFile)
Dim objDatabase
Dim objView
Dim objRecord
Dim objBinaryData
Dim objStream

Const msiReadStreamAnsi = 2
ExtractBinary = False

Set objDatabase = Session.Database
Set objView = objDatabase.OpenView("SELECT * FROM Binary WHERE Name = '" & strBinaryName & "'")
objView.Execute
Set objRecord = objView.Fetch
objBinaryData = objRecord.ReadStream(2, objRecord.DataSize(2), msiReadStreamAnsi)
Set objStream = objFSO.CreateTextFile(strOutputFile, True)
objStream.Write objBinaryData
objStream.Close
If Not objFSO.FileExists(strOutputFile) Then
Exit Function
End If

ExtractBinary = True
Set objStream = Nothing
Set objRecord = Nothing
Set objView
MSI (s) (78:64) [13:03:57:562]: Generating random cookie.
MSI (s) (78:64) [13:03:57:578]: Created Custom Action Server with PID 3048 (0xBE8).
MSI (s) (78:14) [13:03:57:656]: Running as a service.
MSI (s) (78:F0) [13:03:57:656]: Hello, I'm your 32bit Elevated custom action server.
MSI (s) (78:0C) [13:03:57:656]: Entering MsiProvideComponentFromDescriptor. Descriptor: T%i&7oT-C?kaTW(0fqX8Toolbox>M5KDYSUnf(HA*L[xeX)y, PathBuf: D8F3E0, pcchPathBuf: D8F5F0, pcchArgsOffset: D8F3AC
MSI (s) (78:0C) [13:03:57:656]: MsiProvideComponentFromDescriptor called for component {997FA962-E067-11D1-9396-00A0C90F27F9}: returning harcoded oleaut32.dll value
MSI (s) (78:0C) [13:03:57:656]: MsiProvideComponentFromDescriptor is returning: 0
DEBUG: Error 2835: The control ErrorIcon was not found on dialog ErrorDialog
Internal Error 2835. ErrorIcon, ErrorDialog

[hr]
Posted by: anonymous_9363 16 years ago
Red Belt
0
OK, a few things...

- When an error occurs in a CA, the return value will be '3' so ignore log entries which begin 'DEBUG: Error [blah]'. Look for an entry with the text 'Return value 3.'. The offending action will normally be in the 5 or 6 lines above that entry.
- You need to format the call to the function correctly:

Dim blnReturnCode
blnReturnCode = ExtractBinary("MyRegDacl","c:\regdacl.exe")
If blnReturnCode Then
'// Do something
Else
'// Say there was an error and then...
Exit Function
End If

- Use the %TEMP% folder to extract files to: you cannot be sure the executing user will have rights to write to the root of the system drive. You cannot even be sure that Windows is running from C: (think about it...) Here's some code which creates a temporary file which you can adapt to get the TEMP folder name:
Dim strTempFile
Dim blnReturn

blnReturn = CreateTempFile(strTempFile)
If blnReturn Then
DeleteFile strTempFile
Else
'// Say there was an error
End If

Function CreateTempFile(ByRef strTemp)
Dim objFSO
Dim objTempFolder
Dim strTempFileName
Dim strTempFile

CreateTempFile = False
Const intTemporaryFolder = 2

Set objFSO = CreateObject("Scripting.FileSystemObject")

With objFSO
Set objTempFolder = .GetSpecialFolder(intTemporaryFolder)
strTempFileName = .GetTempName

strTempFile = objTempFolder.Path & "\" & strTempFileName
If .FileExists(strTempFile) Then
strTemp = strTempFile
CreateTempFile = True
End If
End With

Set objTempFolder = Nothing
Set objFSO = Nothing
End Function

Function DeleteFile(ByVal strFile)
Dim objFSO

DeleteFile = False
On Error Resume Next

Set objFSO = CreateObject("Scripting.FileSystemObject")

objFSO.DeleteFile strFile, True
If Not objFSO.FileExists(strFile) Then
DeleteFile = True
End If

Set objFSO = Nothing
End Function
I'm sure you can work out the rest.
Posted by: anonymous_9363 16 years ago
Red Belt
0
One further point...as the ExtractBinary script uses the Session object, you'll need to run it in Execute Immediate.
Posted by: Bobo 16 years ago
Orange Belt
0
These lines can be good to have in the script with the function ExtractBinary.

Dim objFSO
Set objFSO = CreateObject("Scripting.FileSystemObject")
Posted by: anonymous_9363 16 years ago
Red Belt
0
Good spot, 3 months after the event! :)

I have the FSO object, along with the Shell objects, defined as globals in my script template file. I should have remembered to include the lines you mention. Thanks.
Posted by: jmcfadyen 16 years ago
5th Degree Black Belt
0
even though this is very late. you can also reference the files from the source location by using the call to [SourceDir]

Sometimes you may need to run the RESOLVESOURCE standard action as well in order to access this property early in the sequences.
Rating comments in this legacy AppDeploy message board thread won't reorder them,
so that the conversation will remain readable.
 
This website uses cookies. By continuing to use this site and/or clicking the "Accept" button you are providing consent Quest Software and its affiliates do NOT sell the Personal Data you provide to us either when you register on our websites or when you do business with us. For more information about our Privacy Policy and our data protection efforts, please visit GDPR-HQ