Announcement

Collapse
No announcement yet.

File In Use Determination

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • File In Use Determination

    I'm new to PowerBasic but like it very much. I have a question
    about the proper way to determine if a file is in use. I have
    been Opening the file with LOCK READ WRITE and this seems to
    work but it gets ugly in NT4 because I have to actually read
    a few bytes from the file and write them back and that changes
    the file date etc, etc, etc. So, I decided it was time to ask
    for the correct way or at least a better way.

    Thanks,

    Bob


    ------------------

  • #2
    Bob,

    In a multi-user environment, where several users are accessing
    the same data files, the standard way to open files would
    be the following:

    OPEN FNAME$ FOR BINARY ACCESS READ WRITE SHARED AS #F
    OR
    OPEN FNAME$ FOR INPUT ACCESS READ SHARED AS #F

    using this type of open commands, you need to review
    the LOCK and UNLOCK commands

    Then if you wanted to test to see if another user has
    a file open.

    OPEN fname$ for binary as #F
    ON ERROR GOTO ERRORHANDLER
    A$=SPACE$(1):GET #F,1,A$ ' THIS will result a in error

    or

    OPEN FNAME$ FOR INPUT AS #F
    ON ERROR GOTO ERRORHANDLER
    line input #f,a$ ' this will result in a error


    Phil

    ------------------
    E-Mail: [email protected]
    E-Mail:
    pt AT pursuersoft DOT com

    Comment


    • #3
      Phil,

      Thanks for the reply. I'm doing exactly the way you describe by
      opening the file in binary (the default being LOCK READ WRITE) and
      in W95/W98 I don't even have to do a GET but in NT 4.0 in addition
      to a GET I have to do a PUT to create the ERROR condition. And of
      course that changes the file date etc. Isn't there a better way??

      Thanks,

      Bob

      ------------------

      Comment


      • #4
        Code:
        %HFILE_ERROR = -1
        '====================
        FUNCTION IsFileOpen&(The_File AS ASCIIZ)
        LOCAL result&, ecode&
           
        '_lopen(filename, OF_READ | OF_SHARE_EXCLUSIVE);
        result& = lopen&(The_File, %OF_READ OR %OF_SHARE_EXCLUSIVE)
           
        if (result& = %HFILE_ERROR) then
           '-- Save last error
           ecode& = GetLastError
        else
           '-- If the open was successful, close the file
           lclose result&
        end if
           
        ''msgbox str$(result&) + $CR + str$(ecode&)
        '-- Return TRUE if sharing violation
        function = ((result& = %HFILE_ERROR) AND (ecode& = %ERROR_SHARING_VIOLATION))
        END FUNCTION

        ------------------
        -- Greg
        [email protected]

        Comment


        • #5
          In general, it's not your business whether the file is in use, just whether you can
          access it as needed. To that end, an appropriate OPEN should suffice. If you can
          explain in more detail what you aim to accomplish, perhaps we can help you better.

          Given appropriate access handling, you may not be able to detect whether a file is
          in use, by the way... that depends as much on how others open the file as how you
          open the file.


          ------------------
          Tom Hanlin
          PowerBASIC Staff

          Comment


          • #6
            Tom,

            That's more than fair.

            I am trying to find out when a particular third party program is
            running. When started, the program awaits user information to
            continue or even exit. My program was developed using W95 and
            sucessfully uses a BINARY file OPEN on the third party program
            (default LOCK READ WRITE)to trigger the "Permission Denied"
            response without even having to resort to a GET to input a few
            bytes.

            My problem is making the program work in NT 4.0 where not only
            do I need to use GET but I also need to use PUT to write the bytes
            back to the file before "Permission Denied" is triggered. This
            then results in a Last Write Time change for the third party file
            and begins to get messy. So, that's why I am asking - is there a
            better way??

            Thanks,

            ~Bob


            ------------------

            Comment


            • #7
              I'd expect an OPEN with LOCK READ WRITE to fail if the file is open, but that depends
              on whether the other program also employs file locking and on the way the operating
              system implements file-level locking errors. In this case, it sounds as if you've run
              afoul of one and/or the other. You might look for other techniques. Barring that, the
              pragmatic solution would be to save and restore the file time/date stamp, which is
              simple using Windows API calls.

              It generally isn't difficult to tell whether a given program is running by other
              methods: window name, classes loaded, or whatever. Some such approach may work better
              for you. If you're trying to detect a console app, that may be more of a problem, as
              Windows seems to keep console functionality to a bare minimum.


              ------------------
              Tom Hanlin
              PowerBASIC Staff

              Comment


              • #8
                I ran several tests and MS QBasic/QuickBasic responded identically
                to PowerBasic - that is they all caught the "Permission Denied" response
                in W95 when an in use file was opened for either INPUT or BINARY
                regardless if any data was actually input or output to/from the file.
                However, neither MS QuickBasic or PowerBasic trapped "Permission
                Denied" in when running under NT 4.0.

                The solution for this case turned out to be quite simple and works both
                in W95 and NT 4.0. Attempt to OPEN the file for WRITE access using
                the Win32API instead of PowerBasic per the following:

                Thanks to all for your help!!

                Code:
                FUNCTION IsBusy(F1$) AS LONG
                
                  DIM OFS AS OFSTRUCT
                
                  h& = OpenFile(BYCOPY F1$, OFS, %OF_WRITE)
                  IF h& > 0 THEN
                    ' Not Busy
                    x& = CloseHandle(h&)
                    FUNCTION = FALSE
                  ELSE
                    ' Busy
                    FUNCTION = TRUE
                  END IF
                
                END FUNCTION



                [This message has been edited by Bob Scott (edited March 19, 2001).]

                Comment


                • #9
                  To keep the formatting, start a code block with [ code] and end it with
                  [ /code] (leave out the space after the left bracket!).

                  The OpenFile API has a long history of bugs. You might find CreateFile a
                  safer choice.

                  ------------------
                  Tom Hanlin
                  PowerBASIC Staff

                  Comment


                  • #10
                    Tom,

                    Thanks for all your help. I will try the CreateFile.

                    ~Bob

                    ------------------

                    Comment

                    Working...
                    X