Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Multiple application instances-how prevent multiple file instances or file overwrite

Multiple application instances-how prevent multiple file instances or file overwrite

Scheduled Pinned Locked Moved C / C++ / MFC
c++questiontestingbeta-testinghelp
22 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Offline
    L Offline
    lctrncs
    wrote on last edited by
    #1

    I am a rank amateur fighting scope creep and finalizing (one can always hope!) a general educational program in MFC/C++ Document/View after years of "bang your head on the wall" programming. It is good to allow multiple instances of the program, and extensive testing using multiple instances has uncovered only one apparent issue - the ability of multiple instances of the program to open and edit the same file. When switching with Alt-Tab between two instances of the program with the same file open, it is possible to overwrite the file from either instance, resulting in the ability to lose work by overwriting with an earlier version. How can I use a semaphore (or anything else) to prevent the user from opening a file that is already open, or at least give the user a warning on file open or save? I am having trouble understanding how to use the semaphore (or anything else) to lock the file when I open it or test to see if it is locked when I try to open it again because there just do not seem to be many examples out there due to the apparently prevalent desire to prevent multiple instances of an application. Thanks in advance for your time and consideration.

    "For a successful technology, reality must take precedence over public relations, for nature cannot be fooled." Richard Feynman, Minority Report to the Official Report on the Space Shuttle Challenger Crash

    M S 2 Replies Last reply
    0
    • L lctrncs

      I am a rank amateur fighting scope creep and finalizing (one can always hope!) a general educational program in MFC/C++ Document/View after years of "bang your head on the wall" programming. It is good to allow multiple instances of the program, and extensive testing using multiple instances has uncovered only one apparent issue - the ability of multiple instances of the program to open and edit the same file. When switching with Alt-Tab between two instances of the program with the same file open, it is possible to overwrite the file from either instance, resulting in the ability to lose work by overwriting with an earlier version. How can I use a semaphore (or anything else) to prevent the user from opening a file that is already open, or at least give the user a warning on file open or save? I am having trouble understanding how to use the semaphore (or anything else) to lock the file when I open it or test to see if it is locked when I try to open it again because there just do not seem to be many examples out there due to the apparently prevalent desire to prevent multiple instances of an application. Thanks in advance for your time and consideration.

      "For a successful technology, reality must take precedence over public relations, for nature cannot be fooled." Richard Feynman, Minority Report to the Official Report on the Space Shuttle Challenger Crash

      M Offline
      M Offline
      Mark Salsbery
      wrote on last edited by
      #2

      A named Mutex object would work if you want to synchronize access to the file at the thread level across processes. An easier method would be to open the file in a share mode that doesn't allow others to open the file (or at least denies write access).

      lctrncs wrote:

      a general educational program in MFC/C++ Document/View after years of "bang your head on the wall" programming.

      Some would say with MFC Doc/View you can expect many more years of the same.

      L 1 Reply Last reply
      0
      • L lctrncs

        I am a rank amateur fighting scope creep and finalizing (one can always hope!) a general educational program in MFC/C++ Document/View after years of "bang your head on the wall" programming. It is good to allow multiple instances of the program, and extensive testing using multiple instances has uncovered only one apparent issue - the ability of multiple instances of the program to open and edit the same file. When switching with Alt-Tab between two instances of the program with the same file open, it is possible to overwrite the file from either instance, resulting in the ability to lose work by overwriting with an earlier version. How can I use a semaphore (or anything else) to prevent the user from opening a file that is already open, or at least give the user a warning on file open or save? I am having trouble understanding how to use the semaphore (or anything else) to lock the file when I open it or test to see if it is locked when I try to open it again because there just do not seem to be many examples out there due to the apparently prevalent desire to prevent multiple instances of an application. Thanks in advance for your time and consideration.

        "For a successful technology, reality must take precedence over public relations, for nature cannot be fooled." Richard Feynman, Minority Report to the Official Report on the Space Shuttle Challenger Crash

        S Offline
        S Offline
        Stephen Hewitt
        wrote on last edited by
        #3

        The Win32 CreateFile function's dwShareMode parameter can be use to control this without the need to mutexes. Passing in a value of 0 should do the trick.

        Steve

        L 2 Replies Last reply
        0
        • S Stephen Hewitt

          The Win32 CreateFile function's dwShareMode parameter can be use to control this without the need to mutexes. Passing in a value of 0 should do the trick.

          Steve

          L Offline
          L Offline
          lctrncs
          wrote on last edited by
          #4

          Thank you for responding. Won't this collide with my existing code for opening files?

          "For a successful technology, reality must take precedence over public relations, for nature cannot be fooled." Richard Feynman, Minority Report to the Official Report on the Space Shuttle Challenger Crash

          1 Reply Last reply
          0
          • S Stephen Hewitt

            The Win32 CreateFile function's dwShareMode parameter can be use to control this without the need to mutexes. Passing in a value of 0 should do the trick.

            Steve

            L Offline
            L Offline
            lctrncs
            wrote on last edited by
            #5

            Thank you for the nice clue. Including a CreateFile function passing a dwSharedMode 0 in my OnOpenDocument allows me to open a file when I use the lpszPathName of OnOpenDocument as the first argument in the CreateFile function. If I then try to open the file a second time using a different instance of my app, a "sharing violation" message appears. If I try to save the first instance of the file using the first instance of my app, a First Chance Exception occurs that passes "access denied" back to the program. I have tried various file attributes, but am probably doing something more basic wrong. Any suggestions?

            "For a successful technology, reality must take precedence over public relations, for nature cannot be fooled." Richard Feynman, Minority Report to the Official Report on the Space Shuttle Challenger Crash

            S 1 Reply Last reply
            0
            • M Mark Salsbery

              A named Mutex object would work if you want to synchronize access to the file at the thread level across processes. An easier method would be to open the file in a share mode that doesn't allow others to open the file (or at least denies write access).

              lctrncs wrote:

              a general educational program in MFC/C++ Document/View after years of "bang your head on the wall" programming.

              Some would say with MFC Doc/View you can expect many more years of the same.

              L Offline
              L Offline
              lctrncs
              wrote on last edited by
              #6

              Mark Salsbery wrote:

              Some would say with MFC Doc/View you can expect many more years of the same.

              As a biochemistry type, I find programming to be like an incredibly difficult puzzle. You can move the parts around and try them here and there, and eventually they fit. I am trying to learn what the parts are and how they fit together, but my numb biologist's brain may not be correctly configured for such endeavors. Thank you for the nice clue. Including a CreateFile function passing a dwSharedMode 0 in my OnOpenDocument allows me to open a file when I use the lpszPathName of OnOpenDocument as the first argument in the CreateFile function. If I then try to open the file a second time using a different instance of my app, a "sharing violation" message appears. If I try to save the first instance of the file using the first instance of my app, a First Chance Exception occurs that passes "access denied" back to the program. I have tried various file attributes, but am probably doing something more basic wrong. Any suggestions?

              "For a successful technology, reality must take precedence over public relations, for nature cannot be fooled." Richard Feynman, Minority Report to the Official Report on the Space Shuttle Challenger Crash

              M 1 Reply Last reply
              0
              • L lctrncs

                Mark Salsbery wrote:

                Some would say with MFC Doc/View you can expect many more years of the same.

                As a biochemistry type, I find programming to be like an incredibly difficult puzzle. You can move the parts around and try them here and there, and eventually they fit. I am trying to learn what the parts are and how they fit together, but my numb biologist's brain may not be correctly configured for such endeavors. Thank you for the nice clue. Including a CreateFile function passing a dwSharedMode 0 in my OnOpenDocument allows me to open a file when I use the lpszPathName of OnOpenDocument as the first argument in the CreateFile function. If I then try to open the file a second time using a different instance of my app, a "sharing violation" message appears. If I try to save the first instance of the file using the first instance of my app, a First Chance Exception occurs that passes "access denied" back to the program. I have tried various file attributes, but am probably doing something more basic wrong. Any suggestions?

                "For a successful technology, reality must take precedence over public relations, for nature cannot be fooled." Richard Feynman, Minority Report to the Official Report on the Space Shuttle Challenger Crash

                M Offline
                M Offline
                Mark Salsbery
                wrote on last edited by
                #7

                lctrncs wrote:

                If I try to save the first instance of the file using the first instance of my app, a First Chance Exception occurs that passes "access denied" back to the program.

                How are you saving the file? Have you overridden OnSaveDocument() as well? If not, then you should, and use CloseHandle() to close the file handle returned by CreateFile() in your OnOpenDocument() override.

                lctrncs wrote:

                As a biochemistry type, I find programming to be like an incredibly difficult puzzle. You can move the parts around and try them here and there, and eventually they fit. I am trying to learn what the parts are and how they fit together, but my numb biologist's brain may not be correctly configured for such endeavors.

                Thanks for reminding me that questions can come from a different point of view. Apparently I'm bitter about the Doc/View architecture. I used it for years with both Borland's OWL framework and MFC (even had an article published on the subject). Because of the direction my user interface code ended up going, Doc/View became more and more of a nuisance and at this point I still have code using it a bit but not completeley. Some day I hope to have the time to remove it. It's actually a great model and well implemented in MFC for RAD but I've found that extending it gets complex unless one knows the MFC code intimately. I guess I have a love/hate relationship with Doc/View. Way off topic, I know, but my comment in the first reply was really unnecessary and you reminded me of that, so thanks :)

                L 1 Reply Last reply
                0
                • L lctrncs

                  Thank you for the nice clue. Including a CreateFile function passing a dwSharedMode 0 in my OnOpenDocument allows me to open a file when I use the lpszPathName of OnOpenDocument as the first argument in the CreateFile function. If I then try to open the file a second time using a different instance of my app, a "sharing violation" message appears. If I try to save the first instance of the file using the first instance of my app, a First Chance Exception occurs that passes "access denied" back to the program. I have tried various file attributes, but am probably doing something more basic wrong. Any suggestions?

                  "For a successful technology, reality must take precedence over public relations, for nature cannot be fooled." Richard Feynman, Minority Report to the Official Report on the Space Shuttle Challenger Crash

                  S Offline
                  S Offline
                  Stephen Hewitt
                  wrote on last edited by
                  #8

                  lctrncs wrote:

                  If I try to save the first instance of the file using the first instance of my app, a First Chance Exception occurs that passes "access denied" back to the program.

                  Try to find out where this exception is coming from. First you need to find out the kind of exception (first chance is not an exception type; it just means the debugger is being given the change to process to exception before the application gets its turn). Once you know that you need to setup your debugger to break on this exception so you can see where it’s coming from. On MSVC 6 this is done via the “Debug”->”Exceptions…” menu item which is accessible while an application is being debugged. Try to set this option as late as possible before you trigger the fault.

                  Steve

                  1 Reply Last reply
                  0
                  • M Mark Salsbery

                    lctrncs wrote:

                    If I try to save the first instance of the file using the first instance of my app, a First Chance Exception occurs that passes "access denied" back to the program.

                    How are you saving the file? Have you overridden OnSaveDocument() as well? If not, then you should, and use CloseHandle() to close the file handle returned by CreateFile() in your OnOpenDocument() override.

                    lctrncs wrote:

                    As a biochemistry type, I find programming to be like an incredibly difficult puzzle. You can move the parts around and try them here and there, and eventually they fit. I am trying to learn what the parts are and how they fit together, but my numb biologist's brain may not be correctly configured for such endeavors.

                    Thanks for reminding me that questions can come from a different point of view. Apparently I'm bitter about the Doc/View architecture. I used it for years with both Borland's OWL framework and MFC (even had an article published on the subject). Because of the direction my user interface code ended up going, Doc/View became more and more of a nuisance and at this point I still have code using it a bit but not completeley. Some day I hope to have the time to remove it. It's actually a great model and well implemented in MFC for RAD but I've found that extending it gets complex unless one knows the MFC code intimately. I guess I have a love/hate relationship with Doc/View. Way off topic, I know, but my comment in the first reply was really unnecessary and you reminded me of that, so thanks :)

                    L Offline
                    L Offline
                    lctrncs
                    wrote on last edited by
                    #9

                    Thanks for another clue. I added an OnSaveDocument by hand since the classwizard stopped allowing me to add new member functions a while back. Sadly, overriding OnSaveDocument and using CloseHandle to close the file handle resulted in no change in the program's behavior (I did not check how a second instance of the application's attempt to open the file). I still receive the access denied messge in the primary program when I try to save. I defined a handle in the Doc.h file so both functions could see it. Since I do not understand how CreateFile is working in concert with OnOpen/SaveDocument (and have precious little time to learn) it is difficult for me to proceed. I can probably release my new version as is with it's numerous cosmetic and operational improvements (you can see the current version at www.studypartnernow.com) and just warn users about this issue. I hate to take your time. Any other suggestions?

                    Mark Salsbery wrote:

                    Apparently I'm bitter about the Doc/View architecture.

                    I used to be a Microsoft evangelist - until I worked on the launch of Windows 95 as a "Remote Service Engineer." Microsoft technology COULD have been mega cool, but it appears to me that at some point money became the primary motivation for operations, and everything has been downhill ever since on the technical side, especially in the absence of viable competition.

                    "For a successful technology, reality must take precedence over public relations, for nature cannot be fooled." Richard Feynman, Minority Report to the Official Report on the Space Shuttle Challenger Crash

                    L M 2 Replies Last reply
                    0
                    • L lctrncs

                      Thanks for another clue. I added an OnSaveDocument by hand since the classwizard stopped allowing me to add new member functions a while back. Sadly, overriding OnSaveDocument and using CloseHandle to close the file handle resulted in no change in the program's behavior (I did not check how a second instance of the application's attempt to open the file). I still receive the access denied messge in the primary program when I try to save. I defined a handle in the Doc.h file so both functions could see it. Since I do not understand how CreateFile is working in concert with OnOpen/SaveDocument (and have precious little time to learn) it is difficult for me to proceed. I can probably release my new version as is with it's numerous cosmetic and operational improvements (you can see the current version at www.studypartnernow.com) and just warn users about this issue. I hate to take your time. Any other suggestions?

                      Mark Salsbery wrote:

                      Apparently I'm bitter about the Doc/View architecture.

                      I used to be a Microsoft evangelist - until I worked on the launch of Windows 95 as a "Remote Service Engineer." Microsoft technology COULD have been mega cool, but it appears to me that at some point money became the primary motivation for operations, and everything has been downhill ever since on the technical side, especially in the absence of viable competition.

                      "For a successful technology, reality must take precedence over public relations, for nature cannot be fooled." Richard Feynman, Minority Report to the Official Report on the Space Shuttle Challenger Crash

                      L Offline
                      L Offline
                      lctrncs
                      wrote on last edited by
                      #10

                      Oops - getting crispy in crunch mode. I added and overrode (I think) an OnSaveDocument function, not an OnSaveFunction or OnSaveRecord. Thanks for all your help.

                      "For a successful technology, reality must take precedence over public relations, for nature cannot be fooled." Richard Feynman, Minority Report to the Official Report on the Space Shuttle Challenger Crash

                      1 Reply Last reply
                      0
                      • L lctrncs

                        Thanks for another clue. I added an OnSaveDocument by hand since the classwizard stopped allowing me to add new member functions a while back. Sadly, overriding OnSaveDocument and using CloseHandle to close the file handle resulted in no change in the program's behavior (I did not check how a second instance of the application's attempt to open the file). I still receive the access denied messge in the primary program when I try to save. I defined a handle in the Doc.h file so both functions could see it. Since I do not understand how CreateFile is working in concert with OnOpen/SaveDocument (and have precious little time to learn) it is difficult for me to proceed. I can probably release my new version as is with it's numerous cosmetic and operational improvements (you can see the current version at www.studypartnernow.com) and just warn users about this issue. I hate to take your time. Any other suggestions?

                        Mark Salsbery wrote:

                        Apparently I'm bitter about the Doc/View architecture.

                        I used to be a Microsoft evangelist - until I worked on the launch of Windows 95 as a "Remote Service Engineer." Microsoft technology COULD have been mega cool, but it appears to me that at some point money became the primary motivation for operations, and everything has been downhill ever since on the technical side, especially in the absence of viable competition.

                        "For a successful technology, reality must take precedence over public relations, for nature cannot be fooled." Richard Feynman, Minority Report to the Official Report on the Space Shuttle Challenger Crash

                        M Offline
                        M Offline
                        Mark Salsbery
                        wrote on last edited by
                        #11

                        I'm trying to figure out where the access denied message would even come from. It's a message box that pops up? Can you post the code for your CreateFile() call, especially all the flag/security params you are passing? Also, you're not calling the base class OnOpenDocument/OnSaveDocument I hope.

                        lctrncs wrote:

                        I used to be a Microsoft evangelist

                        :) That always reminds me of "Cup-o-Joe", an evangelist on the worldwide live broadcast of the rollout/introduction of Windows 95 (I think).

                        L 1 Reply Last reply
                        0
                        • M Mark Salsbery

                          I'm trying to figure out where the access denied message would even come from. It's a message box that pops up? Can you post the code for your CreateFile() call, especially all the flag/security params you are passing? Also, you're not calling the base class OnOpenDocument/OnSaveDocument I hope.

                          lctrncs wrote:

                          I used to be a Microsoft evangelist

                          :) That always reminds me of "Cup-o-Joe", an evangelist on the worldwide live broadcast of the rollout/introduction of Windows 95 (I think).

                          L Offline
                          L Offline
                          lctrncs
                          wrote on last edited by
                          #12

                          THANK YOU! I wonder if the problem stems from the flat file database I have hanging off the doc/view. CODE FOR CreateFile call etc. From StudyPartnerDoc.cpp file ///////////////////////////////////////////////////////////////////////////// /////////////////// OnOpenDocument ////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// BOOL CStudyPartnerDoc::OnOpenDocument(LPCTSTR lpszPathName) { if (!CDocument::OnOpenDocument(lpszPathName)) return FALSE; //Get a pointer to the view POSITION pos = GetFirstViewPosition(); CStudyPartnerView* pView = dynamic_cast( GetNextView(pos) ); //Tell the view that its got a new data set if (pView) pView->NewDataSet(); ///////////////////////////////////////////////////////////// // Attempts to prevent file overwrite when multiple copies of app open the same file ///* //CreateFile and dwsharedmode to prevent make file read only when one instance is using it //opens the file - but "access denied" passed through to program on save after First Chance Exception m_hFileLock = CreateFile( lpszPathName, GENERIC_WRITE|GENERIC_READ, // access (read-write) mode //0, //attempt to use "query device attributes without accessing the device." 0,// share mode NULL,// pointer to security descriptor OPEN_EXISTING,// how to create FILE_ATTRIBUTE_NORMAL,// file attributes NULL); // handle to file with attributes to copy //FILE ATTRIBUTES TRIALS //FILE_ATTRIBUTE_NORMAL - crash on save //FILE_ATTRIBUTE_TEMPORARY - access denied //FILE_FLAG_WRITE_THROUGH - First Chance Exception on save //FILE_ATTRIBUTE_HIDDEN DestroyDialog(); //Ensure that the Study Dialog is closed return TRUE; } ///////////////////////////////////////////////////////////////////////////// /////////////////// OnSaveDocument ////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// BOOL CStudyPartnerDoc::OnSaveDocument(LPCTSTR lpszPathName) { if (!CDocument::OnSaveDocument(lpszPathName)) return FALSE; //////////////////////////////////////////////////// // Close the file handle opened for CreateFile and dwShareMode CloseHandle( m_hFileLock ); return TRUE; } /////////////////

                          M 1 Reply Last reply
                          0
                          • L lctrncs

                            THANK YOU! I wonder if the problem stems from the flat file database I have hanging off the doc/view. CODE FOR CreateFile call etc. From StudyPartnerDoc.cpp file ///////////////////////////////////////////////////////////////////////////// /////////////////// OnOpenDocument ////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// BOOL CStudyPartnerDoc::OnOpenDocument(LPCTSTR lpszPathName) { if (!CDocument::OnOpenDocument(lpszPathName)) return FALSE; //Get a pointer to the view POSITION pos = GetFirstViewPosition(); CStudyPartnerView* pView = dynamic_cast( GetNextView(pos) ); //Tell the view that its got a new data set if (pView) pView->NewDataSet(); ///////////////////////////////////////////////////////////// // Attempts to prevent file overwrite when multiple copies of app open the same file ///* //CreateFile and dwsharedmode to prevent make file read only when one instance is using it //opens the file - but "access denied" passed through to program on save after First Chance Exception m_hFileLock = CreateFile( lpszPathName, GENERIC_WRITE|GENERIC_READ, // access (read-write) mode //0, //attempt to use "query device attributes without accessing the device." 0,// share mode NULL,// pointer to security descriptor OPEN_EXISTING,// how to create FILE_ATTRIBUTE_NORMAL,// file attributes NULL); // handle to file with attributes to copy //FILE ATTRIBUTES TRIALS //FILE_ATTRIBUTE_NORMAL - crash on save //FILE_ATTRIBUTE_TEMPORARY - access denied //FILE_FLAG_WRITE_THROUGH - First Chance Exception on save //FILE_ATTRIBUTE_HIDDEN DestroyDialog(); //Ensure that the Study Dialog is closed return TRUE; } ///////////////////////////////////////////////////////////////////////////// /////////////////// OnSaveDocument ////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// BOOL CStudyPartnerDoc::OnSaveDocument(LPCTSTR lpszPathName) { if (!CDocument::OnSaveDocument(lpszPathName)) return FALSE; //////////////////////////////////////////////////// // Close the file handle opened for CreateFile and dwShareMode CloseHandle( m_hFileLock ); return TRUE; } /////////////////

                            M Offline
                            M Offline
                            Mark Salsbery
                            wrote on last edited by
                            #13

                            You're welcome! Calling the base class OnOpenDocument() (CDocument::OnOpenDocument()) the file using a CFile object, reads the file into a CArchive object, and closes the file. No problem there except a waste of CPU cycles and RAM. Calling the base class OnSaveDocument() (CDocument::OnSaveDocument()), on the other hand, opens the file using a CFile object in this mode: "CFile::modeCreate | CFile::modeReadWrite | File::shareExclusive" which will fail miserably since you've opened the file with CreateFile(). Thus, calling the base class methods is a bad idea in this case - you are handling the open/save functionality yourself. :) Once you've opened that file with no sharing enabled, any other attempt to open the file will fail, which should work nicely with your multiple processes. Mark

                            L 1 Reply Last reply
                            0
                            • M Mark Salsbery

                              You're welcome! Calling the base class OnOpenDocument() (CDocument::OnOpenDocument()) the file using a CFile object, reads the file into a CArchive object, and closes the file. No problem there except a waste of CPU cycles and RAM. Calling the base class OnSaveDocument() (CDocument::OnSaveDocument()), on the other hand, opens the file using a CFile object in this mode: "CFile::modeCreate | CFile::modeReadWrite | File::shareExclusive" which will fail miserably since you've opened the file with CreateFile(). Thus, calling the base class methods is a bad idea in this case - you are handling the open/save functionality yourself. :) Once you've opened that file with no sharing enabled, any other attempt to open the file will fail, which should work nicely with your multiple processes. Mark

                              L Offline
                              L Offline
                              lctrncs
                              wrote on last edited by
                              #14

                              You appear to be correct about the failure of other attempts to open the file once I have it open with CreateFile. Such attempts yield a Sharing Violation message. However, the Access Denied exceptions upon attempts to save the primary file and the Invalid Handle exceptions upon attemtps to close the primary instance of the application with the file open or closed remain an issue. X| It appears that I am not even gaining access to the file to save it, AND something else seriously wrong associated with CreateFile is interfering with nominal shutdown of the program. :confused: You can look at an earlier version of the program at www.studypartnernow.com. I wonder if the flat file database that also contributes to the file structure might be part of my problem with the CreateFile. Groff

                              "For a successful technology, reality must take precedence over public relations, for nature cannot be fooled." Richard Feynman, Minority Report to the Official Report on the Space Shuttle Challenger Crash

                              M 2 Replies Last reply
                              0
                              • L lctrncs

                                You appear to be correct about the failure of other attempts to open the file once I have it open with CreateFile. Such attempts yield a Sharing Violation message. However, the Access Denied exceptions upon attempts to save the primary file and the Invalid Handle exceptions upon attemtps to close the primary instance of the application with the file open or closed remain an issue. X| It appears that I am not even gaining access to the file to save it, AND something else seriously wrong associated with CreateFile is interfering with nominal shutdown of the program. :confused: You can look at an earlier version of the program at www.studypartnernow.com. I wonder if the flat file database that also contributes to the file structure might be part of my problem with the CreateFile. Groff

                                "For a successful technology, reality must take precedence over public relations, for nature cannot be fooled." Richard Feynman, Minority Report to the Official Report on the Space Shuttle Challenger Crash

                                M Offline
                                M Offline
                                Mark Salsbery
                                wrote on last edited by
                                #15

                                Maybe I misunderstood....you did remove the calls to the CDocument::OnOpenDocument and CDocument::OnSaveDocument in your derived document class, right? I noticed they were still in the code you posted so I'm not sure if you did that before or after the last messages we exchanged. Those need to be removed or there will be problems for sure! Mark

                                L 1 Reply Last reply
                                0
                                • L lctrncs

                                  You appear to be correct about the failure of other attempts to open the file once I have it open with CreateFile. Such attempts yield a Sharing Violation message. However, the Access Denied exceptions upon attempts to save the primary file and the Invalid Handle exceptions upon attemtps to close the primary instance of the application with the file open or closed remain an issue. X| It appears that I am not even gaining access to the file to save it, AND something else seriously wrong associated with CreateFile is interfering with nominal shutdown of the program. :confused: You can look at an earlier version of the program at www.studypartnernow.com. I wonder if the flat file database that also contributes to the file structure might be part of my problem with the CreateFile. Groff

                                  "For a successful technology, reality must take precedence over public relations, for nature cannot be fooled." Richard Feynman, Minority Report to the Official Report on the Space Shuttle Challenger Crash

                                  M Offline
                                  M Offline
                                  Mark Salsbery
                                  wrote on last edited by
                                  #16

                                  I downloaded the free demo...is that the right one? I get the following error in a messagebox: \Setup.ini Invalid Database. The Installation will be cancelled.

                                  1 Reply Last reply
                                  0
                                  • M Mark Salsbery

                                    Maybe I misunderstood....you did remove the calls to the CDocument::OnOpenDocument and CDocument::OnSaveDocument in your derived document class, right? I noticed they were still in the code you posted so I'm not sure if you did that before or after the last messages we exchanged. Those need to be removed or there will be problems for sure! Mark

                                    L Offline
                                    L Offline
                                    lctrncs
                                    wrote on last edited by
                                    #17

                                    I just was not sure that if (!CDocument::OnOpenDocument(lpszpathname) return FALSE; was the same as CDocument::OnOpenDocument However, I thought I understood you to say that both were to be removed for the success of the CreateFile. I attempted this, but encountered problems when I removed the calls to the base classes. Below, please find a matrix indicating the results of a quicky test of the various possibilities. Column 1 2 3 4 5 OnOpenDoc base class code 0 1 1 1 1 OnSaveDoc base class code 0 0 0 1 0 CreateFile code 1 1 0 1 0 First app opens file? 0 1 1 1 1 First app saves file? x Inv. Hndle 0 Acc.Den. 0 Open second file instance? x 0 1 0 x It appears that the best results occur in column two and four, in which the app opens the file and prevents use by a second app while it has it open. However, both of these configurations result in exceptions when the user attempts to save the file. Note that the base class calls appear to be required for function of the open and save capabilities. It appears that the challenge revolves around restoring functional save capabilities when the base class calls are not present and the CreateFile code is, or overcoming the Access Denied exception that occurs when the open and save base class calls are present in conjunction with the CreateFile code.

                                    "For a successful technology, reality must take precedence over public relations, for nature cannot be fooled." Richard Feynman, Minority Report to the Official Report on the Space Shuttle Challenger Crash

                                    M 2 Replies Last reply
                                    0
                                    • L lctrncs

                                      I just was not sure that if (!CDocument::OnOpenDocument(lpszpathname) return FALSE; was the same as CDocument::OnOpenDocument However, I thought I understood you to say that both were to be removed for the success of the CreateFile. I attempted this, but encountered problems when I removed the calls to the base classes. Below, please find a matrix indicating the results of a quicky test of the various possibilities. Column 1 2 3 4 5 OnOpenDoc base class code 0 1 1 1 1 OnSaveDoc base class code 0 0 0 1 0 CreateFile code 1 1 0 1 0 First app opens file? 0 1 1 1 1 First app saves file? x Inv. Hndle 0 Acc.Den. 0 Open second file instance? x 0 1 0 x It appears that the best results occur in column two and four, in which the app opens the file and prevents use by a second app while it has it open. However, both of these configurations result in exceptions when the user attempts to save the file. Note that the base class calls appear to be required for function of the open and save capabilities. It appears that the challenge revolves around restoring functional save capabilities when the base class calls are not present and the CreateFile code is, or overcoming the Access Denied exception that occurs when the open and save base class calls are present in conjunction with the CreateFile code.

                                      "For a successful technology, reality must take precedence over public relations, for nature cannot be fooled." Richard Feynman, Minority Report to the Official Report on the Space Shuttle Challenger Crash

                                      M Offline
                                      M Offline
                                      Mark Salsbery
                                      wrote on last edited by
                                      #18

                                      lctrncs wrote:

                                      It appears that the challenge revolves around restoring functional save capabilities when the base class calls are not present and the CreateFile code is, or overcoming the Access Denied exception that occurs when the open and save base class calls are present in conjunction with the CreateFile code.

                                      Yes. I looked at your code again and noticed your document class is derived from CRichEditDoc. You'll definitely need the serialization code used in CDocument::OnSaveDocument() to get the changes to save. Sorry about that! I (now) think the simplest solution would be to copy the code from CDocument::OnOpenDocument() and CDocument::OnSaveDocument() into your overridden implementations. Then tweak the CFile related code to hold the file open for the entire time the document is open. Also adjust the open flags appropriately to prevent sharing. Something like this:

                                      class CStudyPartnerDoc : public CRichEditDoc
                                      {
                                      CFile StudyPartnerDocFile;

                                      public:
                                      virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);
                                      virtual BOOL OnSaveDocument(LPCTSTR lpszPathName);
                                      virtual void OnCloseDocument();

                                      };

                                      BOOL CStudyPartnerDoc::OnOpenDocument(LPCTSTR lpszPathName)
                                      {
                                      #ifdef _DEBUG
                                      if (IsModified())
                                      TRACE(traceAppMsg, 0, "Warning: OnOpenDocument replaces an unsaved document.\n");
                                      #endif

                                      CFileException fe;
                                      if (!StudyPartnerDocFile.Open(lpszPathName,
                                      	CFile::modeReadWrite | CFile::shareExclusive, &fe))
                                      {
                                      	ReportSaveLoadException(lpszPathName, &fe,
                                      		FALSE, AFX\_IDP\_FAILED\_TO\_OPEN\_DOC);
                                      	return FALSE;
                                      }
                                      
                                      DeleteContents();
                                      SetModifiedFlag();  // dirty during de-serialize
                                      
                                      CArchive loadArchive(&StudyPartnerDocFile, CArchive::load | CArchive::bNoFlushOnDelete);
                                      loadArchive.m\_pDocument = this;
                                      loadArchive.m\_bForceFlat = FALSE;
                                      TRY
                                      {
                                      	CWaitCursor wait;
                                      	if (StudyPartnerDocFile.GetLength() != 0)
                                      		Serialize(loadArchive);     // load me
                                      	loadArchive.Close();
                                      }
                                      CATCH\_ALL(e)
                                      {
                                      	StudyPartnerDocFile.Abort();
                                      	DeleteContents();   // remove failed contents
                                      
                                      	TRY
                                      	{
                                      		ReportSaveLoadException(lpszPathName, e,
                                      			FALSE, AFX\_IDP\_FAILED\_TO\_OPEN\_DOC);
                                      	}
                                      	END\_TRY
                                      	e->Delete();
                                      	return FALSE;
                                      }
                                      END\_CATCH\_ALL
                                      
                                      SetModifiedFlag(FALSE);     // start off with unmodified
                                      
                                      return TRUE;
                                      

                                      }

                                      BOOL CStudyPartnerDoc::OnSaveDocument(LPCTSTR lpszPathName)
                                      {
                                      StudyPartnerDocFile.SeekToBegin();

                                      CArchive saveArchive(&StudyPartnerDocFile, CArchive::store | CArchive::bNoF
                                      
                                      L 1 Reply Last reply
                                      0
                                      • L lctrncs

                                        I just was not sure that if (!CDocument::OnOpenDocument(lpszpathname) return FALSE; was the same as CDocument::OnOpenDocument However, I thought I understood you to say that both were to be removed for the success of the CreateFile. I attempted this, but encountered problems when I removed the calls to the base classes. Below, please find a matrix indicating the results of a quicky test of the various possibilities. Column 1 2 3 4 5 OnOpenDoc base class code 0 1 1 1 1 OnSaveDoc base class code 0 0 0 1 0 CreateFile code 1 1 0 1 0 First app opens file? 0 1 1 1 1 First app saves file? x Inv. Hndle 0 Acc.Den. 0 Open second file instance? x 0 1 0 x It appears that the best results occur in column two and four, in which the app opens the file and prevents use by a second app while it has it open. However, both of these configurations result in exceptions when the user attempts to save the file. Note that the base class calls appear to be required for function of the open and save capabilities. It appears that the challenge revolves around restoring functional save capabilities when the base class calls are not present and the CreateFile code is, or overcoming the Access Denied exception that occurs when the open and save base class calls are present in conjunction with the CreateFile code.

                                        "For a successful technology, reality must take precedence over public relations, for nature cannot be fooled." Richard Feynman, Minority Report to the Official Report on the Space Shuttle Challenger Crash

                                        M Offline
                                        M Offline
                                        Mark Salsbery
                                        wrote on last edited by
                                        #19

                                        BOOL CStudyPartnerDoc::OnSaveDocument(LPCTSTR lpszPathName)
                                        {
                                        StudyPartnerDocFile.SeekToBegin();
                                        ...

                                        should be

                                        BOOL CStudyPartnerDoc::OnSaveDocument(LPCTSTR lpszPathName)
                                        {
                                        StudyPartnerDocFile.SetLength(0LL);
                                        StudyPartnerDocFile.SeekToBegin();
                                        ...

                                        1 Reply Last reply
                                        0
                                        • M Mark Salsbery

                                          lctrncs wrote:

                                          It appears that the challenge revolves around restoring functional save capabilities when the base class calls are not present and the CreateFile code is, or overcoming the Access Denied exception that occurs when the open and save base class calls are present in conjunction with the CreateFile code.

                                          Yes. I looked at your code again and noticed your document class is derived from CRichEditDoc. You'll definitely need the serialization code used in CDocument::OnSaveDocument() to get the changes to save. Sorry about that! I (now) think the simplest solution would be to copy the code from CDocument::OnOpenDocument() and CDocument::OnSaveDocument() into your overridden implementations. Then tweak the CFile related code to hold the file open for the entire time the document is open. Also adjust the open flags appropriately to prevent sharing. Something like this:

                                          class CStudyPartnerDoc : public CRichEditDoc
                                          {
                                          CFile StudyPartnerDocFile;

                                          public:
                                          virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);
                                          virtual BOOL OnSaveDocument(LPCTSTR lpszPathName);
                                          virtual void OnCloseDocument();

                                          };

                                          BOOL CStudyPartnerDoc::OnOpenDocument(LPCTSTR lpszPathName)
                                          {
                                          #ifdef _DEBUG
                                          if (IsModified())
                                          TRACE(traceAppMsg, 0, "Warning: OnOpenDocument replaces an unsaved document.\n");
                                          #endif

                                          CFileException fe;
                                          if (!StudyPartnerDocFile.Open(lpszPathName,
                                          	CFile::modeReadWrite | CFile::shareExclusive, &fe))
                                          {
                                          	ReportSaveLoadException(lpszPathName, &fe,
                                          		FALSE, AFX\_IDP\_FAILED\_TO\_OPEN\_DOC);
                                          	return FALSE;
                                          }
                                          
                                          DeleteContents();
                                          SetModifiedFlag();  // dirty during de-serialize
                                          
                                          CArchive loadArchive(&StudyPartnerDocFile, CArchive::load | CArchive::bNoFlushOnDelete);
                                          loadArchive.m\_pDocument = this;
                                          loadArchive.m\_bForceFlat = FALSE;
                                          TRY
                                          {
                                          	CWaitCursor wait;
                                          	if (StudyPartnerDocFile.GetLength() != 0)
                                          		Serialize(loadArchive);     // load me
                                          	loadArchive.Close();
                                          }
                                          CATCH\_ALL(e)
                                          {
                                          	StudyPartnerDocFile.Abort();
                                          	DeleteContents();   // remove failed contents
                                          
                                          	TRY
                                          	{
                                          		ReportSaveLoadException(lpszPathName, e,
                                          			FALSE, AFX\_IDP\_FAILED\_TO\_OPEN\_DOC);
                                          	}
                                          	END\_TRY
                                          	e->Delete();
                                          	return FALSE;
                                          }
                                          END\_CATCH\_ALL
                                          
                                          SetModifiedFlag(FALSE);     // start off with unmodified
                                          
                                          return TRUE;
                                          

                                          }

                                          BOOL CStudyPartnerDoc::OnSaveDocument(LPCTSTR lpszPathName)
                                          {
                                          StudyPartnerDocFile.SeekToBegin();

                                          CArchive saveArchive(&StudyPartnerDocFile, CArchive::store | CArchive::bNoF
                                          
                                          L Offline
                                          L Offline
                                          lctrncs
                                          wrote on last edited by
                                          #20

                                          Mark, Thank for all your help. This feature is becoming a bit too much for my current schedule. Chances are that I will return to it at some point. However, for right now I am going to have to put this on the back burner because I need to generate some income (through freelance writing) and find a way to protect my Doc/View based content files (six are ready for posting) so that they cannot be edited and then misrepresented as the work of my company. Since setting the "read only" bit on the file will not be permanent enough, I thought I might save a flag with my original files then override DoSave to prevent saving if the flag is set. Another way might be to somehow embed the file in the program itself, so each content file distributed from my company comes with a program, again with DoSave = NULL in the Save As function or some such thing. This approach has the added benefit that I could distribute the content using Armadillo (which I use to provide 30 day trial functionality) which is not able to protect simple unzippers and non-executables. Since the second approach probably requires the completion of the first, it looks like that will be my starting point. Thank you again. Your posts were very educational, useful and well written. If you were on my team, I'll bet you could fix all of the problems I plan to spend the next 6 months beating my head against the in an afternoon. Thanks again. I hope you enjoy your "greetings seasons." Take the rest of the year off. Groff Schroeder

                                          "For a successful technology, reality must take precedence over public relations, for nature cannot be fooled." Richard Feynman, Minority Report to the Official Report on the Space Shuttle Challenger Crash

                                          M 1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups