Retrieve Absolute Path of DXL Library

Dear all,

does anyone know a way to retrieve the absolute path of a DXL library when executing code in the library itself. I tried to use the function dxlHere(). But this requires to include the library using the absolute path. This is a drawback, when executing DOORS scripts from network located DOORS menus.

I need this path to call a visual basic script from the included library code that is located in the same network located directory as the library.

Best regards

Thomas
rdratlos - Thu Dec 01 09:54:09 EST 2011

Re: Retrieve Absolute Path of DXL Library
llandale - Thu Dec 01 16:05:37 EST 2011

Some time ago I tried real hard and bugged IBM to no avail. I think there is a way but they won't tell me as they fear that clever folks will use it to de-crypt their files.

I did not do this, but I'm pretty sure the following would work.
  • Parse the "addins" environment variable
  • Strip off the path before the 1st semi-colon
  • Append that path to your named relative file (from dxlHere())
  • See if that file exists.
  • If not, strip off the next path and try again.

Try the default path first, <DOORSHome\lib\dxl\addins> I think.

So if your file is "MyAddins\Name.dxl" and the "addins" variable is "c:\MyDoors";\\xyzServer\DoorsAddins" then you would try these three files in this order:
  • c:\Program Files\IBM\Rational\DOORS\lib\dxl\Addins\MyAddins\Name.dxl
  • c:\MyDoors\MyAddins\Name.dxl
  • \\xyzServer\DoorsAddins\MyAddins\Name.dxl

If you get that to work it would be very helpful to post it.

-Louie

Had some dude a few years ago resolve an addins problem on Citrix by using Windows explorer on his PC and selecting the correct folder. I watched him do it but could not duplicate it myself. That is, he first saw no addins in Citrix, used Windows Explorer on his PC, then invoked Citrix DOORS and saw the addins. Anyway, that observation makes me desperately suggest the following:
  • Try also the path you get string s = currentDirectory(), but I really don't know what to think about that but suspect, if it works, it would come before the default path.

Re: Retrieve Absolute Path of DXL Library
OurGuest - Tue Dec 06 08:24:06 EST 2011

One work around is to include a constant within your script that knows the path of current installation.

True, it may be a pain to update the constants as conditions changes -- but I suspect IBM won't shead any tears for anyone having to manually update the constants and therefore a solution will be a long time coming.

Re: Retrieve Absolute Path of DXL Library
llandale - Tue Dec 06 16:57:48 EST 2011

OurGuest - Tue Dec 06 08:24:06 EST 2011
One work around is to include a constant within your script that knows the path of current installation.

True, it may be a pain to update the constants as conditions changes -- but I suspect IBM won't shead any tears for anyone having to manually update the constants and therefore a solution will be a long time coming.

Are you saying that if you know you will deploy the code here:
  • \\MyServer\MyDxl\MyAddins
that you could add this to your code:
  • string DeployLoc = "\\\\MyServer\\MyDxl\\MyAddins"
?

-Louie

Re: Retrieve Absolute Path of DXL Library
PDU - Wed Dec 07 02:15:49 EST 2011

llandale - Tue Dec 06 16:57:48 EST 2011
Are you saying that if you know you will deploy the code here:

  • \\MyServer\MyDxl\MyAddins
that you could add this to your code:
  • string DeployLoc = "\\\\MyServer\\MyDxl\\MyAddins"
?

-Louie

Hi,

i don't know if it is a solution for you, but what i have done (DOORS 9.1) :
 

  • i have my scripts on a server "Myserver" : \\Myserver\Myaddins
  • in registry, the key "HKEY_LOCAL_MACHINE\SOFTWARE\Telelogic\DOORS\9.1\Config" has value "\\Myserver\Myaddins"


When i need absolute path i use :

 

 

string AddinsPath = getRegistry("HKEY_LOCAL_MACHINE\\SOFTWARE\\Telelogic\\DOORS\\9.1\\Config", "addins")



Pierre



 

 

Re: Retrieve Absolute Path of DXL Library
llandale - Wed Dec 07 14:17:07 EST 2011

