RSS

Monthly Archives: January 2018

Azure Batch Deployment and ‘msshrtmi’ Assembly

Azure Batch Deployment Issue

During Azure Batch deployment, I got the following error.

[22:32:51][Step 2/2] Unhandled Exception: System.AggregateException: One or more errors occurred. ---> Microsoft.Practices.Unity.ResolutionFailedException: Resolution of the dependency failed, type = "SomeNamespace.SomeTask", name = "(none)".
[22:32:51][Step 2/2] Exception occurred while: Calling constructor SomeNamespace.Data.Repositories.SomeRepository(SomeNamespace.Common.Repositories.IStorageRepository storageRepository, SomeNamespace.Common.ILoggingService logger).
[22:32:51][Step 2/2] Exception is: TypeInitializationException - The type initializer for 'Microsoft.ServiceRuntime.RoleEnvironment' threw an exception.
[22:32:51][Step 2/2] -----------------------------------------------
[22:32:51][Step 2/2] At the time of the exception, the container was:
[22:32:51][Step 2/2]
[22:32:51][Step 2/2]   Resolving SomeNamespace.SomeTask,(none)
[22:32:51][Step 2/2]   Resolving parameter "analyticsService" of constructor SomeNamespace.SomeTask(SomeNamespace.Common.IConfigurationManager config, SomeNamespace.Services.ServiceLayer.ISomeServiceA chainService, SomeNamespace.Services.ServiceLayer.ISomeServiceB siteService, SomeNamespace.Common.ILoggingService logger, SomeNamespace.Services.ServiceLayer.ISomeServiceC analyticsService)
[22:32:51][Step 2/2]     Resolving SomeNamespace.Services.ServiceLayer.SomeServiceC,(none) (mapped from SomeNamespace.Services.ServiceLayer.ISomeServiceC, (none))
[22:32:51][Step 2/2]         Resolving SomeNamespace.Services.ServiceLayer.SomeServiceI,(none) (mapped from SomeNamespace.Services.ServiceLayer.ISomeServiceI, (none))
[22:32:51][Step 2/2]         Resolving parameter "someRepository" of constructor SomeNamespace.Services.ServiceLayer.SomeServiceI(SomeNamespace.Common.Repositories.ISomeRepository someRepository)
[22:32:51][Step 2/2]           Resolving SomeNamespace.Data..Repositories.SomeRepository,(none) (mapped from SomeNamespace.Common.Repositories.ISomeRepository, (none))
[22:32:51][Step 2/2]           Calling constructor SomeNamespace.Data..Repositories.SomeRepository(SomeNamespace.Common.Repositories.ISomeRepositoryA someRepositoryA, SomeNamespace.Common.ISomeServiceH someServiceH)
[22:32:51][Step 2/2]  ---> System.TypeInitializationException: The type initializer for 'Microsoft..ServiceRuntime.RoleEnvironment' threw an exception. ---> System.IO.FileNotFoundException: Could not load file or assembly 'msshrtmi, Version=2.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.
[22:32:51][Step 2/2]    at Microsoft..ServiceRuntime.RoleEnvironment.InitializeEnvironment()
[22:32:51][Step 2/2]    at Microsoft..ServiceRuntime.RoleEnvironment..cctor()
[22:32:51][Step 2/2]    --- End of inner exception stack trace ---
[22:32:51][Step 2/2]    at Microsoft..ServiceRuntime.RoleEnvironment.get_IsAvailable()
[22:32:51][Step 2/2]    at SomeNamespace.Data..Repositories.SomeRepository..ctor(ISomeRepositoryA someRepositoryA, ISomeServiceH someServiceH, Boolean forceLocal) in F:\TeamCity\buildAgent\work\2b474eac7536416f\SomeNamespace.Data.\Repositories\SomeRepository.cs:line 64
[22:32:51][Step 2/2]    at lambda_method(Closure , IBuilderContext )
[22:32:51][Step 2/2]    at Microsoft.Practices.ObjectBuilder2.DynamicBuildPlanGenerationContext.<>c__DisplayClass1.<GetBuildMethod>b__0(IBuilderContext context)
[22:32:51][Step 2/2]    at Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context)
[22:32:51][Step 2/2]    at Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context)
[22:32:51][Step 2/2]    at Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)
[22:32:51][Step 2/2]    at Microsoft.Practices.ObjectBuilder2.BuilderContext.NewBuildUp(NamedTypeBuildKey newBuildKey)
[22:32:51][Step 2/2]    at Microsoft.Practices.Unity.ObjectBuilder.NamedTypeDependencyResolverPolicy.Resolve(IBuilderContext context)
[22:32:51][Step 2/2]    at lambda_method(Closure , IBuilderContext )

