Problem with building with csc task in Ant - c#

I have an ant build target using csc:
<target name="compile">
<echo>Starting compiling ServiceLauncher</echo>
<csc optimize="true" debug="true" warnLevel="1"
unsafe="false" targetType="exe" failonerror="true"
incremental="false" mainClass = "ServiceLauncher.Launcher"
srcdir="ServiceLauncher/Launcher/"
outputfile="ServiceLauncher.exe" >
<reference file="libs/log4net.dll"/>
<define name="RELEASE"/>
</csc>
</target>
When I run it, the following exception comes up:
csc failed: java.io.IOException: Cannot run program "csc": CreateProcess error=2, The system cannot find the file specified
However, it runs without the exception but never correctly builds the .exe file, when I manually add in an empty ServiceLauncher.exe.
How can I correctly build this .Net project "ServiceLauncher"?

My guess is that csc.exe is not on the execute path.
From the documentation for the csc task:
csc.exe on Windows or mcs on any other platform must be on the execute path, unless another executable or the full path to that executable is specified in the executable parameter

Related

Automatically signing ALL compiled output files

I have a .net-core 3.1 project (Microsoft.NET.Sdk.Web) in gitlab, and am setting up a CI/CD pipeline for it. As the final step, I want to have all the .dll and .exe output files signed by our key. I can do this by manually putting in some 'signtool' commands as a part of the gitlab-ci.yml file, however that requires going into each project and manually tweaking the file to reflect the specifics of that project.
On the other hand, I have been able to add a generic target in the .csproj file which calls signtool as an exec/command on $(TargetDir)$(TargetFileName). This works to a degree - but it doesn't sign everything. In this case, it signs (e.g.) cthulhu.dll, but not also cthulhu.Views.dll (both of which are shown in the CLI output of 'dotnet msbuild') and there's also a cthulhu.exe that is generated but is not shown in the msbuild output and also not signed.
The csproj file has this as the target (tried running both after rebuild and after publish):
<Target Name="SignAssembly" AfterTargets="Rebuild">
<Message Text="Signing assembly '$(TargetDir)$(TargetFileName)'" Importance="high" />
<Exec Command="signtool sign /f "mykey.pfx" /p "snip" /tr http://timestamp.digicert.com "$(TargetDir)$(TargetFileName)"" />
And the gitlab-ci.yml file looks like this (I'm aware that I'm using the sdk docker container, but it seems to let me support .net-core builds anyway, whereas there is a bug preventing the specific .net-core container from working):
image: mcr.microsoft.com/dotnet/framework/sdk:4.8
stages:
- build
- release
build:
stage: build
script:
- 'dotnet build -r win-x64'
release:
stage: release
script:
- 'dotnet add package signtool --version 10.0.17763.132'
- 'dotnet msbuild cthulhu.csproj /t:"Restore;Rebuild;SignAssembly;Publish" /p:SelfContained=True /p:PublishProtocol=FileSystem /p:Configuration=Release /p:Platform=x64 /p:TargetFrameworks=netcoreapp3.1 /p:PublishDir=bin\Release\netcoreapp3.1\publish\win-x64 /p:RuntimeIdentifier=win-x64 /p:PublishReadyToRun=False /p:PublishTrimmed=True'
artifacts:
name: "$CI_JOB_STAGE-$CI_COMMIT_REF_NAME"
paths:
- '.\bin\Release\netcoreapp3.1\publish\win-x64'
Why not use standard tools - Directory.Build.props?
However, now you can add a new property to every project in one step
by defining it in a single file called Directory.Build.props in the
root folder that contains your source. When MSBuild runs,
Microsoft.Common.props searches your directory structure for the
Directory.Build.props file (and Microsoft.Common.targets looks for
Directory.Build.targets). If it finds one, it imports the property.
Directory.Build.props is a user-defined file that provides
customizations to projects under a directory
Indicates that the assembly should be signed:
<SignAssembly>true</SignAssembly>
The key is specified using the following property:
<AssemblyOriginatorKeyFile>key.pfx</AssemblyOriginatorKeyFile>
That is, as a result, these properties will be imported into the projects and you will achieve the desired result.

Could not load file or assembly 'Microsoft.Management.Infrastructure

