ConfuserEx.exe in pre/ post build executing asynchronous in VS - visual-studio

I have an installer project that is generating .msi on build. In the pre-build event, I am calling Confuser.CLI.exe to obfuscate code, but exe is working asynchronous and taking too much time, and the compiler is finished before exe, so I have .msi with old DLLs and then when .msi is generated, new DLLs overwrite old ones. I even tried with the post-build event, but I get the same result.

Inside installer project - .wixproj, I put 2 targets that will execute different commands:
<Target Name="ConfuserExScript" AfterTargets="CopyReferencedProjects">
<Exec Command="Powershell.exe -executionpolicy remotesigned -File "$(SolutionDir)Installers\Scripts\Build\PostBuild_RunConfuserEx.ps1" "$(SolutionDir)\"" />
</Target>
<Target Condition=" '$(ConfigurationName)' == 'ReleaseDC' " Name="Obfuscator" AfterTargets="ConfuserExScript">
<Exec Command="$(SolutionDir)Installers\ConfuserEx\Confuser.CLI.exe $(ProjectDir)ConfuserOutput.crproj" />
</Target>
The first one is gathering DLLs and creating crproj file for ConfuserEx, the second one is running Confuser.CLI.exe and obfuscating code.
Important thing is that I use afterTargets so the second line is executed after the first one is finished.

Related

Post-Build event msbuild. Rename file at end of successful build

I don't know MSbuild scripting and don't have time to learn it right now. I need a method at the end of successful build to rename a dacpac file to include the version that is currently being built.
Example: (TfsDropLocation)\filename.dapac to (TfsDropLocation\filename.1.0.0.0.dacpac)
Is there a way to do this?
Is there a way to do this?
The answer is yes. If you don't mind editing the Visual Studio project file, then there is a simple solution that allows you to use a macro which looks like this:#(VersionNumber):
To accomplish this, unload your project. Then at the very end of the project, just before the end-tag, place below scripts:
<PropertyGroup>
<PostBuildEventDependsOn>
$(PostBuildEventDependsOn);
PostBuildMacros;
</PostBuildEventDependsOn>
</PropertyGroup>
<Target Name="PostBuildMacros">
<GetAssemblyIdentity AssemblyFiles="$(TargetPath)">
<Output TaskParameter="Assemblies" ItemName="Targets" />
</GetAssemblyIdentity>
<ItemGroup>
<VersionNumber Include="#(Targets->'%(Version)')"/>
</ItemGroup>
</Target>
Now as promised, the assembly version is available to your post build event with this macro. So you add rename the file name by copy task in the post-build event with below command line:
copy /Y "(TfsDropLocation)\filename.dapac" "(TfsDropLocation)\filename.#(VersionNumber).dapac"
If you do not want to keep the previous filename.dapac, you can add a del command in the post-build event:
del "(TfsDropLocation)\filename.dapac"
Note: Do not ignore double quotation marks in the post-build event command line.
Then you can check you output and windows explorer, I used the file dll to test, you can check my test result:

Determine whether it's a build or rebuild in .cmd script called in prelink step inside Visual Studio

