Permalink
Fetching contributors…
Cannot retrieve contributors at this time
147 lines (122 sloc) 5.06 KB
' Visual Basic .NET Document
Option Strict On
' <Snippet10>
Imports Microsoft.Win32.SafeHandles
Imports System.IO
Public Class DisposableStreamResource2 : Inherits DisposableStreamResource
' Define additional constants.
Protected Const GENERIC_WRITE As Integer = &H40000000
Protected Const OPEN_ALWAYS As Integer = 4
' Define additional APIs.
Protected Declare Function WriteFile Lib "kernel32.dll" (
safeHandle As SafeFileHandle, lpBuffer As String,
nNumberOfBytesToWrite As Integer, ByRef lpNumberOfBytesWritten As Integer,
lpOverlapped As Object) As Boolean
' Define locals.
Private disposed As Boolean = False
Private filename As String
Private created As Boolean = False
Private safeHandle As SafeFileHandle
Public Sub New(filename As String)
MyBase.New(filename)
Me.filename = filename
End Sub
Public Sub WriteFileInfo()
If Not created Then
Dim hFile As IntPtr = CreateFile(".\FileInfo.txt", GENERIC_WRITE, 0,
IntPtr.Zero, OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL, IntPtr.Zero)
If hFile <> INVALID_HANDLE_VALUE Then
safeHandle = New SafeFileHandle(hFile, True)
Else
Throw New IOException("Unable to create output file.")
End If
created = True
End If
Dim output As String = String.Format("{0}: {1:N0} bytes {2}", filename, Size,
vbCrLf)
WriteFile(safeHandle, output, output.Length, 0&, Nothing)
End Sub
Protected Overloads Overridable Sub Dispose(disposing As Boolean)
If disposed Then Exit Sub
' Release any managed resources here.
If disposing Then
safeHandle.Dispose()
End If
disposed = True
' Release any unmanaged resources not wrapped by safe handles here.
' Call the base class implementation.
MyBase.Dispose(True)
End Sub
End Class
' </Snippet10>
Module Example
Public Sub Main()
Dim d As New DisposableStreamResource2("C:\Windows\Explorer.exe")
d.WriteFileInfo()
d.Dispose()
End Sub
End Module
Public Class DisposableStreamResource : Implements IDisposable
' Define constants.
Protected Const GENERIC_READ As UInteger = &H80000000ui
Protected Const FILE_SHARE_READ As UInteger = &H0000000i
Protected Const OPEN_EXISTING As UInteger = 3
Protected Const FILE_ATTRIBUTE_NORMAL As UInteger = &H80
Protected INVALID_HANDLE_VALUE As New IntPtr(-1)
Private Const INVALID_FILE_SIZE As Integer = &HFFFFFFFF
' Define Windows APIs.
Protected Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (
lpFileName As String, dwDesiredAccess As UInt32,
dwShareMode As UInt32, lpSecurityAttributes As IntPtr,
dwCreationDisposition As UInt32, dwFlagsAndAttributes As UInt32,
hTemplateFile As IntPtr) As IntPtr
Private Declare Function GetFileSize Lib "kernel32" (hFile As SafeFileHandle,
ByRef lpFileSizeHigh As Integer) As Integer
' Define locals.
Private disposed As Boolean = False
Private safeHandle As SafeFileHandle
Private bufferSize As Long
Private upperWord As Integer
Public Sub New(filename As String)
If filename Is Nothing Then
Throw New ArgumentNullException("The filename cannot be null.")
Else If filename = ""
Throw New ArgumentException("The filename cannot be an empty string.")
End If
Dim handle As IntPtr = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ,
IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
IntPtr.Zero)
If handle <> INVALID_HANDLE_VALUE Then
safeHandle = New SafeFileHandle(handle, True)
Else
Throw New FileNotFoundException(String.Format("Cannot open '{0}'", filename))
End If
' Get file size.
bufferSize = GetFileSize(safeHandle, upperWord)
If bufferSize = INVALID_FILE_SIZE Then
bufferSize = -1
Else If upperWord > 0 Then
bufferSize = (CLng(upperWord) << 32) + bufferSize
End If
End Sub
Public ReadOnly Property Size As Long
Get
Return bufferSize
End Get
End Property
Public Sub Dispose() _
Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
Protected Overridable Sub Dispose(disposing As Boolean)
If disposed Then Exit Sub
' Dispose of managed resources here.
If disposing Then
safeHandle.Dispose()
End If
' Dispose of any unmanaged resources not wrapped in safe handles.
disposed = True
End Sub
End Class