Programm ausführen als xxxx

Windowsspezifisches Forum , API ,..
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
Benutzeravatar
Shardik
Beiträge: 746
Registriert: 25.01.2005 12:19

Beitrag von Shardik »

Barratator hat geschrieben:= CallFunction(0, "CreateProcessWithLogonW",user,".",pass,2,file,"",CREATE_DEFAULT_ERROR_MODE,null,null,StartupInfo,ProcessInfo)
Das Problem liegt an dem Wert 2 (= LOGON_NETCREDENTIALS_ONLY). Dies bewirkt, daß nicht das lokale User-Profil (z.B. das des Administrators) geladen wird (dauert möglicherweise einige Zeit). Dafür startet das gewünschte Programm im Kontext der User-ID, die aktuell angemeldet ist (was für einige Aufgaben auch sehr sinnvoll sein kann!). Also einfach den Wert 2 gegen 1 (= LOGON_WITH_PROFILE) tauschen und alles sollte laufen wie gewünscht... :wink:
MSDN-Link: http://msdn.microsoft.com/en-us/library/ms682431.aspx

Hier ein funktionierendes Beispiel zum Ausprobieren (einfach einmal mit #LOGON_NETCREDENTIALS_ONLY und #LOGON_WITH_PROFILE ausprobieren durch Ändern in dem CallFunctionFast-Aufruf sowie die Administrator-UserID und Passwort eintragen), das in einer Konsole ausgibt, in welchem User-Profil man nach dem RunAs-Aufruf arbeitet:

Code: Alles auswählen

EnableExplicit

#LOGON_WITH_PROFILE = 1
#LOGON_NETCREDENTIALS_ONLY = 2

Procedure.L RunAs(UserID.S, Password.S, DomainName.S, CommandLine.S) 
  Protected Buffer.S = Space(#MAX_PATH)
  Protected *CommandLine = AllocateMemory(#MAX_PATH)
  Protected *CurrentDirPath = AllocateMemory(#MAX_PATH)
  Protected *DomainName = AllocateMemory(32)
  Protected *LibFunction
  Protected *Password = AllocateMemory(16) 
  Protected ProcessInfo.PROCESS_INFORMATION 
  Protected StartUpInfo.STARTUPINFO 
  Protected *UserID = AllocateMemory(16) 

  MultiByteToWideChar_(#CP_ACP, 0, UserID, -1, *UserID, #MAX_PATH) 
  MultiByteToWideChar_(#CP_ACP, 0, DomainName, -1, *DomainName, #MAX_PATH) 
  MultiByteToWideChar_(#CP_ACP, 0, Password, -1, *Password, #MAX_PATH) 
  MultiByteToWideChar_(#CP_ACP, 0, CommandLine, -1, *CommandLine, #MAX_PATH) 
  MultiByteToWideChar_(#CP_ACP, 0, GetTemporaryDirectory(), -1, *CurrentDirPath, #MAX_PATH) 

  If OpenLibrary(0, "ADVAPI32.DLL") = 0
    MessageRequester("Fehler", "Die Programm-Bibliothek ADVAPI32.DLL konnte nicht geöffnet werden!", #MB_ICONERROR)
    ProcedureReturn #False
  Else
    *LibFunction = GetFunction(0, "CreateProcessWithLogonW")

    If *LibFunction
      If CallFunctionFast(*LibFunction, *UserID, *DomainName, *Password, #LOGON_NETCREDENTIALS_ONLY, 0, *CommandLine, 0, 0, *CurrentDirPath, @StartUpInfo, @ProcessInfo) = 0
        FormatMessage_(#FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError_(), #LANG_NEUTRAL, @Buffer, #MAX_PATH, 0)
        MessageRequester("Fehler", "Der Aufruf der Windows-Funktion CreateProcessWithLogonW() ist gescheitert:" + #CR$ + #CR$ + Buffer, #MB_ICONERROR)
        ProcedureReturn #False
      EndIf
    Else
      MessageRequester("Fehler", "Die Windows-Funktion CreateProcessWithLogonW() ist auf diesem PC nicht verfügbar!", #MB_ICONERROR)
      ProcedureReturn #False
    EndIf

    CloseLibrary(0)
  EndIf

  ProcedureReturn #True
EndProcedure

Define AdminUserID.S = "XXX"
Define Password.S = "XXX"
Define Domainname.S = "."

RunAs(AdminUserID, Password, DomainName, "Cmd /K Echo %USERNAME%")
Noch ein äußerst wichtiger Tipp: man sollte das Passwort nie wie in meinem obigen Beispiel im Klartext in das Programm eintragen, da sonst jeder neugierige Anwender mit einem Editor oder einfachen Hex-Editor das Passwort herausfinden kann. Ich habe das Beispiel lediglich auf das Wesentliche beschränkt und das verschlüsselte Passwort plus Passwortentschlüsselungsroutine aus meinem Beispiel herausgenommen. <)
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Hier noch mal die Lösung mit Prototype, die ich IMHO besser finde, als alles
selber umzuwandeln:

Code: Alles auswählen

Prototype _CreateProcessWithLogonW(lpUsername.p-unicode, lpDomain.p-unicode, dwLogonFlags.l, lpApplicationName.p-unicode, lpCommandline.p-unicode, dwCreatioFlags.l, *lpEnvironment, lpCurrentDirectory.p-unicode, *lpStartupInfo.STARTUPINFO, *lpProcessInfo.PROCESS_INFORMATION)

If OpenLibrary(0, "Advapi32.dll")
  Debug CreateProcessWithLogonW._CreateProcessWithLogonW = GetFunction(0, "CreateProcessWithLogonW")
EndIf
nicht getestet, sollte aber io sein :wink:

Mit Prototype funktionierts, egal ob unicode oder ascii
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Shardik
Beiträge: 746
Registriert: 25.01.2005 12:19

Beitrag von Shardik »

ts-soft hat natürlich Recht. Die Prototype-Lösung ist kürzer und hat den riesengroßen Vorteil, unverändert als ANSI- und Unicode-Version eingesetzt werden zu können. Der Pseudotype p-unicode läßt dabei den Compiler automatisch die eventuell notwendige Umwandlung von ANSI nach Unicode vornehmen (im ANSI-Modus). Außerdem wird eine genaue Typprüfung der Variablen vorgenommen, die mich dann auch ordentlich Zeit gekostet hat, bis ich den Aufruf komplett korrekt umgesetzt hatte. :wink:
Vor allem für den Parameter lpApplicationName.p-unicode habe ich irgendwie keinen Nullwert bzw. eine leere Zeichenkette übergeben bekommen - egal was ich auch ausprobiert habe... /:->
Ich habe dann beim Studium eines Beispielprogramms für VisualBASIC (http://support.microsoft.com/?scid=kb%3 ... &x=15&y=11) gesehen, daß dort lpApplicationName als Long definiert ist und daher einfach *lpApplicationName als Pointer definiert...
ts-soft hat geschrieben:nicht getestet, sollte aber io sein :wink:
Nicht ganz: Du hast den Parameter lpPassword.p-unicode vergessen :wink:

Code: Alles auswählen

#LOGON_WITH_PROFILE = 1
#LOGON_NETCREDENTIALS_ONLY = 2

Prototype CreateProcessWithLogonW(lpUsername.p-unicode, lpDomain.p-unicode, lpPassword.p-unicode, dwLogonFlags.L, *lpApplicationName, lpCommandline.p-unicode, dwCreationFlags.L, *lpEnvironment, lpCurrentDirectory.p-unicode, *lpStartupInfo.STARTUPINFO, *lpProcessInfo.PROCESS_INFORMATION)

Procedure RunAs(UserName.S, DomainName.S, Password.S, CommandLine.S, CurrentDir.S)
  Protected Buffer.S = Space(#MAX_PATH)
  Protected ProcessInfo.PROCESS_INFORMATION
  Protected StartUpInfo.STARTUPINFO

  If OpenLibrary(0, "Advapi32.dll") = 0
    MessageRequester("Fehler", "Die Programm-Bibliothek ADVAPI32.DLL konnte nicht geöffnet werden!", #MB_ICONERROR)
    ProcedureReturn #False
  Else
    CreateProcessWithLogonW.CreateProcessWithLogonW = GetFunction(0, "CreateProcessWithLogonW")

    If CreateProcessWithLogonW = 0
      MessageRequester("Fehler", "Die Windows-Funktion CreateProcessWithLogonW() ist auf diesem PC nicht verfügbar!", #MB_ICONERROR)
      ProcedureReturn #False
    Else
      If CreateProcessWithLogonW(UserName, DomainName, Password, #LOGON_WITH_PROFILE, 0, CommandLine, 0, 0, CurrentDir, @StartUpInfo, @ProcessInfo) = 0
        FormatMessage_(#FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError_(), #LANG_NEUTRAL, @Buffer, #MAX_PATH, 0)
        MessageRequester("Fehler", "Der Aufruf der Windows-Funktion CreateProcessWithLogonW() ist gescheitert:" + #CR$ + #CR$ + Buffer, #MB_ICONERROR)
        ProcedureReturn #False
      EndIf
    EndIf
  EndIf
  
  ProcedureReturn #True
EndProcedure

Define AdminUserID.S = "XXX"
Define Password.S = "XXX"
Define DomainName.S = "."

RunAs(AdminUserID, DomainName, Password, "Cmd /K Echo %USERNAME%", GetTemporaryDirectory())
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

> Nicht ganz: Du hast den Parameter lpPassword.p-unicode vergessen :wink:
Naja, da sieht man, das es doch Zeit wird, das PB ein Zeilenfortsetzungzeichen
erhält, selbst breite Bildschirme haben da Probleme und das Scrolling in der
IDE ist auch nicht so das wahre :mrgreen:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Barratator
Beiträge: 17
Registriert: 26.04.2008 09:48

Beitrag von Barratator »

Vielen Dank an alle :-) Das klappt jetzt alles wunderbar :) :)



Gruß
Bastian
Antworten