5

我正在测试一个检查文件是否存在于网络中的应用程序。在我的测试中,我故意拔掉网络插头,这样就找不到文件了。问题是这会导致我的应用程序在至少 15 秒内无响应。我在 VB6 中同时使用了 FileExists() 和 GetAttr() 函数。有谁知道如何解决这个问题?(不,我不能停止使用 VB6)

谢谢,查理

4

8 回答 8

6

不幸的是,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 中调用的面向路径的函数的讨论。

于 2008-10-16T01:19:13.093 回答
1

也用这个

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")
于 2011-02-16T17:22:16.767 回答
0

我不确定您是否可以更优雅地处理这个问题 - 如果网络出现问题,超时可能需要一段时间才能表明问题严重到无法正常工作。

如果 VB6 支持线程(老实说我不记得了),您可以将文件打开到后台线程中,并让 UI 允许用户取消它(或在有意义的情况下执行其他操作),但这引入了一个非常重要的额外的复杂性。

于 2008-10-14T20:28:47.237 回答
0

VB 本质上是单线程的,但您可以将工作转移到 COM 组件来执行异步文件检查并在完成时标记事件。这样,UI 线程至少保持响应。麻烦的是 - 这都是理论,我不知道这样的组件。

可是等等!谷歌刚刚发现了这个:Visual Basic 6 Asynchronous File I/O Using the .NET Framework。这可能有帮助吗?

此外,他们在 CodeProject 上也有类似的内容:异步处理 - 基础知识和 VB6/VB.NET 演练

于 2008-10-14T20:53:02.447 回答
0

VB6有一些联网功能,可以测试看网络是否连通。您应该能够在“参考”下添加“NetCon 1.0 类型库”。这会为您添加 NETCONLib。实施后,您应该能够首先测试网络连接,然后测试 FileExists 和 GetAttr。

让我知道这是否有帮助!

于 2008-10-14T20:56:15.577 回答
0

此代码仅用于检查您的一个问题的连接(也许可以帮助您):

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
于 2013-10-08T18:59:08.543 回答
-1

我同意威尔。这样的事情很容易用 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
于 2008-10-14T21:08:32.710 回答
-1

通过网络访问文件可能会导致这些挂起。

已经有一段时间了,但我记得 VB6 中的多线程实现起来相对痛苦。一个快速的解决方案是拥有一个可以处理此问题的小型 .exe(可能也在 VB 中编码)。您可以使用 DDE 进行应用程序间通信,或者使用非常简单但复杂的基于文件的管道,我的意思是两个应用程序将相互读取/写入以处理应用程序间通信的文件。当然,根据这个场景的细节,使用基于文件的管道可能会简单地夸大文件 I/O 延迟。

如果您可以在一定程度上预测用户将从哪里选择文件,您可以考虑先发制人地缓存目录列表并读取它而不是直接读取文件 - 假设目录内容不会经常更改。注意:通过网络获取目录列表将导致与通过网络获取单个文件 I/O 相同的延迟问题。记在脑子里。

于 2008-10-16T00:47:31.317 回答