locked
error C2039: 'Close' : is not a member of 'Windows::Storage::Streams::DataWriter'_

Answers

  • I found self the error in the WASAPI Sample from Microsoft:

    I remarked the important places with a @FIX comment.

    The fixed code:

    HRESULT WASAPICapture::FixWAVHeader()
    {
        auto DataSizeByte = ref new Platform::Array<BYTE>( reinterpret_cast<BYTE*>( &m_cbDataSize ), sizeof(DWORD) );
        
        // Write the size of the 'data' chunk first
        IOutputStream^ OutputStream = m_ContentStream->GetOutputStreamAt( m_cbHeaderSize - sizeof(DWORD) );
        m_WAVDataWriter = ref new DataWriter( OutputStream );
        m_WAVDataWriter->WriteBytes( DataSizeByte );
    
        concurrency::task<unsigned int>( m_WAVDataWriter->StoreAsync()).then(
            [this]( unsigned int BytesWritten )
        {
            DWORD cbTotalSize = m_cbDataSize + m_cbHeaderSize - 8;
            auto TotalSizeByte = ref new Platform::Array<BYTE>( reinterpret_cast<BYTE*>( &cbTotalSize ), sizeof(DWORD) );
    
            // Write the total file size, minus RIFF chunk and size
    
            // @FIX: the OutputStream have to be a member of the class because he is needet for deleteing after
            m_OutputStream = m_ContentStream->GetOutputStreamAt( sizeof(DWORD) );  // sizeof(DWORD) == sizeof(FOURCC)
            m_WAVDataWriter = ref new DataWriter( m_OutputStream );
            m_WAVDataWriter->WriteBytes( TotalSizeByte );
      
            concurrency::task<unsigned int>( m_WAVDataWriter->StoreAsync()).then(
                [this]( unsigned int BytesWritten )
            {
                return m_WAVDataWriter->FlushAsync();
            })
            
            .then(
                [this]( bool f )
            {
                // @FIX:
                // the m_OutputStream AND the m_ContentStream have to be deleted
                // elsewhere the file remains locked!
                delete m_OutputStream;
                m_OutputStream = nullptr;
                delete m_ContentStream;
                m_ContentStream = nullptr;
    
                m_DeviceStateChanged->SetState( DeviceState::DeviceStateStopped, S_OK, true );
            });
        });
    
        return S_OK;
    }

    The same issue demonstrated in c#:

           private async void Button_Click_2(object sender, RoutedEventArgs e)
            {
                var file = await KnownFolders.MusicLibrary.CreateFileAsync("testfile.bin", CreationCollisionOption.ReplaceExisting);
                var stream = await file.OpenAsync(FileAccessMode.ReadWrite);
    
                byte[] totalSizeByte = new byte[100]; 
                IOutputStream outputStream = stream.GetOutputStreamAt(0);
                var dataWriter = new DataWriter( outputStream );
                dataWriter.WriteBytes(totalSizeByte);
                uint bytesWritten = await dataWriter.StoreAsync();
                bool f = await dataWriter.FlushAsync();
                //dataWriter.DetachStream(); 
                //dataWriter.Dispose();
                //dataWriter = null;
                outputStream.Dispose();  // this is necessary
                outputStream = null;
                stream.Dispose();        // this is necessary
                stream = null;
                //file = null;
    
               
             
                // Test if it is unlocked
                var stream2 = await KnownFolders.MusicLibrary.OpenStreamForReadAsync("testfile.bin");
            }

    One question remains:

    Why i can delete a open file in the OS?


    u

    • Marked as answer by urs32 Friday, September 21, 2012 3:42 PM
    Friday, September 21, 2012 2:24 PM

