Bug 1024110 - Change Aurora's default profile behavior to use channel-specific profiles. r=bsmedberg f=gavin,markh
authorPanos Astithas <past@mozilla.com>
Tue, 23 Sep 2014 21:49:03 +0300
changeset 235021 5c1f21521572c64e751e1791a041d82a06601eec
parent 235020 8cf710385663ca9ba60b509ac4a59b62a786d729
child 235022 ed70c889afe8c62151e1cbb6f8e1f103b2b6cc95
push id611
push userraliiev@mozilla.com
push dateMon, 05 Jan 2015 23:23:16 +0000
treeherdermozilla-release@345cd3b9c445 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg
bugs1024110
milestone35.0a2
Bug 1024110 - Change Aurora's default profile behavior to use channel-specific profiles. r=bsmedberg f=gavin,markh
build/appini_header.py
build/application.ini
build/moz.build
configure.in
toolkit/profile/nsIToolkitProfileService.idl
toolkit/profile/nsToolkitProfileService.cpp
toolkit/xre/CreateAppData.cpp
toolkit/xre/nsAppRunner.cpp
toolkit/xre/nsNativeAppSupportWin.cpp
xpcom/build/nsXREAppData.h
xpcom/glue/AppData.cpp
--- a/build/appini_header.py
+++ b/build/appini_header.py
@@ -18,33 +18,34 @@ def main(file):
     except: pass
     try:
         if config.getint('Crash Reporter', 'Enabled') == 1:
             flags.add('NS_XRE_ENABLE_CRASH_REPORTER')
     except: pass
     appdata = dict(("%s:%s" % (s, o), config.get(s, o)) for s in config.sections() for o in config.options(s))
     appdata['flags'] = ' | '.join(flags) if flags else '0'
     appdata['App:profile'] = '"%s"' % appdata['App:profile'] if 'App:profile' in appdata else 'NULL'
