Adapters, BizTalk, BizTalk Server 2010, Pipeline Components

Threading issues in WCF-Adapter Body Path

(I originally wrote this the 5th of May 2014 but did not publish it. I only sent it as internal feedback at the time. I am now choosing to publish it anyway since there has now been ample time for Microsoft to fix the problem)

The scenario

I am using the BizTalk Server WCF adapters in a solicit-response send port and I am getting the response using the Body Path configuration option.

The problem

Main issues that using the WCF Adapter – Messages tab – Inbound BizTalk message body – Path, configured with an XPath and String Node Encoding configuration options produces under load:

  • Deserialization fails producing random and irregular errors seemingly caused by the stream position jumping to an erroneous location.
  • The adapter returns the wrong mismatched response (!!!) back to the pipeline

For the first issue, the following is the error message (or an example of):

System.Xml.XmlException: Start element ‘To s:mustUndersta’ does not match end element ‘sendMessageResult’. Line 1, position 951.

If you catch it and look at the XmlExceptions call stack, you will find this:

at System.Xml.XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader reader, String res, String arg1, String arg2, String arg3)
at System.Xml.XmlUTF8TextReader.ReadEndElement()
at System.Xml.XmlUTF8TextReader.Read()
at System.Xml.XmlSubtreeReader.Read()
at Microsoft.BizTalk.Adapter.Wcf.Runtime.BinaryReaderStream.ReadContentAsString(Byte[] buffer, Int32 offset, Int32 count)
… (call stack continues with custom code)

For the second issue, you will NOT find anything wrong in BizTalk. It will simply associate the wrong response with the wrong request and return the wrong message! This is far worse than the first exception in my opinion since it effectively, successfully and quietly sends back someone else’s response to a caller. When examining it closer it does not appear to swap responses, it just hands one response back to more then one caller, and the other responses simply disappear and are never used. BizTalk will not discover this (at least not in my case where I am always getting the same response MessageType back from the port), only whatever application logic that are either built into BizTalk by you or the system or application calling BizTalk or human intervention might discover what has happened. Perhaps when getting the wrong data back.

Guide to reproduce

Steps (that I took) to build up and test a solution to reproduce the error:

  1. Download the Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4, http://www.microsoft.com/en-us/download/details.aspx?id=21459 (this is not required, though it gives us a simple starting point.
  2. Use the Self-Host sample found at …WCFBasicServicesHostingSelfHostCS and described at http://msdn.microsoft.com/en-us/library/vstudio/ms733765%28v=vs.100%29.aspx. Basically this is the Calculator sample hosted in a Console app (this is not required for repro, it is just for simplicity).
  3. Test it to make sure it’s working.
  4. Extend the Client somewhat to get a bit more simultaneous and multi-threaded. I will show this later but essentially I am using the Calculator Add method and from several threads to create some load.
  5. Test it again and see there are no errors.
  6. Create a receive port and receive location, as well as a send port in BizTalk and route the message through so that BizTalk is between the client and the service.
  7. Test it and make sure it’s working (at this point I still have no issues).
  8. Now consume the Calculator service metadata in a BizTalk project to create the schema for the Add, Subtract, etc methods and their responses. Create a simple BizTalk flat file schema (we need something to store the XPath string we extract), create a pipeline with the Flat File Disassembler configured with that schema (we need to disassemble the string we receive from the adapter into that schema), and then a Map mapping from that schema to the original Calculator service schema and the AddResponse message (we want the client to get the correct response back).
  9. Compile, Deploy and wire everything up inside Biztalk (ie re-configure the ports created to use the receive pipeline we created, and the map we created.
  10. Also configure the send ports WCF Adapter – Messages tab – Inbound BizTalk message body – Path,  with an XPath and String Node Encoding.
  11. Run a single message through to make sure everything works. In fact, run it non-multi-threaded with several messages and make sure it works (which for me it did).
  12. Now run multiple threads to create a load on the system.
  13. Watch as the previously described errors appear. At first it works fine, then I begin getting responses I did not expect (2+2 = 8?) and then I run into the ‘Start element ‘…’ does not match end element ‘…’ exception.

An in-depth look

The service

There is nothing to see here really. It’s your most basic WCF service, same as it comes with the sample (slightly abbreviated in the sample below).

Code

namespace Microsoft.ServiceModel.Samples
{
    // Define a service contract.
    [ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
    public interface ICalculator
    {
        [OperationContract]
        double Add(double n1, double n2);
       ...
    }

    // Service class which implements the service contract.
    // Added code to write output to the console window
    public class CalculatorService : ICalculator
    {
        public double Add(double n1, double n2)
        {
            double result = n1 + n2;
            Console.WriteLine("Received Add({0},{1})", n1, n2);
            Console.WriteLine("Return: {0}", result);
            return result;
        }
        ...

        // Host the service within this EXE console application.
        public static void Main()
        {
            // Create a ServiceHost for the CalculatorService type.
            using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService)))
            {
                // Open the ServiceHost to create listeners and start listening for messages.
                serviceHost.Open();

                // The service can now be accessed.
                Console.WriteLine("The service is ready.");
                Console.WriteLine("Press <ENTER> to terminate service.");
                Console.WriteLine();
                Console.ReadLine();

            }
        }

    }

}

