I am curious if it is possible to specify in a web.config file to have visual studio not publish certain files or a certain directory.
The use case that I am trying to solve for is that I have a Test folder on a web app, that provides a series of useful pages for testing and debugging. The pages are very useful for development and qa. However in production they should not exist. What I would like is that when I publish my code with the release config that these files, or the entire folder is not published.
It doesn't really matter where the build conditions are stored, what is important is how you're gonna use them during build/publish. A conditional msbuild script would easily solve your issue - one of build tasks would be to publish/discard files depending of the value of some internal msbuild property and the property value comes from the web.config or any other external source (build script parameter, external XML file, etc.)
You could exclude the folder from your solution, then in publish it would not push it out. Then, if you want it back in your solution, it will still be there. Just right click the folder and include it.
I don't really if this is the "right" way or even possible to do what you are asking.
What I would suggest is to create a second project for your test. I usually go that way and just deploy the second "project" in my test environement.
Related
I have a WebApi2 application and it references other projects within the solution. One of these includes some files that I want copied on build. These files have their Copy to Output Directory property set to true.
The files are correctly located in the bin folder of their assembly.
However:
After the build I need them to be copied to the App_Data folder of the web application
Included in the files that get published to IIS
Is it possible?
From my experience you are going to have to get your hands dirty with MSBuild. Its been ages since I've used it but you will need to use the Move Task
This is what Visual Studio uses in the background to build the projects. It may seem daunting but is actually pretty simple once you get used to it. There are tons of tutorials online.
Alternatively, and the most straightforward way, is that you include the files in the APP_DATA folder from within the solution.
EDIT: As mentioned by robor78 you will need to call the Move Task in the Post-Build event
Add build events
In Visual Studio -> Solution Explorer -> right click the project -> properties -> go to build events.
Use something like xcopy
Also if click on "Edit Post-Build" you will see a list of useful folders and file names which you can use e.g. $(OutDir)
You can use Xcopy from the Post build event. It is pretty straight forward but will not run if code not changed. So if you update configs etc. you must force the build I beleive.
See here for how to use xcopy.
http://commandwindows.com/xcopy.htm
There are wild cards and all kinds of useful features, but your situation is pretty simple. Just copy from $(ProjectDir)/bin or something like that to a path.
Anyone have a preferred method for making web.config transforms? I am curious as to what others have done for this. I hate having to continuously update the web.config every time I update or republish.
A few years ago Scott Hanselman gave a solution using pre-build events and batch files:
http://www.hanselman.com/blog/ManagingMultipleConfigurationFileEnvironmentsWithPreBuildEvents.aspx
Basically you maintain a separate different configuration for each build and run the batch script pre-build to copy over the Web.Config. The obvious disadvantage is that if you have thirty different build configurations you need thirty different configs, but I find it's nice for projects where you only have two or three configs (like hobby projects, or tools you'll only ever be publishing to internal servers). Plus, it's nice knowing that if you want to you can take extra control of the build process if you want to.
The easiest way to use VS built in support:
You have versions of web.config, for your build versions, (by default Debug and Release)
In the release version you can define transforms what are applied during build. The effective web.config will be the result.
Look into the nuget package for slow cheetah: https://www.nuget.org/packages/SlowCheetah/ This does what you are looking for quite nicely. Be aware that it is for publish transformations only, switching to a different config for local debugging will have no affect.
Create a build configuration for each server you want to deploy to
Example
-Dev Server "copy from debug"-
-Prod Server Debug "copy from debug"-
-Prod Server Release "copy from release"-
Then right click your web.config and select "add config transforms"
You will get new transforms for each configuration you added above.
Now configure your web config transforms for each environment.
Now when you publish you can just select the configuration "Dev, Prod Debug, or Prod Release" and out it goes, no need to update them after that.
Now, the base web.config should always be configured for your local environment, so if you set up in IIS locally it will use web.config without any transforms. Your transforms should transform your local settings in the base web.config to w/e they need to be.
I have a c# ClickOnce application that I need to be able to publish multiple times for OEM purposes.
The way I understand it now is that publish settings are located in the .csproj file.
However, this is inconvenient in the case where I want to publish multiple versions.
for example, Company A needs totally different icons, start menu location, product name etc. from Company B, but the assemblies need not be renamed.
Here are a couple approaches/questions that I can think of to solve this issue...
1.Is there a way to create a separate publish settings file to use during build time?
2.Can I edit specific publish settings (like Start Menu location, etc) at build time with MSBuild.exe? I think this would be ideal...
e.g.
MSBuild.exe project.sln /target:Publish /property:edit-project-publish-settings-here
3.Maybe create a 2nd .csproj file? (Would prefer not to do this...)
Please share your thoughts as to the best approach, or any other clever ways to make this happen. Thanks!
I wish I could give you some brilliant solution, but personally I would probably go with option 3.
I mean, its pretty simple, the changes should be pretty static and it will be difficult(ish) to totally screw it up and deploy the wrong changes to the wrong company.
If you copy the .csproj in your project folder, it will reference all of the same source files and you can just change the executable name. Create another VS solution and you can reference the copied .csproj and get rid of your first one so that you can publish two separate versions.
This isn't ideal for ClickOnce however.
If you use a Singleton object that specifies the "mode" (Company A, B, C, etc.) you can easily store that in the app.config (or another xml file). Then just re-publish your ClickOnce Application but copy the correct version of your configuration file in so it gets shipped with the build. This way, you don't need any additional csprojects Just include all of your icons and set them at run-time on App Start based on your Singleton object.
I found that you are able to edit certain properties using MSBuild.exe like this
MSBuild Solution.sln /target:publish /property:ProductName=ProductA\;Publisher=CompanyA\;ApplicationIcon=companyA.ico
I found another useful post on modifying.csproj files programatically with .NET code. (This would only be needed if you're modifying things that are deeper than just the project properties specified in the ClickOnce documentation below)
The MSBuild documentation here was also useful -- especially under Publishing Properties
I'm currently using a post build event in my project to copy my assemblies to another directory for debugging purposes. This is local to my machine, and is for debugging purposes only, so I would prefer to have it in a *.csproj.user file instead of a *.csproj file. I tried copying the responsible elements from the *.csproj to the *.csproj.user, but that didn't work.
Edit
To clarify, I do not want to put user specific commands in the post-build event in the *.csproj file. Instead, I want to put the post-build event commands in the *.csproj.user file. (From the answers so far, this is looking impossible)
To give more context, it is not a project reference. I am copying my assembly to the directory of the application that loads the assemblies at runtime. (Think plugins)
The short answer is no, not the way you want to do it :|
The slightly longer answer is sorta. You can in theory have specific build events triggered for individual users, but these would still be in the csproj file. You can run external events on builds and then allow these external events to run depending on what user is running them (as a script).
If this is for debug only I'd just insert them, do your build stuff and pull them out before uploading it to your version control system.
Use an if statement and an enviroment variable (in double quotes if required)
if "$(Username)" == "MyUser"
copy /y $(ProjectDir)memcached.$(ConfigurationName).config $(ProjectDir)memcached.config
You can utilize a custom build target that has a condition triggered by an environment variable. Then only set that variable on your machine.
Pre-/Post-build events are kept in the project file. VS provides no options.
You can introduce a custom (external) tool to perform such copying though and call it from menu, or macros and call it too.
I have a Deployment Project for my VS2008 C# application. When installing a new version of my application I want to make sure that files are updated with the files contained in the installer.
I want my installer to automatically remove any old version of the installed application. To do that I follow this procedure (also described here):
Set RemovePreviousVersions to True
Set DetectNewerInstalledVersion to
True
Increment the Version of the
installer
Choose Yes to change the ProductCode
For the assemblies I make sure the AssemblyVersion is set to a higher version:
[assembly: AssemblyVersion("1.0.*")]
Everything is working as intended except for my configuration files (xml files). Since I cannot find a way to "version" these files I cannot make sure that the files are updated if they have been modified on the target machine.
Is there any way to do this and how?
UPDATE: I have tried the approach/solution/workaround found here
Include the file directly in a
project with the following
properties: "Build Action -> Content
file" and "Copy to Output Directory
-> Copy always"
Then add it to the deployment
project via Project
Output->Database->Content Files
Unfortunately it did not make any difference. The behavior is exactly the same.
Add the following property to the Property table of the MSI:
Property REINSTALLMODE with Value amus
Note: This will cause all the files in the MSI (versioned and nonversioned) to overwrite the files that are on the system.
If you're willing to use Orca (there may be another way to do this method, but it's the only one I know of) you may be able to set up RemoveFile directives.
See here for a typically light-weight MSDN document -- could be a starting point.
http://msdn.microsoft.com/en-us/library/aa371201.aspx
Alternatively you could always create a very simple bootstrapper executable that simply calls "msiexec /i REINSTALLMODE=oums" (or whichever command-line switches are needed). Call it setup.exe if you like...
Better option long-term may be to switch to InstallShield or similar -- VS2010 includes a light version of IS and I believe they're moving away from vdproj projects.
Have you tried the approach/solution/workaround found here?
Include the file directly in a
project with the following
properties: "Build Action -> Content
file" and "Copy to Output Directory
-> Copy always"
Then add it to the deployment
project via Project
Output->Database->Content Files
I may be incorrect here, and therefore I am exposing myself to down votes, but here goes anyway!
I believe it is on purpose that config files do not automatically get overwritten; the principle there being that you would not normally want your application's configuration overwritten when you install the new version of the program... at least not without numerous warnings and/or chances to merge configuration first.
Having your application configuration get overwritten by an updated version of a program could make for a very upset end user (in this case, web site admin).
Further, I know that sometimes, the developer may be the person doing the deployment. In such a case, this behavior might not seem so logical when deploying a single site to a single server; but when roles are split and/or you have multiple servers with different configurations, this can be a life saver.
You need to include the new version of your files in your custom installer and manually install these file during Custom Install routine is called
This must be applied to any file that does not have version that can be tracked by the installer.