2010-03-01 96 views
13

一組軟件產品的區別僅在於其資源字符串,二進制資源以及Visual Studio Setup項目使用的字符串/圖形/產品密鑰。創建,組織和維護它們的最佳方式是什麼?相同來源,具有不同資源的多個目標(Visual Studio .Net 2008)

即所有產品基本上由圖形,字符串和其他資源數據定製的相同核心功能組成,以形成每個產品。 想象一下,您正在創建一系列產品,如「銀行家的Excel」,「園丁的Excel」,「首席執行官的Excel」等。每個產品具有相同的功能,但名稱,圖形,幫助文件,包含的模板等不同。

中,這些正在興建的環境是:香草Windows.Forms的/ Visual Studio 2008中/ C#/ .NET

如果我介紹一個新的字符串理想的解決方案將是很容易保持如。 /新的資源項目我沒有添加資源,應該在編譯時失敗,而不是運行時(並且後續產品的本地化也應該是可行的)

希望我已經錯過了這一切的這種盲目顯而易見的方式。它是什麼?

============澄清(S)=====

所謂 「產品」 我指的是包由安裝程序安裝並銷售給最終用戶的軟件。

目前我有一個解決方案,由多個項目(包括一個安裝項目)組成,它構建一組程序集並創建一個安裝程序。

我需要製作的是多個產品/安裝程序,它們都具有類似的功能,它們是從同一套程序集構建而成,但其中一個程序集使用的資源集不同。這樣做的最好方法是什麼?

------------ 95%的解決方案-----------------

基於Daminen_the_unbeliever的答案,一個資源文件每個配置可以實現如下:

  1. 創建一個類庫項目(「衛星」)。
  2. 刪除默認的cs文件,並添加一個文件夾(「默認」)
  3. 文件夾中創建一個資源文件「爲MyResources」
  4. 屬性 - 設置CustomToolNamespace的東西 適當的(如「XXX」)
  5. 確保資源的訪問修飾符是「公共」。添加 的資源。編輯源代碼。 參考資源,你的代碼 爲XXX.MyResources.ResourceName)
  6. 爲每個產品變型(「ConfigN」)
  7. 對於每個產品結構的變形,創建一個文件夾(「VariantN」)
  8. 複製並將MyResources文件粘貼到每個VariantN文件夾中
  9. 卸載「Satellite」項目並編輯。csproj文件
  10. 對於每個「VariantN/MyResources」<Compile><EmbeddedResource>標記, 添加Condition="'$(Configuration)' == 'ConfigN'"屬性。
  11. 保存,重新加載的.csproj,你就大功告成了...

這將創建一個每個配置資源文件,它可以(大概)進一步本地化。編譯錯誤消息是針對缺少資源的任何配置生成的。資源文件可以使用標準方法進行本地化(創建第二個資源文件(MyResources.fr.resx)並像以前一樣編輯.csproj)。

這是一個95%解決方案的原因是,用於初始化表單(例如表格標題,按鈕文本)的資源不能以相同的方式輕鬆處理 - 最簡單的方法似乎是用來自衛星組件。

+0

這個問題有點不清楚。我真的建議你回顧一下你最初的問題,並重新發布在Visual Studio中使用技術術語以及隔離你的問題。 – Roast 2010-03-01 19:57:45

+0

補充說明。目前正在根據構建配置編輯.csproj文件以包含替換資源文件。凌亂保持。有人知道這是否實用? – MZB 2010-03-01 23:29:19

+0

另外考慮創建一個工具來比較資源,以確保兩個文件中存在相同的資源集合以減少迴歸測試...任何人都知道這樣的工具是否存在? – MZB 2010-03-03 21:45:56

回答

11

您可以添加條件到MSBuild文件中的元素。因此,例如,如果您有「調試」資源和「發佈」資源,則可以將它們放在兩個單獨的文件夾中(例如調試和發佈)。然後,你的MSBuild文件中,你可能有:

