Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build problems VersionConverter #380

Closed
CWolffIF opened this issue Apr 23, 2019 · 96 comments
Closed

Build problems VersionConverter #380

CWolffIF opened this issue Apr 23, 2019 · 96 comments
Labels
Bug Reactive.XAF eXpandFrameowrk/DevExpress.XAF project VersionConverter Xpand.VersionConverter
Milestone

Comments

@CWolffIF
Copy link
Member

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.

@CWolffIF CWolffIF added Question Reactive.XAF eXpandFrameowrk/DevExpress.XAF project labels Apr 23, 2019
@apobekiaris
Copy link
Member

The VersionConverter is a dependency for the DevExpress.XAF modules. it installs with them.

Is there something special with your build? you build from vs? is it on parallel?

@apobekiaris
Copy link
Member

hmm looks like the VersionConverter still uses resources even if there is no patching. Can you replace the Xpand.VersionConverter.ps1 from your packages folder.

using namespace System
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(
    [parameter(Mandatory)]
    [string]$projectFile,
    [parameter(Mandatory)]
    [string]$targetPath,
    [string]$referenceFilter = "DevExpress*",
    [string]$assemblyFilter = "Xpand.XAF.*"
)
 
$ErrorActionPreference = "Stop"
set-location $targetPath
# $VerbosePreference="Continue"
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" }
$root = $PSScriptRoot
"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")
}