PDU - Wed Dec 07 02:15:49 EST 2011

Hi,

i don't know if it is a solution for you, but what i have done (DOORS 9.1) :
 

  • i have my scripts on a server "Myserver" : \\Myserver\Myaddins
  • in registry, the key "HKEY_LOCAL_MACHINE\SOFTWARE\Telelogic\DOORS\9.1\Config" has value "\\Myserver\Myaddins"


When i need absolute path i use :

 

 

string AddinsPath = getRegistry("HKEY_LOCAL_MACHINE\\SOFTWARE\\Telelogic\\DOORS\\9.1\\Config", "addins")



Pierre



 

 

The command:
  • string AddinsPathDefault = getenv("addins") // case iNsEnsiTive
will retrieve the default "addins" path, which is the same as your command unless their is a cooresponding HKEY_CURRENT_USER\... "addins" variable.

The command:
  • string AddinsPathNow = getenv("DOORSADDINS") // Oddly, must be UPPERCASE
will retrieve the path being used right now by this instance of DOORS, which is the default path unless there is a command line switch "-a" override.

This thread is about trying to determine the exact file being executed right now which supports using DOORSADDINS as above (where it "is", not where it "should" be). For example you may have your include files deployed on the serve but you also may have an in-development one locally; it may be useful to be able to determine which one is running.

If you have a "Project Addins" menu in addition to the module "addins" menu, then it gets sticky as you don't know from which menu it was executed. You could look for your relative path using DOORSADDINS as the root first, then look for it using DOORSPROJECTADDINS as the root second, but that will fail when you have two DXL files with the same name in the same relative location, one for each. Not sure what to do about that obscure situation other than by policy never allow two DXL files with the same exact name (which is a no-brainer anyway).

  • Louie

I managed to clumsily get around the "9.1" problem in your hard coded path, finding the DOORS version and building that string from that.
  • string ConfigArea = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Telelogic\\DOORS\\" BuildPathName() "\\Config"

Re: Retrieve Absolute Path of DXL Library
PDU - Thu Dec 08 02:00:27 EST 2011

llandale - Wed Dec 07 14:17:07 EST 2011
The command:

  • string AddinsPathDefault = getenv("addins") // case iNsEnsiTive
will retrieve the default "addins" path, which is the same as your command unless their is a cooresponding HKEY_CURRENT_USER\... "addins" variable.

The command:
  • string AddinsPathNow = getenv("DOORSADDINS") // Oddly, must be UPPERCASE
will retrieve the path being used right now by this instance of DOORS, which is the default path unless there is a command line switch "-a" override.

This thread is about trying to determine the exact file being executed right now which supports using DOORSADDINS as above (where it "is", not where it "should" be). For example you may have your include files deployed on the serve but you also may have an in-development one locally; it may be useful to be able to determine which one is running.

If you have a "Project Addins" menu in addition to the module "addins" menu, then it gets sticky as you don't know from which menu it was executed. You could look for your relative path using DOORSADDINS as the root first, then look for it using DOORSPROJECTADDINS as the root second, but that will fail when you have two DXL files with the same name in the same relative location, one for each. Not sure what to do about that obscure situation other than by policy never allow two DXL files with the same exact name (which is a no-brainer anyway).

  • Louie

I managed to clumsily get around the "9.1" problem in your hard coded path, finding the DOORS version and building that string from that.
  • string ConfigArea = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Telelogic\\DOORS\\" BuildPathName() "\\Config"

Thanks Louie

Re: Retrieve Absolute Path of DXL Library
rdratlos - Thu Dec 08 10:45:08 EST 2011

llandale - Thu Dec 01 16:05:37 EST 2011
Some time ago I tried real hard and bugged IBM to no avail. I think there is a way but they won't tell me as they fear that clever folks will use it to de-crypt their files.

I did not do this, but I'm pretty sure the following would work.

  • Parse the "addins" environment variable
  • Strip off the path before the 1st semi-colon
  • Append that path to your named relative file (from dxlHere())
  • See if that file exists.
  • If not, strip off the next path and try again.

