Why is my cpp file not in the ClCompile index, causing LNK2019 and LNK2001 errors? - visual-studio-2010

I was receiving LNK2019 and LNK2001 errors in VS 2010 but not with g++. I searched around looking for reasons but everything talked about making sure the right headers were included, the functions properly defined, etc.
After going to the project directory and opening the .vcxproj file I saw this list:
<ItemGroup>
<ClCompile Include="main.cpp" />
<ClCompile Include="pilElem3.cpp" />
... many lines ...
<ClCompile Include="utlMatrixFull.cpp" />
<ClCompile Include="utlVector.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="pilElem3.h" />
... many lines ...
<ClInclude Include="utlMatrixFull.h" />
<ClInclude Include="utlVector.h" />
</ItemGroup>
<ItemGroup>
<None Include="pilElement.cpp" />
</ItemGroup>
pilElement is the parent class to pilElem3 and pilElem4 which were having the linker error.
I didn't change any of the filters or alter the project since creating it.
a) Why did VS think this file should be ignored?
b) How could I notice this sooner?

In answer to how I suspect that you may have inadvertently right clicked on the file in the project explorer - all to easy to do in VS.
How to make sure it doesn't happen in the future you have 2 options a) Don't use visual studio or b) Use a revision control system such as Mercurial and include the project file in those you are controlling - and do regular commits - you will be able to revert changes to the project file if needed and you should notice if it is in the changed file list when you are not expecting it to have changed.

Related

Why error "FS0239 an implementation of the file or module has already been given"?

Visual Studio is underlining the F# code in one of my source files with a red squiggly. The error message reads, "FS0239 an implementation of the file or module ________ has already been given."
When I search the Visual Studio Solution Explorer, there is only one file or module with the supposedly duplicate name.
What's going on?
I found that my *.fsproj file had several lines duplicated, like this:
<Compile Include="File1.fs" />
<Compile Include="File2.fs" />
<Compile Include="File3.fs" />
<Compile Include="File1.fs" />
<Compile Include="File2.fs" />
<Compile Include="File3.fs" />
Removing the duplicates fixed the problem.
As a side note, I think the duplication was caused by a Git merge.

Conditional compilation new csproj and visual studio solution explorer

I have the following in my csproj file
<ItemGroup>
<Compile Remove="WebControls/**/*" Condition="'$(TargetFramework)' == 'netstandard2.0'" />
<Compile Remove="Lucene/**/*" Condition="'$(TargetFramework)' == 'netstandard2.0'" />
</ItemGroup>
I'm not even sure if this is the right approach, I'm trying to avoid having to go through those files and add a conditional compilation symbol such as "#if NET462".
The problem is that those files disappear from the solution explorer when I add that to csproj, is there a way to switch the target platform to net462 in the solution explorer so that they show again?

Visual Studio, csproj: How can I specify a linked file in DependentUpon?

Suppose I have a default.aspx.cs in my project, but I want to make it dependent upon the default.aspx file that's linked. E.g.:
<Content Include="..\somedir\default.aspx">
<Link>Default.aspx</Link>
</Content>
This doesn't work:
<Compile Include="default.aspx.cs">
<DependentUpon>Default.aspx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
This also doesn't work:
<Compile Include="default.aspx.cs">
<DependentUpon>..\somedir\default.aspx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
For both, I get this error:
The parent file, 'Default.aspx', for file 'default.aspx.cs' cannot be found in the project file.
Is it possible to have a file be dependent upon a linked file?
I tried the same thing and it seems is not supported. Check this: https://bitbucket.org/jfromaniello/nestin/issue/4/error-when-nesting-linked-files "DependentUpon does not work with linked files."

Copy DLL files to bin directory after one-click publishing in VS2010

