Comment inclure le numéro de version dans le nom de fichier de sortie du projet VS Setup

Existe-t-il un moyen d'inclure le numéro de version dans la sortie.nom de fichier msi dans un projet D'installation VS2008?

Je voudrais par exemple un fichier de sortie appelé: "myinstaller-1.0.13.msi " où la partie version est automatiquement définie en fonction du numéro de version que j'ai mis dans les propriétés du projet de déploiement.

24
demandé sur chardy 2010-07-29 10:31:21

6 réponses

Je ne sais pas si vous avez toujours besoin de ceci ou non, mais je voulais répondre à cela car nous avons fait un type d'opération similaire dans l'événement postbuild. En ce qui concerne la recherche que j'ai faite, il n'est pas possible de définir le nom du fichier comme vous le souhaitez en interne via le processus d'installation.

Vous pouvez le faire autrement en nommant le fichier de sortie via une application externe dans l'événement post build.

Voici ce que vous pouvez faire:

Dans l'événement post build- >

[MsiRenamerAppPath] \ MsiRenamer.exe "$(BuildOutputPath) "

Créez une application qui renommera le fichier msi avec le numéro de version du projet de déploiement. Voici le code utilisé pour l'application. Cela devrait répondre à votre exigence, je suppose.

Obtenir le code des propriétés msi est utilisé à partir de alteridem article

class MsiRenamer
  {
    static void Main(string[] args)
    {
      string inputFile;
      string productName = "[ProductName]";

      if (args.Length == 0)
      {
        Console.WriteLine("Enter MSI file:");
        inputFile = Console.ReadLine();
      }
      else
      {
        inputFile = args[0];
      }

      try
      {
        string version;

        if (inputFile.EndsWith(".msi", StringComparison.OrdinalIgnoreCase))
        {
          // Read the MSI property
          version = GetMsiProperty(inputFile, "ProductVersion");
          productName = GetMsiProperty(inputFile, "ProductName");
        }
        else
        {
          return;
        }
        // Edit: MarkLakata: .msi extension is added back to filename
        File.Copy(inputFile, string.Format("{0} {1}.msi", productName, version));
        File.Delete(inputFile);
      }
      catch (Exception ex)
      {
        Console.WriteLine(ex.Message);
      }
    }

    static string GetMsiProperty(string msiFile, string property)
    {
      string retVal = string.Empty;

      // Create an Installer instance  
      Type classType = Type.GetTypeFromProgID("WindowsInstaller.Installer");
      Object installerObj = Activator.CreateInstance(classType);
      Installer installer = installerObj as Installer;

      // Open the msi file for reading  
      // 0 - Read, 1 - Read/Write  
      Database database = installer.OpenDatabase(msiFile, 0);

      // Fetch the requested property  
      string sql = String.Format(
          "SELECT Value FROM Property WHERE Property='{0}'", property);
      View view = database.OpenView(sql);
      view.Execute(null);

      // Read in the fetched record  
      Record record = view.Fetch();
      if (record != null)
      {
        retVal = record.get_StringData(1);
        System.Runtime.InteropServices.Marshal.FinalReleaseComObject(record);
      }
      view.Close();
      System.Runtime.InteropServices.Marshal.FinalReleaseComObject(view);
      System.Runtime.InteropServices.Marshal.FinalReleaseComObject(database);

      return retVal;
    }
  }
12
répondu JPReddy 2014-07-08 16:15:16

Je ne voulais pas utiliser le .méthode exe ci-dessus et avait un peu de temps libre alors j'ai commencé à diggind autour. J'utilise VS 2008 sur Windows 7 64 bits. Quand j'ai un projet D'installation, appelons-le MySetup tous les détails du projet peuvent être trouvés dans le fichier $ (ProjectDir)MySetup.vdproj.

La version du produit sera trouvée sur une seule ligne dans ce fichier sous la forme

ProductVersion="8:1.0.0"

Maintenant, il y a un événement post-build sur un projet d'installation. Si vous sélectionnez un projet d'installation et appuyez sur F4 vous obtenez un complètement différent de propriétés lorsque vous faites un clic droit et sélectionnez propriétés. Après avoir frappé F4, vous verrez que L'un des PostBuildEvent est. Encore une fois en supposant que le projet d'installation est appelé MySetup ce qui suit définira le nom de la .msi pour inclure la date et la version

