Fájlműveletek CreateProcessWithLogon-nal (vb)

Fájlműveletek CreateProcessWithLogon-nal (vb)
2008-08-19T12:24:04+02:00
2008-08-20T22:36:03+02:00
2022-11-10T17:35:36+01:00
SZB2
Sziasztok!

Fájlműveleteket szeretnék végrehajtani visual basic kódból. Ezt eddig Filesystemobject-tel tettem. Most viszont a belépett felhasználótól eltérő jogosultságot igénylő műveleteket kellene elvégeznem kódból.
Arra gondoltam, hogy a CreateProcessWithLogon-nal elindítok egy új process-t azzal a felhasználónévvel és jelszóval, amelynek már engedélyezettek a műveletek, és egy sima DOS parancssorral elvégzem a fájlműveleteket (áthelyezés/átnevezés/törlés). Azért ezzel, mert ezt már legalább egy kicsit ismerem. Viszont úgy tűnik, hogy DOS-os parancsokat nem igazán kezel.
Jól látom?
Ha igen, akkor milyen egyéb lehetőségeim vannak? (Amelyek nem bonyolultabban ennél!!!
Előre is köszi!
Mutasd a teljes hozzászólást!
Nem jól látod, valszeg rosszul hívod meg a függvényt (pl. nem adod meg a cmd.exe elérési útvonalát). Esetleg láthatnánk kódot is?
Mutasd a teljes hozzászólást!

  • Igazad van. Nem adtam meg a CMD.exe elérési útját.
    Az meg sem fordult a fejemben, hogy ez nem alapértelmezett.

    Köszi!!!
    Mutasd a teljes hozzászólást!
  • Esetleg még annyit kérdezhetek, hogy ha nem Domain-ben vagyok, akkor a Createprocesswithlogon-nál az opcionálisan megadható értéknél ""-t vagy Null értéket kellene megadni, esetleg a workgroup nevét, vagy egyáltalán semmit?
    Illetve lehetséges-e az, hogy a cmd.exe teljesen a háttérben fusson (ne villanjon be az ablak)?
    Még egyszer köszi!!!
    Mutasd a teljes hozzászólást!
  • Jól látom?

    Nem.

    Sub test() Shell "cmd.exe /C date" End Sub
    Az utasítás amit a promptnak akarsz átadni a /C után kell legyen.
    Mutasd a teljes hozzászólást!
  • Az meg sem fordult a fejemben, hogy ez nem alapértelmezett.

    Hát ez érdekes, mert ha nem találja meg, akkor a VB azt kiabálja, hogy: "File not found"
    Nálam nem kell útvonal.
    Mutasd a teljes hozzászólást!
  • Kicsit másról van itt szó @sanya!

    Kérdezőnek: Üres sztring tökéletes.
    Mutasd a teljes hozzászólást!
  • A /C kapcsoló csak a művelet elvégzése után bezárja az ablakot. Mivel külső szervere(ke)n végzek fájlműveletet, ezért ez eltart egy darabig (éppen elég ahhoz, hogy bevillogjon nekem a CMD.exe ablak). Nincs valami kapcsoló, ami a CMD ablakot megjelenítését letiltja?
    Mutasd a teljes hozzászólást!
  • Köszi!

    Akkor valami rendszerbeli probléma van. Mert nem sikerül a dolog.

    Ezt a kódot egy modulba tettem:


    Public Const LOGON_WITH_PROFILE = &H1& Public Const LOGON_NETCREDENTIALS_ONLY = &H2& Public Const CREATE_DEFAULT_ERROR_MODE = &H4000000 Public Const CREATE_NEW_CONSOLE = &H10& Public Const CREATE_NEW_PROCESS_GROUP = &H200& Public Const CREATE_SEPARATE_WOW_VDM = &H800& Public Const CREATE_SUSPENDED = &H4& Public Const CREATE_UNICODE_ENVIRONMENT = &H400& Public Const ABOVE_NORMAL_PRIORITY_CLASS = &H8000& Public Const BELOW_NORMAL_PRIORITY_CLASS = &H4000& Public Const HIGH_PRIORITY_CLASS = &H80& Public Const IDLE_PRIORITY_CLASS = &H40& Public Const NORMAL_PRIORITY_CLASS = &H20& Public Const REALTIME_PRIORITY_CLASS = &H100& Public Const INFINITE = -1& Public Type PROCESS_INFORMATION hProcess As Long hThread As Long dwProcessID As Long dwThreadID As Long End Type Public Type STARTUPINFO cb As Long lpReserved As Long lpDesktop As Long lpTitle As Long dwX As Long dwY As Long dwXSize As Long dwYSize As Long dwXCountChars As Long dwYCountChars As Long dwFillAttribute As Long dwFlags As Long wShowWindow As Integer cbReserved2 As Integer lpReserved2 As Byte hStdInput As Long hStdOutput As Long hStdError As Long End Type Public lpUsername As String, lpDomain As String, lpPassword As String, lpApplicationName As String Public lpCommandLine As String, lpCurrentDirectory As String Public Declare Function CreateProcessWithLogon Lib "Advapi32" Alias "CreateProcessWithLogonW" _ (ByVal lpUsername As Long, ByVal lpDomain As Long, ByVal lpPassword As Long, _ ByVal dwLogonFlags As Long, ByVal lpApplicationName As Long, ByVal lpCommandLine As Long, _ ByVal dwCreationFlags As Long, ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As Long, _ lpStartupInfo As STARTUPINFO, lpProcessInfo As PROCESS_INFORMATION) As Long Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long Public Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long Public Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long Public Declare Function CreateProcessA Lib "kernel32" (ByVal _ lpApplicationName As String, ByVal lpCommandLine As String, ByVal _ lpProcessAttributes As Long, ByVal lpThreadAttributes As Long, _ ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _ ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As String, _ lpStartupInfo As STARTUPINFO, lpProcessInformation As _ PROCESS_INFORMATION) As Long Public Function ExecCmdAs(cmdline$) Dim StartInfo As STARTUPINFO, ProcessInfo As PROCESS_INFORMATION ' Initialize the STARTUPINFO structure: StartInfo.cb = LenB(StartInfo) 'initialize structure StartInfo.wShowWindow = SW_HIDE ' Start the shelled application: ret& = CreateProcessWithLogon(StrPtr(lpUsername), StrPtr(lpDomain), StrPtr(lpPassword), LOGON_WITH_PROFILE, StrPtr(lpApplicationName), StrPtr(lpCommandLine), CREATE_DEFAULT_ERROR_MODE Or CREATE_NEW_CONSOLE Or CREATE_NEW_PROCESS_GROUP, ByVal 0&, StrPtr(lpCurrentDirectory), StartInfo, ProcessInfo) ' Wait for the shelled application to finish: ret& = WaitForSingleObject(ProcessInfo.hProcess, INFINITE) Call GetExitCodeProcess(ProcessInfo.hProcess, ret&) Call CloseHandle(ProcessInfo.hThread) Call CloseHandle(ProcessInfo.hProcess) ExecCmdAs = ret& 'StartInfo.dwFlags = 0& 'note that closing the handles of the main thread and the process do not terminate the process End Function Public Function ExecCmd(cmdline$) Dim StartInfo As STARTUPINFO, ProcessInfo As PROCESS_INFORMATION ' Initialize the STARTUPINFO structure: StartInfo.cb = LenB(StartInfo) 'initialize structure StartInfo.dwFlags = STARTF_USESHOWWINDOW StartInfo.wShowWindow = SW_HIDE ' Start the shelled application: ret& = CreateProcessA(vbNullString, cmdline$, 0&, 0&, 1&, NORMAL_PRIORITY_CLASS, 0&, vbNullString, StartInfo, ProcessInfo) ' Wait for the shelled application to finish: ret& = WaitForSingleObject(ProcessInfo.hProcess, INFINITE) Call GetExitCodeProcess(ProcessInfo.hProcess, ret&) Call CloseHandle(ProcessInfo.hThread) Call CloseHandle(ProcessInfo.hProcess) ExecCmd = ret& 'StartInfo.dwFlags = 0& 'note that closing the handles of the main thread and the process do not terminate the process End Function



    És ezzel hívom meg:

    Private Sub Parancsgomb1_Click() lpUsername = "user" lpDomain = "" lpPassword = "pass" parancssor = ExecCmdAs("c:\WINDOWS\system32\cmd.exe /c mkdir c:\próba") End Sub

    Így nem csinál semmit. Se hibaüzenet, se új könyvtár.

    Persze ha csak a CreateProcessA-t hívom meg, akkor működik:

    parancssor = ExecCmd("c:\WINDOWS\system32\cmd.exe /c mkdir c:\próba")

    Nem tudom, hogy mi lehet a hiba.
    Mutasd a teljes hozzászólást!
  • Hol kéne látnod a hibaüzenetet? Az exit code-ot lekérdezed, de nem iratod ki. Nem látok GetLastError()-t sem.

    Return Values

    If the function succeeds, the return value is nonzero.

    If the function fails, the return value is zero. To get extended error information, call GetLastError.
    Mutasd a teljes hozzászólást!
  • Árnyék: Bocsi az előbbiekért.

    Na, de:
    Így nem csinál semmit. Se hibaüzenet, se új könyvtár.

    Hát azért nézd csak meg, hogy hol használod az ExecCmdAs függvényed cmdline paraméterét.
    Mutasd a teljes hozzászólást!
  • OK! Igyekszem rájönni.
    Ilyen az, amikor használok egy kódot, aminek a működését nem is értem teljesen.
    (Kicsit lassan vagyok autodidakta. De nem adom fel! )
    Mutasd a teljes hozzászólást!
  • Jaja

    Kérdezőnek: WS_HIDE csak a GUI-s processzeknél hatásos, a konzolnál nem. Ebből kiindulva a CREATE_NO_WINDOW-re lesz szükséged:
    CREATE_NO_WINDOW
    0x08000000
    The process is a console application that is being run without a console window. Therefore, the console handle for the application is not set.

    This flag is ignored if the application is not a console application, or if it is used with either CREATE_NEW_CONSOLE or DETACHED_PROCESS.

    Deklarációja: Public Const CREATE_NO_WINDOW = &H8000000
    Mutasd a teljes hozzászólást!
  • Látom nem érted!
    Az ExecCmdAs függvényedben sehol nem használod a cmdline paramétert.
    Viszont a lpCommandLine globális változódat annál jobban, ami még inicializálva sincs sehol! Bezony ám.
    Mutasd a teljes hozzászólást!
  • Hát tényleg nem értem. Kevésbé értem, mint amennyire hittem.

    Eddig az idézett deklarációkkal és meghívással simán működött CreateProcessA-val minden. Mondjuk elég bonyolult alkalmazásokat hívtam meg (PDFStamp, ExifTool, IrfanView stb.)
    Ezek a fent említett formában és módon parancssorral simán működtek. sajna jelenleg nem értem, hogy mi a különbség a CreateProcessA és a CreateProcessWithLogon között akkor, ha az utóbbinál meghatározom a logolás részleteit (user/pass/domain).
    Sajnos ehhez én még hülye vagyok.
    A CREATE_NO_WINDOW-ot még valószínűleg megértem (abban nincs túl sok összekuszálási lehetőség.
    A másik problémán meg még túráztatom magam. Jó lenne pár VB-s "példa", amelyek alapján talán megvilágosodnék. De nem találok túl sokat a neten.
    Azért köszi mindkettőtöknek!!!
    Mutasd a teljes hozzászólást!
  • Public Function ExecCmdAs(cmdline$) Dim StartInfo As STARTUPINFO, ProcessInfo As PROCESS_INFORMATION ' Initialize the STARTUPINFO structure: StartInfo.cb = LenB(StartInfo) 'initialize structure StartInfo.wShowWindow = SW_HIDE ' Start the shelled application: ret& = CreateProcessWithLogon(StrPtr(lpUsername), _ StrPtr(lpDomain), StrPtr(lpPassword), _ LOGON_WITH_PROFILE, StrPtr(lpApplicationName), _ StrPtr(lpCommandLine), CREATE_DEFAULT_ERROR_MODE Or _ CREATE_NEW_CONSOLE Or CREATE_NEW_PROCESS_GROUP, _ ByVal 0&, StrPtr(lpCurrentDirectory), StartInfo, ProcessInfo) ' Wait for the shelled application to finish: ret& = WaitForSingleObject(ProcessInfo.hProcess, INFINITE) Call GetExitCodeProcess(ProcessInfo.hProcess, ret&) Call CloseHandle(ProcessInfo.hThread) Call CloseHandle(ProcessInfo.hProcess) ExecCmdAs = ret& 'StartInfo.dwFlags = 0& 'note that closing the handles of the main thread and the process do not terminate the process End Function

    Na mégegyszer, de most már kiskanállal. Ennek a függvényednek van ugye egy paramétere, a cmdline. Ebben lesz a "c:\WINDOWS\system32\cmd.exe /c mkdir c:\próba" string amit le szeretnél futtatni. Viszont ( gondolom elírásból ) a függvényed NEM használja sehol ezt a paramétert, hanem egy másikat, mégpedig a lpCommandLine-t, ami soha nem kap értéket.
    Viszont az ExecCmd függvény azért működik úgy, ahogy elvárod, mert a cmdline paraméter fel van használva ott ahol kell.
    Na, most már capito?
    Mutasd a teljes hozzászólást!


  • Köszi!!!!!

    Már értem. (Ezek szerint a cseh2-őt néztem eddig a kód helyett )
    Mutasd a teljes hozzászólást!
  • 3 db. hozzászólásomba került. Ez sokba fog neked kerülni!
    Mutasd a teljes hozzászólást!
  • Akkor várom a számlát!!!

    Tényleg köszi! Persze Árnyéknak is!!!
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd