Specifying project Property values from within Visual Studio - visual-studio-2010

If I have properties defined in my project file like so
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<foo>bar</foo>
</PropertyGroup>
</Project>
I can easily set these properties on the MSBuild command line using /p:foo=newValue.
Is there a way of specifying the property value within the Visual studio (2010) GUI? I have had a look but could not find anything within the project properties pages.

Are you looking for conditional compilation symbols?
In VS2010:
Go to the project properties
Go to the Build tab
Under General you will see a place to define "Conditional compilation symbols".
You can enter "foo=bar" there, and you will get this in your .csproj file:
<Project ...>
<PropertyGroup ...>
<DefineConstants>Foo=bar</DefineConstants>
</PropertyGroup>
</Project>

I found this question when looking for an answer to the same thing: I can easily use /p or environment variables to control things when calling MSBuild on the command line, but how do you do similar in the IDE?
My solution was to add a “user” properties file. That is
<!-- Running from the IDE, you can't simply set properties via /p or environment variables.
So, this local file is read if it exists. It is not checked in to version control; but can contain
settings to be used for your immediate work.
If you make a settings.props.user file, remember DO NOT check it in!
-->
<ImportGroup>
<Import
Condition="exists('$(MSBuildThisFileDirectory)settings.props.user')"
Project="$(MSBuildThisFileDirectory)settings.props.user" />
</ImportGroup>
I can now edit some properties in the file settings.props.user conveniently located in the same directory, and not worry about accidentally checking in funny settings. Even when building in the IDE, it reads the text file anew when building. So, just keep the props.user file open in a text editor and it's handy enough to change on the fly, without an IDE extension.

Related

Prevent Visual Studio from leaking pdb path in compiled exe

When I build my C# project as a release in Visual Studio, the resulting .exe contains the following string:
C:\Users\jornane\source\repos\«solution»\«project»\obj\Release\«name».pdb
The .exe file leaks my username and the path where I store the project. Is there a way I can prevent this from happening? I understand why that path would be there for Debug builds, but not for Release.
It is possible to replace the stored PDB paths using the -pathmap compiler option, for example the following generates «name».exe with the PDB path stored as .\«name».pdb, instead of using the full path.
C:\Users\«user»\source\repos\«solution»\«project»>csc -debug -pathmap:"%cd%=." «name».cs
The -pathmap option is not exposed in the IDE, but can be set into the .csproj file directly, by adding the following near the end of the file.
<Project>
<!-- ... -->
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<!-- after 'Microsoft.CSharp.targets' for 'IntermediateOutputPath' to be defined -->
<PathMap>$(MSBuildProjectDirectory)\$(IntermediateOutputPath)=.</PathMap>
</PropertyGroup>
</Project>
Replace <PathMap> with <PathMap Condition="'$(Configuration)'=='Release'"> for the option to apply to release build(s), only.
Note: the replacement path is set to "." in the examples above because csc does not allow it to be empty (error CS8101: The pathmap option was incorrectly formatted). Any other non-empty user-defined string will work in place of . as well.

Setting Environment variable in Visual studio C++project

