Тема: CMD/JS: msiprobe скрипт проверки и распаковки MSI файлов
msiexec стандартная утилита для установки/удаления приложений из MSI-файлов. У ней есть различные опции, в частности для распаковки файлов. Иногда может быть полезно.
Написал гибридный CMD/JS скрипт для проверки и распаковки MSI-файлов.
Примеры использования.
Посмотреть информацию о файле
msiprobe filename.msi /property
Посмотреть содержимое файла
msiprobe filename.msi /list
распаковать файл в некоторый каталог
msiprobe filename.msi C:\TEMP\zzz
Актуальная версия лежит здесь
0</*! ::
@echo off
for %%f in ( "%~1" ) do for %%d in ( "%~2" ) do if /i "%%~d" == "" (
echo:Usage: %~n0 msi-file /LIST
echo:Usage: %~n0 msi-file /PROPERTY
echo:Usage: %~n0 msi-file target-dir
) else if /i "%%~d" == "/LIST" (
cscript //nologo //e:javascript "%~f0" "%%~ff" /LIST
) else if /i "%%~d" == "/PROPERTY" (
cscript //nologo //e:javascript "%~f0" "%%~ff" /PROPERTY
) else (
echo:Executing...
echo:msiexec /quiet /a "%%~ff" TARGETDIR="%%~fd"
call msiexec /quiet /a "%%~ff" TARGETDIR="%%~fd"
)
goto :EOF
*/0;
// ========================================================================
try {
var msiFile = WScript.Arguments.item(0);
var mode = WScript.Arguments.item(1);
var msiInfo =
mode.match(/^\/LIST$/i) ? getMsiListing(msiFile) :
mode.match(/^\/PROPERTY$/i) ? getMsiProperty(msiFile) :
'/LIST or /PROPERTY required';
WScript.StdOut.WriteLine(msiInfo);
} catch(e) {
WScript.StdErr.WriteLine('Cannot probe file: ' + msiFile);
WScript.StdErr.WriteLine('Error: ' + e.message);
WScript.Quit(1);
}
// ========================================================================
// JS code was adapted from VBS implementation found by these links:
// https://serverfault.com/a/465717/423234
// http://scriptbox.toll.at/index.php?showcontent=Get%20MSI-File%20properties.vbs&list=1
// https://www.hanselman.com/blog/how-to-list-all-the-files-in-an-msi-installer-using-vbsciript
function getMsiListing(filename) {
var r = getMsiView(filename, 'Select FileSize, FileName From File');
var c = getColumnWidth(r, 0);
for (var i = 0; i < r.length; i++) {
r[i][0] = ( c.padding + r[i][0] ).slice(-c.width);
r[i] = r[i].join(' : ');
}
return r.join('\n');
}
function getMsiProperty(filename) {
var r = getMsiView(filename, 'Select * From Property');
var c = getColumnWidth(r, 0);
for (var i = 0; i < r.length; i++) {
r[i][0] = ( r[i][0] + c.padding ).slice(0, c.width);
r[i] = r[i].join(' : ');
}
return r.join('\n');
}
function getMsiView(filename, sql) {
var installer = new ActiveXObject('WindowsInstaller.Installer');
var installerDatabase = installer.OpenDatabase(filename, 0);
var installerView = installerDatabase.OpenView(sql);
installerView.Execute();
var installerRecord;
var r = [];
while ( installerRecord = installerView.Fetch() ) {
var n = installerRecord.FieldCount;
var s = [];
for (var i = 1; i <= n; i++) {
s.push(installerRecord.StringData(i));
}
r.push(s);
}
return r;
}
function getColumnWidth(r, j) {
var maxLen = 0;
for (var i = 0; i < r.length; i++) {
maxLen = Math.max(maxLen, r[i][j].length);
}
return {
width: maxLen,
padding: new Array(maxLen + 1).join(' ')
};
}
// ========================================================================
// EOF
Близкое по содержанию обсуждение уже поднималось мной же здесь: Распаковка (не инсталляция) MSI файлов