|
That's what I do -- it is usually "invalid handle" at the WriteFile, and I've verified that the handle at that time is still identical to the handle just given by CreateFile.
Thanks,
Richard
|
|
|
|
|
Unless the types your using to Declare the functions aren't right, I have no idea what's going wrong. It could be because of optimizations done in the Release version that are not done in the Debug. I've never seen this problem, in Managed Code anyway. What do the Declares look like for CreateFile and whatever else you're using that's related.
Dave Kreskowiak
Microsoft MVP - Visual Basic
-- modified at 7:25 Monday 19th June, 2006
|
|
|
|
|
Believe me, it makes no sense to me either, other than as a compiler or linker bug. Here's the declares:
Public Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" _
(ByVal lpFilename As String, ByVal dwDesiredAccess As Int32, _
ByVal dwShareMode As Int32, ByVal lpSecurityAttributes As Int32, _
ByVal dwCreationDisposition As Int32, ByVal dwFlagsAndAttributes As Int32, _
ByVal hTemplateFile As Int32) As Int32
Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Int32, ByVal lpBuffer As String, ByVal nNumberOfBytesToWrite As Int32, _
ByRef lpNumberOfBytesWritten As Int32, ByRef lpOverlapped As Int32) As Int32
Private Const GENERIC_WRITE As Int32 = &H40000000
Here's the two calls:
Dim lMailslotHandle As Int32
Dim lResult As Int32
Dim lNumWritten As Int32
lMailslotHandle = CreateFile(sMailSlot, GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0)
lResult = WriteFile(lMailslotHandle, sMsg2, Len(sMsg2), lNumWritten, 0)
Private Const FILE_SHARE_READ As Int32 = &H1
Note that for mailslots, one MUST use FILE_SHARE_READ in CreateFile.
The error in release mode is typically "invalid handle" on the Writefile. Here's a bit more. If I run the release version form the IDE (i.e. in debug mode, but not debug compile) it does not give the error, and works fine. Perhaps that really uses debug mode.
There's more weirdness. The DLL that contains this is supposed to be called via COM, and I have the appropriate COM registration for this. I have two test programs for the DLL -- one in .NET, one in VB6, more or less identical. However, when called from COM (i.e. a VB6 app), the debug version ALSO fails with invalid handle, but succeeds when called from .NET. To make it worse (better?) all I do to test is create an instance of the DLL object, as all this happens in the New() method -- so there isn't any problem in argument or result marshalling to account for this. In all cases (working or failure), logging shows the handle from CreateFile is still intact at the time WriteFile fails.
|
|
|
|
|
Wow, I can tell that the wrong types are being used. Int32 is a signed type, which is not the best for handling bit flags and handles. Instead, you might want to pass those flags as Enums using a base type of UInt32 and the handle values should be stored and passed as IntPtr's. You can find the CreateFile declaration here[^] on Pinvoke.net. There are also listings for the proper enums for the bit flags.
rberman wrote: If I run the release version form the IDE (i.e. in debug mode, but not debug compile)
If the solution configuration selected as Release or Debug? If Debug, the IDE will run the Debug compiled code, not the release. If you run the Release version from in the IDE, by default, you'll get a warning box that says something like "Whatever module was built with optimizations or without debug information... yada yada yada". The debugger won't be able to stop the code with breakpoints if this is the case. If you can stop the code, then you're running the Debug version.
Dave Kreskowiak
Microsoft MVP - Visual Basic
|
|
|
|
|
Dave -- that's what I'd think, but I definitely select "release", get no warning, and breakpoints work -- sort of. The program data will be from the last Debug compilation, and so if I've added or removed any lines, the breakpoints will be off. This seems to indicate it really does allow the release mode to work in the debugger -- or it doesn't rebuild the PDB data (and file dates seem to indicate it did rebuild release version in this case).
Go figure. Anyway, it is incidental to the issue.
Thanks for the info on the declarations -- will definitely check them out and let you know.
|
|
|
|
|
rberman wrote: but I definitely select "release", get no warning, and breakpoints work
Then you're either running the Debug code or you've changed the Project's Configuration options and told the Release configuration to generate debug database when compiled.
Dave Kreskowiak
Microsoft MVP - Visual Basic
|
|
|
|
|
Well.... I think they are incorrect to have IntPtr as the return type -- a handle is NOT a pointer -- it is a system assigned integer used to identify an object. From the application perspective, it IS an integer, and in fact that is the way the API is used in any C program. The only restriction is on whether the handle can be inherited by another task (which requires a security descriptor attached when the handle is created).
Garbage collection should have no impact on handles therefore -- they are a simple identifier, not an address that might be moved in garbage collection.
So now I'm curious why they treat it this way -- is there something else that .NET does to system-assigned handles that might make them susceptible to damage?
|
|
|
|
|
rberman wrote: a handle is NOT a pointer
No. A handle is an unsigned integer the width of the address bus on the machine. So, if you run your code on a 64-bit machine, you'll get handles that are 64-bits wide. This is why it's not a good idea to specify handles as Interger or Int32. They're the same, a signed 32-bit integer, no matter what platform they're running on. So, on a 64-bit machine you'll be trying to stuff a 64-bit handle into a 32-bit space. Not going to happen...
IntPtr's are system-width, no matter what platform they're running on. You don't have to recode your app at all to switch between 32-bit and 64-bit.
rberman wrote: Garbage collection should have no impact on handles therefore -- they are a simple identifier, not an address that might be moved in garbage collection.
Partially correct. Garbage collection will not touch unmanaged handles at all. But, there is a finite number of them that are "checked-out" from the system and are assigned an ID number. If that handle isn't specifically freed, it will never be returned to the pool, and you'll eventually run the system out of handles.
rberman wrote: So now I'm curious why they treat it this way -- is there something else that .NET does to system-assigned handles that might make them susceptible to damage?
Nope. Nothing. The problem comes in when the handle is not marshalled to Managed code properly, like using the wrong managed type to store it.
Dave Kreskowiak
Microsoft MVP - Visual Basic
|
|
|
|
|
OK -- changing these handles to IntPtrs had one interesting difference -- First, a quick summary so this makes sense:
When called from .NET host, the DLL routine worked both in debug and release mode. When called from a COM host, both failed (invalid handle).
With IntPtr... Debug mode compilation works for BOTH .NET and COM hosts, and release-mode compilation FAILS for both! So this is really a net-zero gain if one were keeping score. But, I CAN use the debug-compiled version for production, so if this ends up working on the test and production systems, it will at least be a go.
But it still looks like something rather seriously wrong with the compiler. I see .NET 2.0 has a "safe handle" object, so apparently there IS something dicey about using handles in .NET 1.1
|
|
|
|
|
rberman wrote: But it still looks like something rather seriously wrong with the compiler.
Nope. I've used CreateFile/WriteFile, P/Invoked in .NET 1.0, 1.1 and 2.0, both Release and Debug configurations, with no problems whatsoever. Well, other than my own boneheaded mistakes.
Dave Kreskowiak
Microsoft MVP - Visual Basic
|
|
|
|
|
Hi, I need help to do a source code using visual studio2005.net to do a barchart which has the x-axis for id of people and the co,mmunication error rate. Thanks!
Eric
-- modified at 5:29 Saturday 17th June, 2006
|
|
|
|
|
Help!
I migrated a program from Vb6.0 to VB.NET and I have this line of code:
iRetVal = CopyFileEx(lszNetFile, lszSys32File, AddressOf CopyProgressRoutine, 0, bCancel, COPY_FILE_RESTARTABLE)
which unfortunately generates the following error:
'AddressOf' expression cannot be converted to 'Integer' because 'Integer' is not a delegate type.
What must I do? HELP!!!
Thanks,
MAY
|
|
|
|
|
You've got the Declare for the CopyFileEx function wrong. It should be:
Declare Auto Function CopyFileEx Lib "kernel32" ( _
ByVal lpExistingFilename As String, _
ByVal lpNewFilename As String, _
ByVal lpCopyProgressRoutine As CopyProgressRoutineDelegate, _
ByVal lpData As IntPtr, _
ByRef pCancel As Boolean, _
ByVal dwCopyFlags As CopyFlags)
You can find the definitions for the CopyProgressRoutineDelegate and CopyFile enum at www.pinvoke.net[^]
Dave Kreskowiak
Microsoft MVP - Visual Basic
|
|
|
|
|
when a tab page is closed by exit button then how to focus the control on the same tab
|
|
|
|
|
You can't close a tab page, so your question doesn't make any sense.
Besides, if you "closed" it, how on earth are you going to give the focus to a control on it?
Dave Kreskowiak
Microsoft MVP - Visual Basic
|
|
|
|
|
Am writting an app where i need to have the ability to enable/disable the internet. This is different from disabling the network card or conectivity on a pc.
I thought of using sockets but am not sure if this works fine and i havent managed to do that.
|
|
|
|
|
You can't turn off the Internet portion of the machine. It looks like any other normal traffic comming out of the network card. You'd have to run the traffic through a firewall and control access to resources off the local LAN through that firewall.
Dave Kreskowiak
Microsoft MVP - Visual Basic
|
|
|
|
|
I disagree, cos i know of an internet app that stops IE from running when times runs out. I saw an article about sockets, is it possible to stop trafic that comes out/in from the net or network? In this way i think the IE can be disabled!
|
|
|
|
|
You don't have to do anything with sockets to get IE to stop working. All you have to do is point IE to a proxy server that doesn't exist. Poof! It can't do anything anymore!
The problem with installing something on a machine is that, in most cases, you can only control it if you visit each machine. This becomes an administrative nightmare!
Dave Kreskowiak
Microsoft MVP - Visual Basic
|
|
|
|
|
Is there a reason
Dim mypath
mypath = "V:\"
myname = Dir(MyPath, vbDirectory)
will not work, but
Dim mypath
mypath = "C:\"
myname = Dir(MyPath, vbDirectory)
THe only difference beig one is a network drive, the other is not?
|
|
|
|
|
No-e wrote: Dim mypath
mypath = "V:\"
myname = Dir(MyPath, vbDirectory)
will not work, but
Dim mypath
mypath = "C:\"
myname = Dir(MyPath, vbDirectory)
Try
Dim mypath<br />
mypath = "\\RemoteHostName\ShareName" <br />
myname = Dir(MyPath, vbDirectory)
Tell me whether it is working or not.
|
|
|
|
|
This does not work either. I do not get an error, I just do not get anything for either case (using path or drive letter) Any other ideas?
|
|
|
|
|
Try this code:
Dim mypath<br />
mypath = "\\[IPAddressOfRemoteHost]\ShareName" <br />
myname = Dir(MyPath, vbDirectory)
Example:
Dim mypath<br />
mypath = "\\192.168.1.1\Report" <br />
myname = Dir(MyPath, vbDirectory)
|
|
|
|
|
Thanks, but that is actually the way I tested it.
mypath = "\\10.22.222.150\datadrive\logs" ' Set the path.
myname = Dir(mypath, vbDirectory) ' Retrieve the first entry.
Odd thing is that I do not get any error at all, just no answer.... I have tried several different computers, can not get anything across the network....
|
|
|
|
|
|