VB .NET - Chamando a API do Windows (Win 32 API)
Às vezes para realizar uma tarefa na linguagem VB .NET precisamos usar recursos de terceiros, e, apesar da grande quantidade de recursos disponíveis nas classes, métodos e propriedades da linguagem ainda existem algumas funções disponíveis na API do Windows(Win 32 API) que preenchem uma lacuna existente.
A plataforma .NET é baseada no código gerenciado e às vezes por este motivo não é possível realizar algumas tarefas como obter informações sobre os drives locais, etc. Se você precisar de informações como espaço livre em termos de bytes ou clusters pode usar as funções GetDiskFreeSpaceEx e GetDiskFreeSpace da API do Windows. (Você pode até usar os recursos de My.Computer.FileSystem.GetDriveInfo mas algumas informações não estão disponíveis.)
A API Win32 é muito útil tanto para aplicações Desktop como para aplicações ASP .NET lembrando que no último caso a API opera sempre sobre o servidor e não na máquina do cliente, e, que as chamadas à Win 32 API não são permitidas no SilverLight 3 e SilverLight 4.(Se você tentar chamar a API em aplicações SilverLight via obter a mensagem de erro: "Attempt by security transparent method 'Button1Click' to call native code through method 'Win32APIMethod' failed. Methods must be security critical or security safe-critical to call native code.")
O interessante é que a API Win 32 esta disponível para sua aplicação VB .NET sem que seja preciso incluir qualquer referência, e, como já foi dito, embora a maioria dos recursos presentes na API estejam disponíveis na plataforma .NET Framework ainda existem alguns recursos ou funcionalidades estendidas que existem somente na API.
Se você deseja conhecer mais sobre os recursos da API Win 32 sugiro que veja o artigo: Microsoft Win32 to Microsoft .NET Framework API Map.
Para ilustrar a utilização da API Win 32 em aplicações VB .NET , neste artigo eu vou mostrar como usar os recursos para obter informações sobre os drivers, como podemos colocar o computador para hibernar e como obter a versão do sistema operacional.
Vamos lá...
1- Obtendo informações sobre os drivers locais
Abra o Visual Studio 2010 Express Edition e crie um novo projeto do tipo Windows Application com o nome ChamandoWinAPI;
No formulário padrão inclua um controle Button e um controle ListView conforme o leiaute da figura abaixo:
A seguir inclua o código a seguir:
a- função DiskInfo() que faz a chamada a API Win32 para obter as informações dos drives locais:
Private Sub DiskInfo() Dim RootPath As String = "C:\" Dim SectorsInCluster As Integer = 0 Dim BytesInSector As Integer = 0 Dim NumberFreeClusters = 0 Dim TotalNumberClusters = 0 Call Win32API.GetDiskFreeSpace(RootPath, SectorsInCluster, BytesInSector,NumberFreeClusters, TotalNumberClusters) ListBox1.Items.Add("GetDiskSpace: Cluster livres em C: " & NumberFreeClusters) Dim FreeBytes As Integer = 0 Dim TotalBytes As Integer = 0 Dim TotalFreeBytes As UInt32 = 0 Call Win32API.GetDiskFreeSpaceEx(RootPath, FreeBytes, TotalBytes, TotalFreeBytes) ListBox1.Items.Add("GetDiskSpaceEx: Total de bytes livres em C : " & TotalFreeBytes) Dim DriveType As Integer = Win32API.GetDriveType(RootPath) Dim DriveTypeName As String = String.Empty Select Case DriveType Case 2 : DriveTypeName = "Removível" Case 3 : DriveTypeName = "Fixo" Case 4 : DriveTypeName = "Remoto" Case 5 : DriveTypeName = "CD-Rom" Case 6 : DriveTypeName = "RAM Disk" Case Else : DriveTypeName = "Desconhecido" End Select ListBox1.Items.Add("GetDriveType: Tipo de Drive : " & DriveTypeName) End Sub |
b- A declaração das funções da API
Partial Public Class Win32API Public Declare Function GetDiskFreeSpace Lib "kernel32" _ Alias "GetDiskFreeSpaceA" (ByVal RootPathName As String, ByRef SectorsPerCluster As Integer, ByRef BytesPerSector As Integer, ByRef NumberOfFreeClusters As Integer, ByRef TotalNumberOfClusters As Integer) As Integer Public Declare Function GetDiskFreeSpaceEx Lib "kernel32" _ Alias "GetDiskFreeSpaceExA" (ByVal RootPathName As String, ByRef FreeBytesAvailableToCaller As Integer, ByRef TotalNumberOfBytes As Integer, ByRef TotalNumberOfFreeBytes As UInt32) As Integer Public Declare Function GetDriveType Lib "kernel32" _ Alias "GetDriveTypeA" (ByVal nDrive As String) As Integer End Class |
A chamada à função DiskInfo() é feita no evento Click do controle Button:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Call DiskInfo() End Sub |
Executando o projeto iremos obter (no caso da minha máquina local):
Partial
Classes - Lembre-se que no VB.NET quando você
vai definir uma classe você cria um arquivo com
extensão .vb e ele irá conter a classe completa em um
único arquivo; desta forma você inicia e termina a
classe no mesmo arquivo físico. Ex: Classe1.vb Usando o conceito de partial class você pode separar o código de uma classe em mais de um arquivo físico. |
2- Fazendo o computador hibernar
Podemos fazer o computador hibernar usando a função IsPwrHibernateAllowed da library Powrprof.dll que retorna um valor true (não zero) se a hibernação é permitida ou false (zero) se a hibernação é permitida. Se ela for permitida a função SetSuspendState pode ser chamada para ativar a hibernação.
Inclua um novo botão no formulário do projeto e a seguir inclua o código abaixo que declara a função da API que vamos usar:
Partial Public Class Win32API Public Declare Function IsPwrHibernateAllowed Lib "Powrprof.dll" Alias "IsPwrHibernateAllowed" () As Integer Public Declare Function SetSuspendState Lib "Powrprof.dll" Alias "SetSuspendState" (ByVal Hibernate As Integer, ByVal ForceCritical As Integer, ByVal DisableWakeEvent As Integer) As Integer End Class |
Em seguida inclua no evento Click do botão de comando o código que chama a API:
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click If (Win32API.IsPwrHibernateAllowed() <> 0) Then Win32API.SetSuspendState(1, 0, 0) Else MessageBox.Show("A hibernação não esta disponível.") End If End Sub |
3- Obtendo a versão do sistema Operacional
Para obter a versão do sistema operacional chamamos a função GetVersionEx.
Inclua um novo controle Button no formulário e declare a estrutura e a função da API que vamos usar no formulário:
Public Structure OSVersionInfo Public OSVersionInfoSize As Integer Public majorVersion As Integer Public minorVersion As Integer Public buildNumber As Integer Public platformId As Integer <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=128)> _ Public versionString As String End Structure Declare Ansi Function GetVersionEx Lib "kernel32.dll" _ Alias "GetVersionExA" (ByRef osvi As OSVersionInfo) As Boolean |
Em seguida no evento Click do botão de comando inclua o código abaixo:
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click Dim osvi As New OSVersionInfo osvi.OSVersionInfoSize = Marshal.SizeOf(osvi) If GetVersionEx(osvi) Then Dim resultado As String = String.Format("Versão do Windows : {0}.{1}.{2}.{3}", osvi.majorVersion, osvi.minorVersion, osvi.buildNumber, osvi.platformId) ListBox1.Items.Add(resultado) End If End Sub |
Executando o projeto iremos obter:
Pegue o projeto completo aqui: ChamandoWinAPI_1.zip
Eu sei é apenas VB .NET , mas eu gosto...
Referências:
http://visualstudiomagazine.com/articles/2010/04/20/call-win32-api-functions-in-vb.aspx
José Carlos Macoratti