I am writing a multi-platform c# command line application using .NET Core 3.1 that will need to work as a single executable. I am using Visual Studio 2019 (16.5.4). My OS is Windows 10.0.18363.778 and I intentionally did NOT install Powershell 7. I tested this first bit on my Windows and WSL Ubuntu and it worked until I added Powershell SDK 7. After I installed Microsoft.Powershell.SDK 7.0.0 and when Ì set the project file as follows, everything runs nicely and I can validate I am using PS7 and not Windows PS.
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
However, when I add the runtimeIdentifier in PropertyGroup:
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
Build successfully completes without errors. However when I ran (both debuging or standalone) and application hits Powershell.Invoke, it throws a FileNotFound Exception with message:
"Could not load file or assembly 'Microsoft.Management.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified."
1) What am I missing to get all depdendencies in the executable directory?
2) When I add the following to create the single executable
<PublishSingleFile>true</PublishSingleFile>
<UseAppHost>true</UseAppHost>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
It does not get created. I get the executable if I use:
"dotnet publish -r win-x64 -c Debug"
but nothing happens when I run it. (This step used to work fine before PS7)
Is there anthing else I need to do to get the single executable running?
I did some research and figured the following:
Answer 1: There is no Runtime identifer specific Microsoft.Management.Infrastructure.dll files in the runtimes directory. Either Powershell SDK does not support all runtime identifers or its a bug. I will take it to github.
Answer 2: Running the single Executable file is misleading. My expected result was creation of a log file which is created in the application directory. I figured that when the single exe is run, it actually unzips ALL the files to the temp directory and runs the application from there (not the single executable) and hence the log file is not created where the single file executabe is.
To resolve your problem, you have to add this reference to your project. It take me 1 day to found this.
<PackageReference Include="NETStandard.Library" Version="1.6.1" />

Visual Studio $(ProjectDir) is empty string

I am using Visual Studio 2017 and I want to add a post-build command. when I go to 'Macros' window I see the correct path coresponging to $(ProjectDir) variable. So I added the command:
$(ProjectDir)ClientApp\npm run build
but when I execute build I get the following error:
The command 'ClientApp\npm run build'exited with code 3.
I change MSBuild verbose to Diagnose and in the Output window I saw:
1>Target "PostBuildEvent" in file "C:\Program Files (x86)\Microsoft
Visual
Studio\2017\Community\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets":
1> Using "Exec" task from assembly "Microsoft.Build.Tasks.Core,
Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
1> Task "Exec" 1> Task
Parameter:WorkingDirectory=bin\Debug\netcoreapp1.1\ 1> Task
Parameter:Command=ClientApp\npm run build 1> ClientApp\npm run
build 1> The system cannot find the path specified. 1>
C:\Program Files (x86)\Microsoft Visual
Studio\2017\Community\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets(4933,5):
error MSB3073: The command "ClientApp\npm run build" exited with code
3. 1> Done executing task "Exec" -- FAILED.
In the targets file I got these lines:
<Target
Name="PostBuildEvent"
Condition="'$(PostBuildEvent)' != '' and ('$(RunPostBuildEvent)' != 'OnOutputUpdated' or '$(_AssemblyTimestampBeforeCompile)' != '$(_AssemblyTimestampAfterCompile)')"
DependsOnTargets="$(PostBuildEventDependsOn)">
<Exec WorkingDirectory="$(OutDir)" Command="$(PostBuildEvent)" />
</Target>
Can I change the working dir from $(OutDir) to $(ProjectDir) and how?
Any ideas where I am mistaken?
NB - I added the command in a BAT file, just to test but the result was the same
Try $(MSBuildProjectDirectory) instead
The problem could affect other VS variable as well.
The universal solution is described here.

TeamCity wont create release folder

