我正在测试一个检查文件是否存在于网络中的应用程序。在我的测试中,我故意拔掉网络插头,这样就找不到文件了。问题是这会导致我的应用程序在至少 15 秒内无响应。我在 VB6 中同时使用了 FileExists() 和 GetAttr() 函数。有谁知道如何解决这个问题?(不,我不能停止使用 VB6)
谢谢,查理
不幸的是,VB 并没有让这变得简单,但幸运的是 Win32 API 做到了,而且从 VB 中调用 Win32 函数非常简单。
对于 LAN/WAN,您可以使用以下 Win32 API 调用的组合来告诉您远程连接是否存在,而无需处理网络超时:
Private Declare Function WNetGetConnection Lib "mpr.dll" Alias _
"WNetGetConnectionA" (ByVal lpszLocalName As String, _
ByVal lpszRemoteName As String, ByRef cbRemoteName As Long) As Long
Private Declare Function PathIsNetworkPath Lib "shlwapi.dll" Alias _
"PathIsNetworkPathA" (ByVal pszPath As String) As Long
Private Declare Function PathIsUNC Lib "shlwapi.dll" Alias "PathIsUNCA" _
(ByVal pszPath As String) As Long
对于 Internet,您可以使用 Win32 API 调用:
Private Declare Function InternetGetConnectedState Lib "wininet.dll" _
(ByRef lpdwFlags As Long, ByVal dwReserved As Long) As Long
Const INTERNET_CONNECTION_MODEM = 1
Const INTERNET_CONNECTION_LAN = 2
Const INTERNET_CONNECTION_PROXY = 4
Const INTERNET_CONNECTION_MODEM_BUSY = 8
这个 VB 站点有更多关于可以通过 VB 在 Win32 API 中调用的面向路径的函数的讨论。
也用这个
Dim FlSize as long
flsize=filelen("yourfilepath")
if err.number=53 then msgbox("file not found")
if err.number=78 then msgbox("Path Does no Exist")
我不确定您是否可以更优雅地处理这个问题 - 如果网络出现问题,超时可能需要一段时间才能表明问题严重到无法正常工作。
如果 VB6 支持线程(老实说我不记得了),您可以将文件打开到后台线程中,并让 UI 允许用户取消它(或在有意义的情况下执行其他操作),但这引入了一个非常重要的额外的复杂性。
VB 本质上是单线程的,但您可以将工作转移到 COM 组件来执行异步文件检查并在完成时标记事件。这样,UI 线程至少保持响应。麻烦的是 - 这都是理论,我不知道这样的组件。
可是等等!谷歌刚刚发现了这个:Visual Basic 6 Asynchronous File I/O Using the .NET Framework。这可能有帮助吗?
此外,他们在 CodeProject 上也有类似的内容:异步处理 - 基础知识和 VB6/VB.NET 演练
VB6有一些联网功能,可以测试看网络是否连通。您应该能够在“参考”下添加“NetCon 1.0 类型库”。这会为您添加 NETCONLib。实施后,您应该能够首先测试网络连接,然后测试 FileExists 和 GetAttr。
让我知道这是否有帮助!
此代码仅用于检查您的一个问题的连接(也许可以帮助您):
Private Declare Function InternetGetConnectedState Lib "wininet.dll" (ByRef dwFlags As Long, ByVal dwReserved As Long) As Long
Private Const CONNECT_LAN As Long = &H2
Private Const CONNECT_MODEM As Long = &H1
Private Const CONNECT_PROXY As Long = &H4
Private Const CONNECT_OFFLINE As Long = &H20
Private Const CONNECT_CONFIGURED As Long = &H40
Public Function checknet() As Boolean
Dim Msg As String
If IsWebConnected(Msg) Then
checknet = True
Else
If (Msg = "LAN") Or (Msg = "Offline") Or (Msg = "Configured") Or (Msg = "Proxy") Then
checknet = False
End If
End If
End Function
Private Function IsWebConnected(Optional ByRef ConnType As String) As Boolean
Dim dwFlags As Long
Dim WebTest As Boolean
ConnType = ""
WebTest = InternetGetConnectedState(dwFlags, 0&)
Select Case WebTest
Case dwFlags And CONNECT_LAN: ConnType = "LAN"
Case dwFlags And CONNECT_MODEM: ConnType = "Modem"
Case dwFlags And CONNECT_PROXY: ConnType = "Proxy"
Case dwFlags And CONNECT_OFFLINE: ConnType = "Offline"
Case dwFlags And CONNECT_CONFIGURED: ConnType = "Configured"
Case dwFlags And CONNECT_RAS: ConnType = "Remote"
End Select
IsWebConnected = WebTest
End Function
在您的活动中:
If checknet = False Then
...
else
...
end if
我同意威尔。这样的事情很容易用 Script.FileSystemObject 处理:
Dim objFSO As New FileSystemObject
If objFSO.FileExists("C:\path\to\your_file.txt") Then
' Do some stuff with the file
Else
' File isn't here...be nice to the user.
EndIf
通过网络访问文件可能会导致这些挂起。
已经有一段时间了,但我记得 VB6 中的多线程实现起来相对痛苦。一个快速的解决方案是拥有一个可以处理此问题的小型 .exe(可能也在 VB 中编码)。您可以使用 DDE 进行应用程序间通信,或者使用非常简单但复杂的基于文件的管道,我的意思是两个应用程序将相互读取/写入以处理应用程序间通信的文件。当然,根据这个场景的细节,使用基于文件的管道可能会简单地夸大文件 I/O 延迟。
如果您可以在一定程度上预测用户将从哪里选择文件,您可以考虑先发制人地缓存目录列表并读取它而不是直接读取文件 - 假设目录内容不会经常更改。注意:通过网络获取目录列表将导致与通过网络获取单个文件 I/O 相同的延迟问题。记在脑子里。