At a glance, it seems like an issue with Unity IOC container. But when I look closer, it’s actually missing ‘msshrtmi‘ assembly as you can see in the following error message:

System.IO.FileNotFoundException: Could not load file or assembly ‘msshrtmi, Version=2.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35’

Root Cause

This error happens in the build server, but it’s not happening in local machine.

As a comparision, the build server does have Azure SDK installed, the same version used with the Azure Batch application. It also has .NET Framework installed, but not the SDK.

The local machine, on the other hand, has Visual Studio installed, Azure SDK and .NET Framework, but not .NET Framework SDK.

The exception is caused by build server doesn’t have installed Azure SDK library in its Global Assembly Cache (GAC). In local machine, the installation of Visual Studio put Azure SDK into GAC.

Solution

It’s as easy as adding msshrtmi assembly to Global Assembly Cache (GAC) in the build server. See here for adding GAC.

Advertisements
 
Leave a comment

Posted by on January 30, 2018 in General

 

Tags: , , ,

Azure Batch Exit Code -532462766

Symptom: Task completed with exit code ‘-532462766’

Azure Batch would throw this exception when running the jobs or tasks. Application Insight may or may not catch this exception, but Azure Portal and Batch Labs would show the jobs / tasks exit with code ‘-532462766’.

Troubleshooting

Some ways to troubleshoot:

  • Remote desktop to the machine.
    Set PoolSpecification.KeepAlive to true
    to keep the virtual machine alive after the job is done. This allows you to investigate the TVM.
  • Check Window’s Event Viewer.
  • Run the Job / Task with elevated permission.
    task.UserIdentity = new UserIdentity(new AutoUserSpecification(elevationLevel: ElevationLevel.Admin, scope: AutoUserScope.Task));
  • Set Application Insight to diagnose the service.
  • Use Batch Labs to see more information for a particular pool, TVM, job or task.

Reference

Azure Batch User Accounts
Batch Labs

 
Leave a comment

Posted by on January 23, 2018 in General

 

Tags: ,

What’s My .NET Framework Version?

Using Registry

Most accurate is through registry. For .NET Framework 1-4:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP

And newer .NET Framework:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full

The DWORD represents different .NET Framework version.

Using Code

Easier way is to use code:

void Main()
{
    GetVersionFromRegistry();
    GetNet45PlusFromRegistry();
}