Try the default path first, <DOORSHome\lib\dxl\addins> I think.

So if your file is "MyAddins\Name.dxl" and the "addins" variable is "c:\MyDoors";\\xyzServer\DoorsAddins" then you would try these three files in this order:
  • c:\Program Files\IBM\Rational\DOORS\lib\dxl\Addins\MyAddins\Name.dxl
  • c:\MyDoors\MyAddins\Name.dxl
  • \\xyzServer\DoorsAddins\MyAddins\Name.dxl

If you get that to work it would be very helpful to post it.

-Louie

Had some dude a few years ago resolve an addins problem on Citrix by using Windows explorer on his PC and selecting the correct folder. I watched him do it but could not duplicate it myself. That is, he first saw no addins in Citrix, used Windows Explorer on his PC, then invoked Citrix DOORS and saw the addins. Anyway, that observation makes me desperately suggest the following:
  • Try also the path you get string s = currentDirectory(), but I really don't know what to think about that but suspect, if it works, it would come before the default path.

Dear Louie,
thank you very much for the hint. As you asked, here's the code. I've tested it in various configuration scenarios and it seems to work:
(1) DXL library located in the same directory as the executing script
-> access to all files in this directory works
(2) DXL library located in a special local/remote addins location
-> addins path is specified in registry and/or command line switch -a
-> access to other files in the same location works
(3) DXL library located in the local addins path (addins directory or subdirectory)
-> access to other files in the same location works

To get the full pathname of a file, that is located in the same directory as our DXL
library call function canOpenLibFile with the (short) name of the file.
The code could be condensed, but I desisted for better understanding.
 

// Adapt to your needs:
const string addinsDefaultRelativePath = "lib\\dxl\\"
 
Skip getEnvDOORSADDINSlocations()
//DESCRIPTION: This funtion reads the DOORSADDINS environment variable that
//             contains the absolute path to dxl addins directories.
//             The environment variable can be set in one of the following ways:
//             (1) Registry
//                 Key "Addins" with absolute path(s) as value in
//                 HKEY_LOCAL_MACHINE\SOFTWARE\Telelogic\DOORS\<DOORS version number>\Config
//             (2) Command line switch
//                 -a|-addins "path to the addins directory"
//
//             Output:
//             Skip list with the parsed absolute addins paths.
//
{
    Skip slDoorsAddins = null
        string envDoorsAddins = ""
        int i = 0
        
        Regexp parsePath = regexp "([^;]*)(;[ \t]*)*"
 
        // Set path name separators
        string strSeparator = "\\"            // for WIN32 platforms
        if (platform != "WIN32")
        {
                strSeparator = "/"
        }
 
        // Get the content of the DOORSADDINS environment variable
        // and add a ";" to be on the safe side
        envDoorsAddins = getenv("DOORSADDINS")
        envDoorsAddins = envDoorsAddins ";"
        if (envDoorsAddins != "")
        {
                // DOORSADDINS specifies one or more addins locations
                slDoorsAddins = create
                while (!null envDoorsAddins && parsePath envDoorsAddins)
                {
                        // Store addins location; add a final backslash, if there is none
                        if (envDoorsAddins[match 1] != "")
                        {
                                if (envDoorsAddins[end 1] "" == strSeparator)
                                {
                                        put( slDoorsAddins, i, envDoorsAddins[match 1] )
                                }
                                else
                                {
                                        put( slDoorsAddins, i, envDoorsAddins[match 1] "" strSeparator )
                                }
                        }
                        envDoorsAddins = envDoorsAddins[end 2 + 1:]
                        i++
                }
        }
        return slDoorsAddins
}
 
 
string replaceChar(string str, char strOldPattern, string strNewPattern)
// String find and replace 
// This function particularity is to replace a CHAR by a STRING, which is not 
// possible by standard functions.
//
{
  Buffer b = create
  b = str
  int found = 0
  int cpt = 0
  int indexMax = 0
  while (true)
  {
    indexMax = length( str )-1
        found = contains( b, strOldPattern )
        cpt++
        if (found != -1) 
        {
          str = stringOf( b[0:found-1] ) strNewPattern stringOf( b[found+1:indexMax] )
          b = str
        }
        else
        {
                break
        }
  }
  delete b
  return str
}
 
 
string getMyName()
//DESCRIPTION: This function retrieves the filename of the
//             DXL library or script, whose code is currently executed.
//
//             Output:
//             Name of the executed library or null in case of errors.
//
{
                string myName = ""
 
                // Retrieve the location of this DXL library relative to the addins path;
                // Replace Unix style '/' by Windows style '\' 
                Regexp getMyRelativePath = regexp "^<(.*/)([^:]+):"
                Regexp getMyName = regexp "^<([^:]+):"
                string dxlCode = dxlHere()
                if (getMyRelativePath dxlCode)
                {
                        myName = dxlCode[match 2]
                }
                else if (getMyName dxlCode)
                {
                        myName = dxlCode[match 1]
                }
                return myName
}
 