Config

This is basically the same as the sample, the only exception is that I removed security (simply because that’s what the scenario I was testing had).

    <bindings>
      <wsHttpBinding>
        <binding name="wsConfig">
          <security mode="None" />
        </binding>
      </wsHttpBinding>
    </bindings>
    
    <services>
      <service name="Microsoft.ServiceModel.Samples.CalculatorService" behaviorConfiguration="CalculatorServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8000/ServiceModelSamples/service"/>
          </baseAddresses>
        </host>
        <!-- this endpoint is exposed at the base address provided by host: http://localhost:8000/ServiceModelSamples/service  -->
        <endpoint address="" binding="wsHttpBinding" contract="Microsoft.ServiceModel.Samples.ICalculator" bindingConfiguration="wsConfig"/>
        <!-- the mex endpoint is exposed at http://localhost:8000/ServiceModelSamples/service/mex -->
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>

    <!--For debugging purposes set the includeExceptionDetailInFaults attribute to true-->
    <behaviors>
      <serviceBehaviors>
        <behavior name="CalculatorServiceBehavior">
          <serviceMetadata httpGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="False"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>

The client

Here I have added some multi-threading aspects on top of the sample code.

Code

namespace Microsoft.ServiceModel.Samples
{
    //The service contract is defined in generatedClient.cs, generated from the service by the svcutil tool.

    //Client implementation code.
    class Client
    {
        static void Main()
        {
            Console.WriteLine("Press ENTER to start!");
            Console.ReadLine();

            List<Task> tList = new List<Task>();

            Action a = () =>
            {
                Random random = new Random();
                int mseconds = random.Next(1, 100) * 10;
                System.Threading.Thread.Sleep(mseconds);

                // Create a client
                CalculatorClient client = new CalculatorClient();

                for (int i = 0; i < 10; i++)
                {
                    double result = client.Add(Convert.ToDouble(i), Convert.ToDouble(i));
                    double localResult = Convert.ToDouble(i) + Convert.ToDouble(i);
                    if (result != localResult)
                        Console.WriteLine("{0} !!!!!!!!!!!!!!!!!!! {1}", result, localResult);
                }

                //Closing the client gracefully closes the connection and cleans up resources
                client.Close();
            };

            for (int i = 0; i < 100; i++)
            {
                Task t = new Task(a);
                t.Start();
                tList.Add(t);
            }

            Task.WaitAll(tList.ToArray());

            Console.WriteLine();
            Console.WriteLine("Press <ENTER> to terminate client.");
            Console.ReadLine();
        }
    }
}

As you can see it does not take much, that is – I am not running thousands of threads here, in fact in total I only make a thousand calls, and I get an error every time I have run the app so far.

Let’s examine this a little bit closer. As you can see I am doing the following.

double result = client.Add(Convert.ToDouble(i), Convert.ToDouble(i));
double localResult = Convert.ToDouble(i) + Convert.ToDouble(i);
if (result != localResult)
    Console.WriteLine("{0} !!!!!!!!!!!!!!!!!!! {1}", result, localResult);

That is, I am sending the addition of the two numbers to the service, and the doing the same calculation locally. Then I compare the result I get from the service with my local result. If they do not match, I print the fact.

