GetComputerNameA does not work in VB Dot Net?

F

foo

"An unhandled exception of type 'System.NullReferenceException' occurred in
Project.exe
Additional information: Object reference not set to an instance of an
object."


This worked in ver 6, but in VB dot net it abends at the call to
GetComputerName( )...

Declare Function GetComputerName Lib "kernel32" Alias "GetComputerNameA"
(ByVal lpBuffer As String, ByVal nSize As Long) As Long

Function GetLocalComputerName() As String

Dim strBuffer As String

Dim lngBufSize As Long

Dim lngStatus As Long

lngBufSize = 16 ' max computer name length = 15

strBuffer = Space(lngBufSize + 1)

lngStatus = GetComputerName(strBuffer, lngBufSize)



TIA,



Bill

Cincinnati, OH USA
 
H

Herfried K. Wagner [MVP]

* "foo said:
"An unhandled exception of type 'System.NullReferenceException' occurred in
Project.exe
Additional information: Object reference not set to an instance of an
object."


This worked in ver 6, but in VB dot net it abends at the call to
GetComputerName( )...

Declare Function GetComputerName Lib "kernel32" Alias "GetComputerNameA"
(ByVal lpBuffer As String, ByVal nSize As Long) As Long

Replace all Longs with 'Int32'. Long is 64 bit now.

Why not use 'Environment.MachineName' instead?
 
C

Cor

Hi Bill,

I don't know what is with your code but maybe just take a managed code
aproach, mostly that is that more simple.
\\\
MessageBox.Show(SystemInformation.ComputerName)
///

I hope this helps?

Cor
 
A

Armin Zingler

foo said:
"An unhandled exception of type 'System.NullReferenceException'
occurred in Project.exe
Additional information: Object reference not set to an instance of
an object."


This worked in ver 6, but in VB dot net it abends at the call to
GetComputerName( )...

Have a look at the meaning of the basic data types in VB6 and VB.NET.
 
T

Tom Shelton

foo said:
"An unhandled exception of type 'System.NullReferenceException' occurred
in
Project.exe
Additional information: Object reference not set to an instance of an
object."


This worked in ver 6, but in VB dot net it abends at the call to
GetComputerName( )...

Declare Function GetComputerName Lib "kernel32" Alias "GetComputerNameA"
(ByVal lpBuffer As String, ByVal nSize As Long) As Long

Function GetLocalComputerName() As String

Dim strBuffer As String

Dim lngBufSize As Long

Dim lngStatus As Long

lngBufSize = 16 ' max computer name length = 15

strBuffer = Space(lngBufSize + 1)

lngStatus = GetComputerName(strBuffer, lngBufSize)



TIA,



Bill

Cincinnati, OH USA

As has been mentioned, you will want to change your Long's to Integers.
VB.NET longs are 64-bit. Further, you will probably not want to call this
API anyway because you can get this information from the framework using
Environment.MachineName property...

So, having re-iterated all the other responses - I wanted to add a couple
things about calling API's in general... If you are going to use the
GetComputerName function, then I would declare it like this:

Declare Auto Function GetComputerName Lib "kernel32" _
(ByVal lpBuffer As System.Text.StringBuilder, _
ByVal nSize As Integer) As Integer

There are a couple of things of note in this declaration that are different
then from VB.CLASSIC - so let my point them out:

1) No Alias. In general, you should not be aliasing your api calls to the
specific A/W version. You should instead add the Auto keyword. What this
does for you is lets the runtime determine the appropriate version to call
based on the platform that your application runs on. This is important
because it helps you avoid a lot of unnecessary string conversions when your
app is running on an NT based system. See, like VB.CLASSIC, .NET strings
are Unicode internally. This means that when you call the A version of the
function, the marshaller has to convert your Unicode string into an Ansi
string and then pass the converted string to the API. That has to happen on
a 9x system (for most functions anyway), since the W functions are not
implemented. On NT system though, if you explicitly call the A function,
then there is a lot more work that has to be done because the Marshaller
converts the sting to Ansi and calls the A function. On NT, the A function
converts the Ansi string to Unicode and calls the W function. When the W
function returns the Unicode string is converted to Ansi and returned to the
caller - who in this case turns around and converts it back to Unicode. So,
what you end up with is:

Unicode->Ansi->Unicode->Ansi->Unicode

Where is on NT systems no conversions are necessary. This has always been a
problem in VB - but VB.NET finally has a solution to this problem - Auto...

2) I did not declare the lpBuffer parameter As String. The reason for this
is that this string is intended to be modified by the API call. When you
need to pass a mutable string buffer to an external procedure, you shoule
always use System.Text.StringBuilder rather then string. The reason for
this is that the String type is an immutable object - in other words, once
created it can't be changed - and it causes a lot of extra work on the
VB.NET marshaller if you pass a string buffer to a function that is going to
modify that buffer. So, basically what I'm saying is - If the string
parameter is constant - in other words, the function does not modify the
value of the string - then use As String. If the function is going to
modify the value of the buffer - then use As System.Text.StringBuilder.

The code to use the above declaration would look something like:

Dim lpBuffer As New System.Text.StringBuilder(16)
GetComputerName (lpBuffer, lpBuffer.Capacity)
Return lpBuffer.ToString
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top