Jump to content

How to distinguish a read only drawing without opening it?


Ahankhah

Recommended Posts

Hi everyone,

how is it possible to find out any drawing is read only due to being opened by other one, without opening it?

Link to comment
Share on other sites

  • Replies 35
  • Created
  • Last Reply

Top Posters In This Topic

  • Ahankhah

    10

  • irneb

    10

  • alanjt

    8

  • Lee Mac

    2

Top Posters In This Topic

The best I can think of is to search for the DWL file:

 

(findfile "<Filename>.dwl")

It doesn't always work though. In some cases (e.g. if AC crashes) it doesn't delete this file. Another option is to use the open function to test if it can be opened:
;;; Test if file is already opened by someone / is set to be read-only
(defun FileOpenTest (filename / f)
 (if (setq f (open filename "a"))
   (progn (close f) t)
 )
)

Link to comment
Share on other sites

@ irneb: Since you attempt to open the file in text mode, this will not be influenced by the state of the file (open or not by other application). Your routine will return T no mater the state of argument file.

Also, I'm really not comfortable at all to open that way a binary file...

 

Regards,

Mircea

Link to comment
Share on other sites

"whohas" gives you the info of without searching it

I'm afraid that OP was looking for a way to get that information programmatically - the WHOHAS command cannot be used at command prompt. However, it get the information from those DWL files.

 

Regards,

Mircea

Link to comment
Share on other sites

It doesn't always work though. In some cases (e.g. if AC crashes) it doesn't delete this file. Another option is to use the open function to test if it can be opened:
;;; Test if file is already opened by someone / is set to be read-only
(defun FileOpenTest (filename / f)
 (if (setq f (open filename "a"))
   (progn (close f) t)
 )
)

 

irneb, thanks a lot. It works well.

Link to comment
Share on other sites

@ irneb: Since you attempt to open the file in text mode, this will not be influenced by the state of the file (open or not by other application). Your routine will return T no mater the state of argument file.

Also, I'm really not comfortable at all to open that way a binary file...

 

Regards,

Mircea

 

Mircea, the code written by irneb works nice.

Link to comment
Share on other sites

"whohas" gives you the info of without searching it

 

Dipalo,

as Mircea mentioned, unfortunately whohas is not programmer-friendly.

Link to comment
Share on other sites

With special thanks to you guys, here is a somehow complete function as a conclusion of your offered ways:

 

(defun [b]DwgFileStatus [/b](DwgName / *dwg* *folder* *name* *dwl* *ret* *f*)
  (if (setq *dwg* (findfile DwgName))
     (progn
        (setq *folder* (vl-filename-directory *dwg*))
        (setq *name* (vl-filename-base *dwg*))
        (setq *dwl* (findfile (strcat *folder* "\\" *name* ".dwl")))
     )
  )
  (setq *ret* 
     (cond
        (  (not *dwg*)
           'NoSuchFile
        ) 
        (  (setq *f* (open *dwg* "a"))
           'Editable
        )
        (  (not *dwl*)
           'ReadOnly
        )
        (  (setq *f* (open *dwl* "a"))
           'EditableAfterCrash
        )
        (  (not *f*)
           'InUse
        )
        (  T
           'NotProspected
        )
     )
  )      
  (if *f* (close *f*))
  *ret*
)

Edited by Ahankhah
Link to comment
Share on other sites

@ irneb: Since you attempt to open the file in text mode, this will not be influenced by the state of the file (open or not by other application). Your routine will return T no mater the state of argument file.

Also, I'm really not comfortable at all to open that way a binary file...

 

Regards,

Mircea

It will be influenced by the state of the file, since I'm opening it for write access (note the "a" -append option). Therefore if someone already has it open (even yourself) windows will disallow this call, and the open function will return nil.

 

I'm not too happy with opening it either - but that's about all you really can do in AutoLisp. Even with ActiveX Scripts the filesystem/file objects have no methods to check if a file was opened by someone else. This is definitely not ideal, since you're relying on something to fail/not. Though there shouldn't be any problem with opening it and then closing directly afterwards - note I'm also using the "a" (append) option in case the "w" (rewrite) option deletes the contents of the file.

 

