2016-02-27 126 views
1

我有一個C#解決方案,我希望在構建期間將解決方案的路徑設置爲app.config。例如。可以說我有解決方案c:\temp\visual studio\super fun project\super_fun_project.sln開放。我構建並在其中一個測試項目中將應用程序設置更改爲解決方案的完整路徑。即在構建時或運行時獲取解決方案路徑

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <appSettings> 
    <add key="fullSolutionPath" value="{setAtBuild}"/> 
    </appSettings> 
</configuration> 

,如果我去c:\temp\visual studio\super fun project\Foobar.Tests\bin\Debug\Foobar.Tests.dll.config它看起來是

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <appSettings> 
    <add key="fullSolutionPath" value="c:\temp\visual studio\super fun project\super_fun_project.sln"/> 
    </appSettings> 
</configuration> 

或但它需要得到格式化,這樣,當在運行時我索要價值我確實得到了正確的路徑。我已經看不起Transformation,但我無法弄清楚我將如何獲得解決方案路徑集。有沒有其他的技巧來得到這個?

回答

3

你可以做的就是修改項目文件和:

@echo off > newfile & setLocal ENABLEDELAYEDEXPANSION 
set old="{setAtBuild}" 
set new=%2 
set targetBinary=%3 


cd %1 
for /f "tokens=* delims= " %%a in (%targetBinary%.config) do (
set str=%%a 
set str=!str:%old%=%new%! 
>> newfile echo !str! 
) 

del /F /Q %targetBinary%.config 
rename "newfile" "%targetBinary%.config" 

然後在調用批處理腳本項目屬性添加一個生成後事件添加一個MsBuild Target

目標可以使用Custom Inline Task,該源代碼集成到項目文件中。

所以要加這個任務:

1)卸載項目(右鍵單擊項目節點上,選擇「卸載項目」)

2)編輯項目文件(右鍵單擊項目節點,選擇「編輯」)

3)將以下內容添加到項目文件(例如結束)並重新加載它,現在當您構建時,配置文件將相應地進行修改。

<Project ...> 
    ... 
    <Target Name="AfterBuild"> 
     <RegexReplace FilePath="$(TargetDir)$(TargetFileName).config" Input="setAtBuild" Output="$(SolutionPath)" /> 
    </Target> 
    <UsingTask TaskName="RegexReplace" TaskFactory="CodeTaskFactory" AssemblyName="Microsoft.Build.Tasks.Core" > 
     <ParameterGroup> 
     <FilePath Required="true" /> 
     <Input Required="true" /> 
     <Output Required="true" /> 
     </ParameterGroup> 
     <Task> 
     <Using Namespace="System.Text.RegularExpressions"/> 
     <Code Type="Fragment" Language="cs"><![CDATA[ 
       File.WriteAllText(FilePath, Regex.Replace(File.ReadAllText(FilePath), Input, Output)); 
      ]]></Code> 
     </Task> 
    </UsingTask> 
</Project> 

這裏,我定義的輸出使用Visual Studio的MSBuild Property命名爲SolutionPath,但你可以重用此RegexReplace任務和更新InputOutput參數各種需求。

+0

我打算用這個答案代替另一個。我改變了輸入來匹配'{setAtBuild}',但我喜歡它沒有外部依賴。 –

1

我不知道你的用例是什麼,但你可以調用一個本地生成的批處理文件來從你的項目的生成後事件中做到這一點。

例如:在您的項目名爲「updateconf.bat」創建一個批處理腳本,確保它是ANSII編碼(也許用記事本++編寫劇本並確認ANSII),或者你會得到一個異常,表明在編譯VS項目並檢查輸出時,該文件的前綴是非法字符。

批處理腳本的內容:

call $(ProjectDir)\updateconf.bat "$(TargetDir)" "$(SolutionPath)" $(TargetFileName) 
+0

我無法等待這一切。測試用例是我希望我的單元測試能夠動態加載解決方案文件並讀取解決方案中的項目並查找所有測試程序集。我不想硬編碼的路徑,如果我把它放在GitHub上 –

+0

@RobertSnyder - 好的,如果我瞭解你,那麼這個場景是有意義的。你說的**解決方案文件名**代替了實際上是進入你的測試項目的配置文件。在運行時,您正在詢問實際的解決方案文件以獲取其* .proj文件名中含有say **'Test'**的項目。在這種情況下,我相信這個腳本將會以你所做的方式工作。 – Elmar

+0

我試過了,像魅力一樣工作,我會接受一旦我確認我不想使用其他答案。作爲一個附註,我忘了在我的批處理文件中設置爲ANSII,但我沒有收到VS2015的投訴,並且它在UTF-8上運行得很好。其他人可能感到非常小的煩惱是xml格式化丟失。 –

相關問題