Config

The clients config (by necessity) matches that of the services. It is available in the download but I am not including a dump of it.

The BizTalk solution

To be able to reproduce the problem in a portable manner I created a simple BizTalk solution.

Visual Studio Solution

At this point I have got three projects in Visual Studio, of which my BizTalk project is the first in the below screenshot.

image

It contains the following artifacts:

  • CalculatorService_microsoft_servicemodel_samples.xsd – the schema for the Calculator service that was automatically generated for me (I removed the other generated artifacts as they were non-essential for the purpose of this repro).
  • FFAddResult.xsd – a simple flat file schema that will act as the temporary carrier of the result after I extract it from the incoming xml response until the Map transforms the message back into an AddResponse message.
  • Map1.btm – a map that transforms from FFAddResult to CalculatorService_microsoft_servicemodel_samples#AddResponse.
  • ReceiveFFAddResultPipeline.btp – a disassemble pipeline that will take the incoming string and create an FFAddResult xml message.

The FFAddResult.xsd is extremely simple.

image

As is the Map1.btm.

image

BizTalk Server configuration

In BizTalk I have a receive port and a receive location with very simple configuration; PassThruReceive and PassThruTransmit pipelines, WCF-Custom WS-Http binding (so I can host it in BizTalk and have fewer moving pieces – not essential to the repro, just easier to move around).

image

Everything is according to default configuration except no security.

image

No behaviors, no special parts of the message extracted here or non of that (the xpath is on the send port receive).

Speaking of which, the send port (in the configuration that give me issues) is a solicit-response port running the WCF-WSHttp adapter (to be frank, I have not tested other adapters/bindings) and running the receive pipeline we created.

image

Receive pipeline has trivial config.

image

We have our inbound map configured.

image

And a filter on the receive port name that I won’t include a screenshot of.

The adapter configuration is set to forward the call to the backend service add method.

image

