TheSwamp
Code Red => AutoLISP (Vanilla / Visual) => Topic started by: javilisp on August 11, 2016, 06:07:56 AM
-
Sometimes every month, I try to open a DWG already open, and AutoCAD saids "read only mode".
I want to check before open the DWG if the file are already open by other users.
In the past I think there's a file with ".DWL" extensión, but I can't find this file in a network unit maped like "Z:\\"
At the moment I'm writing a open function with APPEND paremeter, using (open "Z:\\test.dwg" "a") and this return nil if the file is open. If the file is'nt open, this return the pointer to the file and I make a (close ...) inmediatly.
Are this correct?
The problem for implement this in a environment with 8-10 user using the application, every user open 20-30 files every day, there's a hundred off "open" and "close" every day to the Windows file server.
I like use the minimun process necesarys.
Thanks
Javi
-
File locking is handled by the O/S.
The presence or absence of .DWL (and/or .DWL2) files have nothing to do with the file lock status or read-only status of .DWG files.
What is the environment of the location of your .DWG files? Pure Windows server environment or some sort of NAS/SAN thing (https://knowledge.autodesk.com/support/autocad/troubleshooting/caas/sfdcarticles/sfdcarticles/Autodesk-support-for-Network-Attached-Storage-NAS-and-Storage-Area-Networks-SAN.html)?
-
It is true that the network handles the locking of the drawing when it is open, but, in a windows server environment I have never had a time when there was not a lock file with a dwg open in Acad.
I have been using the following routine to check for a lock file and if it exists get the lock information:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Routine: GetLockInfo
;;; Purpose: Takes a lock file and returns a list for inclusion with the file attributes
;;; Arguments: DwgName - string, fully qualified pathname to the lock file, if this has a dwg
;;; extension then the extension is changed to dwl.
;;; Returns: An assoc list - car = 'WARNING, cadr = "File Locked! - <lock time and date> by
;;; <user name>"
;;; Nil, if there is no lock file found, or if the lock file was successfully
;;; deleted.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun GetLockInfo (DwgName / Locktext)
(if (and ;;The dwl file exists
(vl-directory-files
(vl-filename-directory DwgName)
(strcat (vl-filename-base DwgName) ".dwl")
)
(null (vl-file-delete
(strcat (vl-filename-directory DwgName)
"\\"
(vl-filename-base DwgName)
".dwl"
)
)
)
(setq LockText (GetFileTxt
(strcat (vl-filename-directory DwgName)
"\\"
(vl-filename-base DwgName)
".dwl"
)
nil
)
)
) ;end and
(cons 'Warning
(strcat "File Locked! - "
(caddr LockText)
" by "
(car LockText)
)
)
)
)
I am using this in a routine that uses objectdbx to scan the titleblock attributes for my drawings. If someone has the drawing open this routine will let me know. I then copy the drawing to my local drive and scan it from there. I have been using this approach for years without problems.
Mike
-
It's very possible for DWL/DWL2 files to be present when the drawing is NOT open. (When AutoCAD crashes, those files can be left behind)
It's also (less likely) for the file to be open, and the DWL/DWL2 files to NOT be present. (Anyone or anything can delete DWL/DWL2 files with no regard to the status of the associated DWG file).
Why not just check to see if the DWG file itself is open?
-
Why not just check to see if the DWG file itself is open?
Do you use (open fileName "w") for this?
-
It's very possible for DWL/DWL2 files to be present when the drawing is NOT open. (When AutoCAD crashes, those files can be left behind)
It's also (less likely) for the file to be open, and the DWL/DWL2 files to NOT be present. (Anyone or anything can delete DWL/DWL2 files with no regard to the status of the associated DWG file).
Why not just check to see if the DWG file itself is open?
[/quoteIt's very possible for DWL/DWL2 files to be present when the drawing is NOT open. (When AutoCAD crashes, those files can be left behind)
It's also (less likely) for the file to be open, and the DWL/DWL2 files to NOT be present. (Anyone or anything can delete DWL/DWL2 files with no regard to the status of the associated DWG file).
Why not just check to see if the DWG file itself is open?
]
If the dwg is open then the lock file is also open and can't be deleted. My routine attempts that and copies it only if the delete fails.
I check for the dwg in my documents collection before calling this routine.
-
AutoCAD provide WHOHAS command..:)
but I've to admit that AutoCAd must check the file BEFORE trying to opening..
I've made this easier with InfoDWG (http://www.ductisoft.com/idwgDEMO.gif).
-
It is true that the network handles the locking of the drawing when it is open, but, in a windows server environment I have never had a time when there was not a lock file with a dwg open in Acad.
I have been using the following routine to check for a lock file and if it exists get the lock information:...
The routine you posted is missing a the function (getfiletxt).
Below is the function I use. It's very similar to yours. This seems to work well for me in most situations.
;|==============================================================================
Function Name: (pjk-IsDwgLocked)
Arguments:
dwgfile = String; A valid path and name of an AutoCAD DWG file.
A-flg = Boolean; If set to T, an Alert box will display if the drawing
is Locked for editing, including the username of who
had the file open.
Returns:
Boolean; T if the file is Locked or nil for not.
Description:
This function determines if a AutoCAD DWG file is locked for editing by another
user. It has the option of displaying an Alert box with the user name of the person
that has the file open.
================================================================================|;
(defun pjk-IsDwgLocked (Dwgfile A-flg / Dwlfile fl ln Locked)
(if (and Dwgfile (setq Dwgfile (findfile Dwgfile)))
(progn
(if (= (strcase (vl-filename-extension Dwgfile)) ".DWG")
(setq Dwlfile (strcat (vl-filename-directory Dwgfile) "\\" (vl-filename-base Dwgfile) ".dwl"))
(princ (strcat "The file: \"" (pjk-StripPath Dwgfile) "\" is not a DWG file type."))
)
(if (and Dwlfile
(setq Dwlfile (findfile Dwlfile))
(= (vl-file-delete Dwlfile) nil)
)
(progn
(setq locked T
fl (open Dwlfile "r")
ln (read-line fl)
fl (close fl)
)
(if A-flg
(alert
(strcat "The file: \"" (pjk-StripPath Dwgfile) "\" has been locked for editing by \"" ln
"\". It cannot be accessed for editing at this time."
)
)
)
)
)
)
(if Dwgfile
(princ (strcat "\nFile name \"" (pjk-StripPath Dwgfile) "\" does not exist in the path specified. "))
(princ "\nError - No file name is given. ")
)
)
locked
) ;; End Function (pjk-IsDwgLocked)
;|==============================================================================
Function Name: (pjk-StripPath)
Arguments:
path = string; represents a path to format.
Usage: (pjk-StripPath <Path & File name>)
Returns:
string; The filename or folder at the end of the path string with
the rest of the path removed.
Description:
Given a Path and Filename string, this function
strips off any path, leaving the filename and
extension. Uses Recursion
================================================================================|;
(defun pjk-StripPath (pathstr)
(if (wcmatch pathstr "*[\\/]*") (pjk-StripPath (substr pathstr 2)) pathstr)
) ;; End Function (pjk-StripPath)
-
...
The routine you posted is missing a the function (getfiletxt).
...
Here is the missing function:
;|
getfiletxt.lsp
Michael Weaver
Given the name of an existing text file as an argument this routine
will return the contents of the file as a list of strings; one line
of file contents per item in the list.
Arguments:
fname the filename to read
dosearch do a library search if non-nil
Returns:
linelist the list of strings
- nil if the file cannot be opened
- an empty list if the file is empty
|;
(defun getfiletxt ( ;get the contents of a text file
fname ;file to read
dosearch ;library search flag
/ ;end of formal argument list
linelist ;list to return
inline ;line as read from file
fileh ;file handle
) ;end of local variable list
(cond
;;open the file
((not (if dosearch
(setq fileh (open (findfile fname) "r"))
(setq fileh (open fname "r"))
) ;_ end of if
) ;_ end of not
nil
)
;;read the file and build the return list
((not (while (setq inline (read-line fileh))
(setq linelist (append (list inline) linelist))
) ;_ end of while
) ;_ end of not
nil
)
;;close the file and return the list
(T (setq fileh (close fileh)) (reverse linelist))
) ;end cond
) ;end getfiletxt