How can a .cmd script run from within a Visual Studio (2005, 2008, 2010, 2012 and 2013 respectively) project's pre-link stage determine whether this is a full rebuild (Build.RebuildSolution/Build.RebuildOnlyProject) or "ordinary" build (Build.BuildSolution/Build.BuildOnlyProject)?
This is an external script (LuaJIT, if you must know) and I don't want to rebuild the library every single build of the project. Instead I'd like to limit the complete rebuild to situations where I choose exactly that option.
How can a .cmd script run from within a Visual Studio (2005, 2008, 2010, 2012 and 2013 respectively) project's pre-link stage determine whether this is a full rebuild ... or "ordinary" build ... ?
I do not know if the exact thing that you are asking can be done - perhaps someone else knows how to do it. I will, however, suggest an alternate approach.
My approach is to remove the build of the Lua library from the pre-link step to a separate Visual Studio NMake project. If you create an NMake project, you will be able to know which type of build (build or rebuild) is occurring.
Note that later versions of Visual Studio simply refer to the project type as "Make". For discussion purposes here, I will refer to the project type as "NMake". I believe this is just a naming difference, and that the underlying build project remains the same between the two versions.
As a simple test, I created two Visual Studio applications: 1) an NMake project that calls a batch file to create a static library, and 2) a console application that consumes the library from step 1.
The NMake Project
In Visual Studio, if you create a new NMake project, you will see a dialog that allows you to provide MS-DOS commands:
As you can see, there are commands for: Build, Clean, Rebuild, and others. I don't have a screen shot of the above dialog with my commands, but here is my NMake project's properties:
My Build command just checks for the existence of the output file (lua.lib). If it does not exist, then it calls the rebuild.bat batch file. My Rebuild command always calls the batch file. My Clean command just deletes the output. I am not really sure what the Output command is used for, but I just filled in the path to the build output (lua.lib).
Now if you do a build, the lua.lib file will only be created if it is not there. If it is already there, nothing is done. If you do a rebuild, then a new lua.lib file is created.
The Console Application
In my console application, I added a reference to the NMake project - this way the NMake project is built prior to the console application. Here is the console application's reference page:
I also added the lua.lib file as an input during the application's link stage:
When the console application is built (during a build), it will build the NMake project if needed, and use the output (lua.lib) during the linker stage. When the console application is rebuilt (during a rebuild), it will also rebuild the NMake project.
Other Thoughts
My screen shots above only show the debug version of the properties. Your projects will have to account for the release version. There probably is a VS macro to handle this, but I am not sure since it has been ages since I've done anything with C/ C++.
In my testing above I use a single build batch file for both the build and rebuild. Obviously, you could do the same or you could use different batch files.
It may be a bit of a hack, but in .csproj file there are sections
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
You can set an variable from BeforeBuild and retrieve it from cmd script. Later on reset this variable in AfterBuild and you should be good to go.
Ok, this is going to be a long one.
First of all - do not take my code 'as is' - it is terrible one with lots of hacks, I had no idea msbuild is so broken by default (it seems at work I have access to waaaay more commands that make life easier). And another thing - it seems vcxproj is broken at some poin - I was not able to integrate the way I wanted with only BeforeRebuild and AfterRebuild targets - I had to redefine hole Rebuild target (it is located in C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets)
So, the idea is the following: when a Rebuild is happening we create an anchor. Then, during PreLink stage we execute cmd which is able to use created anchor. If the anchor is in place - we deal with Rebuild, if there is no anchor - it is a simple Build. After Rebuild is done - we delete the anchor.
modifications in vcxproj file:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
....
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
....
<PreLinkEventUseInBuild>true</PreLinkEventUseInBuild>
....
</PropertyGroup>
....
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
.....
<PreLinkEvent>
<Command>D:\PreLink\b.cmd</Command>
</PreLinkEvent>
.....
</ItemDefinitionGroup>
.....
<Target Name="BeforeRebuild">
<Exec Command="echo 2 > D:\PreLink\2.txt" />
</Target>
<Target Name="AfterRebuild">
<Exec Command="del D:\PreLink\2.txt" />
</Target>
<!-- This was copied from MS file -->
<PropertyGroup>
<_ProjectDefaultTargets Condition="'$(MSBuildProjectDefaultTargets)' != ''">$(MSBuildProjectDefaultTargets)</_ProjectDefaultTargets>
<_ProjectDefaultTargets Condition="'$(MSBuildProjectDefaultTargets)' == ''">Build</_ProjectDefaultTargets>
<RebuildDependsOn>
BeforeRebuild;
Clean;
$(_ProjectDefaultTargets);
AfterRebuild;
</RebuildDependsOn>
<RebuildDependsOn Condition=" '$(MSBuildProjectDefaultTargets)' == 'Rebuild' " >
BeforeRebuild;
Clean;
Build;
AfterRebuild;
</RebuildDependsOn>
</PropertyGroup>
<Target
Name="Rebuild"
Condition=" '$(_InvalidConfigurationWarning)' != 'true' "
DependsOnTargets="$(RebuildDependsOn)"
Returns="$(TargetPath)"/>
<!-- End of copy -->
</Project>
And the cmd looks like this:
if exist 2.txt (
echo Rebuild818181
) else (
echo Build12312312
)
The output from Output window:
1>Task "Exec" (TaskId:41)
1> Task Parameter:Command=D:\PreLink\b.cmd
1> :VCEnd (TaskId:41)
1> Build12312312 (TaskId:41)
Things to improve:
Use normal variables instead of external file (it seems MsBuild extension pack should do it)
Probably find a way to override only BeforeRebuild and AfterRebuild instead of the hole Rebuild part
It is much easier. Just add the following target to your build file or visual Studio Project
<Target Name="AfterRebuild">
<Message Text="AFTER REBUILD" Importance="High" />
<!--
Do whatever Needs to be done on Rebuild - as the message shows in VS Output
window it is only executed when an explicit rebuild is triggered
-->
</Target>
If you want a two step solution use this as a template:
<PropertyGroup>
<IsRebuild>false</IsRebuild>
</PropertyGroup>
<Target Name="BeforeRebuild">
<Message Text="BEFORE REBUILD" Importance="High" />
<PropertyGroup>
<IsRebuild>true</IsRebuild>
</PropertyGroup>
</Target>
<Target Name="BeforeBuild">
<Message Text="BEFORE BUILD: IsRebuild: $(IsRebuild)" Importance="High" />
</Target>