-    expected = ('App:vendor', 'App:name', 'App:version', 'App:buildid',
+    expected = ('App:vendor', 'App:name', 'App:remotingname', 'App:version', 'App:buildid',
                 'App:id', 'Gecko:minversion', 'Gecko:maxversion')
     missing = [var for var in expected if var not in appdata]
     if missing:
         print >>sys.stderr, \
             "Missing values in %s: %s" % (file, ', '.join(missing))
         sys.exit(1)
 
     if not 'Crash Reporter:serverurl' in appdata:
         appdata['Crash Reporter:serverurl'] = ''
 
     print '''#include "nsXREAppData.h"
              static const nsXREAppData sAppData = {
                  sizeof(nsXREAppData),
                  NULL, // directory
                  "%(App:vendor)s",
                  "%(App:name)s",
+                 "%(App:remotingname)s",
                  "%(App:version)s",
                  "%(App:buildid)s",
                  "%(App:id)s",
                  NULL, // copyright
                  %(flags)s,
                  NULL, // xreDirectory
                  "%(Gecko:minversion)s",
                  "%(Gecko:maxversion)s",
--- a/build/application.ini
+++ b/build/application.ini
@@ -13,16 +13,17 @@
 ; This Source Code Form is subject to the terms of the Mozilla Public
 ; License, v. 2.0. If a copy of the MPL was not distributed with this
 ; file, You can obtain one at http://mozilla.org/MPL/2.0/.
 #endif
 #filter substitution
 [App]
 Vendor=@MOZ_APP_VENDOR@
 Name=@MOZ_APP_BASENAME@
+RemotingName=@MOZ_APP_REMOTINGNAME@
 #ifdef MOZ_APP_DISPLAYNAME
 CodeName=@MOZ_APP_DISPLAYNAME@
 #endif
 Version=@MOZ_APP_VERSION@
 #ifdef MOZ_APP_PROFILE
 Profile=@MOZ_APP_PROFILE@
 #endif
 BuildID=@APP_BUILDID@
--- a/build/moz.build
+++ b/build/moz.build
@@ -22,17 +22,17 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'andr
         'mobile/sutagent/android/watcher',
         'mobile/sutagent/android/ffxcp',
         'mobile/sutagent/android/fencp',
         'mobile/robocop',
     ]
 
 for var in ('GRE_MILESTONE', 'MOZ_APP_VERSION', 'MOZ_APP_BASENAME',
             'MOZ_APP_VENDOR', 'MOZ_APP_ID', 'MAR_CHANNEL_ID',
-            'ACCEPTED_MAR_CHANNEL_IDS'):
+            'ACCEPTED_MAR_CHANNEL_IDS', 'MOZ_APP_REMOTINGNAME'):
     DEFINES[var] = CONFIG[var]
 
 if CONFIG['MOZ_APP_DISPLAYNAME'] != CONFIG['MOZ_APP_BASENAME']:
     DEFINES['MOZ_APP_DISPLAYNAME'] = CONFIG['MOZ_APP_DISPLAYNAME']
 
 if CONFIG['MOZ_BUILD_APP'] == 'browser':
     DEFINES['MOZ_BUILD_APP_IS_BROWSER'] = True
 
--- a/configure.in
+++ b/configure.in
@@ -8675,26 +8675,32 @@ AC_SUBST(MOZ_CHILD_PROCESS_BUNDLE)
 # the absence of a "Profile" field (see below), and various system
 # integration hooks (Unix remoting, Windows MessageWindow name, etc.)
 # - MOZ_APP_DISPLAYNAME: Used in user-visible fields (DLL properties,
 # Mac Bundle name, Updater, Installer), it is typically used for nightly
 # builds (e.g. Aurora for Firefox).
 # - MOZ_APP_VERSION: Defines the application version number.
 # - MOZ_APP_NAME: Used for e.g. the binary program file name. If not set,
 # defaults to a lowercase form of MOZ_APP_BASENAME.
+# - MOZ_APP_REMOTINGNAME: Used for the internal program name, which affects
+# profile name and remoting. If not set, defaults to MOZ_APP_NAME.
 # - MOZ_APP_PROFILE: When set, used for application.ini's
 # "Profile" field, which controls profile location.
 # - MOZ_APP_ID: When set, used for application.ini's "ID" field, and
 # crash reporter server url.
 # - MOZ_PROFILE_MIGRATOR: When set, enables profile migrator.
 
 if test -z "$MOZ_APP_NAME"; then
    MOZ_APP_NAME=`echo $MOZ_APP_BASENAME | tr A-Z a-z`
 fi
 
+if test -z "$MOZ_APP_REMOTINGNAME"; then
+   MOZ_APP_REMOTINGNAME=$MOZ_APP_NAME
+fi
+
 # For extensions and langpacks, we require a max version that is compatible
 # across security releases. MOZ_APP_MAXVERSION is our method for doing that.
 # 24.0a1 and 24.0a2 aren't affected
 # 24.0 becomes 24.*
 # 24.1.1 becomes 24.*
 IS_ALPHA=`echo $MOZ_APP_VERSION | grep a`
 if test -z "$IS_ALPHA"; then
   changequote(,)
@@ -8704,16 +8710,17 @@ else
   MOZ_APP_MAXVERSION=$MOZ_APP_VERSION
 fi
 
 MOZ_B2G_VERSION=${MOZ_B2G_VERSION:-"1.0.0"}
 AC_DEFINE_UNQUOTED(MOZ_B2G_VERSION,"$MOZ_B2G_VERSION")
 AC_DEFINE_UNQUOTED(MOZ_B2G_OS_NAME,"$MOZ_B2G_OS_NAME")
 
 AC_SUBST(MOZ_APP_NAME)
+AC_SUBST(MOZ_APP_REMOTINGNAME)
 AC_SUBST(MOZ_APP_DISPLAYNAME)
 AC_SUBST(MOZ_APP_BASENAME)
 AC_SUBST(MOZ_APP_VENDOR)
 AC_SUBST(MOZ_APP_PROFILE)
 AC_SUBST(MOZ_APP_ID)
 AC_SUBST(MAR_CHANNEL_ID)
 AC_SUBST(ACCEPTED_MAR_CHANNEL_IDS)
 AC_SUBST(MOZ_PROFILE_MIGRATOR)
@@ -8994,16 +9001,20 @@ if test "$ACCESSIBILITY" -a "$MOZ_ENABLE
     ATK_MAJOR_VERSION=`echo ${ATK_FULL_VERSION} | $AWK -F\. '{ print $1 }'`
     ATK_MINOR_VERSION=`echo ${ATK_FULL_VERSION} | $AWK -F\. '{ print $2 }'`
     ATK_REV_VERSION=`echo ${ATK_FULL_VERSION} | $AWK -F\. '{ print $3 }'`
     AC_DEFINE_UNQUOTED(ATK_MAJOR_VERSION, $ATK_MAJOR_VERSION)
     AC_DEFINE_UNQUOTED(ATK_MINOR_VERSION, $ATK_MINOR_VERSION)
     AC_DEFINE_UNQUOTED(ATK_REV_VERSION, $ATK_REV_VERSION)
 fi
 
+if test "$MOZ_UPDATE_CHANNEL" = "aurora"; then
+    AC_DEFINE(MOZ_DEV_EDITION)
+fi
+
 if test "$MOZ_DEBUG"; then
     A11Y_LOG=1
 fi
 case "$MOZ_UPDATE_CHANNEL" in
 aurora|beta|release|esr)
     ;;
 *)
     A11Y_LOG=1
@@ -9312,16 +9323,17 @@ if test -n "$MOZ_GLUE_PROGRAM_LDFLAGS"; 
 fi
 if test -n "$ZLIB_IN_MOZGLUE"; then
    MOZ_ZLIB_LIBS=
 fi
 export MOZ_NATIVE_ZLIB
 export MOZ_ZLIB_CFLAGS
 export MOZ_ZLIB_LIBS
 export MOZ_APP_NAME
+export MOZ_APP_REMOTINGNAME
 export DONT_POPULATE_VIRTUALENV=1
 export PYTHON
 export MOZILLA_CENTRAL_PATH=$_topsrcdir
 export STLPORT_CPPFLAGS
 export STLPORT_LIBS
 export JS_STANDALONE=no
 export MOZ_LINKER
 export ZLIB_IN_MOZGLUE
--- a/toolkit/profile/nsIToolkitProfileService.idl
+++ b/toolkit/profile/nsIToolkitProfileService.idl
@@ -13,19 +13,31 @@ interface nsIProfileLock;
 [scriptable, uuid(b81c33a6-1ce8-4695-856b-02b7f15cc114)]
 interface nsIToolkitProfileService : nsISupports
 {
     attribute boolean startWithLastProfile;
     attribute boolean startOffline;
 
     readonly attribute nsISimpleEnumerator /*nsIToolkitProfile*/ profiles;
 
+    /**
+     * The currently selected profile (the one used or about to be used by the
+     * browser).
+     */
     attribute nsIToolkitProfile selectedProfile;
 
     /**
+     * The default profile (the one used or about to be used by the
+     * browser if no other profile is specified at runtime). This is the profile
+     * marked with Default=1 in profiles.ini and is usually the same as
+     * selectedProfile, except on Developer Edition.
+     */
+    attribute nsIToolkitProfile defaultProfile;
+
+    /**
      * Get a profile by name. This is mainly for use by the -P
      * commandline flag.
      *
      * @param aName The profile name to find.
      */
     nsIToolkitProfile getProfileByName(in AUTF8String aName);
 
     /**
--- a/toolkit/profile/nsToolkitProfileService.cpp
+++ b/toolkit/profile/nsToolkitProfileService.cpp
@@ -134,16 +134,17 @@ private:
                                    const nsACString* aAppName,
                                    const nsACString* aVendorName,
                                    /*in*/ nsIFile** aProfileDefaultsDir,
                                    bool aForExternalApp,
                                    nsIToolkitProfile** aResult);
 
     nsRefPtr<nsToolkitProfile>  mFirst;
     nsCOMPtr<nsIToolkitProfile> mChosen;
+    nsCOMPtr<nsIToolkitProfile> mDefault;
     nsCOMPtr<nsIFile>           mAppData;
     nsCOMPtr<nsIFile>           mTempData;
     nsCOMPtr<nsIFile>           mListFile;
     bool mDirty;
     bool mStartWithLast;
     bool mStartOffline;
 
     static nsToolkitProfileService *gService;
@@ -419,16 +420,17 @@ nsToolkitProfileService::Init()
     nsAutoCString buffer;
     rv = parser.GetString("General", "StartWithLastProfile", buffer);
     if (NS_SUCCEEDED(rv) && buffer.EqualsLiteral("0"))
         mStartWithLast = false;
 
     nsToolkitProfile* currentProfile = nullptr;
 
     unsigned int c = 0;
+    bool foundAuroraDefault = false;
     for (c = 0; true; ++c) {
         nsAutoCString profileID("Profile");
         profileID.AppendInt(c);
 
         rv = parser.GetString(profileID.get(), "IsRelative", buffer);
         if (NS_FAILED(rv)) break;
 
         bool isRelative = buffer.EqualsLiteral("1");
@@ -436,17 +438,19 @@ nsToolkitProfileService::Init()
         nsAutoCString filePath;
 
         rv = parser.GetString(profileID.get(), "Path", filePath);
         if (NS_FAILED(rv)) {
             NS_ERROR("Malformed profiles.ini: Path= not found");
             continue;
         }
 
-        rv = parser.GetString(profileID.get(), "Name", buffer);
+        nsAutoCString name;
+
+        rv = parser.GetString(profileID.get(), "Name", name);
         if (NS_FAILED(rv)) {
             NS_ERROR("Malformed profiles.ini: Name= not found");
             continue;
         }
 
         nsCOMPtr<nsIFile> rootDir;
         rv = NS_NewNativeLocalFile(EmptyCString(), true,
                                    getter_AddRefs(rootDir));
@@ -465,25 +469,58 @@ nsToolkitProfileService::Init()
                                        getter_AddRefs(localDir));
             NS_ENSURE_SUCCESS(rv, rv);
 
             rv = localDir->SetRelativeDescriptor(mTempData, filePath);
         } else {
             localDir = rootDir;
         }
 
-        currentProfile = new nsToolkitProfile(buffer,
+        currentProfile = new nsToolkitProfile(name,
                                               rootDir, localDir,
                                               currentProfile, false);
         NS_ENSURE_TRUE(currentProfile, NS_ERROR_OUT_OF_MEMORY);
 
         rv = parser.GetString(profileID.get(), "Default", buffer);
-        if (NS_SUCCEEDED(rv) && buffer.EqualsLiteral("1"))
+        if (NS_SUCCEEDED(rv) && buffer.EqualsLiteral("1") && !foundAuroraDefault) {
+            mChosen = currentProfile;
+            this->SetDefaultProfile(currentProfile);
+        }
+#ifdef MOZ_DEV_EDITION
+        // Use the dev-edition-default profile if this is an Aurora build.
+        if (name.EqualsLiteral("dev-edition-default")) {
             mChosen = currentProfile;
+            foundAuroraDefault = true;
+        }
+#endif
     }
+
+#ifdef MOZ_DEV_EDITION
+    // Check if we are running Firefox, as we don't want to create a profile
+    // on webapprt.
+    bool isFirefox = strcmp(gAppData->ID,
+                            "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}") == 0;
+    if (!foundAuroraDefault && isFirefox) {
+        // If a single profile exists, it may not be already marked as default.
+        // Do it now to avoid problems when we create the dev-edition-default profile.
+        if (!mChosen && mFirst && !mFirst->mNext)
+            this->SetDefaultProfile(mFirst);
+
+        // Create a default profile for aurora, if none was found.
+        nsCOMPtr<nsIToolkitProfile> profile;
+        rv = CreateProfile(nullptr,
+                           NS_LITERAL_CSTRING("dev-edition-default"),
+                           getter_AddRefs(profile));
+        if (NS_FAILED(rv)) return rv;
+        mChosen = profile;
+        rv = Flush();
+        if (NS_FAILED(rv)) return rv;
+    }
+#endif
+
     if (!mChosen && mFirst && !mFirst->mNext) // only one profile
         mChosen = mFirst;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsToolkitProfileService::SetStartWithLastProfile(bool aValue)
 {
@@ -565,16 +602,35 @@ nsToolkitProfileService::SetSelectedProf
     if (mChosen != aProfile) {
         mChosen = aProfile;
         mDirty = true;
     }
     return NS_OK;
 }
 
 NS_IMETHODIMP
+nsToolkitProfileService::GetDefaultProfile(nsIToolkitProfile* *aResult)
+{
+    if (!mDefault) return NS_ERROR_FAILURE;
+
+    NS_ADDREF(*aResult = mDefault);
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsToolkitProfileService::SetDefaultProfile(nsIToolkitProfile* aProfile)
+{
+    if (mDefault != aProfile) {
+        mDefault = aProfile;
+        mDirty = true;
+    }
+    return NS_OK;
+}
+
+NS_IMETHODIMP
 nsToolkitProfileService::GetProfileByName(const nsACString& aName,
                                           nsIToolkitProfile* *aResult)
 {
     nsToolkitProfile* curP = mFirst;
     while (curP) {
         if (curP->mName.Equals(aName)) {
             NS_ADDREF(*aResult = curP);
             return NS_OK;
@@ -927,17 +983,19 @@ nsToolkitProfileService::Flush()
         end += sprintf(end,
                        "[Profile%u]\n"
                        "Name=%s\n"
                        "IsRelative=%s\n"
                        "Path=%s\n",
                        pCount, cur->mName.get(),
                        isRelative ? "1" : "0", path.get());
 
-        if (mChosen == cur) {
+        nsCOMPtr<nsIToolkitProfile> profile;
+        rv = this->GetDefaultProfile(getter_AddRefs(profile));
+        if (NS_SUCCEEDED(rv) && profile == cur) {
             end += sprintf(end, "Default=1\n");
         }
 
         end += sprintf(end, "\n");
 
         cur = cur->mNext;
         ++pCount;
     }
--- a/toolkit/xre/CreateAppData.cpp
+++ b/toolkit/xre/CreateAppData.cpp
@@ -96,23 +96,24 @@ XRE_ParseAppData(nsIFile* aINIFile, nsXR
   nsINIParser parser;
   rv = parser.Init(aINIFile);
   if (NS_FAILED(rv))
     return rv;
 
   nsCString str;
 
   ReadString strings[] = {
-    { "App", "Vendor",    &aAppData->vendor },
-    { "App", "Name",      &aAppData->name },
-    { "App", "Version",   &aAppData->version },
-    { "App", "BuildID",   &aAppData->buildID },
-    { "App", "ID",        &aAppData->ID },
-    { "App", "Copyright", &aAppData->copyright },
-    { "App", "Profile",   &aAppData->profile },
+    { "App", "Vendor",        &aAppData->vendor },
+    { "App", "Name",          &aAppData->name },
+    { "App", "RemotingName",  &aAppData->remotingName },
+    { "App", "Version",       &aAppData->version },
+    { "App", "BuildID",       &aAppData->buildID },
+    { "App", "ID",            &aAppData->ID },
+    { "App", "Copyright",     &aAppData->copyright },
+    { "App", "Profile",       &aAppData->profile },
     { nullptr }
   };
   ReadStrings(parser, strings);
 
   ReadFlag flags[] = {
     { "XRE", "EnableProfileMigrator", NS_XRE_ENABLE_PROFILE_MIGRATOR },
     { nullptr }
   };
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -1649,17 +1649,17 @@ HandleRemoteArgument(const char* remote,
 }
 
 static RemoteResult
 RemoteCommandLine(const char* aDesktopStartupID)
 {
   nsresult rv;
   ArgResult ar;
 
-  nsAutoCString program(gAppData->name);
+  nsAutoCString program(gAppData->remotingName);
   ToLowerCase(program);
   const char *username = getenv("LOGNAME");
 
   const char *temp = nullptr;
   ar = CheckArg("a", true, &temp);
   if (ar == ARG_BAD) {
     PR_fprintf(PR_STDERR, "Error: argument -a requires an application name\n");
     return REMOTE_ARG_BAD;
@@ -4143,17 +4143,17 @@ XREMain::XRE_mainRun()
 
   if (!mShuttingDown) {
 #ifdef MOZ_ENABLE_XREMOTE
     // if we have X remote support, start listening for requests on the
     // proxy window.
     if (!mDisableRemote)
       mRemoteService = do_GetService("@mozilla.org/toolkit/remote-service;1");
     if (mRemoteService)
-      mRemoteService->Startup(mAppData->name, mProfileName.get());
+      mRemoteService->Startup(mAppData->remotingName, mProfileName.get());
 #endif /* MOZ_ENABLE_XREMOTE */
 
     mNativeApp->Enable();
   }
 
 #ifdef MOZ_INSTRUMENT_EVENT_LOOP
   if (PR_GetEnv("MOZ_INSTRUMENT_EVENT_LOOP")) {
     bool logToConsole = true;
@@ -4191,16 +4191,19 @@ XREMain::XRE_main(int argc, char* argv[]
   gArgc = argc;
   gArgv = argv;
 
   NS_ENSURE_TRUE(aAppData, 2);
 
   mAppData = new ScopedAppData(aAppData);
   if (!mAppData)
     return 1;
+  if (!mAppData->remotingName) {
+    SetAllocatedString(mAppData->remotingName, mAppData->name);
+  }
   // used throughout this file
   gAppData = mAppData;
 
   ScopedLogging log;
 
   mozilla::IOInterposerInit ioInterposerGuard;
 
 #if defined(MOZ_WIDGET_GTK)
--- a/toolkit/xre/nsNativeAppSupportWin.cpp
+++ b/toolkit/xre/nsNativeAppSupportWin.cpp
@@ -479,17 +479,17 @@ struct MessageWindow {
     // Class name: appName + "MessageWindow"
     static const wchar_t *className() {
         static wchar_t classNameBuffer[128];
         static wchar_t *mClassName = 0;
         if ( !mClassName ) {
             ::_snwprintf(classNameBuffer,
                          128,   // size of classNameBuffer in PRUnichars
                          L"%s%s",
-                         NS_ConvertUTF8toUTF16(gAppData->name).get(),
+                         NS_ConvertUTF8toUTF16(gAppData->remotingName).get(),
                          L"MessageWindow" );
             mClassName = classNameBuffer;
         }
         return mClassName;
     }
 
     // Create: Register class and create window.
     NS_IMETHOD Create() {
--- a/xpcom/build/nsXREAppData.h
+++ b/xpcom/build/nsXREAppData.h
@@ -42,16 +42,23 @@ struct nsXREAppData
   /**
    * The name of the application. This must be ASCII, and is normally
    * mixed-case, e.g. "Firefox". Required (must not be null or an empty
    * string).
    */
   const char* name;
 
   /**
+   * The internal name of the application for remoting purposes. When left
+   * unspecified, "name" is used instead. This must be ASCII, and is normally
+   * lowercase, e.g. "firefox". Optional (may be null but not an empty string).
+   */
+  const char* remotingName;
+
+  /**
    * The major version, e.g. "0.8.0+". Optional (may be null), but
    * required for advanced application features such as the extension
    * manager and update service. Must not be the empty string.
    */
   const char* version;
 
   /**
    * The application's build identifier, e.g. "2004051604"
--- a/xpcom/glue/AppData.cpp
+++ b/xpcom/glue/AppData.cpp
@@ -38,16 +38,17 @@ SetAllocatedString(const char*& aStr, co
 ScopedAppData::ScopedAppData(const nsXREAppData* aAppData)
 {
   Zero();
 
   this->size = aAppData->size;
 
   SetAllocatedString(this->vendor, aAppData->vendor);
   SetAllocatedString(this->name, aAppData->name);
+  SetAllocatedString(this->remotingName, aAppData->remotingName);
   SetAllocatedString(this->version, aAppData->version);
   SetAllocatedString(this->buildID, aAppData->buildID);
   SetAllocatedString(this->ID, aAppData->ID);
   SetAllocatedString(this->copyright, aAppData->copyright);
   SetAllocatedString(this->profile, aAppData->profile);
   SetStrongPtr(this->directory, aAppData->directory);
   this->flags = aAppData->flags;
 
@@ -65,16 +66,17 @@ ScopedAppData::ScopedAppData(const nsXRE
     SetAllocatedString(this->UAName, aAppData->UAName);
   }
 }
 
 ScopedAppData::~ScopedAppData()
 {
   SetAllocatedString(this->vendor, nullptr);
   SetAllocatedString(this->name, nullptr);
+  SetAllocatedString(this->remotingName, nullptr);
   SetAllocatedString(this->version, nullptr);
   SetAllocatedString(this->buildID, nullptr);
   SetAllocatedString(this->ID, nullptr);
   SetAllocatedString(this->copyright, nullptr);
   SetAllocatedString(this->profile, nullptr);
 
   NS_IF_RELEASE(this->directory);