Building a layer file from XPO files


Updated 30-06-2012 official beta version available here: http://informationsource.dynamics.com/RFPServicesOnline/Rfpservicesonline.aspx?ToolName=Microsoft+Dynamics+AX+2012+Combine+XPO+Tool+Beta+1.0

Updated 14-01-2011 to support UniCode XPO files. Notice the change in parameters.

So now you are using version control – and you just realized the master is no longer the AOD layer file, but instead a zillion of XPO files. Still you want to provide an AOD file to your consumers, as that is the way to deploy an AX application.

Page 96 in Inside Dynamics AX 2009 contains a description on how to build an AOD file from XPO files. In this section an SDK and a tool are mentioned. While we are working on providing you with the SDK for building a layer file, I can make the CombineXPOs.exe tool available.

See the attached file.

Usage: CombineXPOs.exe -XpoDir XPOfolder -CombinedXpoFile DestinationFile.xpo -utf8

Example: CombineXPOs.exe -XpoDir USR -CombinedXpoFile myFile.xpo

Files in the XPOFolder folder must match the AOT structure. This is automatically ensured when using AX version control integration.

This posting is provided “AS IS” with no warranties, and confers no rights.

 

 

 

CombineXPOs.zip

Comments (20)

  1. Hello says:

    Can you please provide step by step process on how to use this combineXPO file as we got a requirement to combine multiple XPOs into a single XPO.

  2. Gert says:

    does the tool also work for visual studio projects in the AOT?

  3. Peterson says:

    Hey Kurt, you can explain better how you create the automated build with TFS? You can share with us? thx!

  4. msmfp says:

    I'm not too proud of my turnaround time here… 🙂

  5. Ashish says:

    Thanks Michael for uploading new version so quickly.

  6. msmfp says:

    ksp – a new version has just been uploaded. It supports UniCode. Sorry for taking so long, and thank you to Ashish for pointint this out to me offline.

  7. msmfp says:

    Ashish – the problem and solution is described above. You have empty files in your depot.

  8. Ashish says:

    I am using combinedXPO.exe file to create the combined xpo file from my local repository.

    It ignored most of the objects in my repository and not included them in the combinedxpo file.

    I got the latest copy from tfs before running the combinedXPO exe.

    Could you please let me know the cause why combinedXPO tool is ignoring some xpo files and how it will include all objects in combinexpo file.

  9. Ashish says:

    Can you please send me the script to create automated build at ashish_2003@yahoo.com?

    Thanks

  10. ksp says:

    Is it possible to get a new version of CombineXPO.exe?

    We have an issue with the provided version as it creates XPO files in a different format than AX 2009. AX 2009 uses UTF-8 for XPO fils and the files created by the tool are "UTF-8 without BOM" format.

    That causes umlauts ä,ö,ü etc to be destroyed in the created file.

  11. blitz says:

    I’m trying to call the CombineXPOs cmd, and I’m having a path issue. I’m obviously have this wrong – how should it be?

    <exec command="CombineXPOs.exe C:DAX_Mainusr C:Main.xpo" />

  12. Problem with special characters says:

    We are using the the CombineXPO tool for for moving XPO’s between the different environments within the our OTAP setup. Unfortunattely we are experiencing problems with special characters within labels and code. How can we avoid this problem using the tool?

    Example:

    Extract from Individual XPO:

    <Table:Field name="Label">Geëxporteerd naar exact</Table:Field>

    Extract from Combined XPO:

    <Table:Field name="Label">Geëxporteerd naar exact</Table:Field>

  13. msmfp says:

    Instead of the "-startupcmd=AotImport_" you should use "-AOTImportFile=<filename>"  It will skip dialogs, and is somewhat faster.

  14. KurtVdB says:

    We are creating an automatic build procedure for AX 2009 using Team Foundation Server as a repository.

    Within the procedure we are using the <CombineXPOs.exe>.

    After the CombineXPOs we want to do an import of the newly created XPO. During the import (using ax32.exe –internal=noModalBoxes -startupcmd=AOTImport_.newVersion.xpo) we are prompted with messages e.g. : "Overwrite <object> ?".

    The automatic build should be able to run during the night as a job (no user interface)

    – Is it possible to skip the dialogs or provide a default answer (YES)?

    KVdB

    kurt@dev.be

  15. Chris Rothery says:

    Sorry to be spamming this post but I’ve thought a bit more about my code above.  It could (and should) be easily adapted to move the files to one side (e.g. rename to _<filename>) and move them back again (pass a 2nd argument to rename any _<filename> files) which should appease Ax.

    Chris

  16. Chris Rothery says:

    I’ve written a program that deletes the offending files (so you could write a bat file that runs this then CombineXPOs.exe).

    The idea is that these files shouldn’t really have hit Visual SourceSafe yet as they haven’t been committed by the developer.  When they commit their new creation it will properly be in the directory.

    Next time you do ‘get latest’ from SourceSafe, the files reappear. (possible future improvement might be to have the ‘get latest’ run from my bat file.

    It compiles up OK in Visual Studio 2008 C# Express Edition so if you don’t have VS installed, now’s a good excuse to!  Please study the code carefully and be very sure you’re happy to run it before you do as this code is provided with no guarantees or warranties.

    Also if this is a really bad idea, I’d appreciate someone telling me!!  So far the only side effect I can see is that Ax gets a bit confused if it was actually you that did the create (it’ll offer you the chance to create again as it can’t find the xpo) but if you ignore that and check in as normal that still works ok.

    Here’s the code:

    using System;

    using System.Text;

    using System.IO;

    namespace DeleteEmptyXPOs

    {

       class Program

       {

           private String _baseDir;

           private String[] linesToCheckFor = {

                                        "Exportfile for AOT version 1.0 or later",

                                        "Formatversion: 1",

                                        "",

                                        "***Element: END"

                                    };

           public Program(String baseDir)

           {

               _baseDir = baseDir;

           }

           static void Main(string[] args)

           {

               if (args.Length == 0)

               {

                   Console.WriteLine("Usage: DeleteEmptyXPOs <baseDir>");

                   return;

               }

               Program p = new Program(args[0]);

               p.FindFiles();

               Console.WriteLine("Press enter");

               Console.ReadLine();

           }

           void FindFiles()

           {            

               Console.WriteLine("Directory {0}", _baseDir);

               String[] fileNames = Directory.GetFiles(_baseDir, "*", SearchOption.AllDirectories);

               String readLine;

               Boolean found;

               foreach (String fileName in fileNames)

               {

                   StreamReader sr = new StreamReader(fileName);

                   found = true;

                   foreach (String lineToCheckFor in linesToCheckFor)

                   {

                       readLine = sr.ReadLine();

                       if (!lineToCheckFor.Equals(readLine))

                       {

                           found = false;

                           break;

                       }                    

                   }

                   sr.Close();

                   if (found)

                   {

                       try

                       {

                           FileAttributes a = FileAttributes.Normal;                        

                           File.SetAttributes(fileName, a);

                           File.Delete(fileName);

                       }

                       catch (System.IO.IOException e)

                       {

                           Console.WriteLine("Error deleting {0}n    {1}", fileName, e.Message);

                       }

                       Console.WriteLine("  {0} deleted", fileName);

                   }

               }            

           }

       }

    }

  17. Chris Rothery says:

    I’ve been trying this tool out as I really like the sound of this as an alternative to the rather flaky Syncronize source control option that we’ve been using.

    I however have the same problem in that objects that have been created by a developer in AX but not checked in yet create a 4 line xpo like thensley’s above which causes an exception in CombineXPOs.exe.

    Are there any updates to the tool available or, failing that, can the community have a go at fixing it?

    Regards and keep up the good work

    Chris Rothery

  18. thensley@firstsolar.com says:

    Actually, I am also getting this error for new objects that people have created but not yet checked in.

    Apparently, as soon as you create a new object in the AOT, you get an XPO file like this in VSS:

    <begin XPO>

    Exportfile for AOT version 1.0 or later

    Formatversion: 1

    ***Element: END

    <end XPO>

    CombineXPOs does NOT like these.

    Any chance of opening up the source for CombineXPOs so we can tweak it ourselves?

  19. msmfp says:

    This happens if you have a perspective without any tables in.

  20. satishdalal says:

    Hi Michael,

    I’m really impressed with this tool!!! and want to start using this for my projects!!! But, I just can’t get it to work with AX 4.0 SP1 🙁

    When i try using it, i get a string of errors as below:

    System.ArgumentOutOfRangeException: Length cannot be less than zero.

    Parameter name: length

      at System.String.InternalSubStringWithChecks(Int32 startIndex, Int32 length,

    Boolean fAlwaysCopy)

      at Microsoft.BusinessSolutions.Axapta.CombineXpos.XpoReader..ctor(String file

    )

      at Microsoft.BusinessSolutions.Axapta.CombineXpos.MainClass.AddFile(BinaryWri

    ter destinationFile, String filename)

      at Microsoft.BusinessSolutions.Axapta.CombineXpos.MainClass.AddFolder(BinaryW

    riter destinationFile, String path)

      at Microsoft.BusinessSolutions.Axapta.CombineXpos.MainClass.Main(String[] arg

    s)

Skip to main content