I realize that similar questions were posted earlier but I need slightly different solution.
I have VS2012 C++ project A.vcxproj,that has debug1 configuration( platform x64) , and it builds corresponding .exe. It also uses a dll from other VS2012 C project B.vcxproj from a path that must be added to the environment variables. A.vcxproj.user file has following text
<LocalDebuggerEnvironment>PATH=%PATH%;C:\Program Files\libsndfile\bin;..\..\lib\simulink\;$(LocalDebuggerEnvironment) </LocalDebuggerEnvironment>
I need to add this setting automatically to the "A"project with following constraints
I cannot export user file as it as "per user", so cannot upload to our SCM system where other users can download it.
I tried adding code in main function, something like
_putenv("PATH = ....\lib\simulink");
but this does not work, as before the main file is compiled, it needs to search for the dll from specified path, which it dosn't .
Can anyone suggest a easy, portable fix , that i could distribute to all users through SCM, along with the project file.
I have also tried following:
--Created batch file setpath.bat with following content
#ECHO %PATH% set PATH = %PATH%;C:\Program Files\libsndfile\bin;C:\dev\lib\simulink
-- added to A.vcxproj settings->build event->Pre-build->Command line
call C:\setpath.bat
and I don't see the added paths under vS op window. neither does the VS User file gets the change, and running the project complains for missing dll error.
--I tried to execute the batch file in
A.vcxproj settings->
Custom build step->Execute before "Run"
and still no result.
I guess the solution needs to add needed path to current environment variable for the time VS project is "run".
Thanks
sedy
added to A.vcxproj settings-> Build Events ->Pre-Build event
call setdllpath.bat
where the file contains the following:
#ECHO %PATH%
set COMSPEC = "%VCINSTALLDIR%\vcvarsall.bat" amd64
setx PATH "C:\Program Files\libsndfile\bin;..\..\lib\simulink"
#ECHO %PATH%
So, once I build the Project, close Visual studio and open it again, and run the files wiithin project, it picks up dll correctly.
Contents in *.vcxproj.user, *.vcxproj.user or *.props use the same xml schema so can be easily exchanged or included.
First if usefull you can add UserMacros to define the path to your libraries.
Like bellow for the following two variable
PYTHONHOME=$(USERPROFILE)\AppData\Local\Programs\Python\Python37
PYTHONPATH=$(PYTHONHOME)\DLLs;$(PYTHONHOME)\Lib;$(PYTHONHOME)\Lib\site-packages
Edit the .vcxproj adding inside <Project>:
<Project .... >
...
<PropertyGroup Label="UserMacros">
<PYTHONHOME>$(USERPROFILE)\AppData\Local\Programs\Python\Python37</PYTHONHOME>
<PYTHONPATH>$(PYTHONHOME)\DLLs;$(PYTHONHOME)\Lib;$(PYTHONHOME)\Lib\site-packages;</PYTHONPATH> </PropertyGroup>
...
</Project>
After you can add inside your build configuration, the following to set the $(Path) variable.
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<LocalDebuggerEnvironment>Path=$(Path);$(PYTHONHOME);$(PYTHONHOME)\DLLs;$(PYTHONHOME)\Lib;$(PYTHONHOME)\Lib\site-packages;$(PYTHONHOME)\Scripts;$(PYTHONHOME);</LocalDebuggerEnvironment>

Custom Build Rule fails after converting to VS2013