<ItemGroup> 
    <Compile Include="Debug\Resource1.Designer.cs" Condition=" '$(Configuration)' == 'Debug' "> 
     <AutoGen>True</AutoGen> 
     <DesignTime>True</DesignTime> 
     <DependentUpon>Resource1.resx</DependentUpon> 
    </Compile> 
    <Compile Include="Program.cs" /> 
    <Compile Include="Properties\AssemblyInfo.cs" /> 
    <Compile Include="Queue.cs" /> 
    <Compile Include="Release\Resource1.Designer.cs" Condition=" '$(Configuration)' == 'Release' "> 
     <AutoGen>True</AutoGen> 
     <DesignTime>True</DesignTime> 
     <DependentUpon>Resource1.resx</DependentUpon> 
    </Compile> 
    <Compile Include="Stack.cs" /> 
    </ItemGroup> 
    <ItemGroup> 
    <Content Include="XMLFile1.xml" /> 
    </ItemGroup> 
    <ItemGroup> 
    <EmbeddedResource Include="Debug\Resource1.resx" Condition=" '$(Configuration)' == 'Debug' "> 
     <Generator>ResXFileCodeGenerator</Generator> 
     <LastGenOutput>Resource1.Designer.cs</LastGenOutput> 
     <CustomToolNamespace>Resources</CustomToolNamespace> 
    </EmbeddedResource> 
    <EmbeddedResource Include="Release\Resource1.resx" Condition=" '$(Configuration)' == 'Release' "> 
     <Generator>ResXFileCodeGenerator</Generator> 
     <LastGenOutput>Resource1.Designer.cs</LastGenOutput> 
     <CustomToolNamespace>Resources</CustomToolNamespace> 
    </EmbeddedResource> 
    </ItemGroup> 

提供了所有你訪問你的資源都可以通過Resources.Resource1類,那麼你得到兩套不同的資源用於調試和發佈版本。顯然,這可以擴展到進一步的配置。

不幸的是,我不認爲你可以強制資源使用相同的baseName(提供給ResourceManager構造函數),因爲它基於項目內的路徑,而且我找不到一種方法來覆蓋。如果您確實需要它們使用相同的名稱(例如,如果您手動創建ResourceManagers),那麼我會建議在項目的頂層有一個Resources1.resx(加上相關的cs文件),而不是源代碼管理。作爲預生成事件,根據需要將所需的.resx文件從Debug或Release目錄中複製出來。 (在這種情況下,你可能要迫使它的子目錄中的不編譯了.Designer.cs文件。

編輯

忘了提(儘管它從上面摘錄見過MSBuild的文件),您必須設置自定義工具命名空間上的每個.resx文件相同的值(例如資源),否則它也默認爲包括文件夾名稱。

編輯2

響應查詢一下檢查每個資源文件是否包含相同的資源 - 如果您正在使用Resource類(例如, Resources.Resource1.MyFirstStringResource)來訪問你的資源,那麼如果所需的資源不存在,切換配置會導致構建錯誤,所以你會很快找到它。

對於真正的偏執狂(即如果您的構建過程需要3天來構建所有配置,或者同樣瘋狂),在一天結束時,.resx文件只是XML文件 - 您只需要一些東西來檢查每個具有相同文件名的.resx文件包含相同數量的<數據>元素,具有相同的名稱屬性。

+0

我認爲這就是我正在尋找的東西 - 只需要弄清楚如何從這裏到達那裏......(找不到除MSBuild格式的參考文檔之外的東西,並且不確定它與IDE的交互。)看起來我應該爲每個產品(在IDE中)創建一個額外的資源文件,每個資源文件位於單獨的目錄中,僅引用程序代碼中的資源,然後根據上述內容編輯.csproj文件,以僅編譯/嵌入適當的資源每個配置。我的理解是否正確? – MZB 2010-03-03 21:36:23

+0

@Mike - 好吧,上面摘錄自我的「play area」.csproj文件只用了五分鐘就敲完了。本身沒有IDE支持,但在IDE中的配置之間切換時它編譯得很好。一旦創建了兩個具有相同名稱(位於不同目錄中)的資源文件並更改了它們的命名空間,那麼在對csproj文件進行條件編輯之前,至少會發生構建錯誤。 – 2010-03-04 07:11:25

0

您正在尋找多種配置?看看:Build Configurations

+0

我看不到一種方法來根據構建配置來改變項目中使用的資源 - 或者我錯過了什麼? – MZB 2010-03-01 20:35:33

+0

我想你錯過了什麼。使用VS 2008點擊<配置管理器>並創建一個新的配置「測試」並複製您的發佈調試配置。 然後點擊<...屬性>,它會彈出一個多標籤的對話框,讓你改變資源,添加後生成命令(可以是你喜歡的任何程序),設置,文件路徑等。 因此,假設你想要4種不同的配置,他們B1,B2 ..B4。他們都可以構建到不同的目標目錄,從不同的目錄鏈接等。 – JonnyBoats 2010-03-02 03:30:39

+0

只有「構建」選項卡似乎允許每個配置選項 - 這限制了我改變輸出目錄和定義條件定義。問題是4種不同的資源或設置 - 這兩種資源或設置似乎都不敏感於選擇哪種配置。 – MZB 2010-03-02 12:47:31

1

您的方法 - 使用multiple, separate resource-only projects(和程序集) - 聽起來很健全,並且對於本地化應用程序以及其他場景很典型。有一些命名空間和範圍問題需要注意 - VS2005總是生成資源類型作爲內部(或VB中的朋友),而VS2008允許你改變它。爲了能夠從主程序中訪問多個衛星程序集,您必須做正確的事情 - 公開資源類型的範圍。

一旦擁有主DLL和各種資源DLL,就可以選擇部署。一種是分別部署不同的DLL,並在運行時加載正確的DLL。假設你的主EXE被稱爲app.exe;那麼對於所有的衛星程序集,您還可以擁有Sat1.dll,sat2.dll,sat3.dll等等。你的安裝項目只包含任何合適的DLL。

另一個選擇是合併DLL與ILMerge。在這種情況下,你會合並app.exe和sat1.dll,獲得app1.exe。同樣app.exe + sat2.exe => app2.exe。

要谷歌周圍這個,使用「本地化」和「衛星集會」。

3

這是我的解決方案。原來的問題是,Autodesk發佈每個AutoCAD dll都有不同的東西,並且每3年就會打破一次兼容性。但我們的代碼實際上是一樣的。這是Develop-TFS-TFSbuild-DomainControllerInstallationOfApps的一個痛苦點。

的解決方案如下:

  1. 讓你媽項目,所有的結構,可以說爲AutoCAD 2012
  2. 引用然後創建第二個項目,爲AutoCAD 2013在同一個解決方案,參考它自己的DLLS。
  3. 現在您必須爲每個項目設置一個編譯符號 - 第一個項目爲acad2012,第二個爲acad2013。
  4. 然後在2013項目中,轉到添加現有項目並指向2012項目的來源,然後單擊添加按鈕右側的點擊並指向添加爲鏈接
  5. 如果2012年和2012年之間存在任何圖書館差異2013,你可以圍繞他們#if acad2012 #endif or #if acad2013 #endif

這樣,你將有隻有一個源代碼維護,並有單獨編譯的模塊:)