[Assembly]::Load([File]::ReadAllBytes("$monoPath\Mono.Cecil.dll")) | Out-Null
[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")
$devExpressAssemblyName = Invoke-Command {

    Write-Verbose "Finding DX assembly name"
    $dxAssemblyPath = Get-ChildItem $targetPath "$referenceFilter*.dll" | Select-Object -First 1
    if ($dxAssemblyPath) {
        $dxAssembly = [AssemblyDefinition]::ReadAssembly($dxAssemblyPath.FullName)
        Write-Verbose "$($dxAssembly.Name.Name) found from $($dxAssemblyPath.FullName)"
        $dxAssembly.Name
    }
    else {
        $name = ($dxReferences | Where-Object { $_.Include -like "*Version*" } | Select-Object -First 1).Include
        New-Object System.Reflection.AssemblyName($name)
    }
} | Select-Object -last 1
if (!$devExpressAssemblyName) {
    throw "Cannot find $referenceFilter version in $($projectFileInfo.Name)"
}

$references | Where-Object { $_.Include -like $assemblyFilter } | ForEach-Object {
    "$targetPath\$([Path]::GetFileName($_.HintPath))", "$($projectFileInfo.DirectoryName)\$($_.HintPath)" | ForEach-Object {
        if (Test-Path $_) {
            $modulePath = (Get-Item $_).FullName
            $readerParams = New-Object ReaderParameters
            $readerParams.ReadWrite = $true
            $readerParams.AssemblyResolver=New-Object MyDefaultAssemblyResolver
            $readerParams.SymbolReaderProvider = New-Object PdbReaderProvider
            $readerParams.ReadSymbols = $true
            $moduleAssembly = [AssemblyDefinition]::ReadAssembly($modulePath, $readerParams)
            Write-Verbose "Checking $modulePath references.."
            $moduleAssembly.MainModule.AssemblyReferences.ToArray() | Write-Verbose
            $needPatching=$false
            $moduleAssembly.MainModule.AssemblyReferences.ToArray() | Where-Object { $_.FullName -like $referenceFilter } | ForEach-Object {
                $nowReference = $_
                Write-Verbose "Checking $_ reference..."
                if ($nowReference.Version -ne $devExpressAssemblyName.Version) {
                    $moduleAssembly.MainModule.AssemblyReferences.Remove($nowReference)
                    $newMinor = "$($devExpressAssemblyName.Version.Major).$($devExpressAssemblyName.Version.Minor)"
                    $newName = [Regex]::Replace($nowReference.Name, ".(v[\d]{2}\.\d)", ".v$newMinor")
                    $regex = New-Object Regex("PublicKeyToken=([\w]*)")
                    $token = $regex.Match($nowReference).Groups[1].Value
                    $regex = New-Object Regex("Culture=([\w]*)")
                    $culture = $regex.Match($nowReference).Groups[1].Value
                    $newReference = [AssemblyNameReference]::Parse("$newName, Version=$($devExpressAssemblyName.Version), Culture=$culture, PublicKeyToken=$token")
                    $moduleAssembly.MainModule.AssemblyReferences.Add($newreference)
                    $moduleAssembly.MainModule.Types | ForEach-Object {
                        $moduleAssembly.MainModule.GetTypeReferences() | Where-Object { $_.Scope -eq $nowReference } |ForEach-Object { 
                            $_.Scope = $newReference 
                        }
                    }
                    Write-Verbose "$($_.Name) version changed from $($_.Version) to $($devExpressAssemblyName.Version)" 
                    $needPatching=$true
                }
                else {
                    Write-Verbose "Versions ($($nowReference.Version)) matched nothing to do."
                }
            }
            if ($needPatching){
                $writeParams = New-Object WriterParameters
                $writeParams.WriteSymbols=$true
                $f = New-Object FileStream("$root\Xpand.snk", [FileMode]::Open)
                $writeParams.StrongNameKeyPair = New-Object System.Reflection.StrongNameKeyPair ( $f)
                $moduleAssembly.Write($writeParams)
                $f.Dispose()
            }
            
            $moduleAssembly.Dispose()   
        }
    }
}

@apobekiaris
Copy link
Member

now it will only go to the exception line if patching is to be done which is determined by looking the nugets installation folder.

let me know if this relaxed the problem, or should I try the mutext approach as well.

@expand
Copy link
Member

expand commented Apr 23, 2019

The DevExpress.XAF repository includes commit Update Build Version to ALl #380,VersionConverter: Does not release resources on error #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.

@expand expand added this to the 18.2.704.0 milestone Apr 23, 2019
@CWolffIF
Copy link
Member Author

Thanks, it works.

@CWolffIF
Copy link
Member Author

Sorry,

but now is the problem in the Reactive Module.

C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.13\build\Xpand.VersionConverter.targets(4,9): error : ForEach-Object : Ausnahme beim Aufrufen von "ReadAssembly" mit 2 Argument(en): "Der Prozess kann nicht auf die Datei
4>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.13\build\Xpand.VersionConverter.targets(4,9): error : "C:\DevProjects\iXISJH\iXISXRM\iXISXRM.Module.Win\bin\Debug\Xpand.XAF.Modules.Reactive.dll" zugreifen, da sie von
4>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.13\build\Xpand.VersionConverter.targets(4,9): error : einem anderen Prozess verwendet wird."
4>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.13\build\Xpand.VersionConverter.targets(4,9): error : In C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.13\build\Xpand.VersionConverter.ps1:87 Zeichen:109
4>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.13\build\Xpand.VersionConverter.targets(4,9): error : + ... "$($projectFileInfo.DirectoryName)$($_.HintPath)" | ForEach-Object {
4>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.13\build\Xpand.VersionConverter.targets(4,9): error : + ~~~~~~~~~~~~~~~~
4>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.13\build\Xpand.VersionConverter.targets(4,9): error : + CategoryInfo : NotSpecified: (:) [ForEach-Object], MethodInvocationException
4>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.13\build\Xpand.VersionConverter.targets(4,9): error : + FullyQualifiedErrorId : IOException,Microsoft.PowerShell.Commands.ForEachObjectCommand
4>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.13\build\Xpand.VersionConverter.targets(4,9): error :
4>C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.13\build\Xpand.VersionConverter.targets(4,9): error MSB3073: Der Befehl "powershell.exe –NonInteractive –ExecutionPolicy Unrestricted –command "& { &'C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.13\build\Xpand.VersionConverter.ps1' 'C:\DevProjects\iXISJH\iXISXRM\iXISXRM.Module.Win\iXISXRM.Module.Win.csproj' 'C:\DevProjects\iXISJH\iXISXRM\iXISXRM.Module.Win\bin\Debug' } "" wurde mit dem Code 1 beendet.

@CWolffIF CWolffIF reopened this Apr 26, 2019
@apobekiaris
Copy link
Member

do u see a way of reproducing it?

@apobekiaris
Copy link
Member

Der Prozess kann nicht auf die Datei

this is a side effect of a previous exception, can you uncomment this line
https://github.com/eXpandFramework/DevExpress.XAF/blob/70f60fc02517ddaf180cd00c5a9c8cbc38b6824a/tools/Xpand.VersionConverter/Xpand.VersionConverter.ps1#L16
in your
C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.13\build\Xpand.VersionConverter.ps1
and report back the VS output window contents the first time the error occurred

@apobekiaris
Copy link
Member

please update your packages, i belive all your issues are addressed

@apobekiaris apobekiaris added the VersionConverter Xpand.VersionConverter label Apr 26, 2019
@apobekiaris
Copy link
Member

apologies the problem is still here, but I managed to reproduce it, soon will have a patch.

@apobekiaris
Copy link
Member

the workaround until the patch is to disable parallel builds

image

@expand
Copy link
Member

expand commented Apr 28, 2019

The DevExpress.XAF repository includes commit Cross process patching synchronization #380,DevExpress version is not resolved #380,Destroy AppDomain to release resource #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
Copy link
Member

Unfortunately I couldn't find a way to repro the issue. Here the the steps I followed.

  1. Install eXpandFramework in GAC
Set-ExecutionPolicy Bypass -Scope Process -Force;iex "$(([System.Net.WebClient]::new()).DownloadString('http://install.expandframework.com'));Install-Xpand -Assets @('Assemblies','Nuget','VSIX','Source')  #-Version '18.2.704.0'"
  1. Create a new XAF empty solution and open VS package manager console and type:

  2. Install XpandPosh

Install-Module XpandPosh -MinimumVersion 1.9.5
  1. Update to 4.6.1 as I wanted to install all modules.
Update-ProjectTargetFramework
  1. Install all packages
Find-XpandPackage Xpand*|Install-Packge
  1. Register the installed packages by paste the next snippet in the constructor of my agnostic module as instructed by readme.
          RequiredModuleTypes.Add(typeof(Xpand.XAF.Modules.ViewEditMode.ViewEditModeModule));
          RequiredModuleTypes.Add(typeof(Xpand.XAF.Modules.SuppressConfirmation.SupressConfirmationModule));
          RequiredModuleTypes.Add(typeof(Xpand.XAF.Modules.ModelViewInheritance.ModelViewInheritanceModule));
          RequiredModuleTypes.Add(typeof(Xpand.XAF.Modules.MasterDetail.MasterDetailModule));
          RequiredModuleTypes.Add(typeof(Xpand.XAF.Modules.CloneModelView.CloneModelViewModule));
          RequiredModuleTypes.Add(typeof(Xpand.XAF.Modules.CloneMemberValue.CloneMemberValueModule));
          RequiredModuleTypes.Add(typeof(Xpand.XAF.Modules.AutoCommit.AutoCommitModule));
  1. Build the solution which failed in the first build complaining about a conflict in the system.valuetuple and suggesting to Enable Automatic Binding redirection in the properties of my csproject.
  2. Build again and open VS designer with no errors.

@apobekiaris
Copy link
Member

for this I use the latest standalone packages from the lab which I will publish official soon.

@apobekiaris apobekiaris removed their assignment Apr 28, 2019
@expand
Copy link
Member

expand commented Apr 28, 2019

eXpand.lab release 18.2.703.10 includes commit Update XAF modules 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.

@CWolffIF
Copy link
Member Author

Hi Tolis,

I did everything like your instruction. But now I can´t build a Project anymore.

C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.17\build\Xpand.VersionConverter.targets(4,9): error : Cannot find DevExpress Version
C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.17\build\Xpand.VersionConverter.targets(4,9): error : In C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.17\build\Xpand.VersionConverter.ps1:191 Zeichen:5
C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.17\build\Xpand.VersionConverter.targets(4,9): error : + throw $_.Exception
C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.17\build\Xpand.VersionConverter.targets(4,9): error : + ~~~~~~~~~~~~~~~~~~
C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.17\build\Xpand.VersionConverter.targets(4,9): error : + CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException
C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.17\build\Xpand.VersionConverter.targets(4,9): error : + FullyQualifiedErrorId : RuntimeException
C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.17\build\Xpand.VersionConverter.targets(4,9): error :
C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.17\build\Xpand.VersionConverter.targets(4,9): error MSB3073: Der Befehl "powershell.exe –NonInteractive –ExecutionPolicy Unrestricted –command "& { &'C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.17\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
Copy link
Member Author

Hi,

I switched back to VersionConverter.1.0.16 (and the other Xpand.Modules) and I can compile.

@apobekiaris
Copy link
Member

C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.17\build\Xpand.VersionConverter.targets(4,9): error : Cannot find DevExpress Version
C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.17\build\Xpand.VersionConverter.targets(4,9): error : In C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.17\build\Xpand.VersionConverter.ps1:191 Zeichen:5
C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.17\build\Xpand.VersionConverter.targets(4,9): error : + throw $_.Exception
C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.17\build\Xpand.VersionConverter.targets(4,9): error : + ~~~~~~~~~~~~~~~~~~
C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.17\build\Xpand.VersionConverter.targets(4,9): error : + CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException
C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.17\build\Xpand.VersionConverter.targets(4,9): error : + FullyQualifiedErrorId : RuntimeException
C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.17\build\Xpand.VersionConverter.targets(4,9): error :
C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.17\build\Xpand.VersionConverter.targets(4,9): error MSB3073: Der Befehl "powershell.exe –NonInteractive –ExecutionPolicy Unrestricted –command "& { &'C:\DevProjects\NuGetPackages\Xpand.VersionConverter.1.0.17\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.

the cross cross process patch synchronization introduced in 1.0.17, and was required not only for this case but also for FeatureCenter as it had the same problem. This exception should be failry easy to resolve as it only about not finding which DX version to patch. So looking at the Version converter he have.
https://github.com/eXpandFramework/DevExpress.XAF/blob/9ff066b84f67137f9b643ab768f9e762d4fd00c8/tools/Xpand.VersionConverter/Xpand.VersionConverter.ps1#L53-L89

  1. DX version is detected first from the csproj file references hintpath (hintpath should be valid if dx is not in gac e.g. nuget or u simply manully reference from a dir)
$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"
        Use-Object($assembly = Get-MonoAssembly $hintPath) {
            $assembly.name.version
        }
    }

apparently for this case HintPath was null for all your dx references. (You could of course manually add in one and help detection but we want to automate it.)

  1. if hintpath fails 2nd attempt is to look in the bin directory of your project for a dx assembly and get its version
$dxAssemblyPath = Get-ChildItem $targetPath "$referenceFilter*.dll" | Select-Object -First 1
        if ($dxAssemblyPath) {
            Write-Verbose "$($dxAssembly.Name.Name) found from $($dxAssemblyPath.FullName)"
            Use-Object($assembly = Get-MonoAssembly $dxAssemblyPath.FullName) {
                $assembly.name.version
            }
        }

for this case apparently your bin was empty of dx assemblies, again u can put any dx assembly manual there and the exception will not throw.
3. 3rd attempt if hintpath and bin fail is to look in the gac for any dx assembly for the major DX version found from your csproj

$dxReference=($dxReferences|Select-Object -First 1).Include
            $dxAssembly=Get-ChildItem "$env:windir\Microsoft.NET\assembly\GAC_MSIL"  *.dll -Recurse|Where-Object{$_ -like "*$dxReference.dll"}
            if ($dxAssembly){
                Use-Object($assembly = Get-MonoAssembly $dxAssembly.FullName) {
                    $assembly.name.version
                }
            }

if all 3 fail then u get the exception u posted. But now my question is how VS finds your DX assemblies? It looks like hinpath is null gac is null and bin is empty.

@apobekiaris
Copy link
Member

I think I have the answer what this script returns?

Get-ChildItem ((Get-ItemProperty -LiteralPath HKLM:\Software\Wow6432Node\Microsoft\.NETFramework\AssemblyFolders\Xpand)."(Default)") DevExpress*.dll|Select-Object -First 1

@CWolffIF
Copy link
Member Author

Hi,

in that path there are no DevExpress*.dll.

@apobekiaris
Copy link
Member

so whats the path of your DX assemblies in your project? expand the references node, select a dx assembly and post the path that displayed there?

@CWolffIF
Copy link
Member Author

C:\Program Files (x86)\DevExpress 18.2\Components\Bin\Framework\DevExpress.ExpressApp.v18.2.dll

@apobekiaris
Copy link
Member

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
Copy link
Member Author

CWolffIF commented May 1, 2019

Sure it´s OK

@apobekiaris
Copy link
Member

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
Copy link
Member

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
Copy link
Member

expand commented May 1, 2019

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
Copy link
Member

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
Copy link
Member Author

CWolffIF commented May 2, 2019

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
Copy link
Member

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
Copy link
Member Author

CWolffIF commented May 4, 2019

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
Copy link
Member

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

@eXpandFramework eXpandFramework locked as resolved and limited conversation to collaborators May 4, 2019
@apobekiaris apobekiaris removed their assignment May 4, 2019
@CWolffIF
Copy link
Member Author

CWolffIF commented May 4, 2019

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
Copy link
Member Author

CWolffIF commented May 4, 2019

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 apobekiaris self-assigned this May 4, 2019
@apobekiaris
Copy link
Member

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
Copy link
Member Author

CWolffIF commented May 4, 2019

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
Copy link
Member

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
Copy link
Member

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

@apobekiaris
Copy link
Member

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
Copy link
Member

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
Copy link
Member

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
Copy link
Member

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 {
        
    }
}

@apobekiaris apobekiaris removed their assignment May 6, 2019
@expand
Copy link
Member

expand commented May 6, 2019

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
Copy link
Member Author

CWolffIF commented May 7, 2019

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
Copy link
Member Author

CWolffIF commented May 7, 2019

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).

@CWolffIF CWolffIF closed this as completed May 7, 2019
@expand
Copy link
Member

expand commented May 10, 2019

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.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Bug Reactive.XAF eXpandFrameowrk/DevExpress.XAF project VersionConverter Xpand.VersionConverter
Projects
None yet
Development

No branches or pull requests

3 participants