set datevar=%DATE:~6,4%%DATE:~3,2%%DATE:~0,2%
findstr /v PostBuildEvent $(ProjectDir)MySetup.vdproj | findstr ProductVersion >$(ProjectDir)version.txt
set /p var=<$(ProjectDir)version.txt
set var=%var:"=%
set var=%var: =%
set var=%var:.=_%
for /f "tokens=1,2 delims=:" %%i in ("%var%") do @echo %%j >$(ProjectDir)version.txt
set /p realvar=<$(ProjectDir)version.txt
rename "$(ProjectDir)$(Configuration)\MySetup.msi" "MySetup-%datevar%-%realvar%.msi"

Je vais vous emmener à travers ce qui précède.

Datevar est la date actuelle sous la forme AAAAMMJJ.

La ligne findstr passe par MySetup.VDPROJ, supprime toute ligne avec PostBuildEvent dans, renvoie ensuite la seule ligne laissée avec productVersion et la sort dans un fichier. Nous supprimons ensuite les guillemets, les espaces, transformons les points en traits de soulignement.

La ligne for divise la chaîne restante sur deux-points, et prend la deuxième partie, et la sort à nouveau dans un fichier.

Nous avons ensuite mis realvar à la valeur laissée dans le fichier, et renommer MySetup.msi pour inclure la date et la version.

Donc, étant donné la ProductVersion ci-dessus, si c'était le 27 mars 2012, le fichier serait renommé à

MySetup-20120327-1_0_0.msi

Clairement en utilisant cette méthode, vous pouvez saisir L'une des variables dans le fichier vdproj et les inclure dans votre nom de fichier de sortie et nous n'avons pas besoin de construire un supplément .programmes exe pour le faire.

HTH

17
répondu Jim Grimmett 2012-03-27 13:58:08

Même concept que la réponse de Jim Grimmett, mais avec moins de dépendances:

FOR /F "tokens=2 delims== " %%V IN ('FINDSTR /B /R /C:" *\"ProductVersion\"" "$(ProjectDir)MySetupProjectName.vdproj"') DO FOR %%I IN ("$(BuiltOuputPath)") DO REN "$(BuiltOuputPath)" "%%~nI-%%~nxV%%~xI"

Quelques points à noter:

MySetupProjectName.vdproj doit être remplacée par le nom de votre fichier de projet. Oublier de changer cela entraîne une erreur de construction: 'PostBuildEvent' failed with error code '1' et la fenêtre Output montre quel fichier FINDSTR n'a pas pu s'ouvrir.

Description étape par Étape:

FINDSTR /B /R /C:" *\"ProductVersion\"" $(ProjectDir)MySetupProjectName.vdproj

  • recherche la ligne "ProductVersion" = "8:x.y.z.etc" du fichier de projet.

FOR /F "tokens=2 delims== " %%V IN (...) DO ... %%~nxV ...

  • ceci est utilisé pour analysez la partie x.y.z.etc à partir du résultat ci-dessus.

$(BuiltOuputPath)

  • c'est le chemin de sortie d'origine, selon ce qu'il dit dans les "Macros"de la ligne de commande de L'événement Post-build.

FOR %%I IN (...) DO ... %%~nI-%%~nxV%%~xI

  • ceci est utilisé pour convertir la chaîne foo.msi en foo-x.y.z.etc.msi.

REN "$(BuiltOuputPath)" ...

  • cela renomme simplement le chemin de sortie au nouveau nom.

FOR ... DO FOR .. DO REN ...

  • Il est écrit sur une ligne comme ceci de sorte qu'une erreur le long du chemin brise proprement la construction.
8
répondu antak 2014-12-26 05:34:32

Si vous utilisez un projet Wix (par opposition à un projet VS Setup & Deployment) alors Cet article explique exactement comment réaliser ce que vous recherchez.

2
répondu prairiehat 2010-11-02 16:03:51
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using WindowsInstaller;


// cscript //nologo "$(ProjectDir)WiRunSql.vbs" "$(BuiltOuputPath)" "UPDATE `Property` SET `Property`.`Value`='4.0.0.1' WHERE `Property`='ProductVersion'"
// "SELECT `Property`.`ProductVersion` FROM `Property` WHERE `Property`.`Property` = 'ProductVersion'"

