Obtener tu propia versión

Muchos habréis observado que en las propiedades de un ejecutable o una DLL suelen aparecer, en la pestaña Detalles de las propiedades, una serie de nombres y de datos sobre la versión de dicho fichero.

Eso se consigue embebiendo en el ejecutable un recurso de versión, que en Win32 se llama RCVERSION y que consta de una serie de cadenas y valores predefinidos que podemos rellenar a nuestro gusto.

En las imágenes de abajo podemos ver un ejemplo añadido a un ejecutable, tanto desde C++ Builder como desde Visual C++.

image

image 

Si os fijáis, ambas tienen más o menos los mismos elementos, pero en el caso del C++Builder existe la opción de incrementar el número de Build automáticamente. Hasta donde yo sé, eso no lo permite Visual C++ (quizás se haga en conjunción con un CVS o cuando haya uno compatible), y básicamente consiste en incrementar automáticamente el último numerito cada vez que compilemos algo. A lo largo de diferentes versiones del producto, este incremento se producía cuando se hacía un Build, un Make o incluso nunca (debido a un bug). En la versión 2010 se hace cada vez que compilemos algo.

Bueno, una vez que hemos especificado nuestro recurso de versión, es tiempo de que podamos leerlo desde el propio ejecutable para poderlo poner, por ejemplo, en la pantalla de “Acerca”, en la de “Splash” o donde queramos. Si os dais cuenta, esos números suelen aparecer en muchas aplicaciones.

El código es muy sencillo:

DWORD handle;
DWORD size = GetFileVersionInfoSize(Application->ExeName.w_str(), &handle);
wchar_t *buffer = new wchar_t[size + 1];
GetFileVersionInfo(Application->ExeName.w_str(), 0, size, buffer);
VS_FIXEDFILEINFO *pFixedInfo;
UINT uVersionLen;
if (VerQueryValue(buffer, L"\", (void**) & pFixedInfo, (UINT*) & uVersionLen) != 0)
{
    String version = L" " + String(HIWORD(pFixedInfo->dwFileVersionMS)) + L"." + String(LOWORD(pFixedInfo->dwFileVersionMS)) + L"." + String
    (HIWORD(pFixedInfo->dwFileVersionLS)) + L"." + String(LOWORD(pFixedInfo->dwFileVersionLS));
    m_caption = Caption + version + L" - ";
    Caption = m_caption + m_document->FileName;
}
delete[] buffer;

El ejemplo que he puesto es para C++ Builder Unicode, pero resulta trivial convertirlo a C ó C++ estándar. Tan sólo hay que cambiar el tipo de las cadenas por las adecuadas.

Primero se hace una llamada a GetFileVersionInfoSize() pasando la ruta de nuestro ejecutable y un DWORD que de nada sirve. Con el tamaño del recurso, llamamos a GetFileVersionInfo() volviendo a pasar la ruta del ejecutable y un buffer con el tamaño adecuado.

Después creamos un puntero a una estructura del tipo VS_FIXEDFILEINFO y la pasamos a la función VerQueryValue(), que también recibe el buffer original, qué parte del recurso queremos sacar (“\”, es decir, la versión raíz –los recursos de versión se pueden embeber unos dentro de otros) y algún que otro valor más.

Si esta función encuentra lo que le decimos, entonces podemos usar el puntero de la estructura y formatear una cadena con los cuatro números de versión.

Lo que hagamos con esa cadena es cosa nuestra. En este caso la añadimos al título de la ventana actual y lo guardamos en una variable miembro que usaremos cada vez que cambiemos de documento.

Y no nos olvidemos de liberar la cadena asignada.

4 comentarios sobre “Obtener tu propia versión”

  1. Solo que me alegra que despues de tu pesadilla con el C++Builder vuelvas a escribir algo sobre el.
    Te contaré una cosa que suelo hacer para que la prueba de un producto no me estropee nada (eso creo) y es que lo instalo en una máquina virtual (Sun VirtualBox), de forma que lo tengo todo disponible los dias necesarios para probarlo.
    Claro, esto es ultimamente que conocí el producto, antes siempre en maquina aparte, donde un format nunca me preocupaba.
    Saludos y tambien felicitarte por la web

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *