web-dev-qa-db-fra.com

Échapper les guillemets doubles dans la chaîne VB

J'ai utilisé le morceau de code suivant pour exécuter la commande schtasks à partir de VB6. Lors de son exécution, ignore le dossier s'il contient des espaces. Par exemple, "C:\program files\test\test.exe" sera converti en "c:\program ". Comment résoudre ce problème?

MyAppname =  Chr(34) & App.Path & "\" & App.EXEName & ".exe" & Chr(34)
StrCommand = "schtasks /create /sc ONLOGON /RL HIGHEST  /tn myapp  /tr " & MyAppname  
Shell StrCommand, vbHide   

Nouvelle tâche ajoutée en tant que "c:\program" au lieu de "C:\program files\test\test.exe"

Merci d'avance.

39
Suriyan Suresh

Échapper aux guillemets dans les chaînes VB6 ou VBScript est simple en théorie, mais souvent effrayant lorsqu'il est affiché. Vous échappez à une double citation avec une autre citation double.

Un exemple:

"c:\program files\my app\app.exe"

Si je veux échapper aux guillemets doubles afin que je puisse passer cela à la fonction d'exécution Shell répertoriée par Joe ou à la fonction Shell VB6, je l'écrirais:

escapedString = """c:\program files\my app\app.exe"""

Comment cela marche-t-il? Les premier et dernier guillemets enveloppent la chaîne et indiquent à VB qu'il s'agit d'une chaîne. Ensuite, chaque guillemet affiché littéralement dans la chaîne a un autre guillemet double ajouté devant lui pour l'échapper.

Cela devient plus fou lorsque vous essayez de passer une chaîne avec plusieurs sections entre guillemets. N'oubliez pas que chaque devis que vous souhaitez transmettre doit être échappé.

Si je veux passer ces deux phrases entre guillemets comme une seule chaîne séparée par un espace (ce qui n'est pas rare):

"c:\program files\my app\app.exe" "c:\documents and settings\steve"

J'entrerais ceci:

escapedQuoteHell = """c:\program files\my app\app.exe"" ""c:\documents and settings\steve"""

J'ai aidé mes administrateurs système avec certains scripts VBS qui ont encore plus de citations.

Ce n'est pas joli, mais c'est comme ça que ça marche.

67
Steve Massing

Un autre exemple:

Dim myPath As String = """" & Path.Combine(part1, part2) & """"

Bonne chance!

6
Brian Sweeney

Avez-vous essayé d'utiliser des guillemets doubles? Quoi qu'il en soit, personne en 2011 ne devrait être limité par la commande native VB6 Shell. Voici une fonction qui utilise ShellExecuteEx, beaucoup plus polyvalente.

Option Explicit

Private Const SEE_MASK_DEFAULT = &H0

Public Enum EShellShowConstants
        essSW_HIDE = 0
        essSW_SHOWNORMAL = 1
        essSW_SHOWMINIMIZED = 2
        essSW_MAXIMIZE = 3
        essSW_SHOWMAXIMIZED = 3
        essSW_SHOWNOACTIVATE = 4
        essSW_SHOW = 5
        essSW_MINIMIZE = 6
        essSW_SHOWMINNOACTIVE = 7
        essSW_SHOWNA = 8
        essSW_RESTORE = 9
        essSW_SHOWDEFAULT = 10
End Enum

Private Type SHELLEXECUTEINFO
        cbSize        As Long
        fMask         As Long
        hwnd          As Long
        lpVerb        As String
        lpFile        As String
        lpParameters  As String
        lpDirectory   As String
        nShow         As Long
        hInstApp      As Long
        lpIDList      As Long     'Optional
        lpClass       As String   'Optional
        hkeyClass     As Long     'Optional
        dwHotKey      As Long     'Optional
        hIcon         As Long     'Optional
        hProcess      As Long     'Optional
End Type

Private Declare Function ShellExecuteEx Lib "Shell32.dll" Alias "ShellExecuteExA" (lpSEI As SHELLEXECUTEINFO) As Long

Public Function ExecuteProcess(ByVal FilePath As String, ByVal hWndOwner As Long, ShellShowType As EShellShowConstants, Optional EXEParameters As String = "", Optional LaunchElevated As Boolean = False) As Boolean
    Dim SEI As SHELLEXECUTEINFO

    On Error GoTo Err

    'Fill the SEI structure
    With SEI
        .cbSize = Len(SEI)                  ' Bytes of the structure
        .fMask = SEE_MASK_DEFAULT           ' Check MSDN for more info on Mask
        .lpFile = FilePath                  ' Program Path
        .nShow = ShellShowType              ' How the program will be displayed
        .lpDirectory = PathGetFolder(FilePath)
        .lpParameters = EXEParameters       ' Each parameter must be separated by space. If the lpFile member specifies a document file, lpParameters should be NULL.
        .hwnd = hWndOwner                   ' Owner window handle

        ' Determine launch type (would recommend checking for Vista or greater here also)
        If LaunchElevated = True Then ' And m_OpSys.IsVistaOrGreater = True
            .lpVerb = "runas"
        Else
            .lpVerb = "Open"
        End If
    End With

     ExecuteProcess = ShellExecuteEx(SEI)   ' Execute the program, return success or failure

    Exit Function
Err:
    ' TODO: Log Error
    ExecuteProcess = False
End Function

Private Function PathGetFolder(psPath As String) As String
    On Error Resume Next
    Dim lPos As Long
    lPos = InStrRev(psPath, "\")
    PathGetFolder = Left$(psPath, lPos - 1)
End Function
4
Joe Jordan