2008-11-20 10 views
10

यहां मेरी समस्या है:प्रोग्राम के उत्पाद संस्करण को प्रोग्रामिक रूप से कैसे परिवर्तित करें?

मेरे पास कई परिनियोजन परियोजनाएं हैं। किसी एप्लिकेशन को तैनात करने के लिए, मुझे कई कार्य करने की आवश्यकता है, उनमें से एक प्रत्येक तैनाती परियोजना के उत्पाद संस्करण और उत्पाद कोड को बदलना है।

मुझे प्रोग्रामिक रूप से उन्हें बदलने का कोई तरीका नहीं मिल रहा है।

क्या कोई मेरी मदद कर सकता है?

अग्रिम धन्यवाद।

अपडेट: चूंकि यह एक परिनियोजन प्रोजेक्ट है (जो अंततः एक निष्पादन योग्य इंस्टॉलर उत्पन्न करता है), मैं एमएसबिल्ड के साथ काम करने में सक्षम नहीं हूं, इसके बजाय मैं कमांड प्रॉम्प्ट से डेवेनव का उपयोग कर रहा हूं। (ब्रूनो, आपकी त्वरित प्रतिक्रिया के लिए धन्यवाद)।

+0

यह किस प्रकार की परियोजना है? सी ++ या सी #/वीबी? –

+0

प्रोजेक्ट एक सी # तैनाती प्रोजेक्ट है, मैं नेट 2.0 का उपयोग कर रहा हूं। –

+0

पूर्ण स्रोत कोड के साथ कोई अंतिम समाधान? vdproj परियोजनाएं हैं? – Kiquenet

उत्तर

10

मैं आज भी वही चीज़ खोज रहा था। मैंने इसे Google:

static void Main(string[] args) 
{ 
    string setupFileName = @"<Replace the path to vdproj file>"; 
    StreamReader reader = File.OpenText(setupFileName); 
    string file = string.Empty; 

    try 
    { 
     Regex expression = new Regex(@"(?:\""ProductCode\"" = 
     \""8.){([\d\w-]+)}"); 
     Regex expression1 = new Regex(@"(?:\""UpgradeCode\"" = 
     \""8.){([\d\w-]+)}"); 
     file = reader.ReadToEnd(); 

     file = expression.Replace(file, "\"ProductCode\" = \"8:{" + 
     Guid.NewGuid().ToString().ToUpper() + "}"); 
     file = expression1.Replace(file, "\"UpgradeCode\" = \"8:{" 
     + Guid.NewGuid().ToString().ToUpper() + "}"); 
    } 
    finally 
    { 
     // Close the file otherwise the compile may not work 
     reader.Close(); 
    } 

    TextWriter tw = new StreamWriter(setupFileName); 
    try 
    { 
     tw.Write(file); 
    } 
    finally 
    { 
     // close the stream 
     tw.Close(); 
    } 
} 
+0

मैंने अपने बनामप्रोज़ पर उत्पाद कोड बदलने के लिए इस दृष्टिकोण का उपयोग किया है, ताकि जब मेरा एमएसआई बनाया और भाग लिया जाए - यह उपयोगकर्ता को पिछले संस्करण को हटाने के लिए बिना पूछे, अच्छी तरह से अपग्रेड करता है। बहुत धन्यवाद, मैं थोड़ी देर के लिए यह कैसे करना चाहता हूं! –

+0

+1 मुझे एक ही समस्या है और ऐसा लगता है कि रेगेक्स सबसे सरल समाधान हो सकता है। – Beta033

0

आप उत्पाद संस्करण को अपडेट करने के लिए msbuild कार्य का उपयोग कर सकते हैं। इस विषय पर MSBuild टीम से this post देखें।

+0

अब कहाँ है (2012) AssemblyInfoTask? – Kiquenet

1

हम ऐसे प्रोग्राम का उपयोग करते हैं जो कॉन्फ़िगरेशन फ़ाइल मान के आधार पर प्रत्येक AssemblyInfo.cs या AssemblyInfo.vb को अद्यतन करता है। हम प्रत्येक निर्माण से पहले इस निष्पादन योग्य चलाते हैं। यह प्रक्रिया सबसे अच्छी थी जो हम इस प्रक्रिया को स्वचालित करने के लिए कर सकते थे। आप प्री-बिल्ड चरण के रूप में अपनी प्रोजेक्ट कॉन्फ़िगरेशन में इस बैच प्रक्रिया में एक कॉल जोड़ सकते हैं।