I have a web application in VS2010 which has a number of DLLs that need to be copied into the bin directory after doing a publish in VS2010.
I've tried putting the following into my .csproj file (which sits in the root folder of the web applications) but it doesn't seem to work:
<Target Name="AfterBuild">
<ItemGroup>
<_CircularDependencies Include="DLLs\Circular\Dependencies\*.dll" />
</ItemGroup>
<Copy
SourceFiles="#(_CircularDependencies)"
DestinationFiles="#(_CircularDependencies->'bin\%(Filename)%(Extension)')"
SkipUnchangedFiles="true" />
</Target>
For bonus points, I have another set of DLLs copied to be copied post-publish, but I want to use one set when doing a debug publish (for Win32) and a different set when doing a release publish (x86).
Thanks!
OK, I've managed to get this working fully. Thanks to the answers provided above, I've been able to add some MS Build commands to the .csproj file to copy the appropriate DLLs from various folders into the bin folder based on the current build configuration. However as these are unmanaged DLLs (i.e. not .NET) I can't create normal references to them and they fail to be copied during the publish. I got around this by dynamically adding the files to the project as 'content'.
The solution came in three parts. Firstly, create an item group for the files near the top of the .csproj file (I've tried to use generic filenames here to make it clearer), with conditions based on the current build configuration:
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
<_UnmanagedDLLs Include="Win32DLLs\*.dll" />
</ItemGroup>
<ItemGroup Condition="'$(Configuration)' == 'Release'">
<_UnmanagedDLLs Include="x64DLLs\*.dll" />
</ItemGroup>
Then add another item group to include these DLLs (as content, not references) in the build:
<ItemGroup>
<Content Include="#(_UnmanagedDLLs->'bin\%(Filename)%(Extension)')" />
</ItemGroup>
Finally, at the bottom of the .csproj file, I do the copy on the AfterBuild target:
<Target Name="AfterBuild">
<Copy SourceFiles="#(_UnmanagedDLLs)" DestinationFiles="#(_UnmanagedDLLs->'bin\%(Filename)%(Extension)')" SkipUnchangedFiles="true" />
</Target>
It means I can do a debug publish for my windows 32 staging box and a release publish for my x64 production box while keeping my bin folder out of SVN.
Once you get the copy working, separate sets for debug/release is easy with a condition:
<ItemGroup Condition="'$(Configuration)' == 'Release'">
<_CircularDependencies Include="DLLs\Circular\Dependencies\*.dll" />
</ItemGroup>
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
<_CircularDependencies Include="DebugDLLs\Circular\Dependencies\*.dll" />
<_CircularDependencies Include="DebugDLLs\Circular\Dependencies\*.pdb" />
</ItemGroup>
If you want your copy to happen after publish, not after build you need to change your target from:
<Target Name="AfterBuild">
to
<Target Name="AfterPublish">

App.Config Transformation for projects which are not Web Projects in Visual Studio?

For Visual Studio 2010 Web based application we have Config Transformation features by which we can maintain multiple configuration files for different environments. But the same feature is not available for App.Config files for Windows Services/WinForms or Console Application.
There is a workaround available as suggested here: Applying XDT magic to App.Config.
However it is not straightforward and requires a number of steps. Is there an easier way to achieve the same for app.config files?
I tried several solutions and here is the simplest I personally found.
Dan pointed out in the comments that the original post belongs to Oleg Sych—thanks, Oleg!
Here are the instructions:
1. Add an XML file for each configuration to the project.
Typically you will have Debug and Release configurations so name your files App.Debug.config and App.Release.config. In my project, I created a configuration for each kind of environment, so you might want to experiment with that.
2. Unload project and open .csproj file for editing
Visual Studio allows you to edit .csproj files right in the editor—you just need to unload the project first. Then right-click on it and select Edit <ProjectName>.csproj.
3. Bind App.*.config files to main App.config
Find the project file section that contains all App.config and App.*.config references. You'll notice their build actions are set to None and that's okay:
<None Include="App.config" />
<None Include="App.Debug.config" />
<None Include="App.Release.config" />
Next, make all configuration-specific files dependant on the main App.config so Visual Studio groups them like it does designer and code-behind files.
Replace XML above with the one below:
<None Include="App.config" />
<None Include="App.Debug.config" >
<DependentUpon>App.config</DependentUpon>
</None>
<None Include="App.Release.config" >
<DependentUpon>App.config</DependentUpon>
</None>
4. Activate transformations magic (still necessary for Visual Studio versions such as VS2019)
In the end of file after
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
and before final
</Project>
insert the following XML -- please note there are two steps for the proper transformation to occur:
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
<Target Name="BeforeBuild" Condition="Exists('App.$(Configuration).config')">
<!-- Generate transformed app config and replace it: will get the <runtime> node and assembly bindings properly populated -->
<TransformXml Source="App.config" Destination="App.config" Transform="App.$(Configuration).config" />
</Target>
<Target Name="AfterBuild" Condition="Exists('App.$(Configuration).config')">
<!-- Generate transformed app config in the intermediate directory: this will transform sections such as appSettings -->
<TransformXml Source="App.config" Destination="$(IntermediateOutputPath)$(TargetFileName).config" Transform="App.$(Configuration).config" />
<!-- Force build process to use the transformed configuration file from now on.-->
<ItemGroup>
<AppConfigWithTargetPath Remove="App.config" />
<AppConfigWithTargetPath Include="$(IntermediateOutputPath)$(TargetFileName).config">
<TargetPath>$(TargetFileName).config</TargetPath>
</AppConfigWithTargetPath>
</ItemGroup>
</Target>
Now you can reload the project, build it and enjoy App.config transformations!
FYI
Make sure that your App.*.config files have the right setup like this:
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<!--magic transformations here-->
</configuration>
This works now with the Visual Studio AddIn treated in this article: SlowCheetah - Web.config Transformation Syntax now generalized for any XML configuration file.
You can right-click on your web.config and click "Add Config
Transforms." When you do this, you'll get a web.debug.config and a
web.release.config. You can make a web.whatever.config if you like, as
long as the name lines up with a configuration profile. These files
are just the changes you want made, not a complete copy of your
web.config.
You might think you'd want to use XSLT to transform a web.config, but
while they feels intuitively right it's actually very verbose.
Here's two transforms, one using XSLT and the same one using the XML
Document Transform syntax/namespace. As with all things there's
multiple ways in XSLT to do this, but you get the general idea. XSLT
is a generalized tree transformation language, while this deployment
one is optimized for a specific subset of common scenarios. But, the
cool part is that each XDT transform is a .NET plugin, so you can make
your own.
<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/configuration/appSettings">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
<xsl:element name="add">
<xsl:attribute name="key">NewSetting</xsl:attribute>
<xsl:attribute name="value">New Setting Value</xsl:attribute>
</xsl:element>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Or the same thing via the deployment transform:
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<appSettings>
<add name="NewSetting" value="New Setting Value" xdt:Transform="Insert"/>
</appSettings>
</configuration>
Another solution I've found is NOT to use the transformations but just have a separate config file, e.g. app.Release.config. Then add this line to your csproj file.
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<AppConfig>App.Release.config</AppConfig>
</PropertyGroup>
This will not only generate the right myprogram.exe.config file but if you're using Setup and Deployment Project in Visual Studio to generate MSI, it'll force the deployment project to use the correct config file when packaging.
Inspired by Oleg and others in this question, I took the solution https://stackoverflow.com/a/5109530/2286801 a step further to enable the following.
Works with ClickOnce
Works with Setup and Deployment projects in VS 2010
Works with VS2010, 2013, 2015 (didn't test 2012 although should work as well).
Works with Team Build. (You must install either A) Visual Studio or B) Microsoft.Web.Publishing.targets and Microsoft.Web.Publishing.Tasks.dll)
This solution works by performing the app.config transformation before the app.config is referenced for the first time in the MSBuild process. It uses an external targets file for easier management across multiple projects.
Instructions:
Similar steps to the other solution. I've quoted what remains the same and included it for completeness and easier comparison.
0. Add a new file to your project called AppConfigTransformation.targets
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Transform the app config per project configuration.-->
<PropertyGroup>
<!-- This ensures compatibility across multiple versions of Visual Studio when using a solution file.
However, when using MSBuild directly you may need to override this property to 11.0 or 12.0
accordingly as part of the MSBuild script, ie /p:VisualStudioVersion=11.0;
See http://blogs.msdn.com/b/webdev/archive/2012/08/22/visual-studio-project-compatability-and-visualstudioversion.aspx -->
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.targets" />
<Target Name="SetTransformAppConfigDestination" BeforeTargets="PrepareForBuild"
Condition="exists('app.$(Configuration).config')">
<PropertyGroup>
<!-- Force build process to use the transformed configuration file from now on. -->
<AppConfig>$(IntermediateOutputPath)$(TargetFileName).config</AppConfig>
</PropertyGroup>
<Message Text="AppConfig transformation destination: = $(AppConfig)" />
</Target>
<!-- Transform the app.config after the prepare for build completes. -->
<Target Name="TransformAppConfig" AfterTargets="PrepareForBuild" Condition="exists('app.$(Configuration).config')">
<!-- Generate transformed app config in the intermediate directory -->
<TransformXml Source="app.config" Destination="$(AppConfig)" Transform="app.$(Configuration).config" />
</Target>
</Project>
1. Add an XML file for each configuration to the project.
Typically you will have Debug and Release configurations so name your files App.Debug.config and App.Release.config. In my project, I created a configuration for each kind of enironment so you might want to experiment with that.
2. Unload project and open .csproj file for editing
Visual Studio allows you to edit .csproj right in the editor—you just need to unload the project first. Then right-click on it and select Edit .csproj.
3. Bind App.*.config files to main App.config
Find the project file section that contains all App.config and App.*.config references and replace as follows. You'll notice we use None instead of Content.
<ItemGroup>
<None Include="app.config"/>
<None Include="app.Production.config">
<DependentUpon>app.config</DependentUpon>
</None>
<None Include="app.QA.config">
<DependentUpon>app.config</DependentUpon>
</None>
<None Include="app.Development.config">
<DependentUpon>app.config</DependentUpon>
</None>
</ItemGroup>
4. Activate transformations magic
In the end of file after
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
and before final
</Project>
insert the following XML:
<Import Project="AppConfigTransformation.targets" />
Done!
In my experience, the things I need to make environment-specific are things like connection strings, appsettings and often smpt settings. The config system allows to specify these things in separate files. So you can use this in your app.config/web.config:
<appSettings configSource="appsettings.config" />
<connectionStrings configSource="connection.config" />
<system.net>
<mailSettings>
<smtp configSource="smtp.config"/>
</mailSettings>
</system.net>
What I typically do is to put these config-specific sections in separate files, in a subfolder called ConfigFiles (either in the solution root or at the project level, depends). I define a file per configuration, e.g. smtp.config.Debug and smtp.config.Release.
Then you can define a pre-build event like so:
copy $(ProjectDir)ConfigFiles\smtp.config.$(ConfigurationName) $(TargetDir)smtp.config
In team development, you can tweak this further by including the %COMPUTERNAME% and/or %USERNAME% in the convention.
Of course, this implies that the target files (x.config) should NOT be put in source control (since they are generated). You should still add them to the project file and set their output type property to 'copy always' or 'copy if newer' though.
Simple, extensible, and it works for all types of Visual Studio projects (console, winforms, wpf, web).
You can use a separate config file per configuration, e.g. app.Debug.config, app.Release.config and then use the configuration variable in your project file:
<PropertyGroup>
<AppConfig>App.$(Configuration).config</AppConfig>
</PropertyGroup>
This will then create the correct ProjectName.exe.config file depending on the configuration you are building in.
I wrote nice extension to automate app.config transformation like the one built in Web Application Project Configuration Transform
The biggest advantage of this extension is that you don’t need to install it on all build machines
Install "Configuration Transform Tool" in Visual Studio from Marketplace and restart VS. You will be able to see menu preview transform for app.config as well.
https://marketplace.visualstudio.com/items?itemName=GolanAvraham.ConfigurationTransform
Just a little improvement to the solution that seems to be posted everywhere now:
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
that is, unless you are planning to stay with your current VS version forever
So I ended up taking a slightly different approach. I followed Dan's steps through step 3, but added another file: App.Base.Config. This file contains the configuration settings you want in every generated App.Config. Then I use BeforeBuild (with Yuri's addition to TransformXml) to transform the current configuration with the Base config into the App.config. The build process then uses the transformed App.config as normal. However, one annoyance is you kind of want to exclude the ever-changing App.config from source control afterwards, but the other config files are now dependent upon it.
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
<Target Name="BeforeBuild" Condition="exists('app.$(Configuration).config')">
<TransformXml Source="App.Base.config" Transform="App.$(Configuration).config" Destination="App.config" />
</Target>
I have created another alternative to the one posted by Vishal Joshi where the requirement to change the build action to Content is removed and also implemented basic support for ClickOnce deployment. I say basic, because I didn't test it thoroughly but it should work in the typical ClickOnce deployment scenario.
The solution consists of a single MSBuild project that once imported to an existent windows application project (*.csproj) extends the build process to contemplate app.config transformation.
You can read a more detailed explanation at Visual Studio App.config XML Transformation and the MSBuild project file can be downloaded from GitHub.
If you use a TFS online(Cloud version) and you want to transform the App.Config in a project, you can do the following without installing any extra tools.
From VS => Unload the project => Edit project file => Go to the bottom of the file and add the following:
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
<Target Name="AfterBuild" Condition="Exists('App.$(Configuration).config')">
<TransformXml Source="App.config" Transform="App.$(Configuration).config" Destination="$(OutDir)\$(AssemblyName).dll.config" />
AssemblyFile and Destination works for local use and TFS online(Cloud) server.
proposed solution will not work when a class library with config file is referenced from another project (in my case it was Azure worker project library). It will not copy correct transformed file from obj folder into bin\##configuration-name## folder. To make it work with minimal changes, you need to change AfterCompile target to BeforeCompile:
<Target Name="BeforeCompile" Condition="exists('app.$(Configuration).config')">
Note: Due to reputation I cannot comment on bdeem's post. I'm posting my findings as an answer instead.
Following bdeem's post, I did the following (in order):
1. I modified the [project].csproj file. Added the <Content Include="" /> tags to the ItemGroup for the different config files and made them dependent on the original config file.
Note: Using <None Include="" /> will not work with the transformation.
<!-- App.config Settings -->
<!-- Create App.($Configuration).config files here. -->
<Content Include="App.config" />
<Content Include="App.Debug.config">
<DependentUpon>App.config</DependentUpon>
</Content>
<Content Include="App.Release.config">
<DependentUpon>App.config</DependentUpon>
</Content>
2. At the bottom of the [project].csproj file (before the closing </Project> tag), I imported the ${MSBuildToolsPath\Microsoft.CSharp.targets file, added the UsingTask to transform the XML and added the Target to copy the transformed App.config file to the output location.
Note: The Target will also overwrite the App.Config in the local directory to see immediate changes working locally. The Target also uses the Name="Afterbuild" property to ensure the config files can be transformed after the executables are generated. For reasons I do not understand, when using WCF endpoints, if I use Name="CoreCompile", I will get warnings about the service attributes. Name="Afterbuild" resolved this.
<!-- Task to transform the App.config using the App.($Configuration).config file. -->
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
<!-- Only compile the App.config if the App.($Configuration).config file exists. -->
<!-- Make sure to use the AfterBuild name instead of CoreCompile to avoid first time build errors and WCF endpoint errors. -->
<Target Name="AfterBuild" Condition="exists('App.$(Configuration).config')">
<!-- Generate transformed App.config in the intermediate output directory -->
<TransformXml Source="App.config" Destination="$(IntermediateOutputPath)$(TargetFileName).config" Transform="App.$(Configuration).config" />
<!-- Modify the original App.config file with the transformed version. -->
<TransformXml Source="App.config" Destination="App.config" Transform="App.$(Configuration).config" />
<!-- Force build process to use the transformed configuration file from now on. -->
<ItemGroup>
<AppConfigWithTargetPath Remove="App.config" />
<AppConfigWithTargetPath Include="$(IntermediateOutputPath)$(TargetFileName).config">
<TargetPath>$(TargetFileName).config</TargetPath>
</AppConfigWithTargetPath>
</ItemGroup>
</Target>
</Project>
3. Went back into Visual Studio and reloaded the modified files.
4. Manually added the App.*.config files to the project. This allowed them to group under the original App.config file.
Note: Make sure the App.*.config files have the proper XML structure.
<?xml version="1.0" encoding="utf-8"?>
<!-- For more information on using web.config transformation visit https://go.microsoft.com/fwlink/?LinkId=125889 -->
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<connectionStrings>
<add name="myConn" connectionString=""; Initial Catalog=; User ID=; Password=;" xdt:Transform="SetAttributes" xdt:Locator="Match(name)" />
</connectionStrings>
</configuration>
5. Re-built the project.
Yet another variation on #bdeem's answer using Visual Studio 2019 and 2022. My issue was that using that solution, App.config was getting overwritten, and since it's in source control that's not really an option.
The solution for me was to transform the config file directly into the output directory.
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
<Target Name="AfterBuild" Condition="Exists('App.$(Configuration).config')">
<!-- Generate transformed app config to the output directory -->
<TransformXml Source="App.config" Destination="$(OutDir)\$(TargetFileName).config" Transform="App.$(Configuration).config" />
</Target>
It has the added benefit of being quite a bit shorter than the original solution.

Resources