Author Topic: Relative Path problem  (Read 4689 times)

0 Members and 1 Guest are viewing this topic.

shers

  • Guest
Relative Path problem
« on: October 28, 2015, 01:35:49 AM »
Hi,

I have problem with the relative path in code to find a file.  The first time it works. In the same AutoCAD session, the second time, the path changes to C:\Users\xyz\AppData\Roaming\Autodesk\AutoCAD 2012 - English\R18.2\enu. Is there any solution to this problem please?

Thanks

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Relative Path problem
« Reply #1 on: October 28, 2015, 02:30:21 AM »

How are you trying to find the file ??
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

kpblc

  • Bull Frog
  • Posts: 396
Re: Relative Path problem
« Reply #2 on: October 28, 2015, 02:52:19 AM »
What findfile function retrns?
And what is the code? What do you try to find? Maybe 'second time' document is newly created document? Try to save it.
Sorry for my English.

shers

  • Guest
Re: Relative Path problem
« Reply #3 on: October 28, 2015, 04:36:55 AM »
It is to pick the file from a particular location. For example,

string strFile = ".\\test\\abc.txt";

But it goes to the AutoCAD roaming folder.

kpblc

  • Bull Frog
  • Posts: 396
Re: Relative Path problem
« Reply #4 on: October 28, 2015, 05:15:58 AM »
Try this:
Code: [Select]
(defun checkfile (file / _kpblc-conv-string-to-list)
  ;; (checkfile  ".\\test\\abc.txt")
  (defun _kpblc-conv-string-to-list (string separator / i)
    (cond
      ((= string "") nil)
      ((vl-string-search separator string)
       ((lambda (/ pos res)
          (while (setq pos (vl-string-search separator string))
            (setq res    (cons (substr string 1 pos) res)
                  string (substr string (+ (strlen separator) 1 pos))
                  ) ;_ end of setq
            ) ;_ end of while
          (reverse (cons string res))
          ) ;_ end of lambda
        )
       )
      ((wcmatch (strcase string) (strcat "*" (strcase separator) "*"))
       ((lambda (/ pos res _str prev)
          (setq pos  1
                prev 1
                _str (substr string pos)
                ) ;_ end of setq
          (while (<= pos (1+ (- (strlen string) (strlen separator))))
            (if (wcmatch (strcase (substr string pos (strlen separator))) (strcase separator))
              (setq res    (cons (substr string 1 (1- pos)) res)
                    string (substr string (+ (strlen separator) pos))
                    pos    0
                    ) ;_ end of setq
              ) ;_ end of if
            (setq pos (1+ pos))
            ) ;_ end of while
          (if (< (strlen string) (strlen separator))
            (setq res (cons string res))
            ) ;_ end of if
          (if (or (not res) (= _str string))
            (setq res (list string))
            (reverse res)
            ) ;_ end of if
          ) ;_ end of lambda
        )
       )
      (t (list string))
      ) ;_ end of cond
    ) ;_ end of defun

  (car
    (vl-remove nil
               (mapcar
                 (function
                   (lambda (x)
                     (findfile (strcat (vl-string-right-trim "\\" x) "\\" (vl-string-left-trim ".\\" file)))
                     ) ;_ end of lambda
                   ) ;_ end of function
                 (vl-remove "" (_kpblc-conv-string-to-list (getenv "ACAD") ";"))
                 ) ;_ end of mapcar
               ) ;_ end of vl-remove
    ) ;_ end of car
  ) ;_ end of defun
