Why does MSBuild only work properly in the developer command prompt? - command-line

I'm building a project locally using msbuild.exe like:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe MyProject.csproj
When I execute it through the Developer Command Prompt, everything works as expected.
However, when I execute it through the standard Command Prompt, I get an error saying:
The imported project "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v12.0\WebApplications\Microsoft.WebApplication.targets" was not found.
If I look up that folder path, I can indeed verify it's invalid (I only have VS 2015 installed on the machine).
So why isn't it working in Command Prompt, or conversely: why is it working in Developer Command Prompt?
Edit: The .csproj file is pretty much the Visual Studio 2015 default for an ASP.NET 4 website, and it specifies:
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
To me it seems it would default to 10.0 if VisualStudioVersion isn't set, but judging from the error message it's assuming VS version 12.0.
I realize I could just modify the .csproj file, replacing 12 with 14, but I'd rather not go for a workaround, but instead understand why it's working in the Developer Command Prompt, but not the standard one.
I'm guessing it potentially has to do with different environment variables, or something along those lines?

When you run Developer Command Prompt you basically run VsDevCmd.bat from VisualStudio's Tools folder and sets some environment variables for the Console that you will be working with. Without those msbuild can't find correct file.
For example it sets VisualStudioVersion environment variable
#rem VisualStudioVersion
#rem -------------------
#set VisualStudioVersion=14.0
It depends on the .csproj but I suspect you might have something similar in it
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">12.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
So if the $(VisualStudioVersion) is not defined (and it won't in standard Command Prompt) it will use the version 12. And when you run it through Developer Command Prompt this gets set to 14 and you're good to go.

Hans Passant pointed me in the right direction in the comments, and typing where msbuild.exe in the Developer Command Prompt showed that it had two paths to MSBuild:
C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe
C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe
The first one works in both the standard Command Prompt, and the Developer Command Prompt.
The second one (which my build script had retrieved from the registry) only works in Developer Command Prompt, probably explained by what Pawel said in his answer (essentially due to missing/different environment variables).
In my build script, I changed the registry path from...
HKLM\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0\
to...
HKLM\SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0\
...and that produces the proper (current) MSBuild path in the build script.

Related

Include date in web publishing package filename; visual studio

When creating a new deployment package (e.g. per http://msdn.microsoft.com/en-us/library/dd465323(v=vs.110).aspx) you're asked to provide a package location.
I'd like to append a timestamp to this filename, so that I can easily access older versions, just by browsing the output location.
i.e. I'd like to specify a value such as this: Packages\Test\MyProject{yyyy-mm-dd hh.mm.ss}.zip
...where the values in the braces are replaced by the current date/time.
Is this possible through native visual studio?
If so, how can it be done?
you can do that by editing your csproj file as follows (you have to open it as a text file):
- Near the end of the file you will find a comment with the targets AfterBuild and BeforeBuild, right after this comment add the following code
<Target Name="OnBeforePublishMyProject">
<PropertyGroup>
<_PackageTempDir>H:\Cs\Test\build.$([System.DateTime]::Now.ToString("yyyy.MM.dd.HH.mm.ss"))</_PackageTempDir>
<AutoParameterizationWebConfigConnectionStrings>false</AutoParameterizationWebConfigConnectionStrings>
</PropertyGroup>
</Target>
<Target Name="PublishMyProject" DependsOnTargets="Build;OnBeforePublishMyProject;PipelinePreDeployCopyAllFilesToOneFolder">
</Target>
Now you can Publish your project using the Visual Studio Command prompt and the following commands:
cd path_to_your_project
msbuild /t:PublishMyProject
You can create a bat file to execute those commands too

Using Visual Studio 2012, the manifest signed, but the assembly is not

I am using ClickOnce application deployment, and I just got my code certificate from Verisign. I am using this certificate to sign the manifest.
When I download and install the application, the smartscreen comes up with my name on it (lame, but I think this is what is supposed to happen). When the ClickOnce installer completes, the smartscreen comes up again for the execution of the actual application, here it says 'Unknown Publisher'.
Does ClickOnce not sign the assemblies by default? How do I do this?
Edit: Currently I am letting VS sign my manifest (installer) for the ClickOnce, and I am setting a Post-build event to sign my assembly. But still when I install the application it says 'unknown publisher' when I go to actually run it.
That does not sound right to me. I have used exactly the same workflow for multiple applications, and it works fine. Most likely there is an issue with your postbuild step. Make sure that you sign EXE file inside the OBJ folder (because that's where ClickOnce takes all the files from) - not the BIN one.
Do ClickOnce publishing, go to the OBJ folder, right click on your application.exe file, and select properties. It should have six tabs - the last one being "Digital Signature":
If you don't have it, you don't sign your application properly.
And here is my postbuild step - note that I sign "RELEASE" configuration only:
<Target Name="SignOutput" AfterTargets="CoreCompile" Condition="'$(ConfigurationName)'=='Release'">
<PropertyGroup>
<TimestampServerUrl>http://timestamp.verisign.com/scripts/timestamp.dll</TimestampServerUrl>
<ApplicationDescription>my app</ApplicationDescription>
<SigningCertificateCriteria>/n "my company."</SigningCertificateCriteria>
</PropertyGroup>
<ItemGroup>
<SignableFiles Include="$(ProjectDir)obj\$(ConfigurationName)\$(TargetName)$(TargetExt)" />
</ItemGroup>
<Exec Condition=" '$(ConfigurationName)'=='Release'" Command=""c:\Program Files (x86)\Windows Kits\8.0\bin\x64\signtool.exe" sign $(SigningCertificateCriteria) /d "$(ApplicationDescription)" /t "$(TimestampServerUrl)" "%(SignableFiles.Identity)"" />
</Target>

Set Application Name in MSBuild Parameters

I am deploying my web application from command line using this
msbuild WebApplication1.csproj /t:Package /p:configuration=release
It works fine, but the application deployed with the same name that is using in project settings page.
I want to set the name of deployed application using same command line.
Is there any parameter in msbuild to do so or any other approach.
Thanks
You should try this
msbuild WebApplication1.csproj /t:Package /p:configuration=release;DeployIISAppPath="what_ever_name_you_want"
You could get more about these keywords in your project file(.csproj), open it in notepad and search for the default name that is setted by VS. and use that parameter in your command line.
Hope this helps.
MS Build Command line parameters : it doesn't look like you can do it from the command line.
But you can do it in your config file - article using a property group
<PropertyGroup>
<appname>NewApplicationName</appname>
</PropertyGroup>
I can't tell exactly what setting it is in the property pages that you are talking about however the syntax will be something like this:
msbuild WebApplication1.csproj /t:Package /p:configuration=release /p:appname=Test

MSTest.exe not copying all needed project DLLs?

I'm trying to get MSTest.exe to run, and it seems like testcontainer isn't being read properly; while my tests all run successfully in all config environments within Visual Studio.
the command I'm using is:
"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\MSTest.exe" /nologo /usestderr /testSettings:"C:\temp\MyProject\Sources\MyProject\Local.testsettings" /searchpathroot:"C:\temp\MyProject\Binaries" /resultsfileroot:"C:\temp\MyProject\TestResults" /testcontainer:"C:\temp\MyProject\Binaries\MyProject.Services.Server.UnitTests.dll"
The project references within testcontainer project look like this:
<ItemGroup>
<ProjectReference Include="..\..\Services\MyProject.Services.Server\MyProject.Services.Server.csproj">
<Project>{92EC1999-CC0C-47DD-A4D6-17C3B1233C50}</Project>
<Name>MyProject.Services.Server</Name>
</ProjectReference>
<ProjectReference Include="..\..\SvcConfiguration\MyProject.ServiceConfiguration.Interfaces\MyProject.ServiceConfiguration.Interfaces.csproj">
<Project>{8E2E7BA9-75DB-458E-A184-AC1030EAD581}</Project>
<Name>MyProject.ServiceConfiguration.Interfaces</Name>
</ProjectReference>
<ProjectReference Include="..\..\SvcConfiguration\MyProject.ServiceConfiguration.Services\MyProject.ServiceConfiguration.Services.csproj">
<Project>{39514766-23A8-45DB-96EA-B6B4D9C8B086}</Project>
<Name>MyProject.ServiceConfiguration.Services</Name>
</ProjectReference>
</ItemGroup>
Neither the ServiceConfiguration.Interfaces nor the ServiceConfiguration.Services DLL is placed into the Out folder in TestResults.
The project GUIDs do match between the references and the referenced projects.
Is there something that I'm missing in the command line?
mstest.exe will not coy all referenced dll's.
See a blog post on this at https://web.archive.org/web/20111221110459/http://www.dotnetthoughts.net/2011/11/22/mstest-exe-does-not-deploy-all-items/
You can specify exactly what files are copied to the test directory using a test settings file. You can create multiple test settings files in Visual Studio, so you can have one for running from VS, another for running from MSTest, another for server CI builds, and so on. See here for more information: Create Test Settings to Run Automated Tests from Visual Studio
Use the /testsettings:<filename> option to specify it on the command line.
What seems to confuse people at first is that, by default, MSTest's "current directory" is not the MSTest launch directory, but the Out folder of the test results.
As mentioned previously, MSTest does not correctly infer all used assemblies, if you don't have a direct reference, it will not copy the assembly. That said, Visual Studio has similar behaviour in its build too, so a lot of people work around this by adding bogus code references - a terrible solution - I don't recommend it.
However, native DLLs are even more problematic, and I have found that explicitly copying them in the test configuration (test settings) works for them, just as for managed assemblies.
Whether it goes to Out or the build area depends on different factors, however, for the situations where it still doesn't work, you can use a DeploymentItem "hack", or, tweak your runsettings file.
Try looking at this answer: https://stackoverflow.com/a/33344573/2537017

FXCop report hosting on Hudson Dashboard Issue

I generated Fxcop analysis report using ant script. But I am unable to host it on Hudson Dashboard.
Using Nant script, I am able to generate an .xml output. Here is the ant:
<target name="Fxcop">
<echo message="Running Fxcop..." />
<exec command="${fxcop.basedir}\FxCopCmd.exe">
<arg value="/f:Path of my source file/>
<arg value="/out:some path/>
</exec>
</target>
In hudson Configuration, To display Vioaltion Reports, i configured the path of output(only pattern) file of the ant in xml file pattern of fxcop.
But Hudson is unable to find it.
I done the configurations and setting correctly.
Can anyone walk me through where I am going wrong.
Thanks in Advance
Most likely XML is created in different subfolder which relative path is originated from current directory. E.g. if your current working directory is %WORKSPACE%\trunk and relative path for report is /out:result\fxcop-result.xml then it will be created in %WORKSPACE%\trunk\result\fxcop-result.xml.
To fix this I suggest to check current directory from which you are executing FxCop analysis (also try searching this xml on build machine).
Easiest way to implement FxCop analysis in Hudson using Windows batch command will be:
Add "Execute Windows batch command" (this command will be executed from base workspace folder, e.g. C:\hudson\workspace\FxCopJob)
Specify command that will execute analysis, e.g.: ""{FxCopDirectory}\fxcopcmd.exe" /file:"%WORKSPACE%\{path to your file}" /directory="{Assemblies_path}" /rulesetdirectory:"{RuleSetDir}" /out:fxcop-result.xml"
Set fxcop-result.xml in fxcop section of Report Violation (e.g. report will be created in C:\hudson\workspace\FxCopJob\fxcop-result.xml)
Run updated Hudson job and verify that FxCop violations are shown
WBR,
Andrey