Running test case files(tst) as part of MSbuild

I am using TFS 2010 and Visual Studio 2010. I have a build definition which points to my solution. The build runs overnight
I have a set of test case files(*.tst) and i would like my current build to include these as part of the build and to execute them overnight. The test case files are in source control
I read that i have to use MsTest.exe but unsure how to get started?
Can anyone point me please how i can get started on running the test case files as part of the build? Any examples please?
Thanks in advance,
There are several ways you can have your test cases run. One way is to add an invoke process or Exec Command to your build project file or workflow.
Place the call to mstest in the AfterBuild target or workflow step. The other way would be to separate out the build and test cases into different builds.
Here are a couple of links to get you started:
How to: Configure and Run Scheduled Tests After Building Your Application
Example of MSBuild with MSTest
*Based on your comments here is an update of something you can do to get more information about the error or to continue if you encounter an error. You do not need to check for the error code if you just want to stop on any error but if you do want to check the error code then you would do something like this:
<Target Name="AfterBuild">
<Message Text="Running tests..." />
<PropertyGroup Label="TestSuccessOrNot">
<TestSuccessOrNot>5</TestSuccessOrNot>
</PropertyGroup>
<!-- Run MSTest exe-->
<Exec Command="cd ." IgnoreExitCode="False" ContinueOnError="ErrorAndContinue">
<Output TaskParameter="ExitCode" PropertyName="TestSuccessOrNot" />
</Exec>
<Message Text="ExitCode = $(TestSuccessOrNot)" />
<Error Condition="'$(TestSuccessOrNot)' != '0'" Text="Unit tests fail!" /> </Target>

Visual Studio setup project prebuild event

I have a Visual Studio Setup project where some of the deployed files are created by a pre-build event. However, when I build the project Visual Studio first does pre-build validation and then runs the pre-build event. Thus pre-build validation fails, with the error message "ERROR: Unable to find file ...".
Does anyone know a work-around for this?
(The details may not matter, but it is a Windows Installer for a Python app. The pre-build event calls PyInstaller which packages the py files as a single exe file. This exe file and some DLL's and resource files are then packaged by the Setup project as a Windows Installer.)
You must be able to use MSBuild Targets instead of a Prebuild Event. I am not sure about the specifics, but I guess the following link might explain your similar situation.
Edited - July 2017 (due to relocated link):
http://pradeepc.net/using-tfs-teambuild-to-build-setup-projects-in-visual-studio
Sample copied from that link is pasted below - you may want to edit to fit the need:
<Target Name="AfterDropBuild">
<Exec Command="devenv.exe MySolution.sln /Build &quot;Release|Any CPU&quot;" WorkingDirectory="$(SolutionRoot)" />
<ItemGroup>
<SetupFiles Include="$(SolutionRoot)/MySetup/Release/MySetup.msi" />
<SetupFiles Include="$(SolutionRoot)/MySetup/Release/Setup.exe" />
</ItemGroup>
<Copy SourceFiles="#(SetupFiles)" DestinationFolder="\Build-MachineBuild_Drop_FoldersMyProjectMSI$(BuildNumber)" />
<Copy SourceFiles="#(SetupFiles)" DestinationFolder="\Build-MachineBuild_Drop_FoldersMyProjectMSILatest_MSI" />
</Target>

run MsBuild tasks (targets?) after the solution is built?

Since this question seems to have baffled / underwhelmed SO I will rephrase it with a partially formed idea of my own.
Could I somehow set up a batch file or something that runs after the whole solution is built, and this batch file would call msbuild to build specific targets inside a certain project? In order for it to work, I would have to somehow force msbuild build the target without regard to whether it thinks it's "up to date", because that is the core issue I'm butting up against.
Since you are dealing with building specifically you may want to replace your batch file with an MSBuild file. For example:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<SolutionsToBuild Include="MySolution.sln"/>
<Projects Include="Proj1.csproj"/>
<Projects Include="Proj2.csproj"/>
<Projects Include="Proj3.csproj"/>
</ItemGroup>
<Target Name="BuildAll">
<!-- Just executes the DefaultTargets (Build) -->
<MSBuild Projects="#(SolutionsToBuild)"/>
<!-- Call Rebuild if you think its not building correctly -->
<MSBuild Projects="#(Projects)"
Targets="Rebuild"/>
</Target>
</Project>
Then you just invoke msbuild.exe on this file with:
msbuild.exe Build.proj /t:BuildAll
Since you said that you want to build specific projects after the solution is built just put those into the Projects ItemGroup as shown and use the MSBuild task to build them after the solution has been built. I've specified the Rebuild target to make sure you get a clean build.

Resources