none
Writing a TransportAgent for Exchange 2007, 2010, & 2013 RRS feed

Answers

  • No on 2007 and 2010 you need to compile your agent against the Public binaries Microsoft.Exchange.Data.Common.dll and Microsoft.Exchange.Transport.dll. These change between different versions of Exchange and Service Pack levels as functionality does differ at the Service Pack level. If you don't have the Agent compiled against the correct SP version it won't work and will cause the Transport Service to shut down. Also on 2007 the Agent needs to .NET 2.0 and 2010 needs to be .NET 3.51.

    On 2013 support for legacy Transport Agents was introduced so a 2010 should work if configured correctly see http://technet.microsoft.com/en-us/library/jj591524(v=exchg.150).aspx

    The SDK for 2007 is available on http://msdn.microsoft.com/en-us/library/exchange/aa562613(v=exchg.80).aspx (there is no separate Transport Agent SDK on 2007 this started in 2010)

    Cheers
    Glen

    • Marked as answer by DavidThi808 Saturday, August 24, 2013 9:20 PM
    Monday, August 19, 2013 2:55 AM
  • Guys,

    Glen is correct that you must build against the right DLLs otherwise you'll crash the transport service, however....

    Keep in mind that the SDKs are just documentation and examples (and you don't actually even need them to build an agent but the examples are fairly helpful). The actual APIs are exposed by the DLLs of Exchange itself (Microsoft.Exchange.Data.Transport.dll and Microsoft.Exchange.Data.Common.dll etc). More importantly while the SDK may have been the law at the time they were released (e.g. that you need to use 2.0 to build an agent for 2007) Exchange is updated constantly and things change.

    Anyway, try it yourself, you can build an Exchange 2007 agent using 3.5. I've been doing for years and frankly I'd go nuts if I had to use 2.0 again (support for 3.5 was added way back in 2009 from memory).

    Also these Exchange transport agents DLLs are generally forward compatible (and yes that includes from 2007 to 2010). If you choose a base level version of Exchange 2007 that you want your agent to support (for example Exchange 2007 SP2) and build your agent against its DLLs (literally copy the DLLs from a hub server to your development PC and use them as the references in your project), then your agent should work on that version and newer versions of 2007, 2010 (and 2013). If you this wasn't the case you'd need to build a new agent for every single version and service pack of Exchange that was released. Can you imagine the outcry if every service pack or roll-up for Exchange broke every agent for the prior version ?? Luckily that isn't the case.

    Cheers,

    Scott


    Scott Quinn | C# developer & messaging specialist (for hire). Contact me at http://au.linkedin.com/in/scottquinn

    • Marked as answer by DavidThi808 Sunday, August 25, 2013 2:08 PM
    Sunday, August 25, 2013 2:51 AM

All replies

  • No on 2007 and 2010 you need to compile your agent against the Public binaries Microsoft.Exchange.Data.Common.dll and Microsoft.Exchange.Transport.dll. These change between different versions of Exchange and Service Pack levels as functionality does differ at the Service Pack level. If you don't have the Agent compiled against the correct SP version it won't work and will cause the Transport Service to shut down. Also on 2007 the Agent needs to .NET 2.0 and 2010 needs to be .NET 3.51.

    On 2013 support for legacy Transport Agents was introduced so a 2010 should work if configured correctly see http://technet.microsoft.com/en-us/library/jj591524(v=exchg.150).aspx

    The SDK for 2007 is available on http://msdn.microsoft.com/en-us/library/exchange/aa562613(v=exchg.80).aspx (there is no separate Transport Agent SDK on 2007 this started in 2010)

    Cheers
    Glen

    • Marked as answer by DavidThi808 Saturday, August 24, 2013 9:20 PM
    Monday, August 19, 2013 2:55 AM
  • David,

    As long as you build your agent against the most up to date 2007 libraries using .NET 3.5 it will work on 2007 and 2010 (and most likely 2013) as long as the hubs themselves are patched / up to date.

    Cheers,

    Scott


    Scott Quinn | C# developer & messaging specialist (for hire). Contact me at http://au.linkedin.com/in/scottquinn

    Thursday, August 22, 2013 1:39 PM
  • Guys,

    Glen is correct that you must build against the right DLLs otherwise you'll crash the transport service, however....

    Keep in mind that the SDKs are just documentation and examples (and you don't actually even need them to build an agent but the examples are fairly helpful). The actual APIs are exposed by the DLLs of Exchange itself (Microsoft.Exchange.Data.Transport.dll and Microsoft.Exchange.Data.Common.dll etc). More importantly while the SDK may have been the law at the time they were released (e.g. that you need to use 2.0 to build an agent for 2007) Exchange is updated constantly and things change.

    Anyway, try it yourself, you can build an Exchange 2007 agent using 3.5. I've been doing for years and frankly I'd go nuts if I had to use 2.0 again (support for 3.5 was added way back in 2009 from memory).

    Also these Exchange transport agents DLLs are generally forward compatible (and yes that includes from 2007 to 2010). If you choose a base level version of Exchange 2007 that you want your agent to support (for example Exchange 2007 SP2) and build your agent against its DLLs (literally copy the DLLs from a hub server to your development PC and use them as the references in your project), then your agent should work on that version and newer versions of 2007, 2010 (and 2013). If you this wasn't the case you'd need to build a new agent for every single version and service pack of Exchange that was released. Can you imagine the outcry if every service pack or roll-up for Exchange broke every agent for the prior version ?? Luckily that isn't the case.

    Cheers,

    Scott


    Scott Quinn | C# developer & messaging specialist (for hire). Contact me at http://au.linkedin.com/in/scottquinn

    • Marked as answer by DavidThi808 Sunday, August 25, 2013 2:08 PM
    Sunday, August 25, 2013 2:51 AM
  • Hello

    I hope someone can help clarify this a little more as I read conflicting statements.

    I understand that 2010 use Net3.5 and E2013/2016 use Net4+ so it would be best to have two separate releases so I would not have to enable legacy support.

    We are now 2017 so disregarding E2007/2010, how are things with E2013/2016 and all the different CU's?

    Can I build a release against assemblies from E2013 and then have it work directly on E2016 or should I have two different builds against corresponding assemblies?

    And what of the various CU's? I read someone in forum saying that a new CU broke his installation, and only a new build against that solved it. Someone talked about GAC reference redirecting not working properly. Any thoughts on that?

    If backwards compatability is working in newer releases of Exchange do I then have to do anything special to provide for this, or is it automatic?

    If backward is not working what will actually happen when a CU is added to an installation? Will the Transport service fail like Glen writes?

    And lastly concerning assembly references. I have copyied public assemblies to a folder called "References" in my project and referenced those, and have set "Copy Local" false. Will this ensure my agent will automatically find the reference in GAC instead? Is any actions/settings required on my part to facilitate this?

    Any low-level practical directions like how to organise assemblies in which folders and other general practised is highly appreciated.

    I will also conduct test to see if I can verify these things and report any findings so as to help.

    Warm regards, Kristian in Denmark

    Thursday, October 26, 2017 12:54 PM
  • Okay I believe I have finally put it together.

    The EWS assemblies are of course strong name assemblies, and they are in the GAC on an Exchange server.
    So, the first important step is to make sure that the project has set the "Copy Local" to false on these references.
    This ensures that they do not get in to the installer and into the installation folder of the application being developed.

    When the application tries to load the assemblies, it will see the strong name in the manifest of the application.
    In my case it looks like this when looked at by ILDasm.

    .assembly extern Microsoft.Exchange.Data.Transport
    {
      .publickeytoken = (31 BF 38 56 AD 36 4E 35 )                         // 1.8V.6N5
      .ver 15:0:843:0
    }
    .assembly extern Microsoft.Exchange.Data.Common
    {
      .publickeytoken = (31 BF 38 56 AD 36 4E 35 )                         // 1.8V.6N5
      .ver 15:0:843:0
    }

    So the GAC will be queried to located them.

    The default versioning policy, unless overridden by a publisher policy file bindingRedirection, will be to look at the Major.Minor part to determine if it is compatible. When the version number of a component only changes according to its build and revision parts, it is considered compatible. A version is composed like this: Major.Minor.Build.Revision

    MS has made a nice document with all release numbers of Exchange.

    And looking a 2013 I see:

    Exchange Server 2013 CU18 September 19, 2017 15.00.1347.002
    Exchange Server 2013 CU17 June 27, 2017 15.00.1320.004
    ....
    Exchange Server 2013 CU2 July 9, 2013 15.00.0712.024
    Exchange Server 2013 CU1 April 2, 2013 15.00.0620.029
    Release to Manufacturing (RTM) version of Exchange Server 2013 December 3, 2012 15.00.0516.032

    I notice that the Major.Minor does not vary at all. And therefore, it should be expected that an application will not suffer compatibility problems while adding new CU.

    This leaves the question whether or not a TA developed for 2013 will actually also work with 2016.

    As I understand it, then the GAC will not consider the reference compatible by default, because the version of 2016 is:
    <Exchange Server 2016 RTM October 1, 2015 15.01.0225.042>
    So Minor is now .01.

    This can however be amended by a bindingRedirect.

    So if the Major or Minor vary then the CLR will consult the <assemblyBinding> node of the assembly policy (if any is found) to see if there is any overriding redirect in place.

    There is good explanation here:
    https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/redirect-assembly-versions

    Quote:
    Vendors of assemblies can direct apps to a newer version of an assembly by including a publisher policy file with the new assembly. The publisher policy file, which is located in the global assembly cache, contains assembly redirection settings.

    Each major.minor version of an assembly has its own publisher policy file. For example, redirections from version 2.0.2.222 to 2.0.3.000 and from version 2.0.2.321 to version 2.0.3.000 both go into the same file, because they are associated with version 2.0. However, a redirection from version 3.0.0.999 to version 4.0.0.000 goes into the file for version 3.0.999. Each major version of the .NET Framework has its own publisher policy file.

    If a publisher policy file exists for an assembly, the runtime checks this file after checking the assembly's manifest and app configuration file. Vendors should use publisher policy files only when the new assembly is backward compatible with the assembly being redirected.
    Unquote

    (The FUSLOGVW.exe can be used to see bindings or failures. (From Start->VS-> Developer Command Prompt))

    I have scoured around the GAC to look for a policy, but it eluded me a long time.

    Finally found assembly here:
    C:\Windows\Microsoft.NET\assembly\GAC_MSIL\Microsoft.Exchange.Data.Transport\v4.0_15.0.843.0__31bf3856ad364e35

    And policy is in:
    C:\Windows\Microsoft.NET\assembly\GAC_MSIL\policy.15.0.Microsoft.Exchange.Data.Transport\v4.0_15.0.847.30__31bf3856ad364e35

    Open Microsoft.Exchange.Data.Transport.VersionPolicy.cfg with notepad.

    On Exch 2016 you will find policies for all previous versions

    There will be folders called
    policy.15.0.Microsoft.Exchange.Data.Transport
    and
    policy.15.1.Microsoft.Exchange.Data.Transport

    15.0 contains:
    <dependentAssembly>
            <assemblyIdentity
              name="Microsoft.Exchange.Data.Transport"
              publicKeyToken="31bf3856ad364e35"
              culture="neutral" />
            <bindingRedirect
              oldVersion="08.0.681.0-15.00.843.0"
              newVersion="15.00.843.0"/>
          </dependentAssembly>

    So essentially it says that any call to the assembly is backward compatible.

    But notice how it will not be possible to use a reference to 15.1 (2016) on a 2013 installation. You cannot find 15.1 on Exchange 2013, and there is NO redirect either. So, compiling against 2016 assemblies does not give you option to install on Exch 2013. Keep in mind you should develop with lowest version you expect to run on.

    Thus, the only concern is the .Net version being 3.5 in which case it is necessary to enable legacy support if I have understood it correctly because Exch 2013&2016 are both developed for 4.0+ and does not like assemblies compiled for 3.5.

    In summary; if you build against 2013 and install on 2013, then the policy is not in play, and if you build against 2013 and install on 2016 the policy will dictate what happens. I say it like that because in CU1 of Exch 2016 MS bungled the redirect and installed agents failed to run.

    As I am not so well versed in all this please correct me on any point you like.
    It was a long comment, but as I am making an installer for a TA, I needed to know with absolute certainty what was to happen in the future when clients start adding CU's to their installations.

    Monday, October 30, 2017 3:52 PM