English

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

Summary

This document describes how to allow an .apr to be opened by only one user at a time via Avenue.

Procedure

Use a Project Startup and Shutdown script to allow only one user at a time to open a project file.

  1. Open the project that you want only one user to open at a time.
  2. Open a new Script document and rename it "aStartup".
  3. Copy the following code and paste it into the new script called aStartup.

    Code:
    '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. Select Compile from the Script menu.
  5. Select Embed Script from the Script menu.
  6. Open another new Script and rename it "aShutDown".
  7. Copy the following code into the new script called aShutDown.

    Code:
    '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. Select Compile from the Script menu.
  9. Select Embed Script from the Script menu.
  10. Switch to the Project Window.
  11. Select Properties from the Project Menu.
  12. Click the button next to the Startup textline.
  13. Select the "aStartup" script and click OK.
  14. Click the button next to the Shutdown textline.
  15. Select the "aShutDown" script and click OK.
  16. Save the Project and close it and/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, let us assume that I have a project called Rivers.apr. When I open this project with the above Startup and Shutdown scripts, it will create a textfile called riversapr.txt in the same directory. When the project is saved and closed, this textfile will be removed. 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 allow for corruption of the project file.