以下元帅代码几乎可行 [英] The following Marshal code almost works
问题描述
以下几乎可以正常工作。
问题是Marshal.PtrToStringAuto似乎终止于第一个null
所以我没有得到完整的字符串。 />
有关如何解决这个问题的建议吗?
或者如何改进代码?
谢谢
PS我添加了+1,因为据我了解GetLogicalDriveStrings doc
,最后将为Unicode提供一个不计数的null。同意?
Dim lDrives As String
Dim lLenOflDrives As Integer
Dim lPointerToMemory as IntPtr
lLenOflDrives = Kernel.GetLogicalDriveStrings(0,Nothing)
Dim lDrivesSB作为新的StringBuilder(lLenOflDrives + 1)
lDrivesSB.Insert(0,ChrW(33),lLenOflDrives + 1 )
lPointerToMemory = Marshal.StringToHGlobalAuto(lDrivesSB.ToString)
''获取dirves列表。返回一个:\< null> c:\< null>< null>
如果Kernel.GetLogicalDriveStrings(lLenOflDrives,lPointerToMemory)那么
''会如果宣布了GetLogicalDriveStrings则需要使用PtrToStringAnsi
CharSet.Ansi
lDrives = Marshal.PtrToStringAuto(lPointerToMemory,lLenOflDrives + 1)''文字
to first null,例如a:\
Marshal.FreeHGlobal(lPointerToMemory)
''查看aDrive是否在列表中
DriveExists = InStr(1,lDrives,drive,CompareMethod.Text)
结束如果
The following almost works.
The problem is Marshal.PtrToStringAuto seems to terminate at the first null
so I don''t get the full string.
Any suggestions on how to fix this?
Or how to improve the code?
Thanks
PS I added the +1 because as I understand the GetLogicalDriveStrings doc
there will be an uncounted null at the end for Unicode. Agree?
Dim lDrives As String
Dim lLenOflDrives As Integer
Dim lPointerToMemory As IntPtr
lLenOflDrives = Kernel.GetLogicalDriveStrings(0, Nothing)
Dim lDrivesSB As New StringBuilder(lLenOflDrives + 1)
lDrivesSB.Insert(0, ChrW(33), lLenOflDrives + 1)
lPointerToMemory = Marshal.StringToHGlobalAuto(lDrivesSB.ToString)
''Get the list of dirves. Returns a:\<null>c:\<null><null>
If Kernel.GetLogicalDriveStrings(lLenOflDrives, lPointerToMemory) Then
''Would need to use PtrToStringAnsi if GetLogicalDriveStrings were declared
CharSet.Ansi
lDrives = Marshal.PtrToStringAuto(lPointerToMemory, lLenOflDrives + 1) ''Text
to first null, e.g, a:\
Marshal.FreeHGlobal(lPointerToMemory)
''See if aDrive is in the list
DriveExists = InStr(1, lDrives, drive, CompareMethod.Text)
End If
推荐答案
或者如何改进代码?
谢谢
PS我添加了+1,因为据我了解GetLogicalDriveStrings doc
将会有一个不计数的null Unicode的结尾。同意?
Dim lDrives As String
Dim lLenOflDrives as Integer
Dim lPointerToMemory as IntPtr
lLenOflDrives = Kernel.GetLogicalDriveStrings(0,Nothing)
Dim lDrivesSB作为New StringBuilder(lLenOflDrives + 1)
lDrivesSB.Insert(0,ChrW(33),lLenOflDrives + 1)
lPointerToMemory = Marshal.StringToHGlobalAuto(lDrivesSB.ToString)
''获取列表迪尔维斯返回a:\< null> c:\< null>< null>
如果Kernel.GetLogicalDriveStrings(lLenOflDrives,lPointerToMemory)那么
Or how to improve the code?
Thanks
PS I added the +1 because as I understand the GetLogicalDriveStrings doc
there will be an uncounted null at the end for Unicode. Agree?
Dim lDrives As String
Dim lLenOflDrives As Integer
Dim lPointerToMemory As IntPtr
lLenOflDrives = Kernel.GetLogicalDriveStrings(0, Nothing)
Dim lDrivesSB As New StringBuilder(lLenOflDrives + 1)
lDrivesSB.Insert(0, ChrW(33), lLenOflDrives + 1)
lPointerToMemory = Marshal.StringToHGlobalAuto(lDrivesSB.ToString)
''Get the list of dirves. Returns a:\<null>c:\<null><null>
If Kernel.GetLogicalDriveStrings(lLenOflDrives, lPointerToMemory) Then
如果你改变了你的GetLogicalDriveStrings声明,以便最后的
参数是一个Char(),你可以这样简单地调用它。
Dim buffer(lLenOflDrives - 1)作为Char
如果Kernel.GetLogicalDriveStrings(lLenOflDrives,buffer)> 0然后
Mattias
-
Mattias Sj?gren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
请回复到新闻组。
If you change your GetLogicalDriveStrings declaration so that the last
parameter is a Char(), you can simply call it like this
Dim buffer(lLenOflDrives - 1) As Char
If Kernel.GetLogicalDriveStrings(lLenOflDrives, buffer) > 0 Then
Mattias
--
Mattias Sj?gren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
只是我,
我不知道你是否对某些托管代码感兴趣逻辑
驱动器。
但是我把它放在这里,当你没有时,也许是其他人在他/她搜索的时候。
设置参考和Imports System.Management
\\\
昏暗的搜索者作为新的ManagementObjectSearcher _
(SELECT * FROM Win32_LogicalDisk)
Dim ManObjOp作为ManagementObject
如果searcher.Get.Count> 1然后
For Each ManObjOp In searcher.Get
Dim win32 As String =" Win32_LogicalDisk =''" &
ManObjOp(" Name")。ToString& "''"
Dim ManObjLogD As New ManagementObject(win32)
For each diskProperty As PropertyData In
ManObjLogD.Properties >
如果不是diskProperty.Value则没有那么
Console.WriteLine _
(" {0} = {1}",diskProperty.Name, diskProperty.Value)
结束如果
下一页
下一页
结束如果
///
Cor
Just Me,
I don''t know if you are interested in some managed code to get logical
drives.
However I place it here, when you not, maybe somebody else when he/she is
searching.
set a reference and Imports System.Management
\\\
Dim searcher As New ManagementObjectSearcher _
("SELECT * FROM Win32_LogicalDisk")
Dim ManObjOp As ManagementObject
If searcher.Get.Count > 1 Then
For Each ManObjOp In searcher.Get
Dim win32 As String = "Win32_LogicalDisk=''" &
ManObjOp("Name").ToString & "''"
Dim ManObjLogD As New ManagementObject(win32)
For Each diskProperty As PropertyData In
ManObjLogD.Properties
If Not diskProperty.Value Is Nothing Then
Console.WriteLine _
("{0} = {1}", diskProperty.Name, diskProperty.Value)
End If
Next
Next
End If
///
Cor
只是我,
首先,我会改进它通过使用Environment.GetLogicalDrives代替。
你有没有理由不使用Environment.GetLogicalDrives?
根据Adam的书Marshal.PtrToStringAuto( IntPtr,Integer)
* NOT *终止于第一个空字符,其中
Marshal.PtrToStringAuto(IntPtr)。你确定它会被截断
&不仅仅是调试器在null char之后停止显示?记住
调试器将null char视为字符串终止符!
如果我实际需要调用Kernel32.GetLogicalDriveStrings,我会使用
Marshal.AllocHGlobal而不是Marshal.StringToHGlobalAuto,因为
Marshal.StringToHGlobalAuto更适用于需要将字符串传递给
Win32时,不返回Win32中的字符串...
类似于:
Dim lDrives As String
Dim lLenOflDrives As Integer = Kernel.GetLogicalDriveStrings(0,
IntPtr.Zero)
Dim lPointerToMemory As IntPtr = Marshal.AllocHGlobal(lLenOflDrives
* 2)
Dim rc As Integer = Kernel.GetLogicalDriveStrings(lLenOflDrives,
lPointerToMemory)
如果rc<> 0然后
lDrives = Marshal.PtrToStringAuto(lPointerToMemory,
lLenOflDrives)''文本首先为null,例如a:\
Marshal .FreeHGlobal(lPointerToMemory)
Dim drives()As String = lDrives.Split(ControlChars.NullChar)
结束如果
有关P / Invoke的信息,我通常会参考Adam Nathan的书.NET
和COM - The Complete Interoperability Guide。来自SAMS Press。
希望这有帮助
Jay
"只是我 < GR **** @ a-znet.com>在消息中写道
新闻:eI ************* @ TK2MSFTNGP09.phx.gbl ...
Just Me,
First I would "improve it" via using Environment.GetLogicalDrives instead.
Is there a reason you are not using Environment.GetLogicalDrives?
According to Adam''s book Marshal.PtrToStringAuto(IntPtr, Integer) should
*NOT* terminate at the first null character, where as the
Marshal.PtrToStringAuto(IntPtr) does. Are you certain its getting truncated
& not simply the Debugger stops displaying after the null char? Remember the
Debugger treats the null char as a string terminator!
If I actually needed to call Kernel32.GetLogicalDriveStrings I would use
Marshal.AllocHGlobal instead of Marshal.StringToHGlobalAuto, as
Marshal.StringToHGlobalAuto is more for when you need to pass a string into
Win32, not return a string from Win32...
Something like:
Dim lDrives As String
Dim lLenOflDrives As Integer = Kernel.GetLogicalDriveStrings(0,
IntPtr.Zero)
Dim lPointerToMemory As IntPtr = Marshal.AllocHGlobal(lLenOflDrives
* 2)
Dim rc As Integer = Kernel.GetLogicalDriveStrings(lLenOflDrives,
lPointerToMemory)
If rc <> 0 Then
lDrives = Marshal.PtrToStringAuto(lPointerToMemory,
lLenOflDrives) ''Text to first null, e.g, a:\
Marshal.FreeHGlobal(lPointerToMemory)
Dim drives() As String = lDrives.Split(ControlChars.NullChar)
End If
For information on P/Invoke I normally reference Adam Nathan''s book ".NET
and COM - The Complete Interoperability Guide" from SAMS Press.
Hope this helps
Jay
" Just Me" <gr****@a-znet.com> wrote in message
news:eI*************@TK2MSFTNGP09.phx.gbl...
以下几乎可行。<问题是Marshal.PtrToStringAuto似乎终止于第一个
null所以我没有得到完整的字符串。
有关如何解决此问题的任何建议吗?>或者如何改进代码?
谢谢PS我添加了+1,因为据我所知GetLogicalDriveStrings doc
会有一个不计数的null结束Unicode。同意?
Dim lDrives As String
Dim lLenOflDrives as Integer
Dim lPointerToMemory as IntPtr
lLenOflDrives = Kernel.GetLogicalDriveStrings(0,Nothing)
Dim lDrivesSB作为New StringBuilder(lLenOflDrives + 1)
lDrivesSB.Insert(0,ChrW(33),lLenOflDrives + 1)
lPointerToMemory = Marshal.StringToHGlobalAuto(lDrivesSB.ToString)
''获取列表迪尔维斯返回a:\< null> c:\< null>< null>
如果Kernel.GetLogicalDriveStrings(lLenOflDrives,lPointerToMemory)那么
''如果声明了GetLogicalDriveStrings则需要使用PtrToStringAnsi
CharSet.Ansi
lDrives = Marshal.PtrToStringAuto(lPointerToMemory,lLenOflDrives + 1)
''文本首先为null,例如a:\
Marshal.FreeHGlobal(lPointerToMemory)
''查看aDrive是否在列表中
DriveExists = InStr(1,lDrives,drive,CompareMethod.Text)
结束如果
The following almost works.
The problem is Marshal.PtrToStringAuto seems to terminate at the first
null so I don''t get the full string.
Any suggestions on how to fix this?
Or how to improve the code?
Thanks
PS I added the +1 because as I understand the GetLogicalDriveStrings doc
there will be an uncounted null at the end for Unicode. Agree?
Dim lDrives As String
Dim lLenOflDrives As Integer
Dim lPointerToMemory As IntPtr
lLenOflDrives = Kernel.GetLogicalDriveStrings(0, Nothing)
Dim lDrivesSB As New StringBuilder(lLenOflDrives + 1)
lDrivesSB.Insert(0, ChrW(33), lLenOflDrives + 1)
lPointerToMemory = Marshal.StringToHGlobalAuto(lDrivesSB.ToString)
''Get the list of dirves. Returns a:\<null>c:\<null><null>
If Kernel.GetLogicalDriveStrings(lLenOflDrives, lPointerToMemory) Then
''Would need to use PtrToStringAnsi if GetLogicalDriveStrings were declared
CharSet.Ansi
lDrives = Marshal.PtrToStringAuto(lPointerToMemory, lLenOflDrives + 1)
''Text to first null, e.g, a:\
Marshal.FreeHGlobal(lPointerToMemory)
''See if aDrive is in the list
DriveExists = InStr(1, lDrives, drive, CompareMethod.Text)
End If
这篇关于以下元帅代码几乎可行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!