1

I use this code to save the data to XML:

bool CMeetingScheduleAssistantApp::SaveToXML(CString strFileXML, tinyxml2::XMLDocument& rDocXML)
{
    FILE    *fStream = nullptr;
    CString strError, strErrorCode;
    errno_t eResult;
    bool    bDisplayError = false;
    int     iErrorNo = -1;

    using namespace tinyxml2;

    // Does the file already exist?
    if (PathFileExists(strFileXML))
    {
        // It does, so try to delete it
        if (!::DeleteFile(strFileXML))
        {
            // Unable to delete!
            AfxMessageBox(theApp.GetLastErrorAsString(), MB_OK | MB_ICONINFORMATION);
            return false;
        }
    }

    // Now try to create a FILE buffer (allows UNICODE filenames)
    eResult = _tfopen_s(&fStream, strFileXML, _T("w"));
    if (eResult != 0 || fStream == nullptr) // Error
    {
        bDisplayError = true;
        _tcserror_s(strErrorCode.GetBufferSetLength(_MAX_PATH), _MAX_PATH, errno);
        strErrorCode.ReleaseBuffer();
    }
    else // Success
    {
        // Now try to save the XML file
        XMLError eXML = rDocXML.SaveFile(fStream);
        const int fileCloseResult = fclose(fStream);
        if (eXML != XMLError::XML_SUCCESS)
        {
            // Error saving
            bDisplayError = true;
            strErrorCode = rDocXML.ErrorName();
            iErrorNo = rDocXML.GetErrorLineNum();
        }

        if (!bDisplayError)
        {
            if (fileCloseResult != 0)
            {
                // There was a problem closing the stream. We should tell the user
                bDisplayError = true;
                _tcserror_s(strErrorCode.GetBufferSetLength(_MAX_PATH), _MAX_PATH, errno);
                strErrorCode.ReleaseBuffer();
            }
        }
    }

    if (bDisplayError)
    {
        if (iErrorNo == -1)
            iErrorNo = errno;

        strError.Format(IDS_TPL_ERROR_SAVE_XML, strFileXML, strErrorCode, iErrorNo);
        AfxMessageBox(strError, MB_OK | MB_ICONINFORMATION);

        return false;
    }

    return true;
}

The code in itself is fine. Elsewhere in my program I save the file and then go to display a report. It uses a XSL transformation with the XML file in a CHtmlView browser control:

        CMeetingScheduleAssistantApp::SaveToXML(strPreviewXML, myDoc);
        if (ePreviewType == PreviewType::Editor)
        {
            if (m_pHtmlPreview != nullptr)
            {
                CString strURL = strPreviewXML;
                if (iBookmarkId != -1)
                    strURL.Format(_T("%s#week%d"), (LPCTSTR)strPreviewXML, iBookmarkId);

                m_pHtmlPreview->Navigate2(strURL, 0, nullptr);
            }
        }
        else
        {
            if (m_pPrintHtmlPreview != nullptr)
                m_pPrintHtmlPreview->Navigate2(strPreviewXML, 0, nullptr);
        }
    }

I am finding that:

  • Sometimes my preview is white, and after a refresh it shows.
  • At other times if I am working in what I refer to as "weekly mode" and it recreates the XML each week I do get a message about the file already being in use. This does not always happen.

Is there secure way that we can save to the HDD and then not use the file until it has fully been written to disc?

Andrew Truckle
  • 17,769
  • 16
  • 66
  • 164
  • 1
    How about something [like this](https://stackoverflow.com/questions/1746781/waiting-until-a-file-is-available-for-reading-with-win32)? Loop to wait until the file is available. – lakeweb Apr 02 '19 at 20:25
  • 1
    If tinyxml is running on the same thread then file should be available. You can also try `CHtmlView::GetReadyState` to make sure html control does not ignore the navigate request. – Barmak Shemirani Apr 03 '19 at 04:57
  • @BarmakShemirani I assume `tinyxml2` is running on the same thread. When I do a print preview, I initiate a timer every 250 milliseconds which then calls `GetReadyState`. When the return value is `READYSTATE_COMPLETE` it initiates the preview. But I don't follow this logic when I am just saving the XML file and then updating the view. – Andrew Truckle Apr 03 '19 at 07:37

0 Answers0