UPDATE

我需要製作的是多個產品/安裝程序,它們都具有類似的功能,這些功能都是由相同的一組程序構建而成,但其中一個程序集使用的資源集不同。這樣做的最好方法是什麼?

  • 設置的安裝程序項目:這正是我們做什麼,你需要什麼。第5步之後,您必須製作兩個安裝程序項目。我的意思是Windows Installer Xml projects or WiX projects可以說第一個是2012年,第二個是2013年。接下來的問題是生成包含構建所有組件的XML文件。我使用以下腳本的WiX工具包:

    熱。exe文件目錄 「$(TARGETDIR)」 〜CG MyAppComponents -dr INSTALLFOLDER -sfrag -srd -var 「var.FilesPath」 退房手續 「\ MyAppComponents.wxs」

  • 此腳本將建立與所有MyAppComponents.wxs你需要的文件。如果您想了解Wix,請閱讀本書:「WiX 3.6:Windows Installer XML開發人員指南」。閱讀完後,我做了所有需要的東西。

    1. 將MyAppComponents.wxs直接添加到您的主安裝程序項目(讓它爲2012)以及任何其他項目「添加爲鏈接」(讓它爲2013 dlls)。如果您按照步驟5中的說明進行操作,那麼您的構建腳本已經可以針對不同版本的依賴程序集進行編譯。你想要針對兩種不同的依賴關係編譯一個源代碼嗎?這樣你就可以得到它 - 一個包含所有內容的.wxs文件,並且在.cs文件中包含指導編譯的編譯指示。現在

    當你添加新的文件到您的解決方案,你需要將它才能增加你的母親項目,然後「添加爲鏈接」到其他項目,只在一個地方加入.wxs組件登記讓它在所有安裝程序中分發。

    使用第6步中的腳本,您將擁有一個.wxs內的所有版本化的dll,這意味着它們將被編譯在一個安裝程序中。當然,您可以爲您的所有版本創建多個不同的安裝程序,但從長遠來看,只需製作一個安裝程序並在安裝過程中決定將哪個版本的.dll複製到磁盤或決定運行時需要加載的.dll文件記憶。我選擇了決定運行時間,它對我來說工作正常。

    1. 在您的兩個安裝項目區域準備就緒後,您可以使用TFS Build進行集成。您可以更進一步,在構建過程中添加智能彙編等混淆器,以便在最後有兩個或更多獨立安裝程序,並在包含混淆程序集的不同相關庫上單獨構建dll。

    上面所述的一切都是直接來自溝渠,它的工作原理。如果我沒有清楚地列出所有步驟,只需發一條消息澄清並進一步闡述。

    由於過多的IF和條件會隨着時間的推移而出現「另一個Autodesk dll出現」時,我轉移了構建配置。我對此不太確定。也許這是一個解決方案,但你必須非常確定你在做什麼,以便在這種需求的情況下不會制動TFS Build。

    相關問題