MSBuild, NAnt and Unicode symbols - unicode

%username%.
I have a problem with Unicode symbols while building my custom C++ files with MSBuild and NAnt.
Overview:
I write my own extension for MSVS10. In MSBuild scripts I implemented Build, Rebuild and Clean targets. For example in Build target I want to call NAnt.exe with parameters of NAnt build target file and some UNICODE parameter (for example some symbols - ㅇㅀㅇㅀ.cpp). When I call it in MSBuild target with Exec task in Output Window log is OK, I see ㅇㅀㅇㅀ.cpp, but if I use echo target in NAnt target I get ????.cpp in log.
I think that this problem in MSBuild, because when I debug my own functions for NAnt written with C# and MSVS10 and in debugging I start NAnt.exe with UNICODE parameters I get normal UNICODE string to my functions.
What do you think about this problem?

Which version of NAnt are you using?
NAnt v0.91 now has the ability to specify the encoding to use when calling the task.
http://nant.sourceforge.net/release/0.91/help/tasks/echo.html
<echo message="ㅇㅀㅇㅀ.cpp" encoding="unicode" />

Related

MSBuild with WebPublishMethod to package produces wrong file names in zip file

We have standard CI/CD on Azure DevOps. Recently we found, that files with diacritics (accent) in names are published wrong. Seems that instead of original chars all is in utf-8 (or something like that).
In build phase the is normal Visual Studio Build task with common msbuild command and arguments
/t:XXX /p:BuildProjectReferences=true /p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:DesktopBuildPackageLocation="$(build.artifactstagingdirectory)\XXX" /p:outputDir="$(build.artifactstagingdirectory)\XXX" /P:PackageTempRootDir=
After build, zip file contains encoded filenames. So encoding is part of build process.
Tried to simply call msbuild and publish to package from local machine on sample project and the same problem. Output zip package contains encoded filenames. And now it is impossible to extract zip file to get original naming.
My question is - how to force build and package task to not encode names, or use extract zip task to get filanames as they are in project? I found no info how to extract encoded files from artifacts.
Recently we found, that files with diacritics (accent) in names are published wrong.
Based on my test, I could reproduce this issue. When the Folder Name or File name contain the diacritics, their names will be encoded into other formats after Msbuild.
For example:
As you said, this problem also exists in the local msbuild, so this problem exists in msbuild itself. Since the SDK used by msbuild may be of a lower version, it cannot recognize these special characters
I am afraid that there is no such arguments in msbuild to force the original encoding of the file to be maintained.
Workaround1:
In Azure Devops, you could use Extract files task to unzip the zip file.
Then you could use Powershell task to run the script to change the file or folder name:
Folder:
Rename-Item 'C:\xxx\diakritik├│s' -newName 'C:\xxxm\diakritikós'
File:
Rename-Item -Path "c:\logfiles\daily_file.txt" -NewName "monday_file.txt"
Finally, you could use Archive files task to zip the files again.
Sample:
Workaround2:
Based on my test, you could use template for dotnet build.
In this case, dotnet build can keep the file name.
For the issue itself, I suggest you can report it here: Msbuild Issue.

VSTS build does not seem to publish output files to proper directory

I am developing an ASP.NET core application.
I use VSTS online for my source control. I also have a dedicated machine to build the application.
To automate the process, I am now trying to define a build script from VSTS online.
The default VSTS template defines many tasks. I removed all the unneeded tasks for my purpose and am down to just three tasks - "Use NuGet," "NuGet Restore," and "Build Solution."
The default msbuild argument for "Build Solution" task is:
/p:DeployOnBuild=true /p:WebPublishMethod=Package
/p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true
/p:DesktopBuildPackageLocation=
"$(build.artifactstagingdirectory)\WebApp.zip"
/p:DeployIisAppPath="Default Web Site"
Although there is no error in running this script, I need to change it such that the output goes to a folder and is not packaged.
Here is part of my directory structure that is relevant for my question:
C:\Dev\RCWebsite\RCWebsite.sln
C:\Dev\RCWebsite\RCWeb\RCWeb.csproj
C:\Dev\RCWebsite\RCWeb\Properties\PublishProfiles\FolderProfile.pubxml
Here is the content of the publish profile:
<PropertyGroup>
<WebPublishMethod>FileSystem</WebPublishMethod>
<PublishProvider>FileSystem</PublishProvider>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<ProjectGuid>d7d9f3b7-fd0e-49c1-b6d2-3af5dddb6699</ProjectGuid>
<publishUrl>C:\StagingSites\rcweb</publishUrl>
<DeleteExistingFiles>True</DeleteExistingFiles>
</PropertyGroup>
From the console window, I can run the following command:
msbuild .\RCWeb\RCWeb.csproj /p:DeployOnBuild=true
/p:PublishProfile=RCWeb\Properties\PublishProfiles\FolderProfile.pubxml
This works as expected. The final output is generated in C:\StagingSites\rcweb\ directory.
As this command works, I replaced the msbuild argument in VSTS "Build Solution" task as:
/p:DeployOnBuild=true
/p:PublishProfile=rcWeb\Properties\PublishProfiles\FolderProfile.pubxml
Note that I haven't specified .\RCWeb\RCWeb.csproj as an argument. Guess the build mechanism automatically takes care of this.
When I run this build and look at the log file, I see that the solution is built fine. However, it is never copied to C:\StagingSites\rcweb\ directory.
Can someone please tell me what is it that I am missing? Do I need another "deployment" task after "build solution" task? Regards.
Although there is no error in running this script, I need to change it such that the output goes to a folder and is not packaged.
No you do not need another deployment task. Since you do not need to package and deploy the ASP .NET project with msbuild, you can get rid of the /p:DeployOnBuild=true flag to msbuild. Also, after having a look at your publish profile I realized that you aren't really passing any information to msbuild (nothing that can't be passed from msbuild parameters atleast) and since you no longer plan to directly deploy from msbuild, it would be a good idea to keep the publish profile aside.
After trimming down the parameters and adding a few necessary ones (/T:Package tells msbuild that you want to package the binaries but not deploy them), this is what your msbuild command would look like:
/p:OutDir=$(Build.BinariesDirectory) /T:Package /p:PackageLocation=$(Build.BinariesDirectory)\WebApp.zip /p:PackageAsSingleFile=true
This is assuming that you wish to have a .zip file that is ready to be deployed, as the output. If that's not the case and you just require the binaries in a folder that can be directly deployed but not zipped, you can use the below command:
/p:OutDir=$(Build.BinariesDirectory) /T:Package /p:PackageLocation=$(Build.BinariesDirectory)\WebApp.zip /p:PackageAsSingleFile=true p:_PackageTempDir=$(Build.BinariesDirectory)\MyAspNetWebsite
This will generate the zip as well as the binaries folder ready to be deployed (sadly you need the zip for the temporary dir flag to work)
NOTE: If you plan on using the msbuild command within a powershell script, the VSO variables will need to accessed in a different way, like so: 'BUILD_BINARIESDIRECTORY'

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

Nant how do I list all the targets in the current project?

I'm constantly trying to remember some of the buried targets in my nant file.
Is there a command that I can run before I run the target that lists the targets?
Do you mean the command parameter -projecthelp, this will show all targets with the descriptions (when specified)
see also the nant site