/* 
 * That's a .NET wrapper generated by tlbimp.exe, wrapping the ActiveX component c:\windows\system32\msi.dll.  
 * You can let the IDE make one for you with Project + Add Reference, COM tab, 
 * select "Microsoft Windows Installer Object Library". 
 */
namespace PostBuildEventModifyMSI
{
    /* Post build event fro Rename MSI file.
     * $(SolutionDir)PostBuildEventModifyMSI\bin\Debug\PostBuildEventModifyMSI.exe "$(SolutionDir)TestWebApplicationSetup\Debug\TestWebApplicationSetup.msi"
     */

    [System.Runtime.InteropServices.ComImport(), System.Runtime.InteropServices.Guid("000C1090-0000-0000-C000-000000000046")]
    class Installer { }
    class Program
    {
        static void Main(string[] args)
        {
            #region New code.

            string msiFilePath = string.Empty;
            if (args.Length == 0)
            {
                Console.WriteLine("Enter MSI file complete path:");
                msiFilePath = Console.ReadLine();
            }
            else
            {
                Console.WriteLine("Argument Received args[0]: " + args[0]);
                msiFilePath = args[0];
            }

            StringBuilder sb = new StringBuilder();
            string[] words = msiFilePath.Split('\\');
            foreach (string word in words)
            {
                sb.Append(word + '\\');

                if (word.Contains("Debug"))
                {
                    break;
                }
                else
                {

                }
            }

            // Open a view on the Property table for the Label property 
            //UPDATE Property set Value = '2.06.36' where Property = 'ProductVersion'
            Program p = new Program();
            string version = p.GetMsiVersionProperty(msiFilePath, "ProductVersion");
            string productName = p.GetMsiVersionProperty(msiFilePath, "ProductName");

            string newMSIpath = sb.ToString() + string.Format("{0}_{1}.msi", productName, version);
            Console.WriteLine("Original MSI File Path: " + msiFilePath);
            Console.WriteLine("New MSI File Path: " + newMSIpath);


            System.IO.File.Move(msiFilePath, newMSIpath);

            #endregion




            //Console.Read();
        }

        private string GetMsiVersionProperty(string msiFilePath, string property)
        {
            string retVal = string.Empty;

            // Create an Installer instance  
            WindowsInstaller.Installer installer = (WindowsInstaller.Installer) new Installer();

            // Open the msi file for reading  
            // 0 - Read, 1 - Read/Write  
            Database db = installer.OpenDatabase(msiFilePath, WindowsInstaller.MsiOpenDatabaseMode.msiOpenDatabaseModeReadOnly); //// Open the MSI database in the input file 

            // Fetch the requested property  
            string sql = String.Format(
                "SELECT Value FROM Property WHERE Property='{0}'", property);
            View view = db.OpenView(sql);
            //View vw = db.OpenView(@"SELECT `Value` FROM `Property` WHERE `Property` = 'ProductVersion'");
            view.Execute(null);

            // Read in the fetched record  
            Record record = view.Fetch();
            if (record != null)
            {
                retVal = record.get_StringData(1);
                System.Runtime.InteropServices.Marshal.FinalReleaseComObject(record);
            }
            view.Close();

            System.Runtime.InteropServices.Marshal.FinalReleaseComObject(view);
            System.Runtime.InteropServices.Marshal.FinalReleaseComObject(db);

            return retVal;
        }

    }
}
0
répondu Muhammad Mubashir 2013-03-22 11:13:51

Je l'ai fait avec 2 lignes dans powershell.

$versionText=(Get-Item MyProgram.exe).VersionInfo.FileVersion
(Get-Content MySetup.vdproj.template).replace('${VERSION}', $($versionText)) | Set-Content MySetup.vdproj

Renommez votre existant .vdproj pour être MySetup.vdproj.template et insérez "$ {VERSION} " partout où vous voulez insérer la version de votre fichier exe principal.

VS détectera alors le changement dans le fichier vdproj et vous demandera si vous voulez le recharger.

0
répondu Evvo 2018-10-01 19:57:53