Fopen() 2.0.0.5
-
- Posts: 774
- Joined: Wed May 17, 2017 8:50 am
- Location: Germany
Fopen() 2.0.0.5
Guys,
i´m playing with the 2.0.0.5 Fopen() and noticed that if the func fails the errorcode is always 1008 ?
Is that a known issue, or maybe even fixed in the meantime ?
regards
Karl-Heinz
i´m playing with the 2.0.0.5 Fopen() and noticed that if the func fails the errorcode is always 1008 ?
Is that a known issue, or maybe even fixed in the meantime ?
regards
Karl-Heinz
Fopen() 2.0.0.5
Karl Heinz,
Which errorcode do you mean ?
Robert
Which errorcode do you mean ?
Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
The Netherlands
robert@xsharp.eu
-
- Posts: 774
- Joined: Wed May 17, 2017 8:50 am
- Location: Germany
Fopen() 2.0.0.5
Hi Robert,
The file "D:testFFunction.txt" exists. when i change the dir or filename Fopen() fails, and the errorcodes are always the same.
To see in x# the errortext i translated the VO func GetSystemMessage( dwID AS DWORD )
regards
Karl-Heinz
The file "D:testFFunction.txt" exists. when i change the dir or filename Fopen() fails, and the errorcodes are always the same.
Code: Select all
IF ( h := Fopen ( "D:testFFunctio.txt" )) != F_ERROR // file doesn´t exist errcode should be 2
// IF ( h := Fopen ( "D:tesFFunction.txt" )) != F_ERROR // dir doesn´t exist errcode should be 3
? "ok"
Fclose ( h )
ELSE
? "Getlasterror()" , getlasterror() // always 1008
? "Ferror()", Ferror() // always 1008
? "GetDosError()" , Getdoserror() // always 1008
? GetSystemMessage ( fError() ) // localized text is shown
ENDIF
Code: Select all
FUNCTION GetSystemMessage( dwID AS DWORD ) AS STRING
RETURN System.ComponentModel.Win32Exception{ (INT) dwID }.Message
FUNCTION GetSystemMessage() AS STRING
RETURN GetSystemMessage ( (DWORD) System.Runtime.InteropServices.Marshal.GetLastWin32Error() )
Karl-Heinz
-
- Posts: 774
- Joined: Wed May 17, 2017 8:50 am
- Location: Germany
Fopen() 2.0.0.5
BTW. The "magic" number 1008 also appears if the file is locked ( errcode 32 should be shown ) or the path or filename contains "bad chars" ( errcode 123 should be shown )
Fopen() 2.0.0.5
Karl-Heinz,
The X# runtime does not use the same underlying OS calls when opening a file. It uses managed streams in stead.
The File Handle that is returns is just a unique id that matches the stream in a dictionary in the runtime.
Inside the FileStream constructor the "File Not Found" situation is decoded into a FileNotFoundException. We are capturing this and we are assigning Marshal.GetLastWin32Error() to Ferror().
Apparently at that moment GetLastWin32Error has already received a new value.
I can see in the constructor of FileStream that the __Error.WinIOError() method is called with the GetLastWin32Error and when this error is 2 then the FileNotFoundException is generated.
Maybe we should expose the exception object in a FException() function so you can see which exception occurred ?
Or we should decode the exception type back into the numbers and store these numbers in FError() ?
Robert
The X# runtime does not use the same underlying OS calls when opening a file. It uses managed streams in stead.
The File Handle that is returns is just a unique id that matches the stream in a dictionary in the runtime.
Inside the FileStream constructor the "File Not Found" situation is decoded into a FileNotFoundException. We are capturing this and we are assigning Marshal.GetLastWin32Error() to Ferror().
Apparently at that moment GetLastWin32Error has already received a new value.
I can see in the constructor of FileStream that the __Error.WinIOError() method is called with the GetLastWin32Error and when this error is 2 then the FileNotFoundException is generated.
Maybe we should expose the exception object in a FException() function so you can see which exception occurred ?
Or we should decode the exception type back into the numbers and store these numbers in FError() ?
Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
The Netherlands
robert@xsharp.eu
-
- Posts: 774
- Joined: Wed May 17, 2017 8:50 am
- Location: Germany
Fopen() 2.0.0.5
Hi Robert,
Since FError() is a vo/x# specific thing, my first thought is to keep using it. It seems that the CreateManagedFileStream() method is responsible for the errorcode.
FileStream throws, beside others, 4 exceptions of interest:
i have a func that returns the errorcode of an exception. Does it make any differences when you fill fError() in this way
regards
Karl-Heinz
Since FError() is a vo/x# specific thing, my first thought is to keep using it. It seems that the CreateManagedFileStream() method is responsible for the errorcode.
Code: Select all
private static method createManagedFileStream(cFIle as string , oMode as VOFileMode ) as FileStream
local result as FileStream
//
result := null
try
result := FileStream{cFIle, oMode:FileMode, oMode:FileAccess, oMode:FileShare, 4096}
return result
catch ex as Exception
Trace.WriteLine(ex:Message)
Functions.FError((DWord)Marshal.GetLastWin32Error())
return result
end try
Code: Select all
ArgumentException // bad param - illegal chars in pathname or filename detected errorcode 97
( VO gives 123 - shows IMO a better explanation than 97 )
DirectoryNotFound // should show errorcode 3
FileNotFound // should show errorcode 2
IOException // should show errorcode 32 - Access violation
Code: Select all
catch ex as Exception
Trace.WriteLine(ex:Message)
Functions.FError( GetErrorCodeFromException ( eX ) )
return result
or does it make any difference to split the exceptions
catch ex as ArgumentException
Trace.WriteLine(ex:Message)
Functions.FError( GetErrorCodeFromException ( eX ) )
return result
catch ex as DirectoryNotFound
Trace.WriteLine(ex:Message)
Functions.FError( GetErrorCodeFromException ( eX ) )
return result
etc.
FUNCTION GetErrorCodeFromException ( o AS Exception ) AS DWORD
RETURN _and ( (DWORD) System.Runtime.InteropServices.Marshal.GetHRForException ( o ) , 0x0000FFFF )
Karl-Heinz
Fopen() 2.0.0.5
Karl-Heinz,
Can I use this and add it to the exception handling code in the runtime ?
This is what I like so much about open source. Community driven code !
Robert
Thanks for the example. And it works !Karl-Heinz wrote:Code: Select all
FUNCTION GetErrorCodeFromException ( o AS Exception ) AS DWORD RETURN _and ( (DWORD) System.Runtime.InteropServices.Marshal.GetHRForException ( o ) , 0x0000FFFF )
Can I use this and add it to the exception handling code in the runtime ?
This is what I like so much about open source. Community driven code !
Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
The Netherlands
robert@xsharp.eu
-
- Posts: 774
- Joined: Wed May 17, 2017 8:50 am
- Location: Germany
Fopen() 2.0.0.5
Hi Robert,
Great news !
Glad to hear that it works, and of course, you may use the code !!
Compared to what you and your team is doing, this "two Liner" is nothing, it´s just a translation of a c# snippet that i´ve found somewhere.
One question: GetLastWin32Error() still shows 1008, right ?
regards
Karl-Heinz
Great news !
Glad to hear that it works, and of course, you may use the code !!
Compared to what you and your team is doing, this "two Liner" is nothing, it´s just a translation of a c# snippet that i´ve found somewhere.
One question: GetLastWin32Error() still shows 1008, right ?
regards
Karl-Heinz
Fopen() 2.0.0.5
Karl-Heinz,
If you mean the Marshal.GetLastWin32Error(). We are not touching that. So it keeps on returning 1008. And our DosError() returns the same because it calls that method.
I have changed the code that touches FError() to:
TRY
clearErrorState()
// do something
CATCH e as Exception
setErrorState(e)
END TRY
Inside clearErrorState the last errorcode and last exception are cleared.
Inside setErrorState() the exception is saved and the errorcode is retrieved using the method that you indicated.
Ferror() now returns what you expect.
I have also added FException() that returns the Exception object for more information.
Robert
Robert
If you mean the Marshal.GetLastWin32Error(). We are not touching that. So it keeps on returning 1008. And our DosError() returns the same because it calls that method.
I have changed the code that touches FError() to:
TRY
clearErrorState()
// do something
CATCH e as Exception
setErrorState(e)
END TRY
Inside clearErrorState the last errorcode and last exception are cleared.
Inside setErrorState() the exception is saved and the errorcode is retrieved using the method that you indicated.
Ferror() now returns what you expect.
I have also added FException() that returns the Exception object for more information.
Robert
Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
The Netherlands
robert@xsharp.eu
-
- Posts: 774
- Joined: Wed May 17, 2017 8:50 am
- Location: Germany
Fopen() 2.0.0.5
Hi Robert,
In Github i see the changes you´ve made. BTW. it´s a very nice feature to be able to jump to the latest sources via the [view source] button in the help file.
regards
Karl-Heinz
In Github i see the changes you´ve made. BTW. it´s a very nice feature to be able to jump to the latest sources via the [view source] button in the help file.
regards
Karl-Heinz