English

How To: Allow a project file (.apr) to be opened by only one user at a time [SCRIPT]

Procedure

Product: ArcView 3.x

Summary

We store all of our .apr files on a network drive. From time to time two users open the same .apr at the same time, not realizing that the other has it open. They may do some updating to the .apr. This can cause severe problems.

Cause

Avenue checks if a project is open or in use.

Solution

Warning:
WARNING: The instructions below include making changes to essential parts of your operating system. It is recommended that you backup your operating system and files, including the registry, before proceeding. Consult with a qualified computer systems professional, if necessary.

ESRI cannot guarantee results from incorrect modifications while following these instructions. Therefore, use caution and proceed at your own risk.

Using Avenue, you can allow only one user at a time to open a project file. Use the following sample scripts as the project
Startup script and Shutdown Script.

1. Open the project that you only want one user to open at a time.

2. Open a New Script document, and rename it 'aStartup'.

3. Copy the following code into 'aStartup'.

'Startup Script --------------------------------------

ps = av.getproject.getfilename.clone
psd = ps.stripfile
'MsgBox.Info(ps.AsString,"")

ptitleapr = av.GetProject.GetWin.GetTitle.Clone
ptitle = ptitleapr.AsString.Substitute(".apr","apr")
text_file = "\"+ptitle+".txt"

thefilestr = psd.AsString+text_file.AsString

_textfilename = thefilestr.AsString.AsFileName