private static void GetVersionFromRegistry()
{
    // Opens the registry key for the .NET Framework entry.
    using (RegistryKey ndpKey =
        RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, "").
        OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\"))
    {
        // As an alternative, if you know the computers you will query are running .NET Framework 4.5
        // or later, you can use:
        // using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,
        // RegistryView.Registry32).OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\"))
        foreach (string versionKeyName in ndpKey.GetSubKeyNames())
        {
            if (versionKeyName.StartsWith("v"))
            {
                RegistryKey versionKey = ndpKey.OpenSubKey(versionKeyName);
                string name = (string)versionKey.GetValue("Version", "");
                string sp = versionKey.GetValue("SP", "").ToString();
                string install = versionKey.GetValue("Install", "").ToString();
                //no install info, must be later.
                if (install == "")
                {
                    var version = versionKeyName + "  " + name;
                    Console.WriteLine(version);
                    version.Dump();
                }
                else
                {
                    if (sp != "" && install == "1")
                    {
                        var version = versionKeyName + "  " + name + "  SP" + sp;
                        Console.WriteLine(version);
                        version.Dump();
                    }
                }
                if (name != "")
                {
                    continue;
                }
                foreach (string subKeyName in versionKey.GetSubKeyNames())
                {
                    RegistryKey subKey = versionKey.OpenSubKey(subKeyName);
                    name = (string)subKey.GetValue("Version", "");
                    if (name != "")
                        sp = subKey.GetValue("SP", "").ToString();
                    install = subKey.GetValue("Install", "").ToString();
                    //no install info, must be later.
                    if (install == "")
                    {
                        var version = versionKeyName + "  " + name;
                        Console.WriteLine(version);
                        version.Dump();
                    }
                    else
                    {
                        if (sp != "" && install == "1")
                        {
                            var version = "  " + subKeyName + "  " + name + "  SP" + sp;
                            Console.WriteLine(version);
                            version.Dump();
                        }
                        else if (install == "1")
                        {
                            var version = "  " + subKeyName + "  " + name;
                            Console.WriteLine(version);
                            version.Dump();
                        }
                    }
                }
            }
        }
    }
}

private static void GetNet45PlusFromRegistry()
{
    const string subkey = @"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\";
    string version = string.Empty;

    using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(subkey))
    {
        if (ndpKey != null && ndpKey.GetValue("Release") != null)
        {
            version = ".NET Framework Version: " + CheckFor45PlusVersion((int)ndpKey.GetValue("Release"));
            Console.WriteLine(version);
            version.Dump();
        }
        else
        {
            version = ".NET Framework Version 4.5 or later is not detected.";
            Console.WriteLine(version);
            version.Dump();
        }
    }
}

// Checking the version using >= will enable forward compatibility.
private static string CheckFor45PlusVersion(int releaseKey)
{
    if (releaseKey >= 461308)
        return "4.7.1 or later";
    if (releaseKey >= 460798)
        return "4.7";
    if (releaseKey >= 394802)
        return "4.6.2";
    if (releaseKey >= 394254)
    {
        return "4.6.1";
    }
    if (releaseKey >= 393295)
    {
        return "4.6";
    }
    if ((releaseKey >= 379893))
    {
        return "4.5.2";
    }
    if ((releaseKey >= 378675))
    {
        return "4.5.1";
    }
    if ((releaseKey >= 378389))
    {
        return "4.5";
    }
    // This code should never execute. A non-null release key should mean
    // that 4.5 or later is installed.
    return "No 4.5 or later version detected";
}

Reference
Microsoft Docs

 
Leave a comment

Posted by on January 22, 2018 in General

 

Tags: ,

GAC and GACUTIL in a Nutshell

What’s GAC?

Global Assembly Cache.

What’s in the GAC?

See GAC content:

C:\> gacutil -l
or
C:\> gacutil /l
or a specific assembly:
C:\> gacutil -l msshrtmi

Or alternatively, look into the following folders:

.NET Framework 4 and newer: %windir%\Microsoft.NET\assembly.
Earlier versions of the .NET Framework: %windir%\assembly.

Accessing GACUTIL

If you have Visual Studio installed, GACUTIL should be accessible in Visual Studio Developer Command Prompt:

C:\Users\JohnDoe\Source> gacutil

Where’s GACUTIL?

If you don’t have Visual Studio, chances are GACUTIL is not recognized in the command prompt. But it doesn’t mean you don’t have it.

Try look in the following folders:

C:\Program Files (x86)\Microsoft SDKs\Windows\v6.0A\bin
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin
C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools
C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.2 Tools

Or any other version available.

GACUTIL comes with Windows SDK. If you still can’t find, download Windows SDK.

Installing New GAC

C:\> gacutil /i MyLibrary.dll

GACUTIL will place the assembly in the GAC directory based on the version of .NET Framework used to compile the assembly.

You don’t need to restart your computer for the installation to take effect.

References

Global Assembly Cache GAC
GACUTIL
View GAC Content

 
1 Comment

Posted by on January 14, 2018 in References

 

Tags: , , ,

 
%d bloggers like this: