J'utilise le code de JHPJHP pour creer des services (http://www.purebasic.fr/english/viewtop ... 12&t=60881), mais je plante sur un point.
Le service lance un programme, et tout ce passe bien, mais si je regle cet exe a necessiter les droits d'administrateurs, ca ne marche plus.
Est ce que les services n'ont pas acces aux programmes necessitant droits d'administration, ou j'ai mal configure quelque chose?
Merci.
n.b. tant que j'y suis, n'y-a-t-il pas un moyen plus facile (et plus court) pour creer un service?
ci joint le code de JHP
Code : Tout sélectionner
Global ServiceName.s = ProgramParameter()
Global lpServiceStatus.SERVICE_STATUS
Global hServiceStatus
Prototype protoGetProcessImageFileName(hProcess, lpImageFileName, nSize)
Prototype protoQueryFullProcessImageName(hProcess, dwFlags, lpExeName, lpdwSize)
Prototype protoWTSGetActiveConsoleSessionId()
Prototype protoWTSQueryUserToken(SessionId, phToken)
Prototype protoCreateEnvironmentBlock(lpEnvironment, hToken, bInherit)
Prototype protoDestroyEnvironmentBlock(lpEnvironment)
Procedure AdjustCurrentProcessPrivilege(LookupPrivilege.s, PrivilegeState)
Result = #False
If OpenProcessToken_(GetCurrentProcess_(), #TOKEN_ADJUST_PRIVILEGES | #TOKEN_QUERY, @TokenHandle)
lpLuid.LUID : #SE_PRIVILEGE_REMOVED = 4
If LookupPrivilegeValue_(#Null, LookupPrivilege , @lpLuid)
NewState.TOKEN_PRIVILEGES
With NewState
\PrivilegeCount = 1
\Privileges[0]\Luid\LowPart = lpLuid\LowPart
\Privileges[0]\Luid\HighPart = lpLuid\HighPart
If PrivilegeState
\Privileges[0]\Attributes = #SE_PRIVILEGE_ENABLED
Else
\Privileges[0]\Attributes = #SE_PRIVILEGE_REMOVED
EndIf
EndWith
Result = AdjustTokenPrivileges_(TokenHandle, #False, @NewState, SizeOf(TOKEN_PRIVILEGES), @PreviousState.TOKEN_PRIVILEGES, @ReturnLength)
EndIf
CloseHandle_(TokenHandle)
EndIf
ProcedureReturn Result
EndProcedure
Procedure.s GetProcessPath(hProcess)
Protected GetProcessImageFileName.protoGetProcessImageFileName
Protected QueryFullProcessImageName.protoQueryFullProcessImageName
Result.s = ""
If hProcess
Select OSVersion()
Case #PB_OS_Windows_XP
psapi = OpenLibrary(#PB_Any, "psapi.dll")
If IsLibrary(psapi)
GetProcessImageFileName = GetFunction(psapi, "GetProcessImageFileNameW")
If GetProcessImageFileName
nSize = #MAX_PATH
Dim lpBuffer.c(nSize)
lpImageFileName.s = Space(nSize)
GetProcessImageFileName(hProcess, @lpImageFileName, nSize)
BufferLength = GetLogicalDriveStrings_(nSize, @lpBuffer(0))
Repeat
lpDeviceName.s = ""
While lpBuffer(rtnCount)
lpDeviceName + Chr(lpBuffer(rtnCount))
rtnCount + 1
Wend
lpDeviceName = Left(lpDeviceName, Len(lpDeviceName) - 1)
lpTargetPath.s = Space(nSize)
QueryDosDevice_(lpDeviceName, @lpTargetPath, nSize)
If Left(lpImageFileName, Len(lpTargetPath)) = lpTargetPath
Result = Trim(ReplaceString(lpImageFileName, lpTargetPath, lpDeviceName))
Break
EndIf
rtnCount + 1
Until rtnCount >= BufferLength
EndIf
CloseLibrary(psapi)
EndIf
Default
kernel32 = OpenLibrary(#PB_Any, "kernel32.dll")
If IsLibrary(kernel32)
QueryFullProcessImageName = GetFunction(kernel32, "QueryFullProcessImageNameW")
If QueryFullProcessImageName
lpdwSize = #MAX_PATH
lpExeName.s = Space(lpdwSize)
QueryFullProcessImageName(hProcess, 0, @lpExeName, @lpdwSize)
Result = Trim(lpExeName)
EndIf
CloseLibrary(kernel32)
EndIf
EndSelect
CloseHandle_(hProcess)
EndIf
ProcedureReturn Result
EndProcedure
Procedure.s GetProcessList()
Result.s = ""
hSnapshot = CreateToolhelp32Snapshot_(#TH32CS_SNAPPROCESS, #Null)
If hSnapshot
ProcEntry.PROCESSENTRY32
ProcEntry\dwSize = SizeOf(PROCESSENTRY32)
If Process32First_(hSnapshot, @ProcEntry)
While Process32Next_(hSnapshot, @ProcEntry)
AdjustCurrentProcessPrivilege("SeTcbPrivilege", #True)
dwProcessId = ProcEntry\th32ProcessID
hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_VM_READ, #False, dwProcessId)
If hProcess
Result + GetProcessPath(hProcess) + #CRLF$
CloseHandle_(hProcess)
EndIf
Wend
CloseLibrary(kernel32)
EndIf
CloseHandle_(hSnapshot)
EndIf
ProcedureReturn Result
EndProcedure
Procedure RunProcessAsUser(lpApplicationName, lpCommandLine = #Null, lpCurrentDirectory = #Null)
Protected WTSGetActiveConsoleSessionId.protoWTSGetActiveConsoleSessionId
Protected WTSQueryUserToken.protoWTSQueryUserToken
Protected CreateEnvironmentBlock.protoCreateEnvironmentBlock
Protected DestroyEnvironmentBlock.protoDestroyEnvironmentBlock
Result = #False
kernel32 = OpenLibrary(#PB_Any, "kernel32.dll")
If IsLibrary(kernel32)
WTSGetActiveConsoleSessionId = GetFunction(kernel32, "WTSGetActiveConsoleSessionId")
dwSessionId = WTSGetActiveConsoleSessionId()
If dwSessionId
wtsapi32 = OpenLibrary(#PB_Any, "wtsapi32.dll")
If IsLibrary(wtsapi32)
WTSQueryUserToken = GetFunction(wtsapi32, "WTSQueryUserToken")
If WTSQueryUserToken(dwSessionId, @TokenHandle)
sa.SECURITY_ATTRIBUTES
#SecurityImpersonation = 2
#TokenPrimary = 1
If DuplicateTokenEx_(TokenHandle, #MAXIMUM_ALLOWED, @sa, #SecurityImpersonation, #TokenPrimary, @ImpersonateToken)
If ImpersonateLoggedOnUser_(ImpersonateToken)
userenv = OpenLibrary(#PB_Any, "userenv.dll")
If IsLibrary(userenv)
CreateEnvironmentBlock = GetFunction(userenv, "CreateEnvironmentBlock")
DestroyEnvironmentBlock = GetFunction(userenv, "DestroyEnvironmentBlock")
If CreateEnvironmentBlock(@pEnvironment, ImpersonateToken, #False)
#CREATE_UNICODE_ENVIRONMENT = $400
dwCreationFlags = #NORMAL_PRIORITY_CLASS | #CREATE_NEW_CONSOLE | #CREATE_UNICODE_ENVIRONMENT
si.STARTUPINFO
ZeroMemory_(@si, SizeOf(STARTUPINFO))
si\cb = SizeOf(STARTUPINFO)
si\lpDesktop = @"WinSta0\Default"
pi.PROCESS_INFORMATION
ZeroMemory_(@pi, SizeOf(PROCESS_INFORMATION))
Result = CreateProcessAsUser_(ImpersonateToken, lpApplicationName, lpCommandLine, @sa, @sa, #False, dwCreationFlags, pEnvironment, lpCurrentDirectory, @si, @pi)
SetLastError_(0)
DestroyEnvironmentBlock(pEnvironment)
EndIf
CloseLibrary(userenv)
EndIf
RevertToSelf_()
EndIf
CloseHandle_(ImpersonateToken)
EndIf
CloseHandle_(TokenHandle)
EndIf
CloseLibrary(wtsapi32)
EndIf
EndIf
CloseLibrary(kernel32)
EndIf
EndProcedure
Procedure ServiceHandler(fdwControl)
Select fdwControl
Case #SERVICE_CONTROL_PAUSE
lpServiceStatus\dwCurrentState = #SERVICE_PAUSED
Case #SERVICE_CONTROL_CONTINUE
lpServiceStatus\dwCurrentState = #SERVICE_RUNNING
Case #SERVICE_CONTROL_STOP, #SERVICE_CONTROL_SHUTDOWN
With lpServiceStatus
\dwCurrentState = #SERVICE_STOP_PENDING
\dwWin32ExitCode = 0
\dwServiceSpecificExitCode = 0
\dwCheckPoint = 0
\dwWaitHint = 0
EndWith
SetServiceStatus_(hServiceStatus, @lpServiceStatus)
lpServiceStatus\dwCurrentState = #SERVICE_STOPPED
SetServiceStatus_(hServiceStatus, @lpServiceStatus)
Case #SERVICE_CONTROL_INTERROGATE
EndSelect
SetServiceStatus_(hServiceStatus, @lpServiceStatus)
EndProcedure
Procedure ServiceMain()
With lpServiceStatus
\dwServiceType = #SERVICE_WIN32_OWN_PROCESS | #SERVICE_INTERACTIVE_PROCESS
\dwCurrentState = #SERVICE_START_PENDING
\dwControlsAccepted = #SERVICE_ACCEPT_STOP | #SERVICE_ACCEPT_SHUTDOWN
\dwWin32ExitCode = 0
\dwServiceSpecificExitCode = 0
\dwCheckPoint = 0
\dwWaitHint = 0
EndWith
hServiceStatus = RegisterServiceCtrlHandler_(ServiceName, @ServiceHandler())
If hServiceStatus
SetServiceStatus_(hServiceStatus, @lpServiceStatus)
lpServiceStatus\dwCurrentState = #SERVICE_RUNNING
SetServiceStatus_(hServiceStatus, @lpServiceStatus)
ServiceFile.s = GetPathPart(ProgramFilename()) + ServiceName + ".exe"
While lpServiceStatus\dwCurrentState = #SERVICE_RUNNING
If FindString(GetProcessList(), ServiceFile, 1, #PB_String_NoCase) = 0
RunProcessAsUser(@ServiceFile, @ServiceName)
EndIf
Delay(10000)
Wend
With lpServiceStatus
\dwCurrentState = #SERVICE_STOP_PENDING
\dwWin32ExitCode = 0
\dwServiceSpecificExitCode = 0
\dwCheckPoint = 0
\dwWaitHint = 0
EndWith
SetServiceStatus_(hServiceStatus, @lpServiceStatus)
lpServiceStatus\dwCurrentState = #SERVICE_STOPPED
SetServiceStatus_(hServiceStatus, @lpServiceStatus)
EndIf
EndProcedure
Procedure ServiceInit()
Dim lpServiceTable.SERVICE_TABLE_ENTRY(2)
lpServiceTable(0)\lpServiceName = @ServiceName
lpServiceTable(0)\lpServiceProc = @ServiceMain()
lpServiceTable(1)\lpServiceName = #Null
lpServiceTable(1)\lpServiceProc = #Null
StartServiceCtrlDispatcher_(@lpServiceTable())
EndProcedure
ServiceInit()