checkfile = FileName.FindInSystemSearchPath (_textfilename.AsString)
if (checkfile <> nil) then
theLineFile = linefile.make(_textfilename,#FILE_PERM_READ)
thelist = List.Make
numlines = theLineFile.GetSize
source = theLineFile.Read( theList,numlines )
a = theList.count
pos = theLineFile.SetPos (0)
info_list = list.make
for each l in theList
theline = theLineFile.ReadElt
info_list.Add(theline)
end
MsgBox.Warning(info_list.Get(0).AsString++
"is currently using this project on"++info_list.Get(1).AsString+NL+
"Login date and time:"++info_list.Get(2).AsString+NL+
"Check with the above user. Closing the project","W A R N I N G !!")
av.run("Project.Close",nil)

else

' DETERMINE IS OPERATING SYSTEM IS WINDOW BASED
' SET %SystemRoot% IF WINDOWS NT OR 95

OSvar = System.GetOSVariant
if (OSvar = #SYSTEM_OSVARIANT_MSWNT) then
wd = system.GetEnvVar("windir")

_WinSysDir = wd+"\system32\"

elseif (OSvar = #SYSTEM_OSVARIANT_MSW95) then
wd = system.GetEnvVar("windir")

_WinSysDir = wd+"\system32\"
else
MsgBox.Warning("This project is designed for use" +NL+
"by WindowsNT and Windows95 PCs.","Stop")
av.GetProject.Close
end

' DETERMINE THE USER LOGIN NAME
'
'Make the DLL object
dllAdvAPI32 = dll.make((_WinSysDir + "advapi32.dll").AsFileName)

'Make the DLLProc object
dpGetUserNameA = dllproc.make(dllAdvAPI32, "GetUserNameA",
#DLLPROC_TYPE_INT32,{#DLLPROC_TYPE_STR, #DLLPROC_TYPE_PINT32})

'Make the string buffer
uname = String.MakeBuffer(12)
buflen = 10
retValue = Number.MakeNull

'Call the function which returns the username to the buffer
retValue = dpGetUserNameA.Call({uname, buflen})

tf = LineFile.Make(_textfilename, #FILE_PERM_APPEND)

mystr = Uname.AsString
'MsgBox.Info(mystr.AsString,"")
tf.WriteElt(mystr)

' DETERMINE THE COMPUTER NAME
'Make the DLL object
dllKernel32 = dll.make((_WinSysDir + "kernel32.dll").AsFileName)

'Make the DLLProc object
dpGetComputerNameA = dllproc.make(dllkernel32, "GetComputerNameA",
#DLLPROC_TYPE_INT32,{#DLLPROC_TYPE_STR, #DLLPROC_TYPE_PINT32})

'Make the string buffer
cname = String.MakeBuffer(12)
buflen = 10
retValue = Number.MakeNull

'Call the function which returns the username to the buffer
retValue = dpGetComputerNameA.Call({cname, buflen})

compname = cname.AsString
'MsgBox.Info(compname,"")
tf.WriteElt(compname)

d = Date.Now.AsString
tf.WriteElt(d)

tf.close

end

'END OF STARTUP SCRIPT ---------------------------------
4. Compile the Script (check-mark button), but DO NOT run it.

5. Go to the Script Menu, and select Embed Script.

6. Open another New Script, and rename it: aShutDown

7. Copy the following code and paste it into the new script (aShutDown).
'ShutDown Script -------------------------------------

OSvar = System.GetOSVariant
if (OSvar = #SYSTEM_OSVARIANT_MSWNT) then
wd = system.GetEnvVar("windir")

_WinSysDir = wd+"\system32\"

elseif (OSvar = #SYSTEM_OSVARIANT_MSW95) then
wd = system.GetEnvVar("windir")

_WinSysDir = wd+"\system32\"
else
MsgBox.Warning("This project is designed for use" +NL+
"by WindowsNT and Windows95 PCs.","Stop")
av.GetProject.Close
end

' DETERMINE THE USER LOGIN NAME
'
'Make the DLL object
dllAdvAPI32 = dll.make((_WinSysDir + "advapi32.dll").AsFileName)

'Make the DLLProc object
dpGetUserNameA = dllproc.make(dllAdvAPI32, "GetUserNameA",
#DLLPROC_TYPE_INT32,{#DLLPROC_TYPE_STR, #DLLPROC_TYPE_PINT32})

'Make the string buffer
uname = String.MakeBuffer(12)
buflen = 10
retValue = Number.MakeNull

'Call the function which returns the username to the buffer
retValue = dpGetUserNameA.Call({uname, buflen})
mystr = Uname.AsString

' DETERMINE THE COMPUTER NAME
'Make the DLL object
dllKernel32 = dll.make((_WinSysDir + "kernel32.dll").AsFileName)

'Make the DLLProc object
dpGetComputerNameA = dllproc.make(dllkernel32, "GetComputerNameA",
#DLLPROC_TYPE_INT32,{#DLLPROC_TYPE_STR, #DLLPROC_TYPE_PINT32})

'Make the string buffer
cname = String.MakeBuffer(12)
buflen = 10
retValue = Number.MakeNull

'Call the function which returns the username to the buffer
retValue = dpGetComputerNameA.Call({cname, buflen})

compname = cname.AsString

info_list = list.make
checkfile2 = FileName.FindInSystemSearchPath (_textfilename.AsString)
if (checkfile2 <> nil) then
theLineFile2 = linefile.make(_textfilename,#FILE_PERM_READ)
thelist = List.Make
numlines = theLineFile2.GetSize
source = theLineFile2.Read( theList,numlines )
a = theList.count
pos = theLineFile2.SetPos (0)

for each l in theList
theline = theLineFile2.ReadElt
info_list.Add(theline)
end
end

if (info_list.Count > 0) then
user = info_list.Get(0).AsString
comp = info_list.Get(1).AsString
else
return nil
end

if ((mystr = user) and (compname = comp)) then
_theLineFile = nil
_tf = nil
theLineFile2 = nil
av.PurgeObjects

File.Delete(_textFileName)

else

end

'END OF SHUTDOWN SCRIPT --------------------------------------
8. Compile the Script, the checkmark button, but DO NOT run it.

9. Go to the Script Menu, and select Embed Script.

10. Activate the Project Window.

11. Go to the Project Menu > Properties.

12. Click the button next to the Startup textline.

13. Select the Script called aStartup. Click OK.

14. Click the button next to the Shutdown textline.

15. Select the Script called aShutDown. Click OK.

16. Click Save.

17. Close the Project, or Exit ArcView.
The next time the project is opened, it will create a textfile in the same directory in which the project resides. For example: If a project called Rivers.apr is opened with the above Startup and Shutdown scripts, it creates a textfile in the same directory called riversapr.txt. When the project is saved and closed, it will remove this textfile. This textfile prevents others from opening the project.
Warning:
Users should never open two versions of the application, with the same project file on their local machine. This could corrupt the project file.