+0

इसे प्री-कंडीशन का उपयोग करके निर्माण प्रक्रिया में शामिल किया जा सकता है। –

0

यह आपके द्वारा किए जाने वाले काफी कुछ नहीं हो सकता है, लेकिन समय की गलतियों में जिस तरह से मैंने stampver नामक कुछ लिखा है, जो पोस्ट-बिल्ड चरण के रूप में सीधे .exe फ़ाइल में बिल्ड नंबर को स्वचालित रूप से बढ़ा सकता है।

5

मुझे पता है कि मूल पोस्टर इस समस्या के लिए .NET 2.0 समाधान की तलाश में है। हालांकि, चूंकि इसे .NET के रूप में टैग नहीं किया गया था, इसलिए मैं समस्या के लिए अपने सी ++ समाधान की पेशकश करूंगा। यह .NET भूमि में लागू हो सकता है, लेकिन मैं इसे दूसरों को छोड़ दूंगा।

यह न केवल बॉक्स के बारे में संस्करण जानकारी और मेरे एप्लिकेशन के लिए लॉग फ़ाइल को अपडेट करता है, बल्कि विंडोज एक्सप्लोरर में दिखाई देने वाली सभी विंडोज़ संस्करण जानकारी भी अपडेट करता है।

अद्यतन: मेरे मूल उत्तर के बाद से मैंने कुछ बदलावों को जोड़ा है।

///////////////////////////////////////////////////////////////////////////// 
// 
// Version 
// 

VS_VERSION_INFO VERSIONINFO 
FILEVERSION FILE_VER 
PRODUCTVERSION PROD_VER 
FILEFLAGSMASK 0x3fL 
#ifdef _DEBUG 
    FILEFLAGS 0x1L 
#else 
    FILEFLAGS 0x0L 
#endif 
    FILEOS 0x4L 
    FILETYPE 0x1L 
    FILESUBTYPE 0x0L 
BEGIN 
    BLOCK "StringFileInfo" 
    BEGIN 
     BLOCK "040904e4" 
     BEGIN 
      VALUE "CompanyName", "MyCompany" 
      VALUE "FileDescription", "Software Description" 
      VALUE "FileVersion", 1,0,0,1 
      VALUE "InternalName", "FileName.exe" 
      VALUE "LegalCopyright", "(c) 2008 My Company. All rights reserved." 
      VALUE "OriginalFilename", "FileName.exe" 
      VALUE "ProductName", "Product Name" 
      VALUE "ProductVersion", 1,0,0,1 
     END 
    END 
    BLOCK "VarFileInfo" 
    BEGIN 
     VALUE "Translation", 0x409, 1252 
    END 
END 

यह अनिवार्य रूप से संस्करण जानकारी सामान है कि आप संसाधन से संपादित करेंगे के सभी परिवहन करता है:

सबसे पहले, मैं अपने Project.rc2 फाइल करने के लिए मेरी Project.rc फ़ाइल से पूरे संस्करण जानकारी ब्लॉक ले जाया गया एक अलग फ़ाइल में संपादक। इससे ऐसा होता है कि संपादक के बाहर से संसाधन फ़ाइल को संपादित करते समय आपको त्रुटियां नहीं मिलती हैं। नकारात्मकता यह है कि अब आप संसाधन संपादक से संस्करण जानकारी संपादित नहीं कर सकते हैं। लेकिन, चूंकि हम चाहते हैं कि यह सामान स्वचालित रूप से अपडेट हो जाए, यह एक बड़ा सौदा नहीं है।

अगला, मैंने एक संस्करणइन्फो बनाया।ज फ़ाइल और अपने प्रोजेक्ट के लिए यह कहा:

#pragma once 

//major release version of the program, increment only when major changes are made 
#define VER_MAJOR 2 

//minor release version of the program, increment if any new features are added 
#define VER_MINOR 0 

//any bugfix updates, no new features 
#define VER_REV 0 

