skip to Main Content

I’m working on a C# solution, containing two projects, a client and a server.

Both are normally built using "Any CPU" (which means in my opinion) that they are build as 64-bit processes.

I’m facing different problems, most probably due to some enhancer issue, but I have no idea what this might be.

I have already offered a bounty of 200 points for the first problem but I got no response. As I now have a second problem, instead of creating a second StackOverflow post and waiting two days for starting another bounty, I will add the second problem to this question and start a bounty immediately.

Problem 1: older problem

While building the client, now I get the following error message:

The specified assembly 'C:UsersDDMAppDataLocalTemp_ptil_15736Client_Program.Client.dll' cannot be loaded. The problem might be that the enhancer runs in a .NET framework 2.0 vm and the assembly to enhance is a .NET 4.0 assembly or you are trying to enhance a x86 assembly in a 64 bit process or a x64 assembly in a 32 bit process. Please change the required version inside the enhancer.exe.config or venhance.exe.config or switch to ‘Any CPU’ for this project.

Now, some efforts:

  • The mentioned directory C:UsersDDMAppDataLocalTemp_ptil_15736 does not even exist.
  • Changing the build platform from "Any CPU" to "x86" sometimes makes the client work, sometimes not.

On the internet, I’ve found following URL, explaining something about 32-bit and 64-bit and some things about enhancers, whatever that might be.

Extra efforts:

In both my server application as my client application, I have quite some references to Telerik DLLs. Most have version "v4. …", but Telerik.OpenAccess and Telerik.OpenAccess.35.Extensions and Telerik.OpenAccess.Runtime have version "v2.0.50727".

As far as enhancers is concerned, this is the place where I find them:

C:<all_projects>packagesTelerik.DataAccess.Fluent.2013.3.1320.1toolsenhancerenhancer.exe.config
C:<all_projects>packagesTelerik.DataAccess.Fluent.2013.3.1320.1toolsenhancervenhance.exe.config
C:<all_projects>packagesTelerik.DataAccess.Fluent.2016.2.822.1toolsenhancerenhancer.exe.config
C:<all_projects>packagesTelerik.DataAccess.Fluent.2016.2.822.1toolsenhancervenhance.exe.config

(I have no idea which ones of those are actually used.)

All of those "*enhance*.exe.config" files have the same content:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <startup>
    <!--The enhancer is compiled against .NET 4.0.-->
    <!--To be able to enhance an .NET 2.0 assembly please comment out the next line:-->
    <supportedRuntime version="v4.0"/>
  </startup>
</configuration>

Having a further look at the mentioned URL, there is following quote:

Visual Studio starts the MsBuild.exe as 32-bit process

Well, I had a look the different "MSBuild.exe" files on my computer, and this is what I come up with:

