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?
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)
Please log in to answer
Posted by:
anonymous_9363
16 years ago
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
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
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
Posted by:
anonymous_9363
16 years ago
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
When I run the script I now get error 1720.
VbScab could you please help me out?
This is what I have done:
[hr]
[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]
VbScab could you please help me out?
This is what I have done:
[hr]
- make a test.msi (with one file in it).
- add an entry to the Resources: MyRegDacl --> Regdacl.exe
- made a bogus Set Property with PropertyName: Action1
- create a "Call VBScript from Embedded Code" (Custom Action Name: Action1) in Execute Deffered (before InstallFinalize).
- copied your script and added a line at the top: Call ExtractBinary ("MyRegDacl","c:\regdacl.exe")
- execute msi
[hr]
Below a transcript of the logging during the error:
[hr]
Dim objDatabase
Dim objView
Dim objRecord
Dim objBinaryData
Dim objStream
Const msiReadStreamAnsi = 2
Set objDatabase = Session.Database
objView.Execute
objStream.Write objBinaryData
objStream.Close
Exit Function
End If
ExtractBinary = True
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
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:
- 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:
- 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
Posted by:
Bobo
16 years ago
Posted by:
anonymous_9363
16 years ago
Posted by:
jmcfadyen
16 years ago
Rating comments in this legacy AppDeploy message board thread won't reorder them,
so that the conversation will remain readable.
so that the conversation will remain readable.