I have a solution with 25 C# projects aprox.
For every compilation of the solution, I tweak some project configuration usings precompilers directives.
When I need to add a directive to a configuration. I have to go to every project and add that directive. When I add a new configuration it is the same an worse.
In a C++ project I would had a .h file that would be included in all projects, to have something like a global configuration file.
But, how can I do something like that using Visual Studio and C#?
A good way to do this would be to reference external config files from each projects configuration.
You can create just one config file with the information/directories that are frequently changing and reference it from each projects config files.
For example:
directives.confg:
<appSettings>
<add key="ThisDirectory" value="This\Directory\Path"/>
<add key="ThatDirectory" value="That\Directory\Path"/>
</appSettings>
And in your web/app config you would have:
<configuration>
<appSettings file="C:\PathToYourExternalConfigFile\directives.config">
<add key="OtherKeyNotInExternalConfig" value="SomeValue" />
</appSettings>
</configuration>
Now only the directives.config file will need to be updated and all other projects will automatically have the latest config changes.
If you build your project using msbuild then all you need to do is set an environment variable with the same name as your define.
#if OPTION_ONE
// option one code here
#else
// option one not set
#endif
Then from the developer command prompt you can build like so
set OPTION_ONE=true
msbuild YourSolution.sln
If that doesn't work you could add the following to your project file
<DefineConstants Condition="'%(OPTION_ONE)' != ''">OPTION_ONE</DefineConstants>
Edit:
Create a common c# file for definitions the just like you would in c++ with a header.
Create a user file (i.e. MyProject.csproj.user) to include the common cs file. The user file doesn't need to be included in the project. Visual studio will automatically use it if it exists:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
<Compile Include="$(SolutionDir)CommonFile.cs"/>
</Project>
Copy that file to each project directory, changing the file name to match the project.
Or you can just add the common file as a link by adding existing item and click the option arrow next to Add and select Add As Link
Related
I want to change nuget package folder but it doesn't work.
I tried very much tricks but not work.
I restart many times VS but not work.
My config:
Visual Studio Community 2019
Windows 10 1909 x64
I have a VS solution folder
MyProjectSln\
HelloWorld\
bin
nuget_packages
NuGet.Config
I want VS studio nuget package manager console use the "NuGet.Config" file and put all packages downloaded in "nuget_packages"
So nuget packages must be in D:\MyProjetSln\HelloWorld\nuget_packages.
Content example of D:\MyProjetSln\HelloWorld\NuGet.Config :
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<config>
<add key="globalPackagesFolder" value=".\nuget_packages" />
<!-- I have also tried with repositoryPath but not work -->
</config>
</configuration>
The xml syntax is correct in my case (in my file).
Example, when i execute the command "install-package NUnit" from Package Manager Console, it put downloaded packages in D:\MyProjectSln\packages\ and I don't want that.
Thank you for helping !
Just as this document said, the new nuget.config file must be under the same level directory of the project folder rather than put the file inside the project folder.
In other words, it must be located in at least the solution directory or a higher-level directory.
Note: if you use this way, it will act on all the projects in the same level directory and all the projects in the sub directory.
So you should put the new nuget.config file on the D:\MyProjetSln.
Then modify its content as:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<config>
<add key="repositoryPath" value="HelloWorld\nuget_packages" />
</config>
</configuration>
Then, close VS and then reopen your project to enable that function.
In my side,
At the time of writing this message, what I want is not possible at the moment.
Maybe it will be a feature later.
I have a solution containing 1 console application and 2 libraries.
In the libraries I have two different app.configs for an example my data.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="OutputFileFolder" value="c:\\log" />
<add key="OutputIndexFile" value="c:\\log\index.xml" />
</appSettings>
</configuration>
And in this library class I have in the constructor
_indexPath = ConfigurationManager.AppSettings["OutputIndexFile"];
But how should I load the Data.config file from my main console application (this should be the main config file)?
Config files in your dll projects are not relevant at runtime. The config file (if any) in your console application project is the one that will get used.
If you want to use a configuration file in two separate projects, you can add it as a link to your second project, or you could use a post-build event to copy it over. However both of these seem a little hacky.
Libraries don't really have associated configuration files as such - they operate under an executable (a console application, in your case).
You should put all the configuration in the app.config file of the application for the code in the libraries to have access to it.
You can load multiple config files by have multiple Configuration instances from multiple calls to ConfigurationManager.OpenMappedExeConfiguration (add your config file to the file map, the global file will be added automatically and specify a ConfigurationUserLevel.None.
Something like:
var fileMap = new ExeConfigurationFileMap {
ExeConfigFilename = Path of dll's config file
};
var cfg = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
var result = cfg.AppSettings["OutputIndexFile"];
I'm trying to get web.config transformations working as described here. We've used this method on other projects and it works without issue, but not on this new project.
Here's what I've tried testing without success
Changing name of wpp.targets file in case I got the project name wrong. I know the current one I'm using works since it's the only one that causes web.config to be rebuilt from web.template.xml this transform works. Only the sub templates don't work.
Tried with xdt:Locator="Match(name)"
Tried .config extension vs .xml, our other projects where this works use .xml
Configuration manager is set to use the "Test" configuration for the project I'm working on.
web.template.Test.xml has xdt:Transform="Replace" for the section I want to replace
web.template.xml has the placeholder
Tried removing the "CopyWebTemplateConfig" section from wpp.targets as suggested on the stack question linked below. Our other projects have this and the "PropertyGroup" section commented out and I've tried both combinations.
I've read through the above link multiple times and this related stack question, but can't see what the problem is.
Note The publish transform does work in a way. It creates a web.template.xml file that contains the values from web.template.Test.xml, but does not create a web.config.xml as the wpp.targets instructs. So this is more of an issue with getting the build transform working it seems.
Anyone have an idea of what's missing?
wpp.targets
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Make sure web.config will be there even for package/publish -->
<Target Name="CopyWebTemplateConfig" BeforeTargets="Build">
<Copy SourceFiles="web.template.xml"
DestinationFiles="web.config"/>
</Target>
<PropertyGroup>
<PrepareForRunDependsOn>
$(PrepareForRunDependsOn);
UpdateWebConfigBeforeRun;
</PrepareForRunDependsOn>
</PropertyGroup>
<!-- This target will run right before you run your app in Visual Studio -->
<Target Name="UpdateWebConfigBeforeRun">
<Message Text="Configuration: $(Configuration): Web.template.$(Configuration).xml"/>
<TransformXml Source="web.template.xml"
Transform="web.template.$(Configuration).xml"
Destination="web.config" />
</Target>
<!-- Exclude the config template files from the created package -->
<Target Name="ExcludeCustomConfigTransformFiles" BeforeTargets="ExcludeFilesFromPackage">
<ItemGroup>
<ExcludeFromPackageFiles Include="web.template.xml;web.template.*.xml"/>
</ItemGroup>
<Message Text="ExcludeFromPackageFiles: #(ExcludeFromPackageFiles)" Importance="high"/>
</Target>
</Project>
web.template.xml
<?xml version="1.0" encoding="utf-8"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=152368
-->
<configuration>
<configSections>
<sectionGroup name="TestSettings"></sectionGroup>
....
</configSections>
....
<TestSettings>
</TestSettings>
....
</configuration>
web.template.Test.xml
<?xml version="1.0"?>
<!-- For more information on using transformations
see the web.config examples at http://go.microsoft.com/fwlink/?LinkId=214134. -->
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<TestSettings xdt:Transform="Replace">
...
</TestSettings>
</configuration>
MSBuild output
Target "UpdateWebConfigBeforeRun: (TargetId:143)" in file "C:\...\Project.wpp.targets" from project "C:\...\Project.csproj" (target "PrepareForRun" depends on it):
Task "Message" (TaskId:93)
Configuration: Test: Web.template.Test.xml (TaskId:93)
Done executing task "Message". (TaskId:93)
Task "TransformXml" (TaskId:94)
Transforming Source File: Web.template.xml (TaskId:94)
Applying Transform File: Web.template.Test.xml (TaskId:94)
Executing Replace (transform line 5, 18) (TaskId:94)
on /configuration/TestSettings (TaskId:94)
Applying to 'TestSettings' element (source line 121, 4) (TaskId:94)
Replaced 'TestSettings' element (TaskId:94)
Done executing Replace (TaskId:94)
Output File: web.config (TaskId:94)
Transformation succeeded (TaskId:94)
Done executing task "TransformXml". (TaskId:94)
Done building target "UpdateWebConfigBeforeRun" in project "Project.csproj".: (TargetId:143)
I had installed StyleCop and that was doing the overwrite for me.
So I uninstalled it and the issue was resolved.
Funny is that I re-installed the StyleCop and the transform was still working!
Also at some points I noticed that I should remove the CopyWebTemplateConfig target section as well.
I've got a solution to my problem, but not sure what the cause is, so not sure if this will solve it in other cases.
I reviewed the output of the MSBuild diagnostic and noticed that towards the end there was another section that copied web.template to web.config. Note that this is after the UpdateWebConfigBeforeRun target already ran and made its updates from the sub template transform file to web.config. It looked like this last step was overriding the web.config with the transform I wanted.
I wasn't sure where this last set of copy instruction was coming from, so I did a search for all files on my PC looking for other wpp.target files. I found another one in Slow Cheetah's extensions folder and saw some section up top that was setting a property "transformOnBuild" to false.
Thinking there was a conflict with SlowCheetah, I uninstalled it and the transformations started working as expected. This was still a bit odd since the other solutions worked with SlowCheetah enabled. On a whim I re-installed SlowCheetah and the transformation continued to work as expected.
So my solution ended up being a re-installation of SlowCheetah. I'm still confused about what the cause of this issue was, so if anyone else posts an answer to this I'll give them the bounty.
I've had a similar issue last week.
Turns out that whenever you add a project to a solution in VS 2010 the right project configuration doesn't get applied all the time.
So you think you have a configuration active but another is actually active on that project, thus the transformation you expect doesn't get applied.
Check the steps in last comment of this issue: Custom solution configuration not showing up in Visual Studio 2010
"I know the current one I'm using works since it's the only one that causes web.config to be rebuilt from web.template.xml this transform works. Only the sub templates don't work."
Does this mean, transformation works but TestSettings section alone does not get transformed?
Can you share build output with msbuild with verbosity set to diagnostic / detailed?
I wrote a blog post about this subject. I use it everyday in our web application. I wrote the blog post because the feature in slowcheetah isn't ready yet.
http://www.locktar.nl/general/use-config-transforms-when-debugging-your-web-application/
I'm using this code (in my DAL project):
ConfigurationManager.AppSettings["server"]
to access appsettings section in web.config file (from web project):
<appSettings>
<add key="server" value="server.name.com"/>
<add key="database" value="databasename"/>
</appSettings>
and in a Web.Debug.config I'm using a following transformation
<add key="server" value="MY-LAPTOP"
xdt:Locator="Match(key)" xdt:Transform="Replace"/>
after that when I start application the config file isn't transformed. First line of code returns the nontransformed infromation. What's wrong with the code? What am i missing?
I have tried to publish it and when I check config file everything is ok like it is ment to be.
The web.config transformation is only perform during the publish process. You can still enable it on every build, when you it F5, see
ASP.NET Web Projects: web.debug.config & web.release.config
SlowCheetah - XML Transforms
Making Visual Studio 2010 Web.config Transformations Apply on Every Build
It's an MSBuild task to add.
I discovered few days ago that we can use Configuration files in .NET and trying to use it in my applications.
First of all, configure correctly the use of configuration file is really borring :
Configuration file should have the same name as the application (understandable)
Then think to add the System.Configuration reference (understandable too)
When file is added, go in it's properties and change it to copy the file in output directory (less understandable).
Configuration file isn't taken into account in debug mode (because of *.vhosts.exe)
It takes me time to understand why this file wasn't taken into account...
So question is pretty simple, how can I fix this and use configuration files in Debug Mode ?
I would use it in order to configure my trace switches.
Here is my App.config file :
<configuration>
<appSettings>
<add key="A" value="B"/>
</appSettings>
<system.diagnostics>
<switches>
<add name="myFirstSwitch" value="1" />
<add name="MySecondSwitch" value="Error" />
</switches>
</system.diagnostics>
</configuration>
Thanks.
I think you created your config file the wrong way, the right way is:
On the Project menu, click Add New Item. The Add New Item dialog box
appears.
Select the Application Configuration
File template and then click Add. A
file named App.config is added
to your project.
This config file is automatically copied to the build folder when you build the project and works in both Debug and Release mode.