C:>dir /S /B "msbuild.exe"
C:Program FilesMicrosoft Visual Studio2022EnterpriseMSBuildCurrentBinMSBuild.exe
C:Program FilesMicrosoft Visual Studio2022EnterpriseMSBuildCurrentBinamd64MSBuild.exe
C:Program Files (x86)Microsoft Visual Studio2017EnterpriseMSBuild15.0BinMSBuild.exe
C:Program Files (x86)Microsoft Visual Studio2017EnterpriseMSBuild15.0Binamd64MSBuild.exe
C:Program Files (x86)Microsoft Visual Studio2019EnterpriseMSBuildCurrentBinMSBuild.exe
C:Program Files (x86)Microsoft Visual Studio2019EnterpriseMSBuildCurrentBinamd64MSBuild.exe
C:Program Files (x86)MSBuild12.0BinMSBuild.exe
C:Program Files (x86)MSBuild12.0Binamd64MSBuild.exe
C:Temp_FolderDefaultMSBuild.exe
C:Temp_FolderNativeImageMSBuild.exe
C:WindowsassemblyGAC_32MSBuild3.5.0.0__b03f5f7f11d50a3aMSBuild.exe
C:WindowsassemblyGAC_64MSBuild3.5.0.0__b03f5f7f11d50a3aMSBuild.exe
C:WindowsMicrosoft.NETassemblyGAC_32MSBuildv4.0_12.0.0.0__b03f5f7f11d50a3aMSBuild.exe
C:WindowsMicrosoft.NETassemblyGAC_32MSBuildv4.0_4.0.0.0__b03f5f7f11d50a3aMSBuild.exe
C:WindowsMicrosoft.NETassemblyGAC_64MSBuildv4.0_12.0.0.0__b03f5f7f11d50a3aMSBuild.exe
C:WindowsMicrosoft.NETassemblyGAC_64MSBuildv4.0_4.0.0.0__b03f5f7f11d50a3aMSBuild.exe
C:WindowsMicrosoft.NETFrameworkv2.0.50727MSBuild.exe
C:WindowsMicrosoft.NETFrameworkv3.5MSBuild.exe
C:WindowsMicrosoft.NETFrameworkv4.0.30319MSBuild.exe
C:WindowsMicrosoft.NETFramework64v2.0.50727MSBuild.exe
C:WindowsMicrosoft.NETFramework64v3.5MSBuild.exe
C:WindowsMicrosoft.NETFramework64v4.0.30319MSBuild.exe
C:WindowsWinSxSamd64_msbuild_b03f5f7f11d50a3a_10.0.19041.1_none_fa6e7f402dbc0227MSBuild.exe
C:WindowsWinSxSamd64_msbuild_b03f5f7f11d50a3a_3.5.19041.1_none_82a6b3679b68b331MSBuild.exe
C:WindowsWinSxSamd64_msbuild_b03f5f7f11d50a3a_4.0.15805.0_none_dc3886319c616739MSBuild.exe
C:WindowsWinSxSamd64_msbuild_b03f5f7f11d50a3a_4.0.15840.3_none_dc3389e19c65e13fMSBuild.exe
C:WindowsWinSxSwow64_msbuild_b03f5f7f11d50a3a_4.0.15805.0_none_0606cd4b5dabfc56MSBuild.exe
C:WindowsWinSxSwow64_msbuild_b03f5f7f11d50a3a_4.0.15840.3_none_0601d0fb5db0765cMSBuild.exe
C:WindowsWinSxSx86_msbuild_b03f5f7f11d50a3a_10.0.19041.1_none_421bb61742382b2dMSBuild.exe
C:WindowsWinSxSx86_msbuild_b03f5f7f11d50a3a_3.5.19041.1_none_268817e3e30b41fbMSBuild.exe

How can I know which one is used and how can I replace this by a 64-bit MSBuild.exe?

Edit:
While building my application, I see following warning, does anybody know what it means?

MSBUILD : OpenAccess Enhancer warning : No persistent classes found. Is the metadata information missing?

  1. What are persistent classes (in Telerik OpenAccess terminology)?
  2. What is the mentioned metadata, and where and how can I read/write it?

Edit2: just for getting more attention, as the bounty is about to expire.

Problem 2: current problem

In my company, it is common to start with some kind of base classes, which have their objects stored in an SQL-server database. The last column in database of the base class is voa_class, showing the real class of the mentioned object.

Now I have a Vehicles base class and a subclass <Company>.Viastore.Server.Domain.ViastoreSrm, and in database I have a table, called Vehicles, containing an entry with voa_class <Company>.Viastore.Server.Domain.ViastoreSrm and another table ViastoreSrm, containing an entry with the same id value as the one from the Vehicles table (both id fields being equal allow both entries to be linked to each other).

In source code, I have following line:

namespace <Product>.<Customer>.Server
{
    ViastoreSrm viastore = database.GetData<ViastoreSrm>().FirstOrDefault();

Although this is standard (this way of getting data from the Telerik Openaccess database is used for more than ten years), now I get the following Exception:

System.ArgumentOutOfRangeException: Type is enhanced and registered, but not available from the database class meta data. This can be caused by a wrong connection id or configuration.
Parameter name: type
Actual value was <Product>.Viastore.Server.Domain.ViastoreSrm.
   at OpenAccessRuntime.ObjectScope.GetMetaData(Type type)
   at OpenAccessRuntime.ObjectScope.CheckPersistentType(Type type)
   at Telerik.OpenAccess.ExtensionMethods.Extent[T](IObjectScope scope)
   at Telerik.OpenAccess.OpenAccessContext.GetAllCore[T]()
   at Telerik.OpenAccess.OpenAccessContext.GetAll[T]()
   at <Product>.Server.OpenAccess.Database.GetData[T]()
   at <Product>.<Customer>.Agv.Server.Manager.CheckViastoreOrder(IDatabaseConnection database) in C:...<Customer><Product>.<Customer>.Agv.ServerManager.Viastore.cs:line 53

As you see, the Exception message is talking about connection id (what connection id?), configuration (what part of the configuration?), … but most of all that enhancer gets back in the picture!

I have the impression that that enhancer is responsible for a lot of bad behaviour of my application. As this code is working without problems on the PC of a colleague, I believe this enhancer should be something outside of the development environment, but what?

Is there anybody who can shed a light on this matter? What is that enhancer? How do I configure (or get of) it? … and most importantly: how can I make sure that it does not hinder my development anymore?

Thanks a lot in advance.

2

Answers