It also has security set to none (not shown in screenshot) as well as on the Messages tab having the Inbound BizTalk message body – Path,  set to an XPath and String Node Encoding. the xpath in this case is /*[local-name()=’AddResponse’ and namespace-uri()=’http://Microsoft.ServiceModel.Samples’]/*[local-name()=’AddResult’ and namespace-uri()=’http://Microsoft.ServiceModel.Samples’%5D, which will forward the string value inside the AddResult node for the pipeline.

Executing the failing code

Below is a screenshot of the app running, where as you can notice, the response is not as expected.

image

As mentioned before, the app gets a number if these mismatched erroneous responses and then crashes (due to the previously mentioned exception and the sample apps lack of exception handling).

Here is also some sample output from the service (in this case the screenshot is from a test where it has been able to run to completion and what we are seeing are the final tasks/threads doing their last calls).

image

The workaround

Ok, now that we are aware of the failing component. Can we work around it?

Enter the XPathExtractor pipline component, based of some of BizTalks hidden gems.

Essentially, the solution is – don’t use the BizTalk message body – Path option. Instead, just get the body and extract the XPath you want in a pipeline component. Although I have not done any performance comparisons but I am not expecting the code to have any noticeably difference in performance. You might want to think twice before running very large message through it (as will become evident in the source code included later). But I think the same is true for using the adapters Body Path option, which (as we can see from the callstack the exception had) also gets the content of the node as a string.

I created a new port and a new pipeline, getting only he body in the adapter and instead extracting the string in the pipeline. Configuration as follows.

image

The Execute method of the pipeline component does this:

Stream stream = new ReadOnlySeekableStream(pInMsg.BodyPart.GetOriginalDataStream());

XmlTextReader xmlTextReader = new XmlTextReader(stream);
XPathCollection xPathCollection = new XPathCollection();
xPathCollection.Add(this.XPath);
XPathReader xPathReader = new XPathReader(xmlTextReader, xPathCollection);

bool matchFound = false;
while (xPathReader.ReadUntilMatch())
{
    if (xPathReader.Match(0))
    {
        string val = xPathReader.ReadString();
        stream = new VirtualStream(new MemoryStream(System.Text.Encoding.GetEncoding(this.Encoding).GetBytes(val)));
        matchFound = true;
        //break; // don't break, read to end to play nice with other components 
                    // that have a streaming approach and might want to process the full message
    }
}

if (!matchFound)
    throw new Exception("xPathReader.ReadUntilMatch() found no match");

stream.Seek(0, SeekOrigin.Begin);
pInMsg.BodyPart.Data = stream; 
pContext.ResourceTracker.AddResource(xPathReader);

I have run this a number of times and never as of yet gotten the same exception.

Remember that if you have any objections on the code in this component (like why is he adding the xPathReader to the resourceTracker, or whatever else) that this is not used when I get the issues, this is used to get around them.

Quick performance comparison

Quick and dirty indeed. This has no intention to go deep or be thorough. With that out of the way…

Without Adapter Body Path

Red is proc. Blue is message publishing rate. Green is memory (not sure I got the right counter for that one, but I’ll ignore that for putting together this post).

image

With Adapter Body Path

image

It’s not really applicable to performance measures because it fails quite early. The most interesting thing with this graph I would say is that I don’t have to reach higher than 4 simultaneous request to start getting issues.

With XPath extraction in pipeline component

image

Also note that due to the randomness of my Task execution this may not be altogether comparable, so just keep that in mind. I post it mainly to illustrate that I am not running a really massive load, to show how early it fails, and to note that the workaround is not terrible.

My environment

My repro environment is a Hyper-V virtual machine with 4608MB allocated running alone on a 8 core host machine. It’s BizTalk Server 2010 with CU6, Windows Server 2008 R2 fully patched, SQL Server 2008 R2 SP1 (yes, I am aware there is a later service pack, but at the time it was not applied. I would be very surprised if it makes a difference). I have reproduced this error on several environments so it’s not isolated to mine. Although I am running BizTalk Server 2010 I would not be surprised to find this in BizTalk Server 2009, BizTalk Server 2006 R2 or even BizTalk Server 2013. Though I can neither confirm not deny since I have not tried.

Download

The full source code and bindings for everything I have mentioned in this article, including the code for the pipeline component, is available for download here.

BizTalk Server 2010, Book, Certification, Learning

Published: (MCTS): Microsoft BizTalk Server 2010 (70-595) Certification Guide

The book has finally been published. I couldn’t be happier about it. It’s been a fun ride but reaching the finish line is always sweet.

The book itself is targeted at the BizTalk Server certification 70-595. We have done our very best to be as brief and as focused on the areas of the certification as possible, while still keeping it far away from being verbatim or a cheat sheet. We want people to come away having learned useful pieces of BizTalk Server, not only be able to successfully answer the certification questions. The book does contain a healthy number of certification style (but not certification copied) question and answers, with a short explanation of why and why not the correct answer applies. All you need to know is there, explained and put into context. Hand in hand with being certification bound and focused also goes carrying a thread throughout and across chapters that will make the book an easy and time efficient read. I hope, in the end, that we succeeded in that.

You can read all about the book and it’s content, as well as making purchases 😉 on either Packt or Amazon (or if you prefer and are in Sweden from Bokus).

4927EN_cov

Authoring a book was more of a challenge than I anticipated. Not so much the writing in itself, but all the things that goes around it. All the editing and proof reading and keeping track of changes etc. The latter took basically half of the time if not more, both calendar wise and in number of spent hours. I would do it again if the title was interesting enough, but right now I have other plans for the summer.

Completing a book is a real team effort, and without the team at Packt and our reviewers the quality would not be at the level it is. Thanks to Kent and Morten, to all the people at Packt, Kerry especially, and to our reviewers, Jan Eliasen, Mikael Håkansson, Steef-Jan Wiggers, Todd Uhl among others.

Kent has written two post (1, 2) on the progress of the book as well.

Administration, BizTalk Server 2010, Maintenance

Updates to bLogical.BizTalkManagement powershell BizTalk Server database restore commandlets

I’ve uploaded a new version of the bLogical.BizTalkManagement restore powershell commandlets originally posted by Mikael. The updates are minor and adress the parsing of filenames and cleanup of the code to get rid of some god intentions that never became more then intentions, aka unused code.


If you have no idea what I am talking about, feel free to read the original article and give them a try. We are using these heavily for customers instead of log shipping and it really makes the whole process of restoring your databases easy.

64-bit, BizTalk Server 2010, HIS, MQ

How I diagnosed en elusive ‘is not a valid Win32 application’ exception

We were using BizTalk Server 2010 and the MQ Client (MQSC) adapter from Host Integration Server 2010 (HIS 2010). We had been getting an exception on and off on servers without really knowing why it appeared on some servers and not on others. We even opened a case with Microsoft, but they are only human like the rest of us and can’t magically diagnose and solve errors remotely based on vague input, so that really didn’t lead anywhere other then things like “Make sure you are running the adapter in a 64-bit process”. The exception message was this:

The adapter "MQSC" raised an error message. 
Details "Could not load file or assembly 'Microsoft.BizTalk.Adapter.Mqsc.ImqWrapper.dll'
or one of its dependencies. is not a valid Win32 application. (Exception from HRESULT: 0x800700C1)".

It’s enough to say that we investigated the error in a number of ways, including making sure that the specific dll mentioned was present. But as we all know the “or one of its dependencies” can hide any number of referenced dlls. So we made sure that the machines that worked and the ones that didn’t had the same assemblies available, which they did. Still no luck in narrowing it down. Luckily the exception happened right when you enabled a receive location so it was easy to identify and therefore to reproduce and troubleshoot.

I resorted to using Process Monitor (not to be confused with Process Explorer, although also a great tool not the best in this scenario). I started the tool, found the PID for the process running my MQSC adapter process (see this post for details on identifying the BTSNTSvc process that belong to a certain host and get the PID) and set a filter for just that PID to reduce the noise. Finally I enabled the receive location. That gave me this:

clip_image001

As you can see in the image BizTalk Server is probing for an assembly in different locations, and it’s not the Microsoft.BizTalk.Adapter.Mqsc.ImqWrapper.dll. It’s the imqb23vn.dll from the WebSphere MQ installation. It’s trying to locate the assembly and finding it in the WebSphere MQBin64 folder. However it gets an Access Denied when trying to access it, so it then continues on to the WebSphere MQBin folder, where it locates the 32-bit version, which is does have access to, and so it loads it.

The exception message then is not saying that a 32-bit process is trying to use an assembly meant for a 64-bit process, but the opposite; that the assembly we are trying to load cannot be loaded as the application that is loading it (in this case BTSNTSvc64.exe) is a 64-bit process, aka not a valid win32 application.

Setting the correct permission on the file and hooking onto the process once again to see what it is doing verified the theory. The image below shows how it loads the correct 64-bit version of the imqb23vn.dll and the continues on to the next assembly which has the same issue and causes the exception once again. The exact same exception, but this time caused by another underlying referenced assembly:

clip_image001[4] 

Setting appropriate access permissions on the entire folder made the process complete without exceptions and the adapter able to successfully connect to the MQ queue and pick up the messages on it and deliver them to the messagebox. Why the folders ended up getting different permissions in this way is still a mystery…

HTH,

/Johan

BizTalk Server 2010, Certification

The 70-595 exam and the first rule of fight club

I’ve had a not-so-few asks to blog about the 70-595 exam. I’m answering those calls with this post.

The exam launched on march 30th. I actually tried taking it on the 7th of April, though due to technical difficulties, on Prometric and the testing sites behalf, I had to leave without getting a chance to do it after waiting 90 minute for the issue to be resolved (see my twitter history if you want more on that story). I found the time to come back a week later though, on the 14th, and manage to successfully pass the exam.

70-595 is the Developing Business Process and Integration Solutions using BizTalk Server 2010 exam. Its coverage includes core BizTalk functionality as well as extended capabilities. The excerpt from the exams Microsoft learning page is:

Configuring a Messaging Architecture (20 percent)
Developing BizTalk Artifacts (20 percent)
Debugging and Exception Handling (17 percent)
Integrating Web Services and Windows Communication Foundation (WCF) Services (14 percent)
Implementing Extended Capabilities (13 percent)
Deploying, Tracking, and Supporting a BizTalk Solution (16 percent)

Which brings me to the first rule of fight club, and why Tyler Durden would be a good MCP (therefore not claiming that we (MCPs) are all insomnia cursed paranoid schizophrenics in any way ;).  But, “You don’t talk about fight club”, as in “You don’t talk about the contents of certification exams”. In fact you actually agree to an NDA about the contents of the exam – not that that stops any of the cheat sheet providers out there or the people that use them, but it does me. Therefore, you will not find any details as to what kind of questions or what specific areas were covered. All I’m going to say about the contents of the exam is that it pretty much mirrored that division into areas.  So let’s delve into that…

…and rephrase those percentages in another way:
Core functionality (like messaging, development, debugging, deploying, tracking and troubleshooting) make up roughly 90%, and BAM, BRE, RFID and EDI make up the other 10 percent.

Since the test is 50 questions, that would mean that on an average 45 question would be on the core functionality and 5 questions on the rest.

Following on with the math lesson that means that you are very likely to make the passing score of 700 (out of 1000), without any deeper knowledge on the “extended capabilities”. Which I know will be a soothing thought for a lot of people. No guarantees though, because it’s not always a 1 question =  1000/50 points kind of thing.

If you want to truly ace the test, you’ll really need to know all of your BizTalk, including reading into things like RFID. I did not ace the test (as in a perfect 1000), though I did reasonably well; close enough for me to be pleased and well within the margin.

How did I prepare is a question that often follow along with the ask to write a post on the subject. Others might compose a prep guide. I won’t. Not in this post anyway. I do have a simple answer with two sides to it for you though. One the one side – I didn’t. On the other – I prepared working in real BizTalk projects over the course of 6 years, 5 version of the product and took the two exams that came before this one. What I am saying is – if that sounds anything like you you are likely to just as I did just go take the test, and you’ll likely be fine. If it doesn’t – well, you know yourself best – perhaps you need to study?

On the note of previous tests, I found this to be about the same level of difficulty as the 2006 exam, though easier then the 2006 R2 exam. I don’t know about the 2004 exam – I never did that – you’ll have to ask someone like Jan or Thiago about that comparison.

Anyway, I encourage you to go take the exam, and if you do – best of luck to you!

BizTalk Server 2010

BizTalk Standard Edition and the continued tale of 6 applications

Before I uninstall BizTalk Server 2010 Standard Edition and go back to Developer I thought I’d run one additional test that points to a limit with Standard and a peculiarity “discovered” earlier this year that I can’t take any credit for noticing. It’s blogged about here – In essence: BizTalk Server 2009 Standard supports 6 “custom” BizTalk applications, not just the five that the license mentions. Or rather – It supports 5 additional applications on top of the ones created by install/configure by default (for those of you that do not understand what the term application means at this point, and how it affects us, can read this link). So the question then is – Does this hold true for the 2010 Standard RTM as well?

Sure enough, as you would expect, I am stopped from creating more than 5 additional applications by the following dialog.

image

I can however rename BizTalk Application 1 and use that for whatever purposes.

image

I can also just delete the BizTalk Application 1 and create a new application named whatver-I-want.

image

So. The answer to the question I asked above is – Yes it holds true. BizTalk Server 2010 Standard allows 6 applications on top of the BizTalk.System application, which is read-only. Nothing has changed from 2009 on this account.

64-bit, BizTalk Server 2010

BizTalk Server 2010 Standard DOES support 64-bit

A while back I posted about BizTalk Server 2009 Standard not supporting 64-bit hosts. It was an odd thing in these times of 64-bit computing. The product group came very close to giving an outright promise to remove the limitation in the 2010 version.

For that reason I was very surprised to still find all references of the documentation suggesting that the limitation was still there. Like the sample below.

image

It might still be due to me misunderstanding exactly what “native 64-bit processing” really means. That’s part of the reason for this article..

When I asked (Paolo Salvatori) though I was told the documentation might be (and was probably) wrong. I took that on faith, but still, what better then a test now once the Standard edition has been release for download.

It started of bad with BizTalk Server Configuration. At this point the “32-bit only” checkboxes were grayed out and selected. Nor promising, but maybe it always looks that way.

image

However, when I got into the BizTalk Server Administration console I could create a 64-bit host.

image

And I could create and start a host instance for that host.

image

And yes, I am using a Standard Edition.

image

Update after Comment from Erik:

image

The process can, as per the picture above, be seen as running as the BTSNTSvc64.exe process.