I need to integrate a legacy VS2008 project into my VS2013 solution. This project uses some custom build rules which initially worked after converting the .vcproj to a .vcxproj. However, when doing a fresh checkout of the project including the .vcxproj, the project file can no longer be opened.
I've tracked it down to this issue:
The project file references a couple of custom build rules like this:
<ImportGroup Label="ExtensionSettings">
<Import Project="..\..\..\tools\build\ms_mc.props" />
(8 similar lines follow)
</ImportGroup>
However, the ms_mc.props file is not present, but there is a ms_mc.rule file. If I convert the VS2008 solution with VS2013 (and assumably also if I opened it in VS2008, which I don't possess), the ms_mc.props file (plus a .targets and a .xml file) is created. However, if I delete that file and open the converted VS2013 project, the file does not get created.
I realized, in the old .vcproj, the corresponding lines are
<ToolFiles>
<ToolFile RelativePath="..\..\..\tools\build\ms_mc.rule" />
(8 similar lines follow)
</ToolFiles>
Why does VS2008 reference the .rule file and VS2013 imports the .props file without specifying the .rule file? And more importantly: How can I make this work again?
The .rule and .props file are added for reference
ms_mc.rule:
<?xml version="1.0" encoding="utf-8"?>
<VisualStudioToolFile
Name="MS MC"
Version="8,00"
>
<Rules>
<CustomBuildRule
Name="MS_MC"
DisplayName="Microsoft Message Catalogue Compiler"
CommandLine="mc [Verbose] [inputs] [RCIncludePath] [CIncludePath]"
Outputs="[$RCIncludePath]\$(InputName).rc;[$RCIncludePath]\$(InputName).h"
FileExtensions="*.mc"
ExecutionDescription="Compiling Message Catalogue $(InputName).mc"
>
<Properties>
<BooleanProperty
Name="Verbose"
DisplayName="Verbose"
Description="Gives verbose output. (-v)"
Switch="-v"
/>
<StringProperty
Name="RCIncludePath"
DisplayName="RC include file path"
Description="Gives the path of where to create the RC include file and the binary message resource files it includes. (-r [pathspec])"
Switch="-r [value]"
DefaultValue=".\"
/>
<StringProperty
Name="CIncludePath"
DisplayName="C include file path"
Description="Gives the path of where to create the include header file. (-h [pathspec])"
Switch="-h [value]"
DefaultValue=".\"
/>
</Properties>
</CustomBuildRule>
</Rules>
</VisualStudioToolFile>
ms_mc.props (after Conversion to VS2013):
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup
Condition="'$(MS_MCBeforeTargets)' == '' and '$(MS_MCAfterTargets)' == '' and '$(ConfigurationType)' != 'Makefile'">
<MS_MCBeforeTargets>Midl</MS_MCBeforeTargets>
<MS_MCAfterTargets>CustomBuild</MS_MCAfterTargets>
</PropertyGroup>
<PropertyGroup>
<MS_MCDependsOn
Condition="'$(ConfigurationType)' != 'Makefile'">_SelectedFiles;$(MS_MCDependsOn)</MS_MCDependsOn>
</PropertyGroup>
<ItemDefinitionGroup>
<MS_MC>
<Verbose>False</Verbose>
<RCIncludePath>.\</RCIncludePath>
<CIncludePath>.\</CIncludePath>
<CommandLineTemplate>mc [Verbose] [inputs] [RCIncludePath] [CIncludePath]</CommandLineTemplate>
<Outputs>%(RCIncludePath)\%(Filename).rc;%(RCIncludePath)\%(Filename).h</Outputs>
<ExecutionDescription>Compiling Message Catalogue %(Filename).mc</ExecutionDescription>
</MS_MC>
</ItemDefinitionGroup>
</Project>
I found this blog post for VS2010 which states the following:
Custom build rule is a build feature introduced in VS2005. It provides the ability for the users to easily Plug-In third party tools to use in their build process. The custom build rule is defined by “.rules” files.
and more importantly
In VS2010, due to the migration to MSBuild, the information in the rules file is represented by three files: .XML, .props and .targets files.
This basically means that the .XML, .props and .targets files are in fact not created by VS2008; instead, they are a replacement of the old .rules file format since VS2010. Using this information, I can now safely check in those new files without breaking the VS2008 solution. I might have to adapt the new files manually in order to make them work as before, as also mentioned in the blog.

Visual Studio - launch .bat file as startup project

I have a C++ program I'm trying to debug. I normally run this from a .bat file which does some file cleanup before running the program. I can run my program from this script and attach the debugger, but it would be more convenient to launch the .bat file from VS. If I set the startup project's Command property to the bat file I get an error that it's an unrecognized binary format (because it's not a binary format, I suppose). I can set the command to cmd.exe and a command shell opens, but I haven't figured out how to pass the .bat file to the command shell. I've tried including it on the properties Command line, with and without a redirection char (<), and tried passing it as the argument to the command, but neither of these work. I've gotten close enough that I think there must be a way to do this, but I'm running out of ideas.
Some visual studios have this option, some don't. I'll post both cases
If your VS has this option
Right click the "project", and go to properties -> debug
In "Start Action" select "start external program", and put c:\Windows\System32\cmd.exe
In start options, put command line arguments: /c your_bat.bat
Set a working directory if necessary
Save and happy debugging
If your VS doesn't have this option
When you do the above, a your_project.csproj.user file is created/updated in the same directory as your_project.csproj, with the following:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectView>ShowAllFiles</ProjectView>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<StartProgram>C:\Windows\System32\cmd.exe</StartProgram>
<StartWorkingDirectory>c:\your_working_directory\</StartWorkingDirectory>
<StartArguments>/c your_bat.bat</StartArguments>
</PropertyGroup>
</Project>
Create or update this file including the above. Careful not to remove other things (if there is any). You can also expand this to other configurations by replicating the PropertyGroup with different configurations like 'Release|AnyCPU' and other configurations that your project might have. (This is possible in some versions of VS via interface)
Warning: you need to reload your project in Visual Studio for this change to take effect. (Right click on the project, unload - then again, load)
I recommend that instead of calling the batch file that is at the end is starting your application, you add a post-build event in your "Build Events" project settings. In the post-Build event type your clean-up code, but omit the "program start" line. Let VS run your program. This way you do not need to attach to the program

