eXpandFramework / eXpand

DevExpress XAF (eXpressApp) extension framework. 𝗹𝗶𝗻𝗸𝗲𝗱𝗶𝗻.𝗲𝘅𝗽𝗮𝗻𝗱𝗳𝗿𝗮𝗺𝗲𝘄𝗼𝗿𝗸.𝗰𝗼𝗺, 𝘆𝗼𝘂𝘁𝘂𝗯𝗲.𝗲𝘅𝗽𝗮𝗻𝗱𝗳𝗿𝗮𝗺𝗲𝘄𝗼𝗿𝗸.𝗰𝗼𝗺 and 𝘁𝘄𝗶𝘁𝘁𝗲𝗿 @𝗲𝘅𝗽𝗮𝗻𝗱𝗳𝗿𝗮𝗺𝗲𝘄𝗼𝗿𝗸 and or simply 𝗦𝘁𝗮𝗿/𝘄𝗮𝘁𝗰𝗵 this repository and get notified from 𝗚𝗶𝘁𝗛𝘂𝗯
http://expand.expandframework.com
Microsoft Public License
220 stars 114 forks source link

Build problems VersionConverter #380

Closed CWolffIF closed 5 years ago

CWolffIF commented 5 years ago

Hi,

I got often Errors building my project, cause the VersionConvertrer is used by another process. The VersionConverter is installed in every Sub-Project (Module, Module-Win, Win). Is this correct?

C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.11\build\Xpand.VersionConverter.targets(4,9): error : New-Object : Ausnahme beim Aufrufen von ".ctor" mit 2 Argument(en): "Der Prozess kann nicht auf die Datei 2>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.11\build\Xpand.VersionConverter.targets(4,9): error : "C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.11\build\Xpand.snk" zugreifen, da sie von einem anderen 2>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.11\build\Xpand.VersionConverter.targets(4,9): error : Prozess verwendet wird." 2>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.11\build\Xpand.VersionConverter.targets(4,9): error : In C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.11\build\Xpand.VersionConverter.ps1:108 Zeichen:18