  1. Problem 1: Enhancer Issues

    The error message suggests an incompatibility between the enhancer tool and the .NET version of your assembly. Here are some steps to troubleshoot:

    1. Ensure that the enhancer versions in the Telerik packages you’ve
      referenced are compatible with .NET 4.0 since your project is
      targeting this version.

    2. If the directory mentioned in the error doesn’t exist, it might be a
      temporary directory used during the build process that gets cleaned
      up.

    3. You can ignore the path if it’s not persistent.

    You might need to explicitly set the platform target to x64 in your project settings if you’re dealing with 64-bit assemblies.

    Regarding the MSBuild version used:

    Visual Studio will generally use the MSBuild that aligns with the platform target and .NET version of your project. However, you can specify the path to the desired MSBuild in your project file or build script if needed.

    Problem 2:

    Persistent Classes and Enhancer Configuration
    Persistent classes in Telerik OpenAccess are classes that are mapped to database tables. The warning you see suggests that no classes have been marked as persistent or that the metadata mapping is not being recognized.

    To fix this:

    1. Check your mappings to ensure they’re correctly set up and that the
      enhancer tool can recognize them.
    2. Validate the connection string and configuration settings in your
      ‘app.config’ or ‘web.config’ to ensure they’re pointing to the
      correct database.

    System.ArgumentOutOfRangeException Exception:

    This exception might occur if there’s a mismatch between the classes defined in your code and the metadata available in the database.

    To resolve this:

    Verify that the database schema is up to date with the classes in your code.
    Ensure that the ‘voa_class’ column in your ‘Vehicles’ table correctly reflects the class hierarchy and any subclass entries.

    Regarding the Enhancer Tool:

    The enhancer is a post-build tool that modifies your compiled .NET assemblies to insert persistence code. It’s not an external tool but part of the Telerik Data Access flow. You cannot get rid of it if you use Telerik’s ORM, but you can configure it through the ‘enhancer.exe.config’ or ‘venhance.exe.config’ files.

    Additional Suggestions:

    Compare the working environment of your colleague’s PC with yours to identify any configuration differences.
    Review the Telerik documentation for any additional steps required for using the enhancer with .NET 4.0 assemblies.
    Consider reaching out to Telerik support or their community forums for specific advice on the enhancer tool and its configuration.
    I hope this helps resolve the issues you’re facing with the Telerik-based DLL and enhancer tool.

    Login or Signup to reply.
  2. C# Telerik Issue

    In your Angular project if you’re looking to set a constants value using a service, directly doing it in an export statement won’t work. That’s because Angular services function through dependency injection, which doesn’t apply in basic TypeScript exports. What you should try:

    1. Factory Provider Approach: Here, you’d create a factory provider. It’s essentially a function that takes your service as an argument and returns the configuration object. For example, in the section where you’re providing AuthConfig, you could do something like this:
    { 
         provide: AuthConfig, 
         useFactory: (myService: MyService) => ({
           url: myService.getUrl()
         }),
         deps: [MyService]
       }
    
    1. Setting It Up in AppComponent: You could also handle this in your AppComponent or another highlevel component. There, you can access services through dependency injection. After fetching your configuration, you can pass it where needed.

    2. Using APP_INITIALIZER: For cases where your configuration must be loaded right as the app starts, the APP_INITIALIZER token is your friend. It lets you run code during the app’s initialization phase.

    The Setup:

    export function initializeApp(myService: MyService): Function {
         return () => myService.loadConfig().then(config => {
           authConfig.url = config.url;
         });
       }
    
       @NgModule({
         providers: [
           {
             provide: APP_INITIALIZER,
             useFactory: initializeApp,
             deps: [MyService],
             multi: true
           }
         ]
       })
    

    Here your myService should be modified to return a Promise and you would adjust authConfig accordingly.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search