Prozess starten aus einem Windows Service heraus mit Argumenten

  • VB.NET
  • .NET (FX) 1.0–2.0

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von Mokki.

    Prozess starten aus einem Windows Service heraus mit Argumenten

    8o Hi Leute,

    war jetzt lange zeit nicht mehr hier im Forum, hatte jetzt leider mein Passwort und Useraccount vergessen und deshalb nun neu dabei.
    Ich stehe aktuell vor folgendem Problem.
    Es soll aus einem Windows Service ein Prozess gestartet werden mit zusätzlichen Argumenten. folgenden Code habe ich (dieser geht auch schon)

    Quellcode

    1. Dim UserTokenHandle As IntPtr = IntPtr.Zero
    2. WindowsApi.WTSQueryUserToken(WindowsApi.WTSGetActiveConsoleSessionId, UserTokenHandle)
    3. Dim ProcInfo As New WindowsApi.PROCESS_INFORMATION
    4. Dim StartInfo As New WindowsApi.STARTUPINFOW
    5. StartInfo.cb = CUInt(Runtime.InteropServices.Marshal.SizeOf(StartInfo))
    6. WindowsApi.CreateProcessAsUser(UserTokenHandle, "C:\PROGRA~1\Openssl\openssl.exe", IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, False, 0, IntPtr.Zero, Nothing, StartInfo, ProcInfo)
    7. If Not UserTokenHandle = IntPtr.Zero Then
    8. WindowsApi.CloseHandle(UserTokenHandle)
    9. End If

    leider weiß ich nicht wo ich die Argumente unterbringen kann, zum testen habe ich version>>version.txt verwendet, dabei sollte openssl eigentlich die version in eine txt datei schreiben.
    Zum Hintergrund: der Dienst schaut in einem Ordner und verschlüsselt eine bestimmte Datei mit openssl und sendet diese an einen weiteren Prozess, dies nur als Hintergrund.
    Die Verschlüsselung per cmd funktioniert schon, nun möchte ich dies halt in dem Dienst umsetzen.

    WindowsAPI Class

    Quellcode

    1. Imports System.Runtime.InteropServices
    2. Public Class WindowsApi
    3. <DllImport("kernel32.dll", EntryPoint:="WTSGetActiveConsoleSessionId", SetLastError:=True)>
    4. Public Shared Function WTSGetActiveConsoleSessionId() As UInteger
    5. End Function
    6. <DllImport("Wtsapi32.dll", EntryPoint:="WTSQueryUserToken", SetLastError:=True)>
    7. Public Shared Function WTSQueryUserToken(ByVal SessionId As UInteger, ByRef phToken As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
    8. End Function
    9. <DllImport("kernel32.dll", EntryPoint:="CloseHandle", SetLastError:=True)>
    10. Public Shared Function CloseHandle(<InAttribute()> ByVal hObject As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
    11. End Function
    12. <DllImport("advapi32.dll", EntryPoint:="CreateProcessAsUserW", SetLastError:=True)>
    13. Public Shared Function CreateProcessAsUser(<InAttribute()> ByVal hToken As IntPtr,
    14. <InAttribute(), MarshalAs(UnmanagedType.LPWStr)> ByVal lpApplicationName As String,
    15. ByVal lpCommandLine As System.IntPtr,
    16. <InAttribute()> ByVal lpProcessAttributes As IntPtr,
    17. <InAttribute()> ByVal lpThreadAttributes As IntPtr,
    18. <MarshalAs(UnmanagedType.Bool)> ByVal bInheritHandles As Boolean,
    19. ByVal dwCreationFlags As UInteger,
    20. <InAttribute()> ByVal lpEnvironment As IntPtr,
    21. <InAttribute(), MarshalAsAttribute(UnmanagedType.LPWStr)> ByVal lpCurrentDirectory As String,
    22. <InAttribute()> ByRef lpStartupInfo As STARTUPINFOW,
    23. <OutAttribute()> ByRef lpProcessInformation As PROCESS_INFORMATION) As <MarshalAs(UnmanagedType.Bool)> Boolean
    24. End Function
    25. <StructLayout(LayoutKind.Sequential)>
    26. Public Structure SECURITY_ATTRIBUTES
    27. Public nLength As UInteger
    28. Public lpSecurityDescriptor As IntPtr
    29. <MarshalAs(UnmanagedType.Bool)>
    30. Public bInheritHandle As Boolean
    31. End Structure
    32. <StructLayout(LayoutKind.Sequential)>
    33. Public Structure STARTUPINFOW
    34. Public cb As UInteger
    35. <MarshalAs(UnmanagedType.LPWStr)>
    36. Public lpReserved As String
    37. <MarshalAs(UnmanagedType.LPWStr)>
    38. Public lpDesktop As String
    39. <MarshalAs(UnmanagedType.LPWStr)>
    40. Public lpTitle As String
    41. Public dwX As UInteger
    42. Public dwY As UInteger
    43. Public dwXSize As UInteger
    44. Public dwYSize As UInteger
    45. Public dwXCountChars As UInteger
    46. Public dwYCountChars As UInteger
    47. Public dwFillAttribute As UInteger
    48. Public dwFlags As UInteger
    49. Public wShowWindow As UShort
    50. Public cbReserved2 As UShort
    51. Public lpReserved2 As IntPtr
    52. Public hStdInput As IntPtr
    53. Public hStdOutput As IntPtr
    54. Public hStdError As IntPtr
    55. End Structure
    56. <StructLayout(LayoutKind.Sequential)>
    57. Public Structure PROCESS_INFORMATION
    58. Public hProcess As IntPtr
    59. Public hThread As IntPtr
    60. Public dwProcessId As UInteger
    61. Public dwThreadId As UInteger
    62. End Structure
    63. End Class


    Bin über jede Hilfe Dankbar
    If the facts don't fit the theory, change the facts. --Albert Einstein

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „p0150n“ ()

    Hallo @p0150n!

    Zur Lösung deines Problems: Du hast für CreateProcessAsUser eine falsche Signatur verwendet. Wenn du dir die MSDN-Spezifikation mal ansiehtst, dann nimm die Funktion als 3. Parameter keinen IntPtr oder sowas, sondern ein LPTSTR.

    Hier ein Beispiel aus Stackoverflow.com.
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell
    hmm, danke schon mal für deine Antwort. Bin leider schon etwas lange raus und habe bisher das nicht ganz verstanden was du meinst.
    Auf jedenfall muss ich schon mal den Parameter lpCommandLine in der funktion createprocessasuser mit einem String verknüpfen.

    magst mir da noch einmal eine hilfestellung geben ? besten Dank
    If the facts don't fit the theory, change the facts. --Albert Einstein

    p0150n schrieb:

    mit einem String verknüpfen
    Im Prinzip das, was ich gesagt habe (nur einfacher erklärt ;) )

    Als allgemeiner Tipp: Wenn du eine WinAPI Funktion hast, schau mal auf pinvoke.net vorbe und such nach der Funktion. Da findest du eingetlich immer die korrekte VB und C# Signatur.

    Zu CreatProcessAsUser: Wie du hier auf pinvoke.net siehst, wird hier beim dritten Parameter nicht, wie bei dir ein IntPtr als Datentyp verwendet sondern ein String. Das wars eingentlich schon.

    Lg Radinator
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell
    Danke für die gute Seite werde ich mir merken.
    habe meinen Quellcode nun wie folgt angepasst:
    W Service:

    VB.NET-Quellcode

    1. Dim UserTokenHandle As IntPtr = IntPtr.Zero
    2. WindowsApi.WTSQueryUserToken(WindowsApi.WTSGetActiveConsoleSessionId, UserTokenHandle)
    3. Dim ProcInfo As New WindowsApi.PROCESS_INFORMATION
    4. Dim StartInfo As New WindowsApi.STARTUPINFOW
    5. StartInfo.cb = CUInt(Runtime.InteropServices.Marshal.SizeOf(StartInfo))
    6. WindowsApi.CreateProcessAsUser(UserTokenHandle, "C:\Windows\System32\cmd.exe", "/c ping 127.0.0.1 ", IntPtr.Zero, IntPtr.Zero, False, 0, IntPtr.Zero, Nothing, StartInfo, ProcInfo)
    7. If Not UserTokenHandle = IntPtr.Zero Then
    8. WindowsApi.CloseHandle(UserTokenHandle)
    9. End If


    Windows API (wie folgt angepasst)

    VB.NET-Quellcode

    1. <DllImport("advapi32.dll", EntryPoint:="CreateProcessAsUserW", SetLastError:=True)>
    2. Public Shared Function CreateProcessAsUser(<InAttribute()> ByVal hToken As IntPtr,
    3. <InAttribute(), MarshalAs(UnmanagedType.LPWStr)> ByVal lpApplicationName As String,
    4. ByVal lpCommandLine As String,
    5. <InAttribute()> ByVal lpProcessAttributes As IntPtr,
    6. <InAttribute()> ByVal lpThreadAttributes As IntPtr,
    7. <MarshalAs(UnmanagedType.Bool)> ByVal bInheritHandles As Boolean,
    8. ByVal dwCreationFlags As UInteger,
    9. <InAttribute()> ByVal lpEnvironment As IntPtr,
    10. <InAttribute(), MarshalAsAttribute(UnmanagedType.LPWStr)> ByVal lpCurrentDirectory As String,
    11. <InAttribute()> ByRef lpStartupInfo As STARTUPINFOW,
    12. <OutAttribute()> ByRef lpProcessInformation As PROCESS_INFORMATION) As <MarshalAs(UnmanagedType.Bool)> Boolean
    13. End Function​


    die CMD öffnet sich aber die Parameter werden leider nicht übergeben. Scheint zu warm im Büro zu sein, finde den Fehler noch nicht. ?(
    If the facts don't fit the theory, change the facts. --Albert Einstein

    prozess mit parametern ausführen

    Ist das überhaupt möglich was ich versuche oder gibt es hier irgendwelche Grenzen. Habe in dem Dienst jetzt auch die Kommunikation zwischen Dienst und Desktop aktiviert, soll zwar ein Sicherheitsrisiko sein,aber erstmal für den Test reicht es. Jemand ein ähnliches Problem schon mal gehabt?
    If the facts don't fit the theory, change the facts. --Albert Einstein
    Nix zu machen, bin schon seit 2 tagen jetzt am probieren und Code verstehen, leider noch keinen Erfolg.
    If the facts don't fit the theory, change the facts. --Albert Einstein
    Die Windows API

    VB.NET-Quellcode

    1. Imports System.Runtime.InteropServices
    2. Imports System.Text
    3. Imports DisplayMessage.WindowsApi
    4. Public Class WindowsApi
    5. <DllImport("kernel32.dll", EntryPoint:="WTSGetActiveConsoleSessionId", SetLastError:=True)>
    6. Public Shared Function WTSGetActiveConsoleSessionId() As UInteger
    7. End Function
    8. <DllImport("Wtsapi32.dll", EntryPoint:="WTSQueryUserToken", SetLastError:=True)>
    9. Public Shared Function WTSQueryUserToken(ByVal SessionId As UInteger, ByRef phToken As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
    10. End Function
    11. <DllImport("kernel32.dll", EntryPoint:="CloseHandle", SetLastError:=True)>
    12. Public Shared Function CloseHandle(<InAttribute()> ByVal hObject As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
    13. End Function
    14. <DllImport("advapi32.dll", EntryPoint:="CreateProcessAsUserW", SetLastError:=True)>
    15. Public Shared Function CreateProcessAsUser(<InAttribute()> ByVal hToken As IntPtr,
    16. <InAttribute(), MarshalAs(UnmanagedType.LPWStr)> ByVal lpApplicationName As String,
    17. <InAttribute(), MarshalAs(UnmanagedType.LPWStr)> ByVal lpCommandLine As String,
    18. <InAttribute()> ByVal lpProcessAttributes As IntPtr,
    19. <InAttribute()> ByVal lpThreadAttributes As IntPtr,
    20. <MarshalAs(UnmanagedType.Bool)> ByVal bInheritHandles As Boolean,
    21. ByVal dwCreationFlags As UInteger,
    22. <InAttribute()> ByVal lpEnvironment As IntPtr,
    23. <InAttribute(), MarshalAsAttribute(UnmanagedType.LPWStr)> ByVal lpCurrentDirectory As String,
    24. <InAttribute()> ByRef lpStartupInfo As STARTUPINFOW,
    25. <OutAttribute()> ByRef lpProcessInformation As PROCESS_INFORMATION) As <MarshalAs(UnmanagedType.Bool)> Boolean
    26. End Function
    27. <StructLayout(LayoutKind.Sequential)>
    28. Public Structure SECURITY_ATTRIBUTES
    29. Public nLength As UInteger
    30. Public lpSecurityDescriptor As IntPtr
    31. <MarshalAs(UnmanagedType.Bool)>
    32. Public bInheritHandle As Boolean
    33. End Structure
    34. <StructLayout(LayoutKind.Sequential)>
    35. Public Structure STARTUPINFOW
    36. Public cb As UInteger
    37. <MarshalAs(UnmanagedType.LPWStr)>
    38. Public lpReserved As String
    39. <MarshalAs(UnmanagedType.LPWStr)>
    40. Public lpDesktop As String
    41. <MarshalAs(UnmanagedType.LPWStr)>
    42. Public lpTitle As String
    43. Public dwX As UInteger
    44. Public dwY As UInteger
    45. Public dwXSize As UInteger
    46. Public dwYSize As UInteger
    47. Public dwXCountChars As UInteger
    48. Public dwYCountChars As UInteger
    49. Public dwFillAttribute As UInteger
    50. Public dwFlags As UInteger
    51. Public wShowWindow As UShort
    52. Public cbReserved2 As UShort
    53. Public lpReserved2 As IntPtr
    54. Public hStdInput As IntPtr
    55. Public hStdOutput As IntPtr
    56. Public hStdError As IntPtr
    57. End Structure
    58. <StructLayout(LayoutKind.Sequential)>
    59. Public Structure PROCESS_INFORMATION
    60. Public hProcess As IntPtr
    61. Public hThread As IntPtr
    62. Public dwProcessId As UInteger
    63. Public dwThreadId As UInteger
    64. End Structure
    65. Public Declare Function WaitForSingleObject Lib "kernel32" (ByVal _
    66. hHandle As Long, ByVal dwMilliseconds As Long) As Long
    67. Public Declare Function GetExitCodeProcess Lib "kernel32" _
    68. (ByVal hProcess As Long, ByVal lpExitCode As Long) As Long
    69. Public Const NORMAL_PRIORITY_CLASS = &H20&
    70. Public Const INFINITE = -1&
    71. End Class

    in den Windows Service

    VB.NET-Quellcode

    1. Dim UserTokenHandle As IntPtr = IntPtr.Zero
    2. WindowsApi.WTSQueryUserToken(WindowsApi.WTSGetActiveConsoleSessionId, UserTokenHandle)
    3. Dim ProcInfo As New WindowsApi.PROCESS_INFORMATION
    4. Dim StartInfo As New WindowsApi.STARTUPINFOW
    5. Dim HK
    6. Dim strCommandLine
    7. strCommandLine = Environment.CommandLine
    8. strCommandLine = " /c ping 127.0.0.1"
    9. HK = Chr(34)
    10. StartInfo.cb = CUInt(Runtime.InteropServices.Marshal.SizeOf(StartInfo))
    11. WindowsApi.CreateProcessAsUser(UserTokenHandle, "C:\Windows\System32\cmd.exe", strCommandLine, IntPtr.Zero, IntPtr.Zero, True, 0, IntPtr.Zero, "C:\Windows\System32\", StartInfo, ProcInfo)
    12. If Not UserTokenHandle = IntPtr.Zero Then
    13. WindowsApi.CloseHandle(UserTokenHandle)
    14. End If
    If the facts don't fit the theory, change the facts. --Albert Einstein