I have the following problematic scenario:
Problematic Scenrio Description Begin---------------------------
I use msiexec to install a package in quiet mode in the following way:
msiexec /i c:\mypackage.msi /quiet
Now I have the package installed. Let's say I entered the command above again:
msiexec /i c:\mypackage.msi /quiet
Problematic Scenrio Description End---------------------------
Now since the package is already installed, the installation should fail. But I have no indication for that.
I use the log option in order to get a log going:
msiexec /i c:\mypackage.msi /quiet /l* log.txt
When errors occur I do see them in the log but in the scenario depicted above the log is empty. There is also nothing written to the system event log. So my question is, How can I get an indication that the installation (The second one) didn't go?
Notes:
I am not willing to solve this problem by writing a batch script that will check if the package is installed prior to the call to msiexec. The reason is that it contradicts our customer deployment requirements.
I have a DLL custom action data, in the second time, the DLL is not activated so I can't use the DLL in order to write the failure somewhere.
Installation does not fail if the package is already installed, it was "successfully reconfigured"
In order to check if a Windows Installer package is installed on the system or not, you're best to use the Windows SDK (not a batch file) - here's a sample script that iterates the list of installed products and triggers MSIEXEC if it is not already installed. (This example searches by name, alternatively you could search by package code)
Option Explicit
Dim productName:productName = "My Awesome Product"
Dim installer : Set installer = Nothing
Set installer = Wscript.CreateObject("WindowsInstaller.Installer")
Dim productCode, property, value, message
For Each productCode In installer.Products
If InStr(1, LCase(installer.ProductInfo(productCode, "ProductName")), LCase(productName)) Then Exit For
Next
If IsEmpty(productCode) Then
Dim WshShell, oExec
Set WshShell = CreateObject("WScript.Shell")
WshShell.Exec("msiexec /i mypackage.msi /qb")
Else
Wscript.Echo productName & " is already installed."
Wscript.Quit 2
End If
Is it your package? If so, put in a prerequisite condition that checks if some key file or registry entry doesn't exist yet.
If it's not your package, wrap it in something (another installer or an exe) that will make the check.
I know this is old thread, but google hits this up and in benefit of others try this
start /wait msiexec /i c:\mypackage.msi /quiet
If error, echo %errorlevel% will be non zero. If calling above programmatically use GetLastError()
Related
On Windows 10, I have tried to do a silent install of an msi package, but the install simply fails without any error.
Here are my commands to get the msi in zip format, unzip, and then install.
wget -q http://kakadusoftware.com/wp-content/uploads/KDU805_Demo_Apps_for_Win64_200602.msi_.zip
cmake -E tar -xf KDU805_Demo_Apps_for_Win64_200602.msi_.zip
msiexec /i KDU805_Demo_Apps_for_Win64_200602.msi /quiet /qn /norestart
Edit: I logged output to file, and found this error
MSI (s) (64:AC) [09:15:20:332]: Product: Kakadu Demo-Apps -- Error 1925. You do not have sufficient privileges to complete this installation for all users of the machine. Log on as administrator and then retry this installation.
The Windows Installer is a "Windows application" (as opposed to a "console application") which means starting it from the command-line will not cause the console to wait. To wait, you need to explicitly wait for the process to exit. One easy way is:
start /wait "" msiexec /i KDU805_Demo_Apps_for_Win64_200602.msi /qn /norestart
Note: The empty string "" is important if you ever need to quote the command-line to start. Otherwise, the start command will use your quoted command-line as the title of the created window (crazy, I know, check start /? for the details).
I have looked around and can't seem to make it work with the research I've done.
I'm going to create a GPO to apply to workstations that will uninstall Malwarebytes 2.0 and 3.0 from a given system. This will allow us to roll out the enterprise version.
What I have in my .bat file is this:
#echo off
cd "C:\Program Files (x86)\Malwarebytes Anti-malware\"
unins000.exe /verysilent /suppressmsgboxes /norestart
cd "C:\Program Files\Malwarebytes\Anti-Malware\"
unins000.exe /verysilent /suppressmsgboxes /norestart
However, I noticed that if one of the paths above doesn't exits (1 will always not exist) than it will pop up a command prompt with an error. I'd like no boxes to pop up at all if possible. I then tried to accomplish this with vbs with the error:
compilation error: Invalid character
This is that script:
Dim objShell
Set objShell = WScript.CreateObject( WScript.Shell )
Sub MalwareBytes()
On Error Resume Next
objShell.Run(%ProgramFiles%Malwarebytes Anti-malwareunins000.exe verysilent
suppressmsgboxes norestart)
objShell.Run(%ProgramFiles(x86)%MalwarebytesAnti-Malwareunins000.exe
verysilent suppressmsgboxes norestart)
End Sub
Set objShell = Nothing
How about, y'know, checking if a path actually exists before trying to go there?
if exist "C:\Program Files (x86)\Malwarebytes Anti-malware" (
cd "C:\Program Files (x86)\Malwarebytes Anti-malware"
unins000.exe /verysilent /suppressmsgboxes /norestart
)
The reason why your VBScript doesn't work is because your syntax is invalid. You need double quotes around the argument to CreateObject() as well as the command strings. With nested double quotes in case of the latter, because you have paths with spaces in them. Not to mention that it would be cleaner to check if a path actually exists in VBScript too.
I've been working on a batch file all day, that I can't get to work open through GPO (another day, another question). So I decided to do it manually with every computer. I have two exe's and one MSI. The exe's work perfectly fine. They get installed, and it all works out. The MSI, however, doesn't. It gives me the error: the installation package could not be opened. Verify that the package exists and that you can access it, or contact the application vendor to verify that this is a valid Windows Installer package.
Now when I go to the network share and use it from there, it works perfectly fine. So there must be an issue with my code.
Here's the code:
#echo off
IF NOT EXIST "C:\Program Files (x86)\Citrix\ICA Client\" (
pushd "\\KOPI-DC01\ACCURO Cloudwerx\ACCURO\1\"
.\CitrixReceiver-4.4.1000.exe /silent
)
IF NOT EXIST "C:\Program Files (x86)\triCerat\Simplify Printing\ScrewDrivers Client v4\" (
pushd "\\KOPI-DC01\ACCURO Cloudwerx\ACCURO\2\"
msiexec.exe /i ".\Screwdriver.msi"
)
IF NOT EXIST "C:\Program Files\Cloudwerx\CloudwerxPlugin\" (
pushd "\\KOPI-DC01\ACCURO Cloudwerx\ACCURO\3\"
.\cloudwerx-setup.exe /silent
)
pause
Any help would be greatly appreciated, thanks.
I am guessing that your problem is the distinction in powershell between the current location (set by the pushd command) and the working directory (unaffected by the pushd command). You can see the working directory of the powershell process using the [Environment]::CurrentDirectory property:
# C:\> [Environment]::CurrentDirectory = "c:\"
# C:\> [Environment]::CurrentDirectory
c:\
# C:\> pushd C:\Temp
# C:\Temp> [Environment]::CurrentDirectory
c:\
# C:\Temp> Get-Location
Path
----
C:\Temp
WHat is probably happening is that msiexec.exe is using the working directory (i.e. [Environment]::CurrentDirectory) and not the current powershell location at invocation. I would just specify the full path to msiexec:
msiexec.exe /i "\\KOPI-DC01\ACCURO Cloudwerx\ACCURO\2\\Screwdriver.msi"
MSI installation packages build with an older WIX utility would throw the error whenever installation was attempted from a batch script that was accessed on a shared drive using UNC path instead of a mapped drive letter. On the other hand whenever the batch file was executed with a mapped drive letter the installation would work normally.
I'm not blaming WIX here because I'm not certain whether they are responsible. I'm just describing symptoms here. It might just be the result of invoking plain vanilla Windows batch script that in turn executes msiexec with a bunch of command line parameters.
Some of our computers run multiple versions of Microsoft Access (97 & 2010) while others run 365. For the pcs running multiple versions, the default is set to 97. I have a batch file that is performing various tests to see if files exist, and finished by running an Access 2010 database called MWO.accdb. See below.
if exist c:\windows\system32\mscomct2.ocx goto step2
rem copy mscomct2 and register
cscript \\file\apps\Database\Maintenance\365\MsgBox.vbs "Preparing necessary libraries."
copy "\\file\apps\Database\Maintenance\365\mscomct2.ocx" "c:\windows\system32\"
regsvr32 /u mscomct2.ocx
regsvr32 /i mscomct2.ocx
:step2
if exist "%USERPROFILE%\Desktop\MWO.lnk" goto step3
rem create shortcut on user's desktop for future use
cscript \\file\apps\Database\Maintenance\365\MsgBox.vbs "Creating shortcut on desktop & adding to start menu."
copy "\\file\apps\Database\Maintenance\MWO-INSTALL.lnk" "%USERPROFILE%\Desktop\MWO.lnk"
mkdir "%USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start Menu\Maintenance"
copy "\\file\apps\Database\Maintenance\MWO-INSTALL.lnk" "%USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start Menu\Maintenance\MWO.lnk"
:step3
\\file\apps\Database\Maintenance\365\MWO.accdb
Is there an easy way to test for the latest version of access, and force the file to open with it to avoid the defaulting to 97 problem?
wmic product where caption="Access" get caption,version
(I don't have access installed, the captionstring may differ)
I am trying to create a setup for an application that I'm developing using the Visual Studio 2010 setup.
One of the things I need to do is run some exe programs.
I am using a custome action to run a VBS.
This the method that im using to execute:
Set objShell = CreateObject("Shell.Application")
objShell.ShellExecute """c:\prog.exe""","-parm bla" ,"","",""
The problem with this is that I cant wait for the program to finish using this method.
So I tried using this method:
Set objShell = WScript.CreateObject("WScript.Shell")
objShell.Run "c:\prog.exe -parm bla",1,True
But is seems that when the MSI runs the script is dosnt have the WScript object.
So my question is can i somehow get acess to the WScript object from the MSI or is there some better way to do this?
Indeed, Windows Installer does not support WScript objects directly. Have you tried to use the "CreateObject" function directly?
Set objShell = CreateObject("WScript.Shell")
Yes you cannot use WScript object in scripts that are called by MSI. As a workaround what you can do is create a new custom action with Action = NewAction, type =38, Source = (blank) TArget = add the vb script file as TARGET by running the following commands
CScript WiTextIn.vbs mymsi.msi CustomAction NewAction Target YourVBscript.vbs.
WiTextIn file is located in C:\Program Files\Microsoft SDKs\Windows\v7.0\Samples\sysmgmt\msi\scripts
(PS: When you try to run VBScript it might fail because vbscripts are disabled and you might have to delete the key from registry and enable vbscript)
This is what I did in my vbs script to open a firewall exception for the service. I couldn't use the standard interactive pop-up for a service (that asks for permission to open the firewall), since it doesn't have a UI.
set oShell = CreateObject("WScript.shell")
oShell.run "cmd /C netsh advfirewall firewall add rule program=""C:\Program Files (x86)\foo\bar\prog.exe"" name=""my-service"" dir=in action=allow"
I added this vbs script to the "Commit" CustomAction of the Setup&Deployment Project, leaving the properties as defaults.
To debug problems with the vbs stage, I ran the msi from DOS using
msiexec /i mysetup.msi /L* install.log
Note that I originally used "Wscript.CreateObject" but that failed. This worked.