Use of automated build system cause multiple problems (Azure DevOps, CC.NET, etc.)

Add-in Express™ Support Service
That's what is more important than anything else

Use of automated build system cause multiple problems (Azure DevOps, CC.NET, etc.)
Using an automated build system compared to the local dev env causes varies inconsistences and other problems in regards to enterprise development 
Jochen Kirst?tter


Guest


Hi ADX team,

(edited as the forum eats backslashes...)

First and foremost, great product and I love using it since several years in various projects.

Recently, I was tasked by one of those client to develop an Outlook add-in. Due to VS2022, Windows 11 and Office 2021 64-bit as well as Microsoft 365, we are using the latest ADX version 10.1.4703.0 (thanks for fixing the setup BTW).

Given their company wide constraint that anything developed has to be build by an automated build process prior to testing or release we ran into several issues with your product. The implementation of the add-in is fairly simple however the head scratching came afterwards.

But let me elaborate a little bit first.
In my local development environment using latest Visual Studio 2022 and an installed Add-in Express for Microsoft Office and .NET they compiled output in the TargetDir is as expected. Meaning that the Loader\adxloader*.* files are updated based on the attribute values in the AssemblyInfo.cs file of the project, and copied into the TargetDir.


[assembly: AssemblyVersion("2022.4.25.1")
[assembly: AssemblyTitle("Acme Ltd.")
[assembly: AssemblyProduct("Awesome Outlook Add-in")
[assembly: AssemblyCopyright("Copyright 2022 Acme")


Note: Other assembly attributes are ignored, hence skipped above. We tried AssemblyFileVersion, AssemblyInformationalVersion, AssemblyCompany, AssemblyDescription, etc. Those four are the essential ones.

Hitting F6 or Build Solution in VS2022 updates the Loader\adxloader*.* files and those appear in the TargetDir of the build configuration. All good.

However, and now the fun starts, we noticed using our automated build system that the "Product version" shown in the Details tab of the file properties remains 0.0.0.0 despite us injecting / updating the value of AssemblyVersion dynamically at the very beginning of the automated build process. Our own assembly (TargetFileName) has the expected version information but not the adxloader*.dll files.

Doing a little (re-)search here in the forum I came across the suggestion that adxpatch.exe should be used to patch the ProductVersion into the final adxloader*.dll - great, let's do that. Well, despite the successful execution of the command in the post-build event of our project there are two small problems.


  <Target Name="PostBuildMacros">
    <GetAssemblyIdentity AssemblyFiles="$(TargetPath)">
      <Output TaskParameter="Assemblies" ItemName="Targets" />
    </GetAssemblyIdentity>
    <ItemGroup>
      <VersionNumber Include="@(Targets->'%(Version)')" />
    </ItemGroup>
  </Target>

  <PropertyGroup>
    <PostBuildEventDependsOn>
		  $(PostBuildEventDependsOn);
		  PostBuildMacros;
	  </PostBuildEventDependsOn>
    <PostBuildEvent>copy /Y $(ProjectDir)Loader\*.* $(TargetDir)

echo AdxLoader DLLs patchen:
"$(TargetDir)adxpatch.exe" "$(TargetDir)adxloader.dll" /ProductVersion=@(VersionNumber)
"$(TargetDir)adxpatch.exe" "$(TargetDir)adxloader64.dll" /ProductVersion=@(VersionNumber)
del "$(TargetDir)adxpatch.exe"

echo Add-in registrieren, Protokoll: $(TargetDir)adxregistrator.log
"$(TargetDir)adxregistrator.exe" /install="$(TargetPath)" /privileges=user /ReturnExitCode=true /generateLogFile=true /logFileLocation="$(TargetDir)"
    </PostBuildEvent>
  </PropertyGroup>

Note: Getting the Targets->Version in a post-build event was found here in the forum.

First, in the build pipeline the adxloader*.dll files are not updated with the Assembly* attributes defined in the AssemblyInfo.cs file of the project and they are not copied into the TargetDir folder. Fine, let's add the copy command to do it manually. Which BTW is also the suggested solution found in several threads here in the forum.

But second, and more severe is the situation that patching those TargetDir\adxloader*.dll after copying sets the Product version as expected but removes the other three attributes and corrupts the resource file. When you open that patched DLL in VS2022 to inspect it you are greeted with an info message


---------------------------
Microsoft Visual Studio
---------------------------
This resource data appears to be corrupted, and will be opened in the binary editor.
---------------------------
OK
---------------------------


compared to the original adxloader*.dll still residing below the Loader folder. Again, this has been mentioned already in another thread here in the forum (referring ADX version 8.x if I remember correctly). The answer from ADX was that this has been addressed and fixed. Unfortunately, this is not the case or it's a regression error.

This can be reproduced stand-alone without an automated build system.

\bin\Debug> .\adxpatch.exe .\adxloader.dll /ProductVersion=2022.4.25.0
Change file version action: The version of file is set to '2022.4.25.0'.


Important: The existing Product version in the source adxloader*.dll must be different from the target version.

Those are the most urgent two problems
- Producing up-to-date adxloader*.dll assemblies
- Keeping the assembly attributes when using adxpatch.exe

Note: The build host environment to build the sources is sealed by another team and cannot be modified by me or other developers.

It would be pleasant to have your input on that.
Are we doing something wrong?
Is there a different way or solution?
How can we realize a fully automated compilation of an ADX add-in?

Of course, if you are interested in more details and some live action I can add you to a staging system running on Azure DevOps. The build logs and produced artifact drops have all the details.

Looking forward to your response and ideas.

Best regards, Jochen
Microsoft MVP - Developer Technologies
Google Developer Expert - Google Cloud



----

In the long run, considering New Year ;-) among others, when and how will it be possible to generate / compile the adxloader assemblies in an automated build process using all four attributes specified in the AssemblyInfo.cs? Speaking of New Year our build system automatically changes the copyright year. Or for any other reason, ie. customatized deployments, we want to inject variable values for AssemblyTitle, AssemblyProduct, and AssemblyCopyright.

How and when are those Loader\adxloader*.dll files generated or patched? OK, those files created during the creation of the ADX COM Add-in project (given the timestamp of 24.03.2022) but those three values based on the assembly attributes are blank. On compilation in Visual Studio those values are set / patched with the information provided in the AssemblyInfo.cs. And those files are also updated each time that the AssemblyInfo.cs file has been changed.

However, binaries usually shall not be added / checked in / pushed to version control in my general understanding. But obviously there are exceptions to the golden rule. ;-) And we need those DLLs in the Loader folder to the automated build.

I assume that you are currently using an event handler or hook in AddinExpress.MSO.2005 assembly, probably ADXAddinModule type, to instruct Visual Studio to patch those Loader\adxloader*.* files. Right now, as my colleague calls it, "it's a kind of magic". ;-)

Only that that magic doesn't work outside a full, local development environment. Actually, it even doesn't work on another machine using Visual Studio without having Add-in Express for Office and .NET installed.
Posted 25 Apr, 2022 14:31:06 Top
Andrei Smolin


Add-in Express team


Posts: 18829
Joined: 2006-05-11
Hello Jochen,

There's an Add-in Express package that Visual Studio loads; it performs some of the functionality that adxpatch.exe provides. I have an impression that for some reason the package doesn't work in your case.

Jochen Kirst?tter writes:
But second, and more severe is the situation that patching those TargetDir\adxloader*.dll after copying sets the Product version as expected but removes the other three attributes and corrupts the resource file. When you open that patched DLL in VS2022 to inspect it you are greeted with an info message


It looks like this is a bug in the code of Add-in Express. We are looking into the code trying to fix the bug. There's no workaround as far as I can see.

Jochen Kirst?tter writes:
but those three values based on the assembly attributes are blank


Alas, adxpatch only supports the file version.

Jochen Kirst?tter writes:
However, binaries usually shall not be added / checked in / pushed to version control in my general understanding. But obviously there are exceptions to the golden rule. ;-) And we need those DLLs in the Loader folder to the automated build.