//if this is some special release (e.g. Alpha 1) put the special release string here 
#define STR_SPECIAL_REL "Alpha 1" 


#define FILE_VER VER_MAJOR,VER_MINOR,VER_REV 
#define PROD_VER FILE_VER 

//these are special macros that convert numerical version tokens into string tokens 
//we can't use actual int and string types because they won't work in the RC files 
#define STRINGIZE2(x) #x 
#define STRINGIZE(x) STRINGIZE2(x) 

#define STR_FILE_VER STRINGIZE(VER_MAJOR) "." STRINGIZE(VER_MINOR) "." STRINGIZE(VER_REV) 
#define STR_PROD_VER STR_FILE_VER " " STR_SPECIAL_REL 

#define STR_COPYRIGHT_INFO "©" BuildYear " Your Company. All rights reserved." 

मैं तो rc2 फ़ाइल में VersionInfo.h शामिल है और निम्न परिवर्तन किए:

#include "VersionInfo.h" 
///////////////////////////////////////////////////////////////////////////// 
// 
// Version 
// 

<no changes> 
      VALUE "FileVersion", STR_FILE_VER 
      <no changes> 
      VALUE "LegalCopyright", STR_COPYRIGHT_INFO 
      <no changes> 
      VALUE "ProductVersion", STR_PROD_VER 
<no changes> 

इस स्थापना के साथ, मैं अपने निर्माण स्क्रिप्ट संपादित कर सकता है (जो पर्ल का उपयोग करता है) devenv कमांड लाइन का उपयोग कर पूरे प्रोजेक्ट को पुनर्निर्माण करने से पहले VersionInfo.h फ़ाइल में संस्करण जानकारी को संशोधित करने के लिए।

एक अतिरिक्त कदम जो मैंने जोड़ा है, वह भी ब्याज का हो सकता है (हालांकि यह अभी तक पूरी तरह से परिपूर्ण नहीं है, और यहां भविष्य का प्रश्न हो सकता है) परियोजना के निर्माण के हर बार एक अद्वितीय निर्माण संख्या उत्पन्न करना है। वर्तमान अवतार में, यह हमेशा पूर्ण पुनर्निर्माण के लिए काम करता है, लेकिन केवल वृद्धिशील बनाता है।

#define CurrentBuildNumber "20081020P1525" 

अनिवार्य रूप से दिनांक और समय है कि निर्माण शुरू किया गया था है कौन सा: क्या मैंने किया था एक फ़ाइल है कि build_number.incl कहा जाता है बनाने के निम्नलिखित था। मैंने एक बैच फ़ाइल बनाई है जो इस फ़ाइल को उत्पन्न करने वाली प्रोजेक्ट में प्री-बिल्ड इवेंट के रूप में चलाया जाता है। स्क्रिप्ट BuildYear को भी परिभाषित करता है ताकि VersionInfo.h फ़ाइल में कॉपीराइट हमेशा सबसे हाल के निर्माण का वर्ष शामिल हो।

echo Generating Build Number 
    @For /F "tokens=2,3,4 delims=/ " %%A in ('Date /t') do @(
    Set Month=%%A 
    Set Day=%%B 
    Set Year=%%C 
    ) 

    @For /F "tokens=1,2,3 delims=/M: " %%A in ('Time /t') do @(
    Set Hour=%%A 
    Set Minute=%%B 
    Set AmPm=%%C 
    ) 

    @echo #define CurrentBuildNumber "%Year%%Month%%Day%%AmPm%%Hour%%Minute%" > "$(ProjectDir)\build_number.incl" 
    @echo #define BuildYear "%Year%" >> "$(ProjectDir)\build_number.incl" 
    echo ---------------------------------------------------------------------- 

इस फ़ाइल में तो परियोजना बिल्ड नंबर का उपयोग करने की जरूरत है कि किसी भी फ़ाइल में शामिल है (यानी बॉक्स के बारे में): बैच स्क्रिप्ट निम्न है।

इनमें से कुछ से this CodeProject post.

gleaned था उम्मीद है कि इस जानकारी मददगार साबित होता है।

-3