2>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.11\build\Xpand.VersionConverter.targets(4,9): error : + ... $f = New-Object FileStream("$root\Xpand.snk", [FileMode]::Open ... 2>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.11\build\Xpand.VersionConverter.targets(4,9): error : + ~~~~~~~~~~~~~ 2>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.11\build\Xpand.VersionConverter.targets(4,9): error : + CategoryInfo : InvalidOperation: (:) [New-Object], MethodInvocationException 2>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.11\build\Xpand.VersionConverter.targets(4,9): error : + FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand 2>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.11\build\Xpand.VersionConverter.targets(4,9): error :
2>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.11\build\Xpand.VersionConverter.targets(4,9): error MSB3073: Der Befehl "powershell.exe –NonInteractive –ExecutionPolicy Unrestricted –command "& { &'C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.11\build\Xpand.VersionConverter.ps1' 'C:\DevProjects\iXISJH\iXISXRM\iXISXRM.Module\iXISXRM.Module.csproj' 'C:\DevProjects\iXISJH\iXISXRM\iXISXRM.Module\bin\Debug\' } "" wurde mit dem Code 1 beendet.

apobekiaris commented 5 years ago

my bad the regex test only if found and returns bool not the actual name of the assembly. Please replace $dxReference=$include -imatch 'DevExpress[^,]*' with

$dxReference=[Regex].Match($include, "DevExpress[^,]*", [RegexOptions]::IgnoreCase).Value
CWolffIF commented 5 years ago

[Regex].Match is not known. Fehler beim Aufrufen der Methode, da [System.RuntimeType] keine Methode mit dem Namen "Match" enthält.

apobekiaris commented 5 years ago
$dxReference=[Regex]::Match($include, "DevExpress[^,]*", [RegexOptions]::IgnoreCase).Value
CWolffIF commented 5 years ago

sorry I should have see it

CWolffIF commented 5 years ago

OK - super it works

apobekiaris commented 5 years ago

meaning no build errors? patching messages ok? did you run the project?

CWolffIF commented 5 years ago

After more-times compiling I got the following messages

5> AUSFÜHRLICH: DevExpress.ExpressApp.v18.2 version will changed from 18.2.7.0 to 18.2.7.0 5> AUSFÜHRLICH: Patching

and an error

C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.18\build\Xpand.VersionConverter.targets(4,9): error : Ausnahme beim Aufrufen von "ReleaseMutex" mit 0 Argument(en): "Die Objektsynchronisationsmethode wurde von einem 4>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.18\build\Xpand.VersionConverter.targets(4,9): error : nicht synchronisierten Codeblock aufgerufen." 4>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.18\build\Xpand.VersionConverter.targets(4,9): error : In C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.18\build\Xpand.VersionConverter.ps1:206 Zeichen:5 4>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.18\build\Xpand.VersionConverter.targets(4,9): error : + $mtx.ReleaseMutex() 4>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.18\build\Xpand.VersionConverter.targets(4,9): error : + ~~~~~~~ 4>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.18\build\Xpand.VersionConverter.targets(4,9): error : + CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException 4>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.18\build\Xpand.VersionConverter.targets(4,9): error : + FullyQualifiedErrorId : ApplicationException 4>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.18\build\Xpand.VersionConverter.targets(4,9): error :
4>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.18\build\Xpand.VersionConverter.targets(4,9): error MSB3073: Der Befehl "powershell.exe –NonInteractive –ExecutionPolicy Unrestricted –command "& { &'C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.18\build\Xpand.VersionConverter.ps1' 'C:\DevProjects\iXISJH\iXISXRM\iXISFramework.Module.Win\iXISFramework.Module.Win.csproj' 'C:\DevProjects\iXISJH\iXISXRM\iXISFramework.Module.Win\bin\Debug\' } "" wurde mit dem Code 1 beendet.

Doing it not parallel works.

apobekiaris commented 5 years ago

it still bites eh?

can u please test this idea:

replace

try {
    $mtx = [Mutex]::OpenExisting("VersionConverterMutex")
}
catch {
    $mtx = [Mutex]::new($true, "VersionConverterMutex")
}

with


 $mtx = [Mutex]::new($true, "VersionConverterMutex")

make sure the previous modifications are still in place.

CWolffIF commented 5 years ago

Yeah,

wait I have one test.

apobekiaris commented 5 years ago

or if there is a way i can repro this in my side it would speed things up for sure.

CWolffIF commented 5 years ago

Wait, I have an Phoneconference and after that I will test it.

CWolffIF commented 5 years ago

If I try it with one parallel Build it works.

With more than one parallel Build: First Error: Reactive.dll is allready in use Second Error (maybe as result): ReleaseMutex

By the way: F.e. ModelViewInheritance Module is as Nuget installed in the projects

is this correct?

C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.18\build\Xpand.VersionConverter.targets(4,9): error : Ausnahme beim Aufrufen von "ReadModule" mit 2 Argument(en): "Der Prozess kann nicht auf die Datei 4>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.18\build\Xpand.VersionConverter.targets(4,9): error : "C:\DevProjects\NuGetPackages\Xpand.XAF.Modules.Reactive.1.2.19\lib\net4.6.1\Xpand.XAF.Modules.Reactive.dll" 4>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.18\build\Xpand.VersionConverter.targets(4,9): error : zugreifen, da sie von einem anderen Prozess verwendet wird." 4>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.18\build\Xpand.VersionConverter.targets(4,9): error : In C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.18\build\Xpand.VersionConverter.ps1:51 Zeichen:5 4>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.18\build\Xpand.VersionConverter.targets(4,9): error : + [ModuleDefinition]::ReadModule($path, $readerParams).Assembly 4>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.18\build\Xpand.VersionConverter.targets(4,9): error : + ~~~~~~~~~~~~~ 4>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.18\build\Xpand.VersionConverter.targets(4,9): error : + CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException 4>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.18\build\Xpand.VersionConverter.targets(4,9): error : + FullyQualifiedErrorId : IOException 4>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.18\build\Xpand.VersionConverter.targets(4,9): error :
4>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.18\build\Xpand.VersionConverter.targets(4,9): error MSB3073: Der Befehl "powershell.exe –NonInteractive –ExecutionPolicy Unrestricted –command "& { &'C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.18\build\Xpand.VersionConverter.ps1' 'C:\DevProjects\iXISJH\iXISXRM\iXISFramework.Module.Win\iXISFramework.Module.Win.csproj' 'C:\DevProjects\iXISJH\iXISXRM\iXISFramework.Module.Win\bin\Debug\' } "" wurde mit dem Code 1 beendet.

CWolffIF commented 5 years ago

Hi,

in my solution I have 2 agnostic projects. I only installed the Xpand.XAF.... in the agnostic projects, even if NugetManagement want them to install in the other projects I removed them. So the solution is:

And everything compiled with 8 parallel Builds.

CWolffIF commented 5 years ago

Ok it compiled but the project didn´t run anymore.

apobekiaris commented 5 years ago

By the way: F.e. ModelViewInheritance Module is as Nuget installed in the projects

it doesn't matter these are XAF modules u may install them everywhere if you want to access their api else go for th agnostic.

even if NugetManagement want them to install in the other projects not following Nuget package managment does not make suggestions

Again do u think you could share in private or here a repro sample?

CWolffIF commented 5 years ago

Hi,

I started with the VideoRental Demo and added Xpand.XAF.

First Compiled: Error => Can´t find DevExpress Versions (cause bin\debug is empty)

Copy one DevExpress* in the bin\debug => Compiled with one parallel build

Compile with 8 parallel build =>OK

Compile new => Can´t find DevExpress Versions (cause bin\debug is empty)

XVideoRental.zip

apobekiaris commented 5 years ago

at the moment the lab does not contain the patches of our discussion, wait a bit i will prepare a build

CWolffIF commented 5 years ago

OK, no problem. With 1 parallel build it works.

expand commented 5 years ago

The DevExpress.XAF repository includes commit Improve Dx verions detection algorithm #380 that relate to this task. Please update the related Nuget packages and test if issues is addressed. These are nightly nuget packages available only from our NugetServer.

Thanks a lot for your contribution.

apobekiaris commented 5 years ago

this is only fro DevExpress.XAF the main build notification is coming

CWolffIF commented 5 years ago

Hi Tolis,

one more thing. In line 108 if ($dxReference.Version -ne $dxVersion) is always true. Cause in the right $dxVersion there one empty space more. You can see it in Write-Verbose "$($.Name) version will changed from $($.Version) to $($dxVersion)" AUSFÜHRLICH: DevExpress.ExpressApp.v18.2 version will changed from 18.2.7.0 to 18.2.7.0 AUSFÜHRLICH: Patching

apobekiaris commented 5 years ago

oops forgot to metnion that https://github.com/eXpandFramework/eXpand.lab/releases/tag/19.1.200.2 contains all previuos patches except your last comment

apobekiaris commented 5 years ago

I also wanted to ask if its ok i add you as collaborator to eXpandFramework I can lock this lenghty ticket for others (collabs have permission to edit)

CWolffIF commented 5 years ago

Sure it´s OK

apobekiaris commented 5 years ago

Hi Tolis,

one more thing. In line 108 if ($dxReference.Version -ne $dxVersion) is always true. Cause in the right $dxVersion there one empty space more. You can see it in Write-Verbose "$($.Name) version will changed from $($.Version) to $($dxVersion)" AUSFÜHRLICH: DevExpress.ExpressApp.v18.2 version will changed from 18.2.7.0 to 18.2.7.0 AUSFÜHRLICH: Patching

I am not sure why powershell treat that as an array but here the fix

$dxVersion = Get-DevExpressVersion $targetPath $referenceFilter $dxReferences|Where-Object{$_}|Select-Object -First 1

in addition to hide the True replace

$moduleReferences.Remove($dxReference)

with

$moduleReferences.Remove($dxReference)|Out-Null
apobekiaris commented 5 years ago

however I do not have a clear picture here as to what is the state of this issue? Let me know please when you are on to it.

expand commented 5 years ago

The DevExpress.XAF repository includes commit VersionConverter: patching happens even if versions match #380 that relate to this task. Please update the related Nuget packages and test if issues is addressed. These are nightly nuget packages available only from our NugetServer.

Thanks a lot for your contribution.

apobekiaris commented 5 years ago

eXpand.lab release 19.1.200.4 includes commit Update Xpand.XAF.Modules #380 that relate to this task. Please test if it addresses the problem. If you use nuget add our LAB NugetServer as a nuget package source in VS.

Thanks a lot for your contribution.

CWolffIF commented 5 years ago

Hi,

I tested it with 8 parallel builds. It works, but there was nothing to patch. I will test it in the evening with patches set true.

apobekiaris commented 5 years ago

thnks waiting for your input so I can push to nuget.

btw when I added u as collaborator GitHUb automatically subscribed u to all notifications, please feel free to unsubscribe if u wish as so many notifications could be overwhelming.

CWolffIF commented 5 years ago

Hi Tolis,

sorry for delay. I tested it with the adaption

Write-Verbose "Versions ($($dxReference.Version)) matched nothing to do. But...." $needPatching = $true

so that patching is needed. I hpe this is agequate for testing.

I cleared all caches, deleted all obj/bin and rebuild big projects more times with parallel builds set to 8.

It works.

apobekiaris commented 5 years ago

thanks a lot for the update!, I ll lock this thread now and push to the official

CWolffIF commented 5 years ago

Hi Tolis,

aaargh, after testing it the whole morning I got the error sometimes(!) back. But only if I set parallel builds >1. I always patched the same project. If I got the error and I set the parallel builds to 1 everything works.

3> AUSFÜHRLICH: Versions (18.2.7.0) matched nothing to do. 3> AUSFÜHRLICH: Patching 3> C:\DevProjects\NuGetPackages\Xpand.XAF.Modules.ViewEditMode.1.2.21\lib\net4.6.1\Xpand.XAF.Modules.ViewEditMode.dll 3>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.20\build\Xpand.VersionConverter.targets(4,9): error : Ausnahme beim Aufrufen von "ReleaseMutex" mit 0 Argument(en): "Die Objektsynchronisationsmethode wurde von einem 3>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.20\build\Xpand.VersionConverter.targets(4,9): error : nicht synchronisierten Codeblock aufgerufen." 3>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.20\build\Xpand.VersionConverter.targets(4,9): error : In C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.20\build\Xpand.VersionConverter.ps1:198 Zeichen:5 3>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.20\build\Xpand.VersionConverter.targets(4,9): error : + $mtx.ReleaseMutex() 3>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.20\build\Xpand.VersionConverter.targets(4,9): error : + ~~~~~~~ 3>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.20\build\Xpand.VersionConverter.targets(4,9): error : + CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException 3>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.20\build\Xpand.VersionConverter.targets(4,9): error : + FullyQualifiedErrorId : ApplicationException 3>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.20\build\Xpand.VersionConverter.targets(4,9): error :
3>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.20\build\Xpand.VersionConverter.targets(4,9): error MSB3073: Der Befehl "powershell.exe –NonInteractive –ExecutionPolicy Unrestricted –command "& { &'C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.20\build\Xpand.VersionConverter.ps1' 'C:\DevProjects\iXISJH\iXISXRM\iXISXRM.Module\iXISXRM.Module.csproj' 'C:\DevProjects\iXISJH\iXISXRM\iXISXRM.Module\bin\Debug\' } "" wurde mit dem Code 1 beendet.

CWolffIF commented 5 years ago

There is a strange thing.

I get the error even if there is nothing to patch.

10> AUSFÜHRLICH: Versions (18.2.7.0) matched nothing to do.

apobekiaris commented 5 years ago

can you try this approach instead please.

Replace this at the bottom of the file

finally {
    $mtx.ReleaseMutex()
    $mtx.Dispose()
}

with

finally {
    try {
        $mtx.ReleaseMutex()
        $mtx.Dispose()
    }
    catch {

    }
}
CWolffIF commented 5 years ago

I tested it after clearing all caches (and killed bin/obj folders) after every test. The "ReleaseMutex" Error disappeared.

But look at the Testseries......

  1. Test: Something to patch 1.1. 8 Parallel Builds: ERROR 1.2. 1 Parallel Build: OK

  2. Test: Nothing to patch 2.1. 8 Parallel Builds: ERROR 2.2. 1 Parallel Build: OK

  3. Test: The project was already build => Rebuild project, there is nothing to patch 3.1. 8 Parallel Builds: OK

  4. Test: The project was already build => Rebuild project, there is something to patch 4.1. 8 Parallel Builds: OK

  5. Test: Menu: Project Clear and then Build Project, there is nothing to patch 5.1. 8 Parallel Builds: ERROR 5.2. 1 Parallel Build: OK

If I think about this Testseries and especially Test 5. Maybe there is no problem with patching rather than with copying of the files? The files (f.e. ModelViewInheritance.dll) must be copied to the destination folder (local copy) and in the parallel build mode the powershellscript has to open the file? In 5.2. there are no parallel builds, so copying and opening the file can not be a conflict?

C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.20\build\Xpand.VersionConverter.targets(4,9): error : Ausnahme beim Aufrufen von "ReadModule" mit 2 Argument(en): "Der Prozess kann nicht auf die Datei "C:\DevProjects\NuGe 9>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.20\build\Xpand.VersionConverter.targets(4,9): error : tPackages\Xpand.XAF.Modules.ModelViewInheritance.1.1.17\lib\net4.5.2\Xpand.XAF.Modules.ModelViewInheritance.dll" 9>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.20\build\Xpand.VersionConverter.targets(4,9): error : zugreifen, da sie von einem anderen Prozess verwendet wird." 9>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.20\build\Xpand.VersionConverter.targets(4,9): error : In C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.20\build\Xpand.VersionConverter.ps1:51 Zeichen:5 9>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.20\build\Xpand.VersionConverter.targets(4,9): error : + [ModuleDefinition]::ReadModule($path, $readerParams).Assembly 9>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.20\build\Xpand.VersionConverter.targets(4,9): error : + ~~~~~~~~~~~~~ 9>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.20\build\Xpand.VersionConverter.targets(4,9): error : + CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException 9>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.20\build\Xpand.VersionConverter.targets(4,9): error : + FullyQualifiedErrorId : IOException 9>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.20\build\Xpand.VersionConverter.targets(4,9): error :
9>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.20\build\Xpand.VersionConverter.targets(4,9): error MSB3073: Der Befehl "powershell.exe –NonInteractive –ExecutionPolicy Unrestricted –command "& { &'C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.20\build\Xpand.VersionConverter.ps1' 'C:\DevProjects\iXISJH\iXISXRM\iXISXRM.Module\iXISXRM.Module.csproj' 'C:\DevProjects\iXISJH\iXISXRM\iXISXRM.Module\bin\Debug\' } "" wurde mit dem Code 1 beendet.

apobekiaris commented 5 years ago

we are going circles, can you prepare an empty solution simulating your current structure and install the XPand.XAF.Modules u have in your solution? There is no need to add any filess just register the Xpand.XAF.Modules in the ctor. This most probably will fail and I can debug it on my side.

apobekiaris commented 5 years ago

I also happy to open a remote connection with u as this a special case and debug it on your side.

apobekiaris commented 5 years ago

though i believe that an empty solution is by far more productive as my system is setup to my needs and will spare both our time.

apobekiaris commented 5 years ago

I would like to spent some time researching if we could use Roslyn to patch the version instead of scripts over msbuild events. The pros of that option are that we most probably avoid any kind of lockings, as the Rosloyn provides a virtual compilation before the actual compilation. The cons is that Roslyn does not actual knows anything about the project location and this might be a showstoppper. Anyway give me a day or two to come up with an VersionAnalyzer instead. For now just switch to 1 parallel job.

Thanks a lot for time you spent on this, much appreciated.

apobekiaris commented 5 years ago

another note on Roslyn analyzers: if you build the solution from the command like you have to ReBuild instead of build else Analyzers won't run. From VS it functions fine.

apobekiaris commented 5 years ago

After researching a bit Roslyn analyzers I decide not to go that path for the reason I mentioned before.

However reading the post again I manage to reproduce it on my side by creating an empty xaf solution with 2 agnostic modules and installing all the packages there.

The problem was that the mutex was open without waiting for release. Fixing it worked fine as the lock is like you use one parallel job. In addition when patch occurred flag directories created in each package folder so the script knows and do not create the mutex on subsequent builds utilizing the msbuild parallel processing.

the modified file will be included in the next lab build and is this:

using namespace System
using namespace System.Threading
using namespace System.Reflection
using namespace System.IO
using namespace System.IO.Compression
using namespace System.Reflection
using namespace System.Text.RegularExpressions
using namespace Mono.Cecil
using namespace Mono.Cecil.pdb
param(
    [string]$projectFile ,
    [string]$targetPath ,
    [string]$referenceFilter = "DevExpress*",
    [string]$assemblyFilter = "Xpand.XAF.*"
)
# $VerbosePreference = "Continue"
$ErrorActionPreference = "Stop"

function Use-Object {
    [CmdletBinding()]
    param (
        [Object]$InputObject,
        [Parameter(Mandatory = $true)]
        [scriptblock]$ScriptBlock
    )
    $killDomain
    try {
        . $ScriptBlock
    }
    catch {
        $killDomain = $true
    }
    finally {
        if ($null -ne $InputObject -and $InputObject -is [System.IDisposable]) {
            $InputObject.Dispose()
            if ($killDomain) {
                Stop-Process -id $pid
            }
        }
    }
}
function Get-MonoAssembly($path, [switch]$Write) {
    $readerParams = New-Object ReaderParameters
    if ($Write) {
        $readerParams.ReadWrite = $true
        $readerParams.SymbolReaderProvider = New-Object PdbReaderProvider
        $readerParams.ReadSymbols = $true
    }
    $readerParams.AssemblyResolver = New-Object MyDefaultAssemblyResolver
    [ModuleDefinition]::ReadModule($path, $readerParams).Assembly
}
function Get-DevExpressVersion($targetPath, $referenceFilter, $dxReferences) {
    Write-Verbose "Finding DevExpress version..."
    $hintPath = $dxReferences.HintPath | foreach-Object { 
        if ($_) {
            $path = $_
            if (![path]::IsPathRooted($path)) {
                $path = "$((Get-Item $projectFile).DirectoryName)\$_"
            }
            if (Test-Path $path) {
                [path]::GetFullPath($path)
            }
        }
    } | Where-Object { $_ } | Select-Object -First 1
    if ($hintPath ) {
        Write-Verbose "$($dxAssembly.Name.Name) found from $hintpath"
        [System.Diagnostics.FileVersionInfo]::GetVersionInfo($hintPath).FileVersion
    }
    else {
        $dxAssemblyPath = Get-ChildItem $targetPath "$referenceFilter*.dll" | Select-Object -First 1
        if ($dxAssemblyPath) {
            Write-Verbose "$($dxAssembly.Name.Name) found from $($dxAssemblyPath.FullName)"
            [System.Diagnostics.FileVersionInfo]::GetVersionInfo($dxAssemblyPath.FullName).FileVersion
        }
        else {
            $include = ($dxReferences | Select-Object -First 1).Include
            $dxReference = [Regex]::Match($include, "DevExpress[^,]*", [RegexOptions]::IgnoreCase).Value
            Write-Verbose "Include=$Include"
            Write-Verbose "DxReference=$dxReference"
            $dxAssembly = Get-ChildItem "$env:windir\Microsoft.NET\assembly\GAC_MSIL"  *.dll -Recurse | Where-Object { $_ -like "*$dxReference.dll" }
            if ($dxAssembly) {
                [System.Diagnostics.FileVersionInfo]::GetVersionInfo($dxAssembly.FullName).FileVersion
            }
            else {
                throw "Cannot find DevExpress Version"
            }

        }
    }
}

function Update-Version($modulePath, $dxVersion) {
    Use-Object($moduleAssembly = Get-MonoAssembly $modulePath -Write) {
        $moduleReferences = $moduleAssembly.MainModule.AssemblyReferences
        Write-Verbose "References:"
        $moduleReferences | Write-Verbose
        $needPatching = $false
        $moduleReferences.ToArray() | Where-Object { $_.FullName -like $referenceFilter } | ForEach-Object {
            $dxReference = $_
            Write-Verbose "Checking $_ reference..."
            if ($dxReference.Version -ne $dxVersion) {
                $moduleReferences.Remove($dxReference) | Out-Null
                $newMinor = "$($dxVersion.Major).$($dxVersion.Minor)"
                $newName = [Regex]::Replace($dxReference.Name, ".(v[\d]{2}\.\d)", ".v$newMinor")
                $regex = New-Object Regex("PublicKeyToken=([\w]*)")
                $token = $regex.Match($dxReference).Groups[1].Value
                $regex = New-Object Regex("Culture=([\w]*)")
                $culture = $regex.Match($dxReference).Groups[1].Value
                $newReference = [AssemblyNameReference]::Parse("$newName, Version=$($dxVersion), Culture=$culture, PublicKeyToken=$token")
                $moduleReferences.Add($newreference)
                $moduleAssembly.MainModule.Types | ForEach-Object {
                    $moduleAssembly.MainModule.GetTypeReferences() | Where-Object { $_.Scope -eq $dxReference } | ForEach-Object { 
                        $_.Scope = $newReference 
                    }
                }
                Write-Verbose "$($_.Name) version will changed from $($_.Version) to $($dxVersion)" 
                $needPatching = $true
            }
            else {
                Write-Verbose "Versions ($($dxReference.Version)) matched nothing to do."
            }
        }
        if ($needPatching) {
            Write-Verbose "Patching $modulePath"
            $writeParams = New-Object WriterParameters
            $writeParams.WriteSymbols = $true
            $key = [byte[]]::new(0)
            $key = [File]::ReadAllBytes("$root\Xpand.snk")
            $writeParams.StrongNameKeyPair = [System.Reflection.StrongNameKeyPair]($key)
            $moduleAssembly.Write($writeParams)
        }   
    }
}

set-location $targetPath
Write-Verbose "Running Version Converter on project $projectFile with target $targetPath"
$projectFileInfo = Get-Item $projectFile
[xml]$csproj = Get-Content $projectFileInfo.FullName
$references = $csproj.Project.ItemGroup.Reference
$dxReferences = $references | Where-Object { $_.Include -like "$referenceFilter" }    
$dxVersion = Get-DevExpressVersion $targetPath $referenceFilter $dxReferences | Where-Object { $_ } | Select-Object -First 1
$analyze = $references | Where-Object { 
    if ($_.Include -like "$assemblyFilter") {
        $packageFile = "$($projectFileInfo.DirectoryName)\$($_.HintPath)"
        if (Test-Path $packageFile) {
            $packageDir = (Get-Item $packageFile).DirectoryName
            $exists = (Test-Path "$packageDir\VersionConverter.v.$dxVersion.DoNotDelete")
            !$exists
        }
    }
} | Select-Object -First 1
if (!$analyze) {
    Write-Verbose "All packages already patched for $dxversion"
    return
}
try {
    $mtx = [Mutex]::OpenExisting("VersionConverterMutex")
}
catch {
    $mtx = [Mutex]::new($false, "VersionConverterMutex")
}
$mtx.WaitOne() | Out-Null
try {

    $root = $PSScriptRoot
    Write-Verbose "Loading Mono.Cecil"
    $monoPath = "$root\mono.cecil.0.10.3\lib\net40"
    if (!(Test-Path "$monoPath\Mono.Cecil.dll")) {
        $client = New-Object System.Net.WebClient
        $client.DownloadFile("https://www.nuget.org/api/v2/package/Mono.Cecil/0.10.3", "$root\mono.cecil.0.10.3.zip")
        Add-Type -AssemblyName System.IO.Compression.FileSystem
        [ZipFile]::ExtractToDirectory("$root\mono.cecil.0.10.3.zip", "$root\mono.cecil.0.10.3")
    }

    [System.Reflection.Assembly]::Load([File]::ReadAllBytes("$monoPath\Mono.Cecil.dll")) | Out-Null
    [System.Reflection.Assembly]::Load([File]::ReadAllBytes("$monoPath\Mono.Cecil.pdb.dll")) | Out-Null
    Add-Type @"
using Mono.Cecil;
public class MyDefaultAssemblyResolver : DefaultAssemblyResolver{
    public override AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters){
        try{
            return base.Resolve(name, parameters);
        }
        catch (AssemblyResolutionException){
            var assemblyDefinition = AssemblyDefinition.ReadAssembly(string.Format(@"$targetPath\{0}.dll", name.Name));
            return assemblyDefinition;
        }
    }
}
"@ -ReferencedAssemblies @("$monoPath\Mono.Cecil.dll")

    $references | Where-Object { $_.Include -like $assemblyFilter } | ForEach-Object {
        $packageFile = "$($projectFileInfo.DirectoryName)\$($_.HintPath)"
        $packageDir = (Get-Item $packageFile).DirectoryName
        Get-ChildItem $packageDir *VersionConverter.v.* -Exclude $dxVersion|ForEach-Object{
            Remove-Item $_.FullName -Recurse -Force
        }
        $versionConverterFlag="$packageDir\VersionConverter.v.$dxVersion.DoNotDelete"
        if (!(Test-Path $versionConverterFlag)){
            "$targetPath\$([Path]::GetFileName($_.HintPath))", $packageFile | ForEach-Object {
                if (Test-Path $_) {
                    $modulePath = (Get-Item $_).FullName
                    Write-Verbose "Checking $modulePath references.."
                    Update-Version $modulePath $dxVersion
                }
            }
            Write-Verbose "Flag $versionConverterFlag"
            New-Item $versionConverterFlag -ItemType Directory|Out-Null
        }
    }
}
catch {
    throw $_.Exception
}
finally {
    try {
        $mtx.ReleaseMutex() | Out-Null
        $mtx.Dispose() | Out-Null
    }
    catch {

    }
}
expand commented 5 years ago

The DevExpress.XAF repository includes commit VersionConverter: resolve synchronization issues when parallel builds #380 that relate to this task. Please update the related Nuget packages and test if issues is addressed. These are nightly nuget packages available only from our NugetServer.

If you do not use the Xpand.XAF.Modules directly but through an module of the main eXpandFramework module, you may wait for the bot to notify you again.

Thanks a lot for your contribution.

CWolffIF commented 5 years ago

Yesterday I tried to repro the problem with an empty solution. But with no success. After adding a second agnostic module (like you) the problem exists. I will test the solution today in our project. Thanks for research & solution

CWolffIF commented 5 years ago

I tested it and it works in my scenarios.

I have one strange thing but maybe it is another thread. I have refrenced Xpand 18.2.704 in my project and only the new Xpand.XAF (f.e. ViewEditMode 1.2.23). On my develop machine the program runs. If I build a release and put it on another machine, it doesn´t run. There is a reference error, cause the Xpand.XAF Version from 18.2.704 (f.e. ViewEditMode 1.2.9) are needed (Error Version dll not correct).

expand commented 5 years ago

eXpand.lab release 19.1.200.8 includes commit Update Standalone nugets #380 that relate to this task. Please test if it addresses the problem. If you use nuget add our LAB NugetServer as a nuget package source in VS.

Thanks a lot for your contribution.