How to get programmatically the number of AppData\Roaming\SDL\ProjectApi folder?

I'm checking Studio 2019 SR2 and found that my code for getting the real default project template is failing...
It's failing because Studio 2019 screwed the folders numbering system which worked for years... Disappointed

So far the numbering system was simple and consistent:

    "Studio2"  {$StudioVersionAppData = "10.0.0.0"}
    "Studio3"  {$StudioVersionAppData = "11.0.0.0"}
    "Studio4"  {$StudioVersionAppData = "12.0.0.0"}
    "Studio5"  {$StudioVersionAppData = "14.0.0.0"}
    "Studio15" {$StudioVersionAppData = "15.0.0.0"}

But now I see that Studio 2019 SR1 - and also SR2 - has AppData\Roaming\SDL\ProjectApi\15.1.0.0 folder :-O :-O :-O

That number does not correspond to anything...
All other such numbered folders have 15.0.0.0 number.
SDLTradosStudio.exe product version is 15.0.0.0, file version is 15.2.0.1041.

So, where does this weird number come from and how do I get it programmatically, please?!
Of course I need it to work 100% realiably across ALL Studio versions, SRs and CUs.

Ultimately, I need to read the AppData\Roaming\ProjectApi\<number>\Sdl.ProjectApi.xml file, so if there is any other way to get its full path, I'm fine with that way too.

Parents Reply Children
  • Hi ,  I was checking back in today to see your progress and surprised to see the list of brusk comments from you in this thread.

    I'm NOT "integrating with" some particular version of Studio. That's an assumption based on very narrow-sighted approach of Studio plugins (that system of building separate plugin for each Studio version is REALLY ridiculous).

    Are you saying that there is no way to programmatically get this number/string?!
    Are you saying that even Studio itself uses such amateurish trial-and-error approach?!
    I can't believe it...

    Actually, in short, yes, you do need to integrate with a Major release of Studio and in your case this is Studio 2019, which corresponds to “15.x.x.x” In the semantic version convention that we employ with our release strategy.

    I confirmed your suspicion and provided you with a suggestion (a work-around if you like) on to how to go about resolving the folder path in question.  How you go about implementing that in your solution is entirely up to you. As it happens, provided you with very clever and probably the most appropriate solution, in identifying the folder path from the AssemblyVersion of that file.  This folder path in Studio is built from the AssemblyVersion information of the IApplication, which is also reflected by that assembly.

    I can also confirm with you that the versioning strategy for identifying these paths will return to [Major.0.0.0] going forward, irrespective of the SP version number.  however, it will not change for Studio 2019 now (e.g. it will remain as 15.1.0.0 > SP1+)

    Now, with regards your extracurricular remarks and assumptions: these are not productive, and although I see that you are seemingly annoyed by all of this -> please try to refrain from such remarks in future.

    We are here to support you in integrating with the product and identifying possible issues such as the one that you have highlighted in this thread.  Join a boxing gym if you feel like punching a bag!

  • Actually, in short, yes, you do need to integrate with a Major release of Studio and in your case this is Studio 2019, which corresponds to “15.x.x.x” In the semantic version convention that we employ with our release strategy.

    And that is exactly the point - all my universally usable tool needs is the major Studio version. I hope you got familiar with how it works by now, so that we can discuss some real thing, not just theory.

    So your suggestion to use the "latest valid path in sequential order" presumably fails to work e.g. when user installs the SR1 or SR2 for Studio (i.e. the 15.1.0.0 and/or 15.2.0.0 or god knows which folders get created) and then downgrades back to Studio 2019.

    Or maybe you need to elaborate in more details on what exactly do you mean by "latest valid" and how exactly am I supposed to identify that it's the latest and valid path.

    I hope you understand that this explanation is needed from SDL and that it's not "up to me" how do I implement it... simply because the fundamental knowledge "how" is - or at least should be - on SDL side, not mine.

    provided you with very clever and probably the most appropriate solution, in identifying the folder path from the AssemblyVersion of that file

    Sure, and I said that it's interesting discovery.
    But without clear confirmation from SDL side it's just an idea, nothing else. That's why I also said we need this confirmation.

    Does it mean that you confirm that this (via the AssemblyVersion of IApplication) is the future-proof way to get the number (or name, to be more precise) of the folder used by an instance of Studio?

    We are here to support you in integrating with the product and identifying possible issues such as the one that you have highlighted in this thread

    That's cool for sure.
    And I hope that you can understand how annoying and frustrating it is to find out that something was changed a) without notifying anyone and b) changed in a negative way (people would probably not be upset by positive changes)... and that it feels really alarming (and again also frustrating) that such issues are only discovered by users instead of being catched by internal testing before release.

  • Hi ,

    You can use the following code sample to identify the default application file; I'll create and publish a sample app later on today.

    private static string GetProjectApiFilePath(string studioInstallationPath)
    {
        var applicationVersion = GetApplicationVersion(studioInstallationPath);
        if (applicationVersion == null)
        {
            return null;
        }

        var applicationDataFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
        var projectApiFolder = Path.Combine(applicationDataFolder, Path.Combine("SDL", "ProjectApi"));
        var projectApiFile = Path.Combine(projectApiFolder, applicationVersion, "Sdl.ProjectApi.xml");

        return File.Exists(projectApiFile) ? projectApiFile : null;
    }

    private static string GetApplicationVersion(string studioInstallationPath)
    {
        var assemblyFile = Path.Combine(studioInstallationPath, "Sdl.ProjectApi.dll");
        return File.Exists(assemblyFile)
            ? System.Reflection.AssemblyName.GetAssemblyName(assemblyFile).Version.ToString()
            : null;
    }

    You can test with the following:

    var studio2014InstallationPath = @"C:\Program Files (x86)\SDL\SDL Trados Studio\Studio3";
    var studio2015InstallationPath = @"C:\Program Files (x86)\SDL\SDL Trados Studio\Studio4";
    var studio2017InstallationPath = @"C:\Program Files (x86)\SDL\SDL Trados Studio\Studio5";
    var studio2019InstallationPath = @"C:\Program Files (x86)\SDL\SDL Trados Studio\Studio15";

    var studio2014ProjectApiFilePath = GetProjectApiFilePath(studio2014InstallationPath);
    var studio2015ProjectApiFilePath = GetProjectApiFilePath(studio2015InstallationPath);
    var studio2017ProjectApiFilePath = GetProjectApiFilePath(studio2017InstallationPath);
    var studio2019ProjectApiFilePath = GetProjectApiFilePath(studio2019InstallationPath);