You could copy loaders from {Add-in Express installation folder}\Redistributables before building the project.

Jochen Kirst?tter writes:
I assume that you are currently using an event handler or hook in AddinExpress.MSO.2005 assembly, probably ADXAddinModule type, to instruct Visual Studio to patch those Loader\adxloader*.* files. Right now, as my colleague calls it, "it's a kind of magic". ;-)


This is done by the package loaded in your Visual Studio.

Jochen Kirst?tter writes:
Only that that magic doesn't work outside a full, local development environment. Actually, it even doesn't work on another machine using Visual Studio without having Add-in Express for Office and .NET installed.


You can copy the Add-in Express installation folder to your build server and use adxpatch.

Regards from Poland (CEST),

Andrei Smolin
Add-in Express Team Leader
Posted 27 Apr, 2022 09:03:47 Top
Jochen Kirst?tter


Guest


Hello Andrei,

Many thanks providing feedback on this matter.

Andrei Smolin writes:
It looks like this is a bug in the code of Add-in Express. We are looking into the code trying to fix the bug. There's no workaround as far as I can see.


Yes, that is also our impression based on the described observation.
You compile the project in VS2022 with installed ADX and the generated/patched adxloader.dll in the Loader folder as well as in the $(TargetDir) has the Assembly attributes as expected. If you now use adxpatch.exe to change the ProductVersion the values of 'File description', 'Product name' and 'Copyright' get erased.

