<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Read Properties from an MSI File</title>
	<atom:link href="http://www.alteridem.net/2008/05/20/read-properties-from-an-msi-file/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.alteridem.net/2008/05/20/read-properties-from-an-msi-file/</link>
	<description>Software by Design</description>
	<lastBuildDate>Sat, 04 Feb 2012 10:08:18 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
	<item>
		<title>By: Fan</title>
		<link>http://www.alteridem.net/2008/05/20/read-properties-from-an-msi-file/comment-page-1/#comment-16246</link>
		<dc:creator>Fan</dc:creator>
		<pubDate>Mon, 12 Sep 2011 23:15:13 +0000</pubDate>
		<guid isPermaLink="false">http://www.alteridem.net/?p=47#comment-16246</guid>
		<description>Awesome article! Thanks so much!</description>
		<content:encoded><![CDATA[<p>Awesome article! Thanks so much!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Robert Prouse</title>
		<link>http://www.alteridem.net/2008/05/20/read-properties-from-an-msi-file/comment-page-1/#comment-13067</link>
		<dc:creator>Robert Prouse</dc:creator>
		<pubDate>Tue, 10 May 2011 13:54:01 +0000</pubDate>
		<guid isPermaLink="false">http://www.alteridem.net/?p=47#comment-13067</guid>
		<description>The post has been updated. I do read my comments, but occasionally I miss a few.</description>
		<content:encoded><![CDATA[<p>The post has been updated. I do read my comments, but occasionally I miss a few.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Whatever</title>
		<link>http://www.alteridem.net/2008/05/20/read-properties-from-an-msi-file/comment-page-1/#comment-13061</link>
		<dc:creator>Whatever</dc:creator>
		<pubDate>Tue, 10 May 2011 07:05:25 +0000</pubDate>
		<guid isPermaLink="false">http://www.alteridem.net/?p=47#comment-13061</guid>
		<description>Mike and Neo are correct, you MUST correct your SQL string in your code, as it generates a COM exception. Don&#039;t you read your comments?

So much for a &quot;consulting&quot; business...</description>
		<content:encoded><![CDATA[<p>Mike and Neo are correct, you MUST correct your SQL string in your code, as it generates a COM exception. Don&#8217;t you read your comments?</p>
<p>So much for a &#8220;consulting&#8221; business&#8230;</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: PeterG</title>
		<link>http://www.alteridem.net/2008/05/20/read-properties-from-an-msi-file/comment-page-1/#comment-12889</link>
		<dc:creator>PeterG</dc:creator>
		<pubDate>Thu, 28 Apr 2011 19:35:55 +0000</pubDate>
		<guid isPermaLink="false">http://www.alteridem.net/?p=47#comment-12889</guid>
		<description>Thank you, thank you, thank you!!!  I&#039;ve fond this code in lots of places, but nowhere does it say what the assemly that you nood to include is! I was about to search through every .NET and COM assembly included, but then I found your article and was saved!

Again, Thank you!</description>
		<content:encoded><![CDATA[<p>Thank you, thank you, thank you!!!  I&#8217;ve fond this code in lots of places, but nowhere does it say what the assemly that you nood to include is! I was about to search through every .NET and COM assembly included, but then I found your article and was saved!</p>
<p>Again, Thank you!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Shah MOHAMOD</title>
		<link>http://www.alteridem.net/2008/05/20/read-properties-from-an-msi-file/comment-page-1/#comment-12867</link>
		<dc:creator>Shah MOHAMOD</dc:creator>
		<pubDate>Wed, 27 Apr 2011 15:47:11 +0000</pubDate>
		<guid isPermaLink="false">http://www.alteridem.net/?p=47#comment-12867</guid>
		<description>Here is an improved version of the above code. This new versions allows to pass in a dictionary of property names whose values are then filled in.

/// 
        /// Uses the Windows Installer COM component to retrieve property values (e.g. ProductCode) from an MSI file.
        /// 
        /// The path to an MSI file.
        /// A dictionary containing the property names whose values need to be retrieved and filled in from the MSI file.
        public static void GetMsiProperties(string msiFile, SortedDictionary propertyNames)
        {
            if (string.IsNullOrEmpty(msiFile))
                throw new ArgumentException(Resources.ErrBlankMsiFilePath, &quot;msiFile&quot;);

            if (propertyNames == null &#124;&#124; propertyNames.Count == 0)
                throw new ArgumentException(Resources.ErrNullOrEmptyPropertyNamesDictionary, &quot;propertyNames&quot;);

            Type classType = Type.GetTypeFromProgID(&quot;WindowsInstaller.Installer&quot;);
            Object installerObj = Activator.CreateInstance(classType);
            Installer installer = (Installer)installerObj;

            // Open the msi file for reading : 0 - Read, 1 - Read/Write    
            Database database = installer.OpenDatabase(msiFile, 0);
            StringBuilder sql = new StringBuilder(&quot;SELECT Property, Value FROM Property WHERE &quot;);

            foreach (KeyValuePair item in propertyNames)
            {
                sql.AppendFormat(&quot;Property = &#039;{0}&#039; OR &quot;, item.Key);
            }

            sql.Remove(sql.Length - 4, 4);  // remove last &quot; OR &quot;
            
            View view = database.OpenView(sql.ToString());
            view.Execute(null);

            Record record = view.Fetch();
            while (record != null)
            {
                propertyNames[record.StringData[1]] = record.StringData[2];
                record = view.Fetch();
            }

            view.Close();
        }</description>
		<content:encoded><![CDATA[<p>Here is an improved version of the above code. This new versions allows to pass in a dictionary of property names whose values are then filled in.</p>
<p>///<br />
        /// Uses the Windows Installer COM component to retrieve property values (e.g. ProductCode) from an MSI file.<br />
        ///<br />
        /// The path to an MSI file.<br />
        /// A dictionary containing the property names whose values need to be retrieved and filled in from the MSI file.<br />
        public static void GetMsiProperties(string msiFile, SortedDictionary propertyNames)<br />
        {<br />
            if (string.IsNullOrEmpty(msiFile))<br />
                throw new ArgumentException(Resources.ErrBlankMsiFilePath, &#8220;msiFile&#8221;);</p>
<p>            if (propertyNames == null || propertyNames.Count == 0)<br />
                throw new ArgumentException(Resources.ErrNullOrEmptyPropertyNamesDictionary, &#8220;propertyNames&#8221;);</p>
<p>            Type classType = Type.GetTypeFromProgID(&#8220;WindowsInstaller.Installer&#8221;);<br />
            Object installerObj = Activator.CreateInstance(classType);<br />
            Installer installer = (Installer)installerObj;</p>
<p>            // Open the msi file for reading : 0 &#8211; Read, 1 &#8211; Read/Write<br />
            Database database = installer.OpenDatabase(msiFile, 0);<br />
            StringBuilder sql = new StringBuilder(&#8220;SELECT Property, Value FROM Property WHERE &#8220;);</p>
<p>            foreach (KeyValuePair item in propertyNames)<br />
            {<br />
                sql.AppendFormat(&#8220;Property = &#8216;{0}&#8217; OR &#8220;, item.Key);<br />
            }</p>
<p>            sql.Remove(sql.Length &#8211; 4, 4);  // remove last &#8221; OR &#8221;</p>
<p>            View view = database.OpenView(sql.ToString());<br />
            view.Execute(null);</p>
<p>            Record record = view.Fetch();<br />
            while (record != null)<br />
            {<br />
                propertyNames[record.StringData[1]] = record.StringData[2];<br />
                record = view.Fetch();<br />
            }</p>
<p>            view.Close();<br />
        }</p>
]]></content:encoded>
	</item>
</channel>
</rss>