आरसीएस, सीवीएस और/या उपversण के उपयोग में देखें। मैं केवल आरसीएस से परिचित हूं; मेरी समझ यह है कि सीवीएस आरसीएस पर आधारित है लेकिन अधिक व्यापक है। मैंने विभिन्न बोर्डों पर पढ़ा है कि विचलन बेहतर है, लेकिन मैंने इसका कभी भी उपयोग नहीं किया है। आरसीएस मेरे सभी दस्तावेजों और सॉफ्टवेयर परियोजनाओं पर परिवर्तनों और संस्करणों का ट्रैक रखने के लिए पर्याप्त रहा है।

आरसीएस यहाँ है: http://www.cs.purdue.edu/homes/trinkle/RCS/

सीवीएस यहाँ है: http://www.nongnu.org/cvs/

सबवर्सन यहाँ है: http://subversion.tigris.org/

+0

प्रश्न (आईएमओ) के पास संस्करण नियंत्रण के साथ कुछ लेना देना नहीं है ... –

+0

मैं गिट पोस्ट-प्रतिबद्ध हुक का उपयोग कर स्रोत कोड पर संस्करण जानकारी अद्यतन करता हूं। – ashwoods

0

Resource Tuner Console

यह कंसोल संसाधन संपादक एक विश्वसनीय और repeatable बनाने की अनुमति देता है proces कमांड प्रॉम्प्ट से निर्माण प्रक्रिया के अंतिम चरण के दौरान उत्पाद संस्करण सूचना संसाधनों को अद्यतन करने के लिए।

अधिक से अधिक जानकारी के लिए विशेष रूप से देखें फ़ाइल संस्करण जानकारी के बैच हेरफेर पेज:

2

मैं एक ही समस्या थी, और मुझे पता चला कि .vdproj संशोधितprebuildevent में फ़ाइल बिल्कुल ठीक नहीं करती है मुझे पसंद है।

मैं सेटअप परियोजना किया गया है निर्माण के बाद msi फ़ाइल फ़ाइल को संशोधित करने के लिए कुछ अन्य कोड का इस्तेमाल किया है, इसलिए मैं postbuildevent का उपयोग करें।

मेरा ब्लॉग-पोस्ट here देखें।

+1

एक ही समस्या में भाग गया। वीएस प्रीबिल्ड चरण चलाने के बाद vdproj को फिर से लोड नहीं करता है, इसलिए या तो दो बार निर्माण करना या पोस्टबिल्ड दृष्टिकोण का उपयोग करना आवश्यक है। – OSH

0

मैं इस एक बहुत पुरानी धागा पता है, लेकिन यहां एक ही अंत को प्राप्त करने के एक vbs समाधान है। बस इसे .vdproj फ़ाइल के बगल में अपने परिनियोजन फ़ोल्डर में रखें।

cd $(SolutionDir)\CustomWebSetup 
cscript -nologo UpdateProductCode.vbs 

यह अगले निर्माण के लिए तैयार करने में एक नया ProductCode साथ vdproj अपडेट कर देगा:

Function CreateGuid() 
    CreateGuid = Left(CreateObject("Scriptlet.TypeLib").Guid,38) 
End Function 

Const ForReading = 1, ForWriting = 2, ForAppending = 8 

Set fso = CreateObject("Scripting.FileSystemObject") 
Set RegEx = CreateObject("VBScript.RegExp") 

For Each file in fso.GetFolder(".").Files 
    if (fso.GetExtensionName(file.Name) = "vdproj") then 
     WScript.Echo "Updating: " + file.Name 
     Set oFile = fso.OpenTextFile(file.Name, ForReading, True) 
     fileContents = oFile.ReadAll 
     oFile.Close 
     RegEx.Pattern = """ProductCode"" = ""8:{.*-.*-.*-.*-.*}" 
     fileContents=Regex.Replace(fileContents, """ProductCode"" = ""8:" & CreateGuid) 
     Set oFile = fso.OpenTextFile(file.Name, ForWriting, True) 
     oFile.Write fileContents 
     oFile.Close 
    end if 
Next 

फिर अपने असली परियोजना में, एक पोस्ट का निर्माण घटना के लिए इसी तरह की है। निर्माण पूरा होने के बाद, वीएस तैनाती परियोजना के पुनः लोड के लिए संकेत देगा।

संबंधित मुद्दे

 संबंधित मुद्दे