string getMyFullName()
//DESCRIPTION: This function retrieves the absolute path and filename of the
//             DXL library or script, whose code is currently executed.
//
//             Output:
//             Full path and name of the executed library or null, if the
//             library cannot be found.
//
{
        Skip slDoorsAddins
        string doorsAddinsPath = ""
        string myLocation = ""
        string myName = ""
        
        string doorsHomePath = getenv("DOORSHOME")
                // Retrieve the location of this DXL library relative to the addins path;
                // Replace Unix style '/' by Windows style '\' 
                Regexp getMyRelativePath = regexp "^<(.*/)([^:]+):"
                string dxlCode = dxlHere()
                if (getMyRelativePath dxlCode)
                {
                        if (platform == "WIN32")
                        {
                                myLocation = replaceChar( dxlCode[match 1] "", '/', "\\" )
                        }
                        else
                        {
                                myLocation = dxlCode[match 1]
                        }
                        myName = dxlCode[match 2]
                }
                else 
                {
                        // This library resides in the same directory as the calling dxl script
                        // and not in a central location; just get my name
                        myName = getMyName()
                        return myName
                }
                
                // Get DOORS dxl addins locations from environment variable
                slDoorsAddins = getEnvDOORSADDINSlocations()
 
                if (!null slDoorsAddins)
                {
                        for doorsAddinsPath in slDoorsAddins do
                        {
                                if(canOpenFile( doorsAddinsPath myLocation myName, false ) ) 
                                {
                                        // Found myself in: "doorsAddinsPath myLocation"
                                        delete slDoorsAddins
                                        return doorsAddinsPath myLocation myName
                                }
                        }
                        delete slDoorsAddins
                }
                
                // Could not find myself. Try the
                // default path for local installations
                myLocation = doorsHomePath addinsDefaultRelativePath myLocation
                if(canOpenFile( myLocation myName, false ) ) 
                {
                        // Found myself in: "myLocation"
                        return myLocation myName
                }
                // Still haven't found myself
                return ""
}
 
string canOpenLibFile(string fileName, bool forWrite)
//DESCRIPTION: This function tests access to library files that are located
//             in the same location as the DXL library, whose code is currently
//             executed. If forWrite is set to true, the file is opened for
//             write and the current contents of the file are cleared.
//             If forWrite is set to false the file is opened read only and the
//             existing contents are unchanged. 
//
//             Input:
//             Filename of the library file (without path information) 
//
//             Output:
//             Returns the file pathname when the file can be opened; otherwise, returns null. 
//
{
        string myName = getMyName()
        string myFullName = getMyFullName()
        
        string absLibFilePathName = ""
        
        int offset = 0
        int length = 0
        
        if (null myFullName || !findPlainText( myFullName, myName, offset, length, true, true ))
        {
                // Could not find my location
                return ""
        }
        
        if (myFullName != myName)
        {
                absLibFilePathName = myFullName[0:offset-1]
        }
 
        absLibFilePathName = absLibFilePathName fileName
        if (!canOpenFile( absLibFilePathName, forWrite ))
        {
                // Could not open file
                return ""
        }
        
        return absLibFilePathName
        
}