Andrei Smolin writes:
You could copy loaders from {Add-in Express installation folder}\Redistributables before building the project.


We had a look at those but won't do any good as those are product-neutral and have not the values of our product according to the AssemblyInfo.cs.

Best outcome at the moment would be that adxpatch sets the ProductVersion as described but doesn't blank the other three values and doesn't corrupt the resources of the DLL. That would be a feasible workaround for us at the moment.

Andrei Smolin writes:
You can copy the Add-in Express installation folder to your build server and use adxpatch.


Yes, thanks for confirmation. That's exactly what we did.
We committed the following folders into TFS/git


  • Loader (as part of the project)
  • Bin
  • Redistributables
  • GAC_MSIL (from Windows folder)


However, with the broken adxpatch we have to leave out the 'Product version' for the moment. Which is not satisfying after all and we hope that you and your team is working on a timely fix to this issue.

Let me know if you'd be interested in further information, access to my staging repository on Azure DevOps, the build pipeline or any screenshots to document or demonstrate the current behaviour and expected outcome.

Thanks so far, and looking forward to your feedback.

Best regards, Jochen
Microsoft MVP - Developer Technologies
Google Developer Expert - Google Cloud

PS: This forum thread is sufficient or would you like me to open a support ticket on that matter?
Posted 27 Apr, 2022 13:46:34 Top
Markus Winhard


Guest


Hello Andrej,

I'm the responsible programmer at Jochen's customer.

In the meantime we have found out that AdxPatch will not satisfy our needs, even if you fix it.

Instead we need a way to call the "magic" on our build server, e.g. in the Post Build event. Or from some script after a successful build.

"Magic" is my word for the fact that Visual Studio applies the Assemblyinfo.cs settings to AdxLoader.dll and AdxLoader64.dll after a build.

And, I'm sorry to say, we need this timely. Clients are waiting. Company rules say that we are only allowed to deliver to our clients what comes from the build server. Manual patching is not allowed. So please tell me, what I have to call on our build server to make this work.

Thank you very much in advance,

Markus
Posted 29 Apr, 2022 09:37:01 Top
Andrei Smolin


Add-in Express team


Posts: 18829
Joined: 2006-05-11
Hello Markus,

We will start working on it tomorrow. We will make adxpatch to update these fields. Once I have the fixed version, I'll send it to you for testing.

Hello Jochen,

Jochen Kirst?tter writes:
PS: This forum thread is sufficient or would you like me to open a support ticket on that matter?


The thread is okay.

Regards from Poland (CEST),

Andrei Smolin
Add-in Express Team Leader
Posted 03 May, 2022 04:46:50 Top
Andrei Smolin


Add-in Express team


Posts: 18829
Joined: 2006-05-11
Hello guys,

We've found out that adxpatch.exe does not clear those fields. It looks like you *always* copy adxloader.dll and adxloader64.dll from the Add-in Express installation folder and then use adxpatch to fix the version. Instead, you can build your project - the fields will be filled after that - and then use adxpatch to fix the version when required.

Regards from Poland (CEST),

Andrei Smolin
Add-in Express Team Leader
Posted 05 May, 2022 05:05:38 Top