When using TeamCity and running a build I get the following error message.
13:20:31]Step 1/1: MSBuild (1s)
[13:20:32][Step 1/1] src\DystopiaOnline.proj.teamcity: Build target: BuildSolution
[13:20:32][src\DystopiaOnline.proj.teamcity] BuildSolution
[13:20:32][BuildSolution] C:\TeamCity\buildAgent\work\8c8eb5050252f271\src\DystopiaOnline.proj(36, 5): error MSB4062: The "DystopiaOnline.Build.Tasks.GetUnixTimestamp" task could not be loaded from the assembly C:\TeamCity\buildAgent\work\8c8eb5050252f271\src\DystopiaOnline.Build.Tasks/bin/Release/DystopiaOnline.Build.Tasks.dll. Could not load file or assembly 'file:///C:\TeamCity\buildAgent\work\8c8eb5050252f271\src\DystopiaOnline.Build.Tasks\bin\Release\DystopiaOnline.Build.Tasks.dll' or one of its dependencies. The system cannot find the file specified. Confirm that the <UsingTask> declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask.
[13:20:32][Step 1/1] Step MSBuild failed
However when I run the build from the developer command prompt the build works fine. Taking a look inside the C:\TeamCity\buildAgent\work\8c8eb5050252f271\src\D ystopiaOnline.Build.Tasks\bin only shows a Debug folder rather than a Release folder. Running the build from the developer command prompt works ok just building from Team City doesn't.
shouldn't the Release folder be created when the build is run from Team City with the Env variable set to prod? what could be causing this? Anyone any ideas?
In my project solution .proj file have the following conditions set to determine a build configuration. can anyone with any experience working with team city offer any advice as to what the problem may be? thanks.
<PropertyGroup>
<Env Condition="'$(Env)' == ''">dev</Env>
<VersionNumber Condition="'$(VersionNumber)' == ''">1</VersionNumber>
<MSBuildCommunityTasksPath>$(MSBuildThisFileDirectory)/Tasks</MSBuildCommunityTasksPath>
<UnityPath Condition="'$(UnityPath)' == ''">c:\Program Files (x86)\Unity</UnityPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Env)' == 'dev'">
<BuildConfig>Debug</BuildConfig>
<Domain>mmo.dystopiaOnline.dev</Domain>
<SetParamsFile>Parameters.Local.config</SetParamsFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Env)' == 'prod'">
<BuildConfig>Release</BuildConfig>
<Domain>mmo.DystopiaOnline.com</Domain>
<SetParamsFile>Parameters.Production.config</SetParamsFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Env)' == 'sta'">
<BuildConfig>Release</BuildConfig>
<Domain>mmo.DystopiaOnline.sta</Domain>
<SetParamsFile>Parameters.Staging.config</SetParamsFile>
</PropertyGroup>
TeamCity build log
[11:45:53]Checking for changes
[11:45:53]Collecting changes in 1 VCS root (1s)
[11:45:55]Clearing temporary directory: C:\TeamCity\buildAgent\temp\buildTmp
[11:45:55]Publishing internal artifacts
[11:45:55]Checkout directory: C:\TeamCity\buildAgent\work\8c8eb5050252f271
[11:45:55]Updating sources: server side checkout
[11:45:55]Step 1/1: MSBuild (4s)
[11:45:55][Step 1/1] Starting: C:\TeamCity\buildAgent\plugins\dotnetPlugin\bin\JetBrains.BuildServer.MsBuildBootstrap.exe /workdir:C:\TeamCity\buildAgent\work\8c8eb5050252f271 "/msbuildPath:C:\Program Files (x86)\MSBuild\12.0\bin\MSBuild.exe"
[11:45:55][Step 1/1] in directory: C:\TeamCity\buildAgent\work\8c8eb5050252f271
[11:45:59][Step 1/1] src\DystopiaOnline.proj.teamcity: Build target: BuildSolution
[11:45:59][src\DystopiaOnline.proj.teamcity] BuildSolution
[11:45:59][BuildSolution] MSBuild
[11:45:59][BuildSolution] C:\TeamCity\buildAgent\work\8c8eb5050252f271\src\DystopiaOnline.proj(36, 5): error MSB4062: The "DystopiaOnline.Build.Tasks.GetUnixTimestamp" task could not be loaded from the assembly C:\TeamCity\buildAgent\work\8c8eb5050252f271\src\DystopiaOnline.Build.Tasks/bin/Release/DystopiaOnline.Build.Tasks.dll. Could not load file or assembly 'file:///C:\TeamCity\buildAgent\work\8c8eb5050252f271\src\DystopiaOnline.Build.Tasks\bin\Release\DystopiaOnline.Build.Tasks.dll' or one of its dependencies. The system cannot find the file specified. Confirm that the <UsingTask> declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask.
[11:45:59][Step 1/1] Process exited with code 1
[11:45:59][Step 1/1] MSBuild output
[11:45:59][Step 1/1] Step MSBuild failed
[11:45:59]Publishing internal artifacts
[11:45:59]Build finished
This is how my project setup look witht the build folder.
link to .proj file on OneDrive
Error after copying release file into TeamCity manually
C:\Program Files (x86)\MSBuild\12.0\bin\Microsoft.Common.CurrentVersion.targets(3797, 5): error MSB3027: Could not copy "C:\TeamCity\buildAgent\work\8c8eb5050252f271\src\DystopiaOnline.Base\bin\Release\DystopiaOnline.Base.dll" to "bin\Release\DystopiaOnline.Base.dll". Exceeded retry count of 10. Failed.
C:\Program Files (x86)\MSBuild\12.0\bin\Microsoft.Common.CurrentVersion.targets(3797, 5): error MSB3021: Unable to copy file "C:\TeamCity\buildAgent\work\8c8eb5050252f271\src\DystopiaOnline.Base\bin\Release\DystopiaOnline.Base.dll" to "bin\Release\DystopiaOnline.Base.dll". The process cannot access the file 'bin\Release\DystopiaOnline.Base.dll' because it is being used by another process.
There is a typo in your DystopiaOnline.proj file in the word "Configuraton":
<MSBuild Projects="DystopiaOnline.Build.Tasks/DystopiaOnline.Build.Tasks.csproj" Properties="Configuraton=$(BuildConfig)" />
I think that this is the reason of the incorrect configuration building.
How have you setup the parameter in the build? It's most likely that it's value is not being passed to the build runner so it defaults to dev
<Env Condition="'$(Env)' == ''">dev</Env>
If you are using teamcity parameters it should be a system or environment parameter. You can also check the parameters used in a build by clicking on it and going to the parameters tabs, might want to double check that it has the value you want.
First keep in mind, that Windows path is '\' NOT '/'. In normal cases there is not any different (eg. when you want to put path in Explorer), but sometimes (I run in to some problems with some task in MsBuild) the mechanism doesn't recognize that this is proper path. So change the path to
<MSBuildCommunityTasksPath>$(MSBuildThisFileDirectory)\Tasks\</MSBuildCommunityTasksPath>
(Also MsBuild convention told us to put trailing slash)
And whenever you have reference to "DystopiaOnline.Build.Tasks.dll": [...]src\DystopiaOnline.Build.Tasks\bin\Release\DystopiaOnline.Build.Tasks.dll.
In the build log, there is not any sign that the MsBuild try to build the DystopiaOnline.Build.Tasks. HOW you specify the order of building your projects? Can you add this project that we can see exactly what MsBuild want to do and in what order.
If you use <UsingTask> inside the same project file that want to build DystopiaOnline.Build.Tasks... It will never work, because MsBuild first try to resolve task and then run targets to build.
It could work on your machine when you already build the project but not in clean environment when there is not (yet) any task.
try creating new system parameter called system.Configuration and set value "Release"

