Solved

Retrieve custom file version properties

Posted on 2007-11-27
5
935 Views
Last Modified: 2013-11-07
I'm attempting to retireve custom version attributes from MS hotfix EXEs.  This is the info in the file properties on the "Version" tab in the "Other version information" (as seen on XP).  MS hotfixes includes additional version attributes here, e.g. "Support path".  I need to retrieve this information through my .NET app.  System.diags.FileVersionInfo allows me to retrieve the standards attributes for the files such as internal name name etc, but doesn't appear to expose custom attributes.

Currently using VB.NET 2005 and building for .NET 2.0.  Any assistance will be appreciated.
0
Comment
Question by:sj_hicks
  • 3
  • 2
5 Comments
 
LVL 96

Expert Comment

by:Bob Learned
ID: 20366101
I have a custom C# class that can do the job, but the code is not translatable to VB.NET, since it uses unsafe pointers.  If you would like to see it, you could build a C# DLL, and then reference it in your VB.NET application.

Bob
0
 
LVL 7

Author Comment

by:sj_hicks
ID: 20370095
Bob, that'd be great, no problems working with a C# class and dll.  Can I take a look at it?
Thanks, Stephen.
0
 
LVL 96

Accepted Solution

by:
Bob Learned earned 500 total points
ID: 20373300
Here you go:
using System;

using System.Collections.Generic;

using System.IO;

using System.Runtime.InteropServices;

using System.Text;

using System.Windows.Forms;
 

public class FileVersionInfoEx

{
 

    [DllImport("version.dll")]

    private static extern bool GetFileVersionInfo(string sFileName,

         int handle, int size, byte[] infoBuffer);
 

    [DllImport("version.dll")]

    private static extern int GetFileVersionInfoSize(string sFileName,

         out int handle);
 

    // The third parameter - "out string pValue" - is automatically 

    // marshaled from ANSI to Unicode: 

    [DllImport("version.dll")]

    private static unsafe extern bool VerQueryValue(byte[] pBlock,

         string pSubBlock, out string pValue, out uint len);
 

    // This VerQueryValue overload is marked with 'unsafe' because 

    // it uses a short*: 

    [DllImport("version.dll")]

    private static unsafe extern bool VerQueryValue(byte[] pBlock,

         string pSubBlock, out short* pValue, out uint len);
 

    public static unsafe List<string> GetFileVersionInfo(string path, params string[] propertyList)

    {

        int handle = 0;

        int size = GetFileVersionInfoSize(path, out handle);

        short* subBlock = null;
 

        List<string> list = new List<string>();
 

        if (size != 0)

        {

            byte[] buffer = new byte[size];
 

            uint len = 0;

            if (GetFileVersionInfo(path, handle, size, buffer) &&

                VerQueryValue(buffer, @"\VarFileInfo\Translation", out subBlock, out len) && len > 2)

            {

                foreach (string property in propertyList)

                    list.Add(FindVersionValue(buffer, subBlock, property));

            }

        }

        return list;

    }
 

    /// <summary>

    /// Get the complete string table for the VS_VERSION_INFO, so that you can look for custom

    /// property names.

    /// </summary>

    public static unsafe string GetStringTable(string path)

    {

        int handle = 0;

        int size = GetFileVersionInfoSize(path, out handle);

        short* subBlock = null;
 

        List<string> list = new List<string>();
 

        if (size != 0)

        {

            byte[] buffer = new byte[size];
 

            uint len = 0;

            if (GetFileVersionInfo(path, handle, size, buffer) &&

                VerQueryValue(buffer, @"\VarFileInfo\Translation", out subBlock, out len) && len > 2)

            {

                return Encoding.Unicode.GetString(buffer).Replace("\0", "");

            }

        }

        return "";

    }
 

    private static unsafe string FindVersionValue(byte[] buffer, short* subBlock, string property)

    {

        string spv = @"\StringFileInfo\" + subBlock[0].ToString("X4") + subBlock[1].ToString("X4") + '\\' + property;

        byte* pVersion = null;

        string value;

        uint len = 0;

        if (VerQueryValue(buffer, spv, out value, out len))

            return value;

        return "";

    }

}

Open in new window

0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 20373305
Sample usage:

            Dim valueList As List(Of String) = FileVersionInfoEx.GetFileVersionInfo("C:\Downloads\WindowsXP-KB896256-v4-x86-ENU.exe",
                "Installer Engine", "Proc. Architecture", "Self-Extractor Version")

Bob
0
 
LVL 7

Author Closing Comment

by:sj_hicks
ID: 31411354
Worked great.  Thanks Bob, you truly are The Learned One.
0

Featured Post

3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Loop not working 29 47
Problem to error 4 46
SQL Login 17 40
I need help making a collection from a class in VB.Net 3 27
In my previous article (http://www.experts-exchange.com/Programming/Languages/.NET/.NET_Framework_3.x/A_4362-Serialization-in-NET-1.html) we saw the basics of serialization and how types/objects can be serialized to Binary format. In this blog we wi…
More often than not, we developers are confronted with a need: a need to make some kind of magic happen via code. Whether it is for a client, for the boss, or for our own personal projects, the need must be satisfied. Most of the time, the Framework…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, just open a new email message. In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
Many functions in Excel can make decisions. The most simple of these is the IF function: it returns a value depending on whether a condition you describe is true or false. Once you get the hang of using the IF function, you will find it easier to us…

895 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now