For this I'd advise Ahankhah to rather put the close call as close as possible to the open - I'd actually place it directly after the open inside each cond condition. Even though you then need 2 duplicates in your function, it's just safer (you never know if you're going to extend your function later and have something work with that *f* variable, this is too critical to leave to chance). Even add a comment there to explain that you should never write anything to the *f* variable, just to remind yourself never to do so.

 

Edit: BTW the DWL file is extremely rarely open by anyone. It will only be the fraction of a second while someone opens/closes the DWG file. So you don't need to check that. You can also open the DWL file in readonly, i.e. (open "FileName.DWL" "r") then read-line through that to find ou who has it open - this is basically what the WHOHAS command does. The 1st line is the username, 2nd the computer name, 3rd the date & time it was opened.

 

Also I think you misunderstood Lee's suggestion of checking for the DWL file. If it exists then it usually means that someone's got the DWG open. If it cannot be found, then the DWG is definitely not open.

Link to comment
Share on other sites

I'd do it this way:

(defun DwgFileStatus (DwgName / dwg folder name dwl str data)
 (if (setq dwg (findfile DwgName))
   (progn
     (setq folder (vl-filename-directory dwg))
     (setq name (vl-filename-base dwg))
     (setq dwl (findfile (strcat folder "\\" name ".dwl")))
   )
 )
 (cond
   ((not dwg) '(NoSuchFile))
   ((setq f (open dwg "a"))
    (close f) ;NEVER WRITE to the f variable inside this function
    (if (and dwl (setq f (open dwl "r")))
      (progn
        (setq data '(EditableAfterCrash))
        (while (setq str (read-line f)) (setq data (cons str data)))
        (close f)
        (reverse data)
      )
      '(Editable)
    )
   )
   ((and dwl (setq f (open dwl "r")))
    (setq data '(InUse))
    (while (setq str (read-line f)) (setq data (cons str data)))
    (close f)
    (reverse data)
   )
   (t '(UnknownReadonly))
 )
)

Note all the returns are lists - so it works the same way whether there's a DWL involved or not. If there's a DWL it also returns the data inside it.

Link to comment
Share on other sites

Also I think you misunderstood Lee's suggestion of checking for the DWL file. If it exists then it usually means that someone's got the DWG open. If it cannot be found, then the DWG is definitely not open.

Except when AutoCAD crashed and leaves the files. I actually wrote a little routine that scans the active drawing's folder at startup and erases any dwl/dwl2,err/log files.

Link to comment
Share on other sites

Except when AutoCAD crashed and leaves the files. I actually wrote a little routine that scans the active drawing's folder at startup and erases any dwl/dwl2,err/log files.
Same as I've mentioned in post #4. And that's why I said "usually" :whistle:.

 

...

 

I hope your routine doesn't simply delete all of them! Since then you'll get the UnknownReadonly returned by my function. :o

Link to comment
Share on other sites

Same as I've mentioned in post #4. And that's why I said "usually" :whistle:.

I know, I was just reiterating.

 

I hope your routine doesn't simply delete all of them! Since then you'll get the UnknownReadonly returned by my function. :o
If the active drawing is using them, it will not delete those.
Link to comment
Share on other sites

Note all the returns are lists - so it works the same way whether there's a DWL involved or not. If there's a DWL it also returns the data inside it.

Excellent:o.

So you can find out who is working on the drawing.

Link to comment
Share on other sites

I know, I was just reiterating.
Oh! ... OK .... sorry :wink:

 

If the active drawing is using them, it will not delete those.
What about other DWG's opened by other people as well as DWGs you've already got open?

 

Excellent:o.

So you can find out who is working on the drawing.

Welcome!

 

That's the idea, though if you have something like Alan's code running then you won't have any DWL's available - except for the one of the current DWG you have open yourself.

Link to comment
Share on other sites

I actually wrote a little routine that scans the active drawing's folder at startup and erases any dwl/dwl2,err/log files.
Just as a side-line suggestion: wouldn't it be "better" to have such a thing run as a login script? Though even then I'd add some form of check before deleting, since others may already have the DWGs open before you login.
Link to comment
Share on other sites

Oh! ... OK .... sorry :wink:

 

What about other DWG's opened by other people as well as DWGs you've already got open?

vl-file-delete will not delete them, nils and moves on to the next file.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...