Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

GetComputerName - API error 203

157 views
Skip to first unread message

Hans

unread,
Nov 4, 2005, 2:02:43 PM11/4/05
to
When I call the API function GetComputerName (see code)

Public Function GetComputerName() As String

On Error Resume Next

Const MAX_COMPUTERNAME_LENGTH As Long = 31

Dim lLen As Long
Dim lRet As Long
Dim sBuffer As String

lLen = MAX_COMPUTERNAME_LENGTH + 1
sBuffer = Space$(lLen)

lRet = WinAPI_GetCompName(sBuffer, lLen)
If lRet <> 0 Then
GetComputerName = Left$(sBuffer, lLen) ' extract ComputerName

Else
GetComputerName = vbNullString

End If

lRet = Err.Number
If lRet = 0 Then lRet = Err.LastDllError

If (lRet <> 0) Then
If DesignMode Then Stop: Resume
ProcessError sNAME, "GetComputerName"
End If
On Error GoTo 0

End Function 'Get_GetComputerName

On Windows XP I get the LastDllError 203 (Environment Variable Not Found).
On Windows 98 I get no errors. Has anybody an idea what the cause is?


TIA

Yours friendly,

Hans Heezemans
www.iservi.com


vbexp

unread,
Nov 4, 2005, 2:41:36 PM11/4/05
to
How did you define GetComputerName?


"Hans" <h...@REMOVECAPSiservi.com> wrote in message
news:eOoi%23KX4F...@TK2MSFTNGP10.phx.gbl...

Thorsten Albers

unread,
Nov 4, 2005, 5:11:30 PM11/4/05
to
Hans <h...@REMOVECAPSiservi.com> schrieb im Beitrag
<eOoi#KX4FH...@TK2MSFTNGP10.phx.gbl>...

> lRet = WinAPI_GetCompName(sBuffer, lLen)
> If lRet <> 0 Then
> GetComputerName = Left$(sBuffer, lLen) ' extract ComputerName
> Else
> GetComputerName = vbNullString
> End If
>
> lRet = Err.Number
> If lRet = 0 Then lRet = Err.LastDllError
>
> If (lRet <> 0) Then
> If DesignMode Then Stop: Resume
> ProcessError sNAME, "GetComputerName"
> End If
> On Error GoTo 0
>
> On Windows XP I get the LastDllError 203 (Environment Variable Not
Found).
> On Windows 98 I get no errors. Has anybody an idea what the cause is?

Your handling of the return code is very bad! The contents of
Err.LastDllError should be taken serious >only< if GetComputerName()
returns 0. If GetComputerName() returns a value <> 0, the function has been
successfull and the contents of Err.LastDllError is >undefined< and not =
0!

lRet = WinAPI_GetCompName(sBuffer, lLen)
If lRet <> 0 Then
GetComputerName = Left$(sBuffer, lLen) ' extract ComputerName
Else

'GetComputerName = vbNullString ' Not necessary


lRet = Err.Number
If lRet = 0 Then lRet = Err.LastDllError
If (lRet <> 0) Then
If DesignMode Then Stop: Resume
ProcessError sNAME, "GetComputerName"
End If

End If

--
----------------------------------------------------------------------
THORSTEN ALBERS Universität Freiburg
albers@
uni-freiburg.de
----------------------------------------------------------------------

MikeD

unread,
Nov 4, 2005, 7:25:21 PM11/4/05
to

"Hans" <h...@REMOVECAPSiservi.com> wrote in message
news:eOoi%23KX4F...@TK2MSFTNGP10.phx.gbl...


As vbexp said, you should also post the declaration you're using.
Frequently, problems are caused by an incorrect declaration. Without knowing
how you declared it, we can't help as much.

I'm also in agreement with Thorsten that your error handling is (to be quite
blunt about it) horrendous and likely the problem (it was when I tried your
code). You're checking for LastDllError AFTER you've assigned a different
value to lRet than what GetComputerName returned. At that point, you're
erroneously checking LastDllError and getting a value from a previous API
function you've called.

I copied and pasted your code into VB6 and used this declaration:

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

The API function succeeded and the computer name string was assigned as the
function's return value. BUT, due to your "error handling" code, the 'If
(lRet <> 0) Then' evaluated to True and the function basically bombed.
Incidently, when stepping through this, at the 'If (lRet <> 0) Then' line
Err.LastDllError DID indeed have a value of 203 (which had gotten assigned
to the lRet variable). Here's how you might re-rewrite this code:

-----BEGIN CODE


Public Function GetComputerName() As String

Const MAX_COMPUTERNAME_LENGTH As Long = 31

Dim lLen As Long
Dim lRet As Long
Dim sBuffer As String


lLen = MAX_COMPUTERNAME_LENGTH + 1

sBuffer = String$(lLen, vbNullChar)

lRet = WinAPI_GetCompName(sBuffer, lLen)
If lRet = 0 Then


If DesignMode Then Stop: Resume
ProcessError sNAME, "GetComputerName"

Else


GetComputerName = Left$(sBuffer, lLen) ' extract ComputerName

End If


End Function 'Get_GetComputerName
-----END CODE

Also, rather than use that 'If DesignMode Then Stop: Resume' code, just use
a Debug.Assert.


Bottom line is that API funtions don't fill in VB's Err object EXCEPT for
the LastDllError property. Therefore, after calling an API funtion, it's
useless (and detriminental) to check Err.Number and perform any action based
on that. But that's exactly what you're doing and it's causing problems.

--
Mike
Microsoft MVP Visual Basic


Thorsten Albers

unread,
Nov 4, 2005, 9:46:07 PM11/4/05
to
MikeD <nob...@nowhere.edu> schrieb im Beitrag
<u7EEk9Z...@TK2MSFTNGP10.phx.gbl>...

> and getting a value from a previous API
> function you've called.

Err.LastDLLError not only returns an error code that was set after an API
function call of oneself. Instead it returns just what the API function
GetLastError() returns. So:

Call to API function A:
- fails
-> Err.LastDLLError = error code A

Call to API function B:
- This internally calls another API function which fails
-> error code X
- Function B is able to handle this and terminates successfully
(unfortunately, like most of the API functions, it 'forgets' to execute
GetLastError(0) before terminating...)

Now Err.LastDLLError doesn't return error code A but >error code X<, i.e.
from an API function you have never called yourself.

Hans

unread,
Nov 5, 2005, 11:33:34 AM11/5/05
to
Private Declare Function WinAPI_GetCompName Lib "kernel32" Alias _
"GetComputerNameA" (ByVal sBuffer As String, lSize As Long) As Long

Sorry, I should have it included it the original posting, but since this is
a very simple API call (and since it worked for years without any problems
on a W98 machine) |I 'forgot' it.


"vbexp" <nob...@cox.net> schreef in bericht
news:e6bvDfX4...@TK2MSFTNGP09.phx.gbl...

Hans

unread,
Nov 5, 2005, 11:35:36 AM11/5/05
to
OK,

You are right. One should only test when appropiate.

"Thorsten Albers" <albe...@MOVEuni-freiburg.de> schreef in bericht
news:01c5e18c$3b1c2b20$078ee684@thaldesk...

Hans

unread,
Nov 5, 2005, 11:37:53 AM11/5/05
to
Ok,

thanks for the explanation. I will adapt the routine.

"MikeD" <nob...@nowhere.edu> schreef in bericht
news:u7EEk9Z...@TK2MSFTNGP10.phx.gbl...

0 new messages