В то время как в документации VB6 указано, что Shell()
возвращает вариант Double ..., который, как представляется, является устаревшей информацией, оставленной из руководств для версий VB для бывших пользователей. Вместо этого, если вы проверяете информацию о typelib (то есть смотрите в обозревателе объектов IDE), она фактически возвращает значение результата типа Double
.
Насколько я могу судить, Shell()
является оберткой вокруг вызова функции WinExec()
.
Возвращаемые значения:
0
Система из памяти или ресурсов.
ERROR_BAD_FORMAT = 11
Файл .exe недействителен.
ERROR_FILE_NOT_FOUND = 2
Указанный файл не найден.
ERROR_PATH_NOT_FOUND = 3
Указанный путь не найден.
- или идентификатор процесса
Также вопреки документации, Shell()
превращает эти значения ошибок в исключения («Файл не найден», «Неверный вызов процедуры или аргумент», и т.д.). Поэтому, если вызов преуспевает, вы всегда возвращаете значение PID.
Во всех случаях это DWORD. Таким образом, он всегда вписывается в Double без возможности переполнения. Если вы видите переполнение, в вашем коде что-то еще не так.
К сожалению, двойное значение здесь не особенно полезно, хотя оно может по крайней мере удерживать весь диапазон значений.Но вы обычно хотите тщательно преобразовать его длинное значение:
Option Explicit
Function DDoubleToDLong(ByVal DDouble As Double) As Long
'Some functions like the intrinsic Shell() return a Double
'to get around the lack of a UI4 type (DWORD, i.e. unsigned
'Long) in VB. Of course this isn't clean to pass to API
'calls, making it sort of worthless so we need to do a type
'conversion such as this:
If DDouble > 2147483647# Then
DDoubleToDLong = CLng(DDouble - 2147483648#) Or &H80000000
Else
DDoubleToDLong = CLng(DDouble)
End If
End Function
Private Sub Form_Load()
Dim DD As Double
Dim DL As Long
AutoRedraw = True
Font.Name = "Courier New" 'Or other handy monospaced font.
Font.Size = [email protected]
DD = 0#: DL = DDoubleToDLong(DD): Print DD, DL, Hex$(DL)
DD = 1#: DL = DDoubleToDLong(DD): Print DD, DL, Hex$(DL)
DD = 2147483647#: DL = DDoubleToDLong(DD): Print DD, DL, Hex$(DL)
DD = 2147483648#: DL = DDoubleToDLong(DD): Print DD, DL, Hex$(DL)
DD = 4294967295#: DL = DDoubleToDLong(DD): Print DD, DL, Hex$(DL)
End Sub
Integer
бесполезен, так как переполнение будет общим. Long
без преобразования может привести к переполнениям время от времени. String
просто глупо.
Вы также должны процитировать значения для EXE и его собственности аргументы, как в:
Option Explicit
Function DDoubleToDLong(ByVal DDouble As Double) As Long
If DDouble > 2147483647# Then
DDoubleToDLong = CLng(DDouble - 2147483648#) Or &H80000000
Else
DDoubleToDLong = CLng(DDouble)
End If
End Function
Private Sub Form_Load()
Dim sUrl As String
Dim PID As Long
sUrl = """C:\Arquivos de Programas\Internet Explorer\IEXPLORE.EXE"" " _
& """http://example.com/WebForms/send.aspx?id=" _
& intCodID _
& "&type=500&usr=" _
& intCodUser _
& """"
PID = DDoubleToDLong(Shell(sUrl, vbMaximizedFocus))
End Sub
Даже это не совсем «право», так как обработка исключений должны быть добавлены. И как intCodID
, так и intCodUser
может потребоваться «очистка» (UrlEncoding) в зависимости от того, какие типы и какие значения они действительно имеют. Это могут быть Integers
на основе имен, при этом вы полагаетесь на неявное принуждение String? Если так, они могут быть Ок.
BTW, как мы видим выше, специальные имена папок локализуются. В этом случае системный диск может вообще не быть C:\
! Таким образом, такие пути никогда не должны быть жестко закодированы, а вместо этого создаваться на основе значений, возвращаемых из вызовов Shell32
, чтобы найти специальную папку.
Кроме того, 'intCodID' и' intCodUser' имеют значения 'Integer'. –
Не уверен, что это связано, но я уверен, что если вы передаете эту строку в командной строке/оболочке, вам нужно предоставить двойные кавычки по пути, поскольку в ней есть пробелы. Что касается ошибки, каковы фактические значения 'intCodID' и' intCodUser'? Выбрасывает ли программа ошибку переполнения строки 'sUrl =' или 'openWeb = Shell (sUrl, vbMaximizedFocus)? – RianBattle
@RianBattle Вам не нужны двойные кавычки для 'Shell'. Но вы делаете для 'WshShell.Run'. – Bond