Visual Studio 2010: How to publish an ASP.NET web app to a target folder with MSBUILD?

In Visual Studio 2010, you know how you can change your configuration (debug, release, etc), right-click a project in the solution explorer, click publish, and have all the important web app project files for the selected configuration copied to a target folder along with an xdt-transformed web.config? Well, I am looking for the MSBUILD equivalent of exactly that.
My challenge to you: Provide the ONE LINE that I need to execute at my command prompt in order to accomplish this. No third party programs. No tutorial videos. Just a single, straight-up command that I can literally copy from your response, paste into a command window, modify as necessary to support my directory structure, and then hit enter.
If not, then perhaps someone could provide a link to a complete MSBUILD reference showing every command, switch, and value I can use at the command line.
Put the below to ProjectPublish.MSBuild.xml file (change PropertyGroup as needed):
<?xml version="1.0" encoding="utf-8" ?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Publish">
<PropertyGroup>
<ProjectFile>Path\To\Web.csproj</ProjectFile>
<PublishDir>Path\For\Publish\Output</PublishDir>
<TempDir>Path\To\Temp\Folder</TempDir>
<BuildConfig>Release|Debug</BuildConfig>
</PropertyGroup>
<Target Name="Publish">
<MSBuild Projects="$(ProjectFile)"
Properties="Configuration=$(BuildConfig);WebProjectOutputDir=$(PublishDir);OutDir=$(TempDir)\;BuildingProject=true"
Targets="ResolveReferences;_CopyWebApplication" />
</Target>
</Project>
Calling this from command line (or .bat file) should do the trick:
%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe ProjectPublish.MSBuild.xml
I found the solution I was looking for after all these months here
In case the above link goes bad, here's the skinny of what it says:
Unload then edit your project file. Look for the line where it's importing Microsoft.WebApplication.targets. Will look like:
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
Beneath that line, paste in this XML:
<Target Name="PublishToFileSystem" DependsOnTargets="PipelinePreDeployCopyAllFilesToOneFolder">
<Error Condition="'$(PublishDestination)'==''" Text="The PublishDestination property must be set to the intended publishing destination." />
<MakeDir Condition="!Exists($(PublishDestination))" Directories="$(PublishDestination)" />
<ItemGroup>
<PublishFiles Include="$(_PackageTempDir)\**\*.*" />
</ItemGroup>
<Copy SourceFiles="#(PublishFiles)" DestinationFiles="#(PublishFiles->'$(PublishDestination)\%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="True" />
</Target>
Now, run this in a command prompt within the same folder as your project file:
msbuild TestWebApp.csproj "/p:Platform=AnyCPU;Configuration=Debug;PublishDestination=C:\pub" /t:PublishToFileSystem
Remember to specify the path to MSBUILD in the command or add the path to your global path environmental variable (which is what I did). On my machine, it was here:
C:\Windows\Microsoft.NET\Framework\v4.0.30319
To test this, I put a config transform in my Web.Release.config to add an AppSetting key (if you do this, make sure the AppSettings node is present in your base config file or you will get an error). When I used the above command to build the debug configuration, the key was not present in the published config file as expected. However, when I used the release config, the key was successfully added to the file.
I really wish Microsoft hadn't obfuscated the heck out of this. At any rate, this is the simplest solution I have found anywhere on the internet. I hope it helps the rest of you.

Resources