<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; CMD/JS: msiprobe скрипт проверки и распаковки MSI файлов]]></title>
		<link>https://forum.script-coding.com/viewtopic.php?id=16216</link>
		<atom:link href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=16216&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «CMD/JS: msiprobe скрипт проверки и распаковки MSI файлов».]]></description>
		<lastBuildDate>Tue, 19 Oct 2021 16:48:15 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: CMD/JS: msiprobe скрипт проверки и распаковки MSI файлов]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=150141#p150141</link>
			<description><![CDATA[<p>Изменения:<br />-- переписал вывод справки<br />-- избавился от повторяющихся кусков кода в JS<br />-- упростил вызов в BATCH-части</p>]]></description>
			<author><![CDATA[null@example.com (Rumata)]]></author>
			<pubDate>Tue, 19 Oct 2021 16:48:15 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=150141#p150141</guid>
		</item>
		<item>
			<title><![CDATA[CMD/JS: msiprobe скрипт проверки и распаковки MSI файлов]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=147043#p147043</link>
			<description><![CDATA[<p>msiexec стандартная утилита для установки/удаления приложений из MSI-файлов. У ней есть различные опции, в частности для распаковки файлов. Иногда может быть полезно. </p><p>Написал гибридный CMD/JS скрипт для проверки и распаковки MSI-файлов.</p><p>Примеры использования.</p><p>Посмотреть информацию о файле<br /></p><div class="codebox"><pre><code>
msiprobe filename.msi /property
</code></pre></div><p>Посмотреть содержимое файла<br /></p><div class="codebox"><pre><code>
msiprobe filename.msi /list
</code></pre></div><p>распаковать файл в некоторый каталог<br /></p><div class="codebox"><pre><code>
msiprobe filename.msi C:\TEMP\zzz
</code></pre></div><div class="fancy_spoiler_switcher"><div class="fancy_spoiler_switcher_header"><strong>+</strong>&nbsp;исходный код</div><div class="fancy_spoiler"><p>Актуальная версия лежит <a href="https://github.com/ildar-shaimordanov/cmd.scripts/blob/master/msiprobe.bat">здесь</a><br /></p><div class="codebox"><pre><code>
0&lt;/*! ::

::Probe and unpack a MSI file.
::
::Usage:
::    msiprobe msi-file /LIST
::    msiprobe msi-file /PROPERTY
::    msiprobe msi-file target-dir

@echo off

if /i &quot;%~2&quot; == &quot;&quot; (
	for /f &quot;usebackq tokens=* delims=:&quot; %%s in ( &quot;%~f0&quot; ) do (
		if /i &quot;%%s&quot; == &quot;@echo off&quot; goto :EOF
		if not &quot;%%s&quot; == &quot;0&lt;/*! ::&quot; echo:%%s
	)
	goto :EOF
)

for %%o in ( LIST PROPERTY ) do if /i &quot;%~2&quot; == &quot;/%%~o&quot; (
	cscript //nologo //e:javascript &quot;%~f0&quot; %*
	goto :EOF
)

echo:Executing...
echo:msiexec /quiet /a &quot;%~f1&quot; TARGETDIR=&quot;%~f2&quot;
call msiexec /quiet /a &quot;%~f1&quot; TARGETDIR=&quot;%~f2&quot;

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) :
		&#039;/LIST or /PROPERTY required&#039;;
	WScript.StdOut.WriteLine(msiInfo);
} catch(e) {
	WScript.StdErr.WriteLine(&#039;Cannot probe file: &#039; + msiFile);
	WScript.StdErr.WriteLine(&#039;Error: &#039; + 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&amp;list=1
// https://www.hanselman.com/blog/how-to-list-all-the-files-in-an-msi-installer-using-vbsciript

function getMsiListing(filename) {
	return getMsiView(filename, {
		sql: &#039;Select FileSize, FileName From File&#039;,
		header: &#039;FileSize FileName&#039;.split(&#039; &#039;),
		align: function(value, width, padding) {
			return ( padding + value ).slice(-width);
		}
	});
}

function getMsiProperty(filename) {
	return getMsiView(filename, {
		sql: &#039;Select * From Property&#039;,
		header: &#039;Property Value&#039;.split(&#039; &#039;),
		align: function(value, width, padding) {
			return ( value + padding ).slice(0, width);
		}
	});
}

function getMsiView(filename, options) {
	var installer = new ActiveXObject(&#039;WindowsInstaller.Installer&#039;);
	var installerDatabase = installer.OpenDatabase(filename, 0);
	var installerView = installerDatabase.OpenView(options.sql);
	installerView.Execute();

	var installerRecord;

	var r = [];
	var maxLen = 0;

	while ( installerRecord = installerView.Fetch() ) {
		var n = installerRecord.FieldCount;
		var s = [];
		for (var i = 1; i &lt;= n; i++) {
			s.push(installerRecord.StringData(i));
		}
		maxLen = Math.max(maxLen, s[0].length);
		r.push(s);
	}

	var padding = new Array(maxLen + 1).join(&#039; &#039;);

	r.unshift(options.header);

	for (var i = 0; i &lt; r.length; i++) {
		r[i][0] = options.align(r[i][0], maxLen, padding);
		r[i] = r[i].join(&#039; : &#039;);
	}

	return r.join(&#039;\n&#039;);
}

// ========================================================================

// EOF
</code></pre></div></div></div><p>Близкое по содержанию обсуждение уже поднималось мной же здесь: <a href="http://forum.script-coding.com/viewtopic.php?id=12176">Распаковка (не инсталляция) MSI файлов</a></p>]]></description>
			<author><![CDATA[null@example.com (Rumata)]]></author>
			<pubDate>Sun, 28 Mar 2021 15:19:49 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=147043#p147043</guid>
		</item>
	</channel>
</rss>