How to set LARGEADRESSAWARE in no signing assembly projects for a ClickOnce app?

I have an application with the next two Post-Compilation commands:
call editbin /LARGEADDRESSAWARE $(TargetPath)
call editbin /LARGEADDRESSAWARE $(ProjectDir)obj\$(PlatformName)\$(ConfigurationName)\$(TargetFileName)
and works fine.
But when I publish into a server as the ClickOne Application works with no errors but when I try install in a client the hash of file is different than the value calculated in the manifest.
I tryed to use the next command:
sn -Ra $(ProjectDir)obj\$(PlatformName)\$(ConfigurationName)\$(TargetFileName) PublicPrivateKeyFile.snk
but does not work and it shows the next message:
app.exe does not represent any strong-named assembly.
I suppose it's because all my projects has the "signing the assembly" option with false value. Before using LARGEADDRESSAWARE the ClickOnce Application worked fine.
It is necesary to set the "signing the assembly" option with true value for all projects or are there any way to use LARGEADDRESSAWARE with false value for this option?
EDIT:
Solution of Mark Sowul works fine:
Also I added in AfterBuild the next lines in order to check if the AfterCompile works fine
call "$(VS110COMNTOOLS)vsvars32.bat"
dumpbin /headers "$(TargetPath)" > "$(TargetPath).info"
findstr "(>2GB)" "$(TargetPath).info"
set BUID_ERRORLEVEL=%ERRORLEVEL%
del "$(TargetPath).info"
if [%BUID_ERRORLEVEL%]==[0] echo EXE program updated to use more than 2GB
if [%BUID_ERRORLEVEL%]==[1] echo ERROR: EXE PROGRAM WAS NOT UPDATED TO USE MORE THAN 2GB
set ERRORLEVEL=%BUID_ERRORLEVEL%
Post Build events are too late in the game. You have found this out to an extent, as I did, by realizing you need to alter the file in obj.
However, Post Build occurs after the manifest generation. So editing the obj file there is too late. The better place to do it is in the AfterCompile build target.
You'll have to edit the csproj; add after the lines you'll already see for this:
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
**<Target Name="AfterCompile">
<Exec Command="
call "$(VS110COMNTOOLS)\vsvars32.bat"
editbin /largeaddressaware "$(IntermediateOutputPath)$(TargetFileName)"
" />
</Target>**

Categories