100分请教:使用API调用ftpfindfirstfile时提示“未将对象引用设置到对象的实例”?
我在做FTP下传滚动条时,想得到FTP服务器上某个文件的大小,
但执行老是报错“未将对象引用设置到对象的实例”,
跟踪时发现这时nFileSizeLow已取出正确的文件大小了,
谁能帮我看看我的代码哪有问题,我怀疑是API声明变量类型不符,
这个问题已经折磨我两个星期了。
最好有vb.net源码
Const FTP_TRANSFER_TYPE_UNKNOWN As Integer = &H0
Const FTP_READ As Long = &H80000000
Const INTERNET_FLAG_RELOAD As Long = &H80000000
Const INTERNET_FLAG_NO_CACHE_WRITE As Integer = &H4000000
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim i As Integer
Dim iCount As Integer
Dim iK As Boolean
Dim pdata As API.WIN32_FIND_DATA
Dim intError As Integer
i = API.InternetOpen("", 1, "", "", 0)
iCount = API.InternetConnect(i, "94.6.13.150", 0, "maps", "maps50", 1, 0, 0)
iK = API.FtpSetCurrentDirectory(iCount, "xuzhe")
iK = API.FtpGetFile(iCount, "jk.txt", "c:\abc.htm", False, 1, 0, 0)
Dim findfile As Integer = 0
pdata.nFileSizeLow = 0
pdata.nFileSizeHigh = 0
pdata.dwReserved0 = 0
pdata.dwReserved1 = 0
pdata.cAlternate = StrDup(14, Chr(0))
pdata.cFileName = StrDup(260, Chr(0))
pdata.dwFileAttributes = 0
'下面这行老报错
findfile = API.FtpFindFirstFile(iCount, "PCM-0170100000-20060408-1.zip", pdata, INTERNET_FLAG_RELOAD Or INTERNET_FLAG_NO_CACHE_WRITE, 0)
End Sub
End Class
Imports System.Runtime.InteropServices
Imports System.Text
Public Class API
Public Structure FILETIME
Public dwLowDateTime As Int32
Public dwHighDateTime As Int32
End Structure
Public Structure WIN32_FIND_DATA
Public dwFileAttributes As Int32
Public ftCreationTime As FILETIME
Public ftLastAccessTime As FILETIME
Public ftLastWriteTime As FILETIME
Public nFileSizeHigh As Int32
Public nFileSizeLow As Int32
Public dwReserved0 As Int32
Public dwReserved1 As Int32
<VBFixedString(260)> Public cFileName As String
<VBFixedString(14)> Public cAlternate As String
End Structure
<DllImport("wininet.dll")> _
Public Shared Function InternetOpen(ByVal sAgent As String, _
ByVal lAccessType As Long, _
ByVal sProxyName As String, _
ByVal sProxyBypass As String, _
ByVal lFlags As Integer) As Integer
End Function
<DllImport("wininet.dll")> _
Public Shared Function InternetConnect(ByVal hInternetSession As Integer, _
ByVal sServerName As String, _
ByVal nServerPort As Integer, _
ByVal sUsername As String, _
ByVal sPassword As String, _
ByVal lService As Integer, _
ByVal lFlags As Integer, _
ByVal lContext As Integer) As Integer
End Function
<DllImport("wininet.dll")> _
Public Shared Function FtpGetFile(ByVal hFtpSession As Integer, _
ByVal lpszRemoteFile As String, _
ByVal lpszNewFile As String, _
ByVal fFailIfExists As Boolean, _
ByVal dwFlagsAndAttributes As Integer, _
ByVal dwFlags As Integer, _
ByVal dwContext As Integer) As Boolean
End Function
<DllImport("wininet.dll")> _
Public Shared Function FtpSetCurrentDirectory(ByVal hFtpSession As Integer, ByVal lpszDirectory As String) As Boolean
End Function
<DllImport("wininet.dll")> _
Public Shared Function FtpFindFirstFile(ByVal hFtpSession As Integer, ByVal lpszSearchFile As String, _
ByRef lpFindFileData As WIN32_FIND_DATA, ByVal dwFlags As long, ByVal dwContext As Long) As Integer
End Function
<DllImport("wininet.dll")> _
Public Shared Function FtpGetFileSize(ByVal hFile As Integer, ByRef lpdwFileSizeHigh As Long) As Long
End Function
<DllImport("wininet.dll")> _
Public Shared Function FtpOpenFile(ByVal hFile As Integer, ByVal lpszFileName As String, _
ByVal dwAccess As Long, ByVal dwFlags As Integer, ByVal dwContext As Long) As Integer
End Function
End Class
问题点数:100、回复次数:26Top
1 楼copico(北北)回复于 2006-06-03 00:43:49 得分 0
你的API是shared,你应该新建一个API的实例去调用它,而不是直接用API.GETFISTFILE
Top
2 楼xuzhe69152(xuzhe)回复于 2006-06-03 01:29:12 得分 0
to copico:
感谢您的回贴,我改成了
dim aaa as new api
findfile = aaa.FtpFindFirstFile(iCount, "PCM-0170100000-20060408-1.zip", pdata, INTERNET_FLAG_RELOAD Or INTERNET_FLAG_NO_CACHE_WRITE, 0)
但还是报错,您能不能给我源代码,我的取文件功能都可以实现呀
Top
3 楼xuzhe69152(xuzhe)回复于 2006-06-03 08:05:41 得分 0
我自己顶Top
4 楼HAVENT(夜雨流星℡)回复于 2006-06-03 08:27:56 得分 0
实例化Top
5 楼xuzhe69152(xuzhe)回复于 2006-06-03 10:30:55 得分 0
具体怎么改?高手请指点Top
6 楼kssys()回复于 2006-06-03 10:47:46 得分 0
楼主有一个没有实例化:
Dim pdata As API.WIN32_FIND_DATA
->
Dim pdata As New API.WIN32_FIND_DATATop
7 楼xuzhe69152(xuzhe)回复于 2006-06-03 11:15:38 得分 0
Dim pdata As New API.WIN32_FIND_DATA
我也试过,但报同样的错,我查了一下,vb.net在声明结构变量时自动
对结构初始化。到底是哪里出了问题
Top
8 楼copico(北北)回复于 2006-06-03 11:31:08 得分 0
你的所有调用的类里面的函数都用实例调用Top
9 楼kssys()回复于 2006-06-03 11:51:49 得分 0
TO:我也试过,但报同样的错,我查了一下,vb.net在声明结构变量时自动对结构初始化
是初始化了,但仍然需要实例化,这是两回事。
另外一个很重要的:你的pdata 结构体里面,并没有全部指定值。
Top
10 楼xuzhe69152(xuzhe)回复于 2006-06-03 11:59:07 得分 0
楼上的大哥,能否给我源代码Top
11 楼kssys()回复于 2006-06-03 12:18:09 得分 0
记错了,结构体是值类型,不需要实例化~_~
pdata.nFileSizeLow = 0
pdata.nFileSizeHigh = 0
pdata.dwReserved0 = 0
pdata.dwReserved1 = 0
pdata.cAlternate = StrDup(14, Chr(0))
pdata.cFileName = StrDup(260, Chr(0))
pdata.dwFileAttributes = 0
'加入以下几行
dim TestFileTime as FILETIME
TestFileTime.dwLowDateTime=0 '时间设为0
TestFileTime.dwHighDateTime=0 '时间设为0,根据实际需要修改
pdata.ftCreationTime=TestFileTime
pdata.ftLastAccessTime=TestFileTime
pdata.ftLastWriteTime=TestFileTimeTop
12 楼xuzhe69152(xuzhe)回复于 2006-06-03 14:47:09 得分 0
to kssys:
按照你说的还是报同样的错,
to cpyico:
我把每个API调用都改为了如下,还是报错,我觉得不是实例化出错,因为调用internetopen、internetconnect、ftpgetfile都成功了。
dim aaa as new api
findfile = aaa.FtpFindFirstFile(iCount, "PCM-0170100000-20060408-1.zip", pdata, INTERNET_FLAG_RELOAD Or INTERNET_FLAG_NO_CACHE_WRITE, 0)Top
13 楼xuzhe69152(xuzhe)回复于 2006-06-03 16:03:00 得分 0
肯请高手给我的程序找找错Top
14 楼kssys()回复于 2006-06-03 16:23:58 得分 0
你的提示挺神奇,我把你的代码下载下来,在本机运行,检测到签名有误,改成这样:
VB中的Long,到.Net应转换成Integer
->
<DllImport("wininet.dll")> _
Public Shared Function InternetOpen(ByVal sAgent As String, _
ByVal lAccessType As Integer, _
ByVal sProxyName As String, _
ByVal sProxyBypass As String, _
ByVal lFlags As Integer) As Integer
End Function
->
<DllImport("wininet.dll")> _
Public Shared Function FtpFindFirstFile(ByVal hFtpSession As Integer, ByVal lpszSearchFile As String, _
ByRef lpFindFileData As WIN32_FIND_DATA, ByVal dwFlags As Integer, ByVal dwContext As Integer) As Integer
End FunctionTop
15 楼xuzhe69152(xuzhe)回复于 2006-06-03 16:47:16 得分 0
我使用的是studio 2003,你是否使用的是studio 2005,
我使用时并没有报签名错,另外明明在监视窗口能看到
正确的文件大小,快救救一个深陷其中的人吧。Top
16 楼kssys()回复于 2006-06-03 17:08:27 得分 0
改过来之后运行正常。
本来数据类型就有错,应该改过来。再来测试Top
17 楼liujiayu10(活着就好)回复于 2006-06-03 17:14:04 得分 0
NewTop
18 楼yinweihong()回复于 2006-06-03 17:31:26 得分 0
对于shared 过程,要求其参数为shared的,那么,那2个结构体也必须为 shared的,里面的成员在NEW的时候也必须指定初始值
得不偿失,,,还不如直接放到module里面算了Top
19 楼xuzhe69152(xuzhe)回复于 2006-06-03 18:06:51 得分 0
to kssys:
您用的是studio2003还是2005?盼答复Top
20 楼kssys()回复于 2006-06-03 18:09:47 得分 0
我用的是2005
这一段程序,首先先更改数据类型,把潜在的错误排除。VB6.0的Long型对应.Net的Int32,即VB.Net的Integer,先改过来,再调试。
另:我把以上类型改过来之后,未出现任何问题,程序正常运行。Top
21 楼kssys()回复于 2006-06-03 18:10:17 得分 0
你的错误不关2003和2005的事~_~Top
22 楼xuzhe69152(xuzhe)回复于 2006-06-03 18:37:44 得分 0
to kssys:
我调整后还是不行,我的信箱是xuzhe_hn@yahoo.com.cn,能否将代码给我发过来,
万分感谢,或将您的邮箱留下,我把我的代码给你发过去。Top
23 楼liujiayu10(活着就好)回复于 2006-06-04 09:54:50 得分 0
顶上去!Top
24 楼kssys()回复于 2006-06-05 09:51:46 得分 0
To楼主:不好意思,这两天没上~_~
Public Class API
Public Structure FILETIME
Public dwLowDateTime As Int32
Public dwHighDateTime As Int32
End Structure
Public Structure WIN32_FIND_DATA
Public dwFileAttributes As Int32
Public ftCreationTime As FILETIME
Public ftLastAccessTime As FILETIME
Public ftLastWriteTime As FILETIME
Public nFileSizeHigh As Int32
Public nFileSizeLow As Int32
Public dwReserved0 As Int32
Public dwReserved1 As Int32
<VBFixedString(260)> Public cFileName As String
<VBFixedString(14)> Public cAlternate As String
End Structure
<DllImport("wininet.dll")> _
Public Shared Function InternetOpen(ByVal sAgent As String, _
ByVal lAccessType As Integer, _
ByVal sProxyName As String, _
ByVal sProxyBypass As String, _
ByVal lFlags As Integer) As Integer
End Function
<DllImport("wininet.dll")> _
Public Shared Function InternetConnect(ByVal hInternetSession As Integer, _
ByVal sServerName As String, _
ByVal nServerPort As Integer, _
ByVal sUsername As String, _
ByVal sPassword As String, _
ByVal lService As Integer, _
ByVal lFlags As Integer, _
ByVal lContext As Integer) As Integer
End Function
<DllImport("wininet.dll")> _
Public Shared Function FtpGetFile(ByVal hFtpSession As Integer, _
ByVal lpszRemoteFile As String, _
ByVal lpszNewFile As String, _
ByVal fFailIfExists As Boolean, _
ByVal dwFlagsAndAttributes As Integer, _
ByVal dwFlags As Integer, _
ByVal dwContext As Integer) As Boolean
End Function
<DllImport("wininet.dll")> _
Public Shared Function FtpSetCurrentDirectory(ByVal hFtpSession As Integer, ByVal lpszDirectory As String) As Boolean
End Function
<DllImport("wininet.dll")> _
Public Shared Function FtpFindFirstFile(ByVal hFtpSession As Integer, ByVal lpszSearchFile As String, _
ByRef lpFindFileData As WIN32_FIND_DATA, ByVal dwFlags As Integer, ByVal dwContext As Integer) As Integer
End Function
<DllImport("wininet.dll")> _
Public Shared Function FtpGetFileSize(ByVal hFile As Integer, ByRef lpdwFileSizeHigh As Long) As Long
End Function
<DllImport("wininet.dll")> _
Public Shared Function FtpOpenFile(ByVal hFile As Integer, ByVal lpszFileName As String, _
ByVal dwAccess As Long, ByVal dwFlags As Integer, ByVal dwContext As Long) As Integer
End Function
End ClassTop
25 楼xuzhe69152(xuzhe)回复于 2006-06-05 13:30:56 得分 0
to kssys:
能否将代码的其它部分也贴上来,另外
public class API
....
end class
是否是放到另一个类库.vb中?
Public ftCreationTime As FILETIME
Public ftLastAccessTime As FILETIME
Public ftLastWriteTime As FILETIME
这三个变量是否需要初始化?
最好能将整个项目文件发到我的信箱
xuzhe_hn@yahoo.com.cn,万分感谢您的帮助,解决后一定给分。
奇怪的是,我在vb6调用ftpfindnfirstfile并不报错,但net2003、2005
都报错。
Top
26 楼kssys()回复于 2006-06-05 15:43:58 得分 100
1.另外的代码和你的一模一样,没有任何改动。
2..Net一个文件可以放多个类,但最好还是放在专门的类里面。
3.不需要初始化。
4.因为VB6的Long类型对应.Net的Integer.
早上刚把源码给删光了~_~,以下是完整的:
Const FTP_TRANSFER_TYPE_UNKNOWN As Integer = &H0
Const FTP_READ As Long = &H80000000
Const INTERNET_FLAG_RELOAD As Long = &H80000000
Const INTERNET_FLAG_NO_CACHE_WRITE As Integer = &H4000000
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim i As Integer
Dim iCount As Integer
Dim iK As Boolean
Dim pdata As API.WIN32_FIND_DATA
Dim intError As Integer
i = API.InternetOpen("", 1, "", "", 0)
iCount = API.InternetConnect(i, "94.6.13.150", 0, "maps", "maps50", 1, 0, 0)
iK = API.FtpSetCurrentDirectory(iCount, "xuzhe")
iK = API.FtpGetFile(iCount, "jk.txt", "c:\abc.htm", False, 1, 0, 0)
Dim findfile As Integer = 0
pdata.nFileSizeLow = 0
pdata.nFileSizeHigh = 0
pdata.dwReserved0 = 0
pdata.dwReserved1 = 0
pdata.cAlternate = StrDup(14, Chr(0))
pdata.cFileName = StrDup(260, Chr(0))
pdata.dwFileAttributes = 0
findfile = API.FtpFindFirstFile(iCount, "PCM-0170100000-20060408-1.zip", pdata, INTERNET_FLAG_RELOAD Or INTERNET_FLAG_NO_CACHE_WRITE, 0)
End Sub
End Class
Public Class API
Public Structure FILETIME
Public dwLowDateTime As Int32
Public dwHighDateTime As Int32
End Structure
Public Structure WIN32_FIND_DATA
Public dwFileAttributes As Int32
Public ftCreationTime As FILETIME
Public ftLastAccessTime As FILETIME
Public ftLastWriteTime As FILETIME
Public nFileSizeHigh As Int32
Public nFileSizeLow As Int32
Public dwReserved0 As Int32
Public dwReserved1 As Int32
<VBFixedString(260)> Public cFileName As String
<VBFixedString(14)> Public cAlternate As String
End Structure
<DllImport("wininet.dll")> _
Public Shared Function InternetOpen(ByVal sAgent As String, _
ByVal lAccessType As Integer, _
ByVal sProxyName As String, _
ByVal sProxyBypass As String, _
ByVal lFlags As Integer) As Integer
End Function
<DllImport("wininet.dll")> _
Public Shared Function InternetConnect(ByVal hInternetSession As Integer, _
ByVal sServerName As String, _
ByVal nServerPort As Integer, _
ByVal sUsername As String, _
ByVal sPassword As String, _
ByVal lService As Integer, _
ByVal lFlags As Integer, _
ByVal lContext As Integer) As Integer
End Function
<DllImport("wininet.dll")> _
Public Shared Function FtpGetFile(ByVal hFtpSession As Integer, _
ByVal lpszRemoteFile As String, _
ByVal lpszNewFile As String, _
ByVal fFailIfExists As Boolean, _
ByVal dwFlagsAndAttributes As Integer, _
ByVal dwFlags As Integer, _
ByVal dwContext As Integer) As Boolean
End Function
<DllImport("wininet.dll")> _
Public Shared Function FtpSetCurrentDirectory(ByVal hFtpSession As Integer, ByVal lpszDirectory As String) As Boolean
End Function
<DllImport("wininet.dll")> _
Public Shared Function FtpFindFirstFile(ByVal hFtpSession As Integer, ByVal lpszSearchFile As String, _
ByRef lpFindFileData As WIN32_FIND_DATA, ByVal dwFlags As Integer, ByVal dwContext As Integer) As Integer
End Function
<DllImport("wininet.dll")> _
Public Shared Function FtpGetFileSize(ByVal hFile As Integer, ByRef lpdwFileSizeHigh As Long) As Long
End Function
<DllImport("wininet.dll")> _
Public Shared Function FtpOpenFile(ByVal hFile As Integer, ByVal lpszFileName As String, _
ByVal dwAccess As Long, ByVal dwFlags As Integer, ByVal dwContext As Long) As Integer
End Function
End ClassTop