All replies

  • Although API documentation contain Close() method,  but DataWriter class has no Close() method for C++. It available on Javascript or other language.

    Actually for C++ DataWriter automatically close when it goes out of scope.

    However You can close it two ways :
          - explicit: by using delete operator (the writer is closed even if there are outstanding references to the objects).
          - implicit: by removing last reference to it (i.e. falling out-of-scope).

        if ( dataWriter != nullptr)
        {
        // Close the data writer.
            delete dataWriter;
            dataWriter = nullptr;
        }


    Wednesday, September 19, 2012 5:52 PM
  • I have tried this in the sample Windows Audio Session (WASAPI) sample in the Function

    FixWAVHeader()

    but with no effect. The File remains locked.

    The curious is i can delete the file but i can not open the file with the "Windows Media Player". After a creation of a new recording the file is unlocked. 

    I can also delete the file if the recording is in Progress (The file increase the size while recording). No exception pop up. Is this not strange? A OS issue? 


    u


    • Edited by urs32 Wednesday, September 19, 2012 11:16 PM
    Wednesday, September 19, 2012 10:59 PM
  • I found self the error in the WASAPI Sample from Microsoft:

    I remarked the important places with a @FIX comment.

    The fixed code:

    HRESULT WASAPICapture::FixWAVHeader()
    {
        auto DataSizeByte = ref new Platform::Array<BYTE>( reinterpret_cast<BYTE*>( &m_cbDataSize ), sizeof(DWORD) );
        
        // Write the size of the 'data' chunk first
        IOutputStream^ OutputStream = m_ContentStream->GetOutputStreamAt( m_cbHeaderSize - sizeof(DWORD) );
        m_WAVDataWriter = ref new DataWriter( OutputStream );
        m_WAVDataWriter->WriteBytes( DataSizeByte );
    
        concurrency::task<unsigned int>( m_WAVDataWriter->StoreAsync()).then(
            [this]( unsigned int BytesWritten )
        {
            DWORD cbTotalSize = m_cbDataSize + m_cbHeaderSize - 8;
            auto TotalSizeByte = ref new Platform::Array<BYTE>( reinterpret_cast<BYTE*>( &cbTotalSize ), sizeof(DWORD) );
    
            // Write the total file size, minus RIFF chunk and size
    
            // @FIX: the OutputStream have to be a member of the class because he is needet for deleteing after
            m_OutputStream = m_ContentStream->GetOutputStreamAt( sizeof(DWORD) );  // sizeof(DWORD) == sizeof(FOURCC)
            m_WAVDataWriter = ref new DataWriter( m_OutputStream );
            m_WAVDataWriter->WriteBytes( TotalSizeByte );
      
            concurrency::task<unsigned int>( m_WAVDataWriter->StoreAsync()).then(
                [this]( unsigned int BytesWritten )
            {
                return m_WAVDataWriter->FlushAsync();
            })
            
            .then(
                [this]( bool f )
            {
                // @FIX:
                // the m_OutputStream AND the m_ContentStream have to be deleted
                // elsewhere the file remains locked!
                delete m_OutputStream;
                m_OutputStream = nullptr;
                delete m_ContentStream;
                m_ContentStream = nullptr;
    
                m_DeviceStateChanged->SetState( DeviceState::DeviceStateStopped, S_OK, true );
            });
        });
    
        return S_OK;
    }

    The same issue demonstrated in c#:

           private async void Button_Click_2(object sender, RoutedEventArgs e)
            {
                var file = await KnownFolders.MusicLibrary.CreateFileAsync("testfile.bin", CreationCollisionOption.ReplaceExisting);
                var stream = await file.OpenAsync(FileAccessMode.ReadWrite);
    
                byte[] totalSizeByte = new byte[100]; 
                IOutputStream outputStream = stream.GetOutputStreamAt(0);
                var dataWriter = new DataWriter( outputStream );
                dataWriter.WriteBytes(totalSizeByte);
                uint bytesWritten = await dataWriter.StoreAsync();
                bool f = await dataWriter.FlushAsync();
                //dataWriter.DetachStream(); 
                //dataWriter.Dispose();
                //dataWriter = null;
                outputStream.Dispose();  // this is necessary
                outputStream = null;
                stream.Dispose();        // this is necessary
                stream = null;
                //file = null;
    
               
             
                // Test if it is unlocked
                var stream2 = await KnownFolders.MusicLibrary.OpenStreamForReadAsync("testfile.bin");
            }

    One question remains:

    Why i can delete a open file in the OS?


    u

    • Marked as answer by urs32 Friday, September 21, 2012 3:42 PM
    Friday, September 21, 2012 2:24 PM