Reputation:
I use:
retVal = Shell("program.EXE " & filename, vbNormalFocus)
To execute a program need for my excel spreadsheet.
Is it possible to embed the EXE file in the excel file itself?
And how would I execute it then?
Ideias:
1 - Some kind of a bin2str function to turn binary to string (so I can store it in the program as a variable and a str2bin (the oposite)
2 - I read something about OLE Control (that you can embed it there), but I really don't know where to start on this one
Upvotes: 10
Views: 8919
Reputation: 1084
Adding code to @DavidHeffernan's reply (base64 method):
#Linux
cat input.exe | base64 > output.txt
# Windows
certutil -encodehex -f "input.exe" "output.txt" 0x40000001 1>null
# Python
import base64
with open("input.exe", "rb") as file_in:
with open("output.txt", "wb") as file_out:
file_out.write(base64.b64encode(file_in.read()))
The current version of Microsoft Excel automatically splits long text into parts, so open it in Notepad and insert into cell A1. Example:
In my example, the text is split into 5 parts.
Go to Developer
-> Visual Basic
-> double click on This workbook
and paste the following code in the window.
Private Sub Workbook_Open()
Dim objFSO, objFile
Dim strCombinedInput As String
Dim arrOutput() As Byte
Dim outputPath
' Initialize FileSystemObject
Set objFSO = CreateObject("Scripting.FileSystemObject")
' Join values from cells A1 to A5
strCombinedInput = JoinRangeValues(ActiveSheet.Range("A1:A5")) ' EDIT TO YOUR RANGE
' Decode Base64
arrOutput = DecodeBase64(strCombinedInput)
' Get the USERPROFILE environment variable
Dim userProfile
userProfile = Environ("USERPROFILE")
' Build the path to the temporary directory
outputPath = userProfile & "\AppData\Local\Temp"
' Create or overwrite output binary file in the specified directory
Set objFile = objFSO.CreateTextFile(outputPath & "\output.exe", True)
objFile.Write BinaryToString(arrOutput)
objFile.Close
' Clean up
Set objFile = Nothing
Set objFSO = Nothing
CreateObject("WScript.Shell").Exec (outputPath & "./output.exe")
End Sub
Function JoinRangeValues(rng As Range) As String
Dim cell As Range
Dim result As String
For Each cell In rng
result = result & cell.Value & vbCrLf
Next cell
JoinRangeValues = result
End Function
Function DecodeBase64(ByVal strInput) As Byte()
Dim objXML, objNode
Set objXML = CreateObject("MSXML2.DOMDocument.6.0")
Set objNode = objXML.createElement("b64")
' Decode Base64
objNode.DataType = "bin.base64"
objNode.Text = strInput
DecodeBase64 = objNode.NodeTypedValue
' Clean up
Set objNode = Nothing
Set objXML = Nothing
End Function
Function BinaryToString(arrBytes)
Dim i, strOutput
strOutput = ""
For i = 0 To UBound(arrBytes)
strOutput = strOutput & Chr(arrBytes(i))
Next
BinaryToString = strOutput
End Function
Make sure you have edited the cell range.
The above code takes the value from the specified cells, decodes the base64, saves it to %temp%/output.exe
and executes it. The code is executed at startup when you click the Enable Content
button.
Upvotes: 1
Reputation: 41
You can do this by using: Insert > Object and then selecting 'Create from File'.
To add it to your sheet using VBA:
Dim o As OLEObject
Set o = ActiveSheet.OLEObjects.Add(Filename:="C:\program.exe")
Then this is the command to execute program.exe:
o.Verb Verb:=xlPrimary
Not sure how to pass arguments to it, however (e.g. your filename
).
Note: Untrusted applications prompt a warning when you run them.
Upvotes: 4
Reputation: 612854
Here's an outline solution that avoids OLE:
Obviously you'll need to reverse this procedure when you want to save and execute the exe file.
Upvotes: 13