So, there is always one installer (msi) in a folder for install generation, but the name changes many times. I tried doing the following:
"C:\Windows\system32\msiexec.exe" /i "C:\test\*.msi" /qn
But sadly, this doesn't work and complains. How can we get the name of the single msi in the folder, and plonk it into the command?
I'm using jenkins and using the "Execute windows batch command" item
Perhaps use a for loop to find all .msi files in that directory, and run it accordingly (obviously if there is more than one .msi you will need to tweak this logic):
for /r "C:\test" %%a in (*.msi) do msiexec /i "%%~dpnxa" /qn
Related
I am currently creating an improvised installer for a cople software packages. To do this I have to install a couple MSI packages first before doing a couple file operations.
To install an MSI package I am using the following command:
start /wait msiexec /i "Myinstaller V2.1.msi" /qb
This command works and installs the package instantly and witout any problems via CMD.
But when I put this command in my batch file and execute it as an administrator, I get the following error:
This installation package could not be opened. Contact the application vendor to verify that this is a valid Windows Installer package
What cold be the problem? Using the same command via the console works flawlessly, only the batch file throws the error...
EDIT: I have also tried the /a parameter in order to install it as an administrator and it does not work either. Full command in batch file:
start /wait msiexec /qn /a "Myinstaller V2.1.msi"
EDIT2: I just realized that it only does not work when I start the batch file with Right click > Run as administrator
When I open a console with administrative rights and start my batch file it works for some reason...
Is there a way to make it work with the Right click > Run as administrator method?
SOLUTION: Thanks to RGuggisberg's answer I now know that the directory changes once the file is executed as an administrator. With a small change the installer gets fired up as an admin and works perfectly starting the installer from a relative path in the same directory:
#echo off
pushd %~dp0
start /wait msiexec /i "Myinstaller V2.1.msi" /qb
pause
I've now also implemented a feature to detect wether or not the installation fails or not:
#echo off
pushd %~dp0
start /wait msiexec /i "Myinstaller V2.1.msi" /qb
if %ERRORLEVEL% EQU 0 echo SUCCESSFULL
if NOT %ERRORLEVEL% EQU 0 echo MyProgram installation FAILED
pause
The current directory changes when you run as administrator. If you want to prove that to yourself, see this post
Difference between "%~dp0" and ".\"?
Include the full path to your filename and it will work.
Essentially I would like to install an msi file silently, and I've got it to work using the following line:
msiexec /i C:\Users\%username%\Downloads\mysqlODBC.msi /passive
One addition I would like to make is to add double quotes to the user name portion of the line to ensure any usernames that may contain spaces are read correctly. ----> "%username%"
The issue is the msi file fails to install when I add this. I have always used this when writing batch scripts with directories. Any idea how this can be addressed to work with msiexec?
Link to MSI file I am trying to quietly install:
https://dev.mysql.com/downloads/file/?id=484649
Network Installation Point?: It is not quite clear to me what you are trying to achieve. Do you want to automate the installation of this MSI on many machines? If so you should create a network installation point accessible via a UNC path and run an administrative image to extract all files and create a network installation point that can be used for all computers:
msiexec.exe /i "\\Server\Share\Setup.msi" /QN /L*V "C:\Temp\msilog.log"
If you have that instillation point there really is no reason to make a folder for each user. Why duplicate installation files? Surely you don't want each user to download the installer? You would want to download once, malware check and then rely on what you downloaded once and for all?
Anyway, if you insist:
msiexec.exe /i "\\Server\Share\%username%\Setup.msi" /QN /L*V "C:\Temp\msilog.log"
Quick Parameter Explanation:
/i = run install sequence
/QN = run completely silently
/L*V "C:\Temp\msilog.log"= verbose logging at specified path
msiexec.exe: See this answer for some further details on the msiexec.exe command line: MSIEXEC what is the difference between qn and quiet. There are two different flavors of it - two different sets of switches: old style and some newer, "friendlier" versions. I only use the old style switches. There is a tool you can use to generate the command lines.
Some Links:
Customize msiexec progress bar?
How to install an MSI silently
TL; DR :
pushd "C:\Users\%username%\Downloads\"
msiexec.exe /a "mysqlODBC.msi" /quiet /norestart /log "%cd%\msiexec_install.log"
popd
Details :
While the fully qualified path should be able to placed in-between double-quotes, an alternative option would be to use pushd and popd to move to an from the directory containing the MSI.
In the example above, I replaced the progress bar (aka /passive) with /quiet. I also used /a rather than /i out of habit - either can be used to install. And I included a log-to-file option which can be useful in troubleshooting.
I have a really messy program in my environment that basically has a jump client on over 7000 machines in my environment. When I upgrade the appliance that the jump client talks to it starts an in place upgrade but if there are computers off or off the network obviously the upgrade times out. Problem is, I cant mass deploy the updated jump client because the previous version has to be uninstalled first.
WMIC uninstaller doesn't work, msiexec uninstaller doesn't work. There is a batch file built into the program stored at %ProgramData%\ClientNameRandomNumbers. Problem is, you can also install a dissolvable client in the moment if needed and everytime the dissolvable client installs, it doesn't clean up after itself. So you have random folders that may or may not be the one that contains the uninstall.bat batch file that I need to run. I wanted to write a script to mass deploy that will start that batch file on each computer but I am having problems.
Basically I want it to search for the folder with a wild card, if it finds it CD to that directory and then try to run the uninstall, if it can't find the uninstall, continue through to deleting the folder as it is an old shell folder. And then go back and look for more folders until it can't find anymore and then go to exit.
This is what I have:
:START
cd %programdata%\bomgar-scc* || IF ERRORLEVEL not = 0 GOTO END
start uninstall.bat /Wait || cd c:\programdata &&
rd C:\programdata\bomgar-scc*
GOTO START
pause
:END
EXIT
Any suggestions?
I think I am understanding your requirements but maybe not. I have commented the code to let you know what it is doing.
#echo off
REM For command will attempt to find all folders
REM that start with bomgar-scc in the programdata folder
for /d %%G IN ("%programdata%\bomgar-scc*") do (
REM If it finds a folder check if an uninstall.bat
REM exists and run the batch file if it does exist.
IF EXIST "%%~G\uninstall.bat" CALL "%%~G\uninstall.bat"
REM Remove the directory found
rd "%%~G"
)
Create a Jump client MSI installer. Run the following command to uninstall it.
msiexec.exe /x "\%networkpath%\bomgar-scc-win64.msi" /quiet
I'm trying to silently uninstall AIM which is installed on a user's profile, not the machine. I'm using a batch script to find a registry entry that is the path where it's installed, then using that path to uninstall it. I'm not the best at writing scripts, but here is what I've put together.
for /f "tokens=3*" %%! in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Low Rights\DragDrop\{7A02967B-018E-41c9-953E-3DCAB144538B}" /v "AppPath" ^|Findstr.exe /ri "\<AppPath\>"') DO (if exist %%! %%!\uninstall.exe /S /PopUpMsgBox="n" /CheckMutx="N)
I'm not sure what the issue is.
I have a Winforms application that I want to publish using ClickOnce. This application comes with an initial database, which must be installed once on a per-machine basis. After much ado, I have landed on the idea of using a custom pre-requisite to install the .sdf file. I have used Bootstrapper Manifest Generator (BMG) to create a package for the .cmd file I want to run, and I have included the .sdf file as an "additional file."
My expectation was that the two files would end up in the same directory, and I would be able to copy the .sdf file to the place where I want it (They do end up in the same directory.) The pre-requisite shows up in Visual Studio just fine. It get's deployed to the client system just fine, and the setup program kicks off the prerequisite just fine.
The only problem is that the current working directory that the .cmd file is executing is C:\Documents and Settings\\Desktop!
Neither of the two files (.cmd or .sdf) are located there - they were downloaded elsewhere, e.g., "C:\Documents and Settings\drogers\Local Settings\Temp\VSD5A.tmp". So, although I know where to xcopy to, I have no idea where to xcopy from.
How can I resolve this?
Here is the .cmd file:
REM Modify this file to reflect your manufacturer name [FHCRC] and product name [ClickOnceSharedDataDemo].
SET TargetBase=%ALLUSERSPROFILE%
IF NOT "%TargetBase%"=="C:\ProgramData" SET TargetBase=%ALLUSERSPROFILE%\Application Data
REM We only want to do this copy for the first user!
if exist "%TargetBase%\FHCRC\ClickOnceSharedDataDemo\shareddata.sdf" GOTO EXIT
if not exist "%TargetBase%\FHCRC" mkdir "%TargetBase%\FHCRC"
if not exist "%TargetBase%\FHCRC\ClickOnceSharedDataDemo" mkdir "%TargetBase%\FHCRC\ClickOnceSharedDataDemo"
CACLS "%TargetBase%\FHCRC\ClickOnceSharedDataDemo" /E /T /C /G "Users":C
xcopy shareddata.sdf "%TargetBase%\FHCRC\ClickOnceSharedDataDemo\"
if not exist "%TargetBase%\FHCRC\ClickOnceSharedDataDemo\shareddata.sdf" PAUSE
if not exist "%TargetBase%\FHCRC\ClickOnceSharedDataDemo\shareddata.sdf" exit /B -1
:EXIT
PAUSE
exit /B 0
Thanks,
David
Well, I am not altogether happy with this solution, but it works. I now have two prerequisites. the first is just the command file which runs the CACLS commands to set permissions. It is basically a shortened version of the above:
REM Modify this file to reflect your manufacturer name [Manufacturer] and product name [ProductName].
SET TargetBase=%ALLUSERSPROFILE%
IF NOT "%TargetBase%"=="C:\ProgramData" SET TargetBase=%ALLUSERSPROFILE%\Application Data
REM We only want to do this copy for the first user!
if exist "%TargetBase%\Manufacturer\ProductName\shareddata.sdf" GOTO EXIT
if not exist "%TargetBase%\Manufacturer" mkdir "%TargetBase%\Manufacturer"
if not exist "%TargetBase%\Manufacturer\ProductName" mkdir "%TargetBase%\Manufacturer\ProductName"
CACLS "%TargetBase%\Manufacturer\ProductName" /E /T /C /G "Users":C
:EXIT
ECHO exit /B 0
The second prerequisite is an "all users = true" setup project which has a custom folder located at default location:
"[CommonAppDataFolder][Manufacturer][ProductName]".
Into this folder I put the sdf file.
Finally, I used Bootstrapper Manifest Generator to make packages for both, making the second dependent on the first. I copied the packages to the appropriate VS2010 directory, included them as prerequisites, and published.
I now have per-machine .sdf files published to both WinXP and Win7. Why does this have to be so difficult!?!?
I'm still looking for less complicated solutions, that will install to both Windows 7 and Windows XP.
Did you try MSDeploy? It is able to fulfil all your needs.
Cheers!
You could just include the .sdf file with the ClickOnce application, then have your program copy it to somewhere else the first time it runs. I never recommend keeping the data in the CLickOnce cache anyway, it's safer to handle it yourself. See if this article helps at all:
http://robindotnet.wordpress.com/2009/08/19/where-do-i-put-my-data-to-keep-it-safe-from-clickonce-updates/