Code won't convert 'normal' relative path (like "..\\..\\..\\abc.txt") to 'absolute path.
Sorry for my English.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Relative Path problem
« Reply #5 on: October 28, 2015, 06:03:58 AM »
Try this:
Code: [Select]
(defun checkfile (file / _kpblc-conv-string-to-list)
  ;; (checkfile  ".\\test\\abc.txt")
 
Code won't convert 'normal' relative path (like "..\\..\\..\\abc.txt") to 'absolute path.

sresh is working in .NET, not vlisp
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Relative Path problem
« Reply #6 on: October 28, 2015, 06:06:34 AM »
It is to pick the file from a particular location. For example,

string strFile = ".\\test\\abc.txt";

But it goes to the AutoCAD roaming folder.

in isolation, this is almost useless
please provide some compilable code to demonstrate the issue.
Do you really expect others to guess as well as generate a possible code ??
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Relative Path problem
« Reply #7 on: October 28, 2015, 06:11:21 AM »

sresh,
Is the current drawing saved. ??
If so, where is it saved.

Perhaps it's defaulting to the user folder because it doesn't know where the .\xxx is ?
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

kpblc

  • Bull Frog
  • Posts: 396
Re: Relative Path problem
« Reply #8 on: October 28, 2015, 07:00:34 AM »
Try this:
Code: [Select]
(defun checkfile (file / _kpblc-conv-string-to-list)
  ;; (checkfile  ".\\test\\abc.txt")
 
Code won't convert 'normal' relative path (like "..\\..\\..\\abc.txt") to 'absolute path.

sresh is working in .NET, not vlisp
Ah, sorry.
Sorry for my English.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Relative Path problem
« Reply #9 on: October 28, 2015, 07:01:38 AM »
:)
no problems.
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Keith Brown

  • Swamp Rat
  • Posts: 601
Re: Relative Path problem
« Reply #10 on: October 28, 2015, 08:19:39 AM »
As Kerry said it is difficult to diagnose without some example code.  That being said this is what I use to make a path relative.  I didnt write the code but found it on http://www.stackoverflow.com

Code - C#: [Select]
  1. /// <summary>
  2. /// Creates a relative path from one file or folder to another.
  3. /// </summary>
  4. /// <remarks>Found at http://stackoverflow.com/questions/275689/how-to-get-relative-path-from-absolute-path </remarks>
  5. /// <param name="fromPath">
  6. /// Contains the directory that defines the start of the relative path.
  7. /// </param>
  8. /// <param name="toPath">Contains the path that defines the endpoint of the relative path.</param>
  9. /// <returns>The relative path from the start directory to the end path.</returns>
  10. /// <exception cref="ArgumentNullException"></exception>
  11. /// <exception cref="UriFormatException"></exception>
  12. /// <exception cref="InvalidOperationException"></exception>
  13. public static string MakeRelativePath(string fromPath, string toPath)
  14. {
  15.         if (string.IsNullOrEmpty(fromPath)) throw new ArgumentNullException(nameof(fromPath));
  16.         if (string.IsNullOrEmpty(toPath)) throw new ArgumentNullException(nameof(toPath));
  17.  
  18.         var fromUri = new Uri(fromPath);
  19.         var toUri = new Uri(toPath);
  20.  
  21.         if (fromUri.Scheme != toUri.Scheme) { return toPath; } // path can't be made relative.
  22.  
  23.         var relativeUri = fromUri.MakeRelativeUri(toUri);
  24.         var relativePath = Uri.UnescapeDataString(relativeUri.ToString());
  25.  
  26.         if (toUri.Scheme.ToUpperInvariant() == "FILE")
  27.         {
  28.                 relativePath = relativePath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
  29.         }
  30.  
  31.         return relativePath;
  32. }
Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Relative Path problem
« Reply #11 on: October 28, 2015, 09:27:05 AM »
Sounds like you got Automatic save turned on and that's after its first save

n.yuan

  • Bull Frog
  • Posts: 348
Re: Relative Path problem
« Reply #12 on: October 28, 2015, 09:35:40 AM »
You'd better explain the relative path ".\xxxxx\xxxx.xxx" is RELATIVE to WHAT: current AutoCAD working directory? current drawing's directory? the location of .NET dll that uses this "relative path"? If the said file in that relative path can be searchable via AutoCAD' supporting paths?

Since you post in .NET forum, I assume the "relative path" would mean RELATIVE to the location of the .NET dll that uses this relative path. IN this case, you can use System.Reflection.Assembly.GetExecutingAssemly().Location to determine the location of running DLL, then you can determine the full path of the "relative path" accordingly.

CADbloke

  • Bull Frog
  • Posts: 344
  • Crash Test Dummy
Re: Relative Path problem
« Reply #13 on: October 28, 2015, 05:04:23 PM »
Here's what I used recently to deal with relative / absolute paths: https://github.com/CADbloke/CodeLinker/blob/master/CodeLinker/PathMaker.cs (Great minds, eh Keith? ... line 17 in that)

I agree with Norman - you're not making sense. You have given us no context. What do you expect the path to be relative to? You may as well ask us "what's that on my desk just to my left?"

Relative to AutoCAD? AppDomain.CurrentDomain.BaseDirectory may be of help.

You'd better explain the relative path ".\xxxxx\xxxx.xxx" is RELATIVE to WHAT: current AutoCAD working directory? current drawing's directory? the location of .NET dll that uses this "relative path"? If the said file in that relative path can be searchable via AutoCAD' supporting paths?

Since you post in .NET forum, I assume the "relative path" would mean RELATIVE to the location of the .NET dll that uses this relative path. IN this case, you can use System.Reflection.Assembly.GetExecutingAssemly().Location to determine the location of running DLL, then you can determine the full path of the "relative path" accordingly.

Keith Brown

  • Swamp Rat
  • Posts: 601
Re: Relative Path problem
« Reply #14 on: October 28, 2015, 05:16:22 PM »
Here's what I used recently to deal with relative / absolute paths: https://github.com/CADbloke/CodeLinker/blob/master/CodeLinker/PathMaker.cs (Great minds, eh Keith? ... line 17 in that)


I looked at mine again earlier this morning and noticed that I was documenting the exceptions (kinda) that were being thrown instead of handling them.  I decided to go ahead and wrap it all up in a try/catch block similar to yours and return the toPath if there was an error same as you.


One quick comment about your code.  Your try/catch block encompasses your argument null exceptions.  Won't they be caught by your catch block which I assume you don't want?  Or since you are throwing them they won't be caught?  I have never tried that before to see what would happen.


This is what I came up with for mine earlier.

P.S.  If you use resharper then look in to Exceptional as an Addin.  It can force you to either document all exceptions or make sure that you catch them.


Code - C#: [Select]
  1. /// <summary>
  2. /// Creates a relative path from the destination file/folder to the source file/folder to another.
  3. /// </summary>
  4. /// <remarks>Found at http://stackoverflow.com/questions/275689/how-to-get-relative-path-from-absolute-path </remarks>
  5. /// <param name="fromPath">
  6. /// Contains the directory that defines the start of the relative path.
  7. /// </param>
  8. /// <param name="toPath">Contains the path that defines the endpoint of the relative path.</param>
  9. /// <returns>The relative path from the start directory to the end path.</returns>
  10. /// <exception cref="ArgumentNullException"><paramref name="fromPath"/> or <paramref name="toPath"/> is <see langword="null" />.</exception>
  11. public static string MakeRelativePath(string fromPath, string toPath)
  12. {
  13.    if (string.IsNullOrEmpty(fromPath)) throw new ArgumentNullException(nameof(fromPath));
  14.    if (string.IsNullOrEmpty(toPath)) throw new ArgumentNullException(nameof(toPath));
  15.  
  16.    var relativePath = toPath;
  17.  
  18.    try
  19.    {
  20.       var fromUri = new Uri(fromPath);
  21.       var toUri = new Uri(toPath);
  22.  
  23.       if (fromUri.Scheme != toUri.Scheme)
  24.       {
  25.          return toPath;
  26.       } // path can't be made relative.
  27.  
  28.       var relativeUri = fromUri.MakeRelativeUri(toUri);
  29.       relativePath = Uri.UnescapeDataString(relativeUri.ToString());
  30.  
  31.       if (toUri.Scheme.ToUpperInvariant() == "FILE")
  32.       {
  33.          relativePath = relativePath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
  34.       }
  35.    }
  36.    // ReSharper disable ExceptionNotDocumentedOptional
  37.    catch (ArgumentNullException exception)
  38.    {
  39.       Log.Logger.Error(exception, "Unable to determine the relative path, the path variables passed to the URI are null."); // Should never happen.
  40.    }
  41.    catch (UriFormatException exception)
  42.    {
  43.       Log.Logger.Error(exception, "Unable to determine the relative path, an invalid Uniform Resource Identifier is detected.");
  44.    }
  45.    catch (InvalidOperationException exception)
  46.    {
  47.       Log.Logger.Error(exception, "Unable to determine the relative path, the instance represents a relative URI and this property is valid only for absolute URI's.");
  48.    }
  49.    // ReSharper restore ExceptionNotDocumentedOptional
  50.    return relativePath;
  51. }
« Last Edit: October 28, 2015, 05:32:48 PM by Keith Brown »
Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013