PGia Posted July 1 Posted July 1 Hi Good morning everyone I've searched the internet for information about this without success, so I thought I'd ask this here. Is it possible to detect with Lisp if any Windows application running is doing so with administrator privileges? Quote
lido Posted July 2 Posted July 2 I think you could do this by testing whether an operation that requires administrative rights can be performed. For example, copying a file to the Windows\System folder. Quote
mhupp Posted July 2 Posted July 2 (edited) like lido said In AutoLISP, cannot directly check for Windows Admin privileges, because AutoLISP is sandboxed within AutoCAD and cant see those types of windows things. tho I wouldn't try and copy files into sys folder. because if you do (admin rights) you would have a bunch of junk files in there. then the next step is to delete the copied file. that is a hop skip and a jump away from delete something needed. I suggest using cmd prompt. it can list admin users and you can output that to a txt file that autocad can then read. if user name true. something like "net localusers administrators > c:\admintest.txt" Edited July 2 by mhupp 1 Quote
Steven P Posted July 2 Posted July 2 what is your end goal with detecting privileges / admin access? There might be other ways to do what you want of course. Quote
PGia Posted July 2 Author Posted July 2 Thanks for the answers. I’ve done some research and found that all processes invoked from AutoCAD inherit the same privilege level. Therefore, it may be enough to know the privilege level with which AutoCAD is running (although ideally, it should work to check any process). I need this to predict whether a task that requires privileges can be carried out or not Quote
BlackBox Posted July 2 Posted July 2 6 minutes ago, PGia said: Thanks for the answers. I’ve done some research and found that all processes invoked from AutoCAD inherit the same privilege level. Therefore, it may be enough to know the privilege level with which AutoCAD is running (although ideally, it should work to check any process). I need this to predict whether a task that requires privileges can be carried out or not Post your code. Those that know how do this may feel that it's sus to 'check privileges to see if a task can be carried out', based on what little info you've posted, FWIW. Quote
GLAVCVS Posted July 2 Posted July 2 (edited) 7 hours ago, PGia said: Thanks for the answers. I’ve done some research and found that all processes invoked from AutoCAD inherit the same privilege level. Therefore, it may be enough to know the privilege level with which AutoCAD is running (although ideally, it should work to check any process). I need this to predict whether a task that requires privileges can be carried out or not Hi Indeed, any process started from AutoCAD will inherit its privilege level. For example, if AutoCAD opens an instance of Word, that instance will inherit the same privilege level as AutoCAD. However, if a Word instance is already running and AutoCAD starts controlling it, its privilege level might be different. In that case, it might be necessary to check it in order to warn the user. Could your issue be something similar to that? As @mhupp says, there is no direct way to determine this from VLisp. But there are some tricks to achieve it: For example: (defun acadAdmin? (/ arch r ruta ruta1 f sh) (if (findfile (setq ruta1 (strcat (getenv "TEMP") "\\acAdmin.si"))) (vl-file-delete ruta1) ) (if (setq arch (open (setq ruta (strcat (getenv "TEMP") "\\ea.bat")) "w")) (progn (write-line "@echo off net session >nul 2>&1 if %errorlevel% == 0 ( echo SI> \"%temp%\\acAdmin.si\" )" arch ) (close arch) (setq sh (vlax-create-object "WScript.Shell")) (vlax-invoke sh 'Run ruta 0 :vlax-true) (vlax-release-object sh) (vl-file-delete ruta) (if (setq r (findfile ruta1)) (progn (vl-file-delete ruta1) T ) ) ) ) ) This simply writes a .bat that when executed, creates the file "acAdmin.si" only if AutoCAD is running as admin Edited July 2 by GLAVCVS 2 Quote
PGia Posted Monday at 09:55 PM Author Posted Monday at 09:55 PM (edited) Hi, Sorry for not replying earlier. I've been traveling for several days. @BlackBox: I don't understand what's so special about implementing a Lisp function that returns the privileges with which another application, controlled by AutoCAD, was launched. Do you need my code? Here it is: (setq Access (vl-catch-all-apply 'vlax-get-object '("Access.Application"))) (if (vl-catch-all-error-p Access) (progn (setq privileges (adminP "acad")) (setq msg (strcat "\nThere is no current instance of Access\nA new one will open with the same privileges as AutoCAD: " privileges)) (alert msg) (setq Access (vl-catch-all-apply 'vlax-create-object '("Access.Application"))) (if (vl-catch-all-error-p Access) (princ "\nIt was not possible to open a new instance of Access") (progn (vlax-put-property Access 'Visible :vlax-true) (princ "\nConnection successful") ) ) ) (progn (setq privileges (adminP "access")) (setq msg (strcat "\nAn instance of Microsoft Access was found with the folowing privileges: " privileges "\nConnection successful")) (alert msg) ) ) Where adminP is the function I need. It's something I found somewhere and I'm trying to adapt it to my needs. This code will be used on 3 PCs. Currently, in all cases, AutoCAD is configured to start as Administrator. Therefore, any application launched from AutoCAD should inherit the same privileges, as far as I understand. However, I would also like to cover the case where AutoCAD controls an already running instance of Access, as you mentioned. So I tried to add something to the code to take that possibility into account. Is it possible to create a Lisp function that returns whether an already opened instance of Access has Administrator privileges or not? Edited Tuesday at 11:36 AM by SLW210 Added Code Tags!! Quote
BIGAL Posted Monday at 11:53 PM Posted Monday at 11:53 PM (edited) @PGia "where AutoCAD controls an already running instance of Access" You should be able to use get application, this is for Excel. Try this line with Access. The code works with Word and I am pretty sure works with Access. Have your access open when running the code. ;; Try to get or create Excel instance (setq myxl (vl-catch-all-apply 'vlax-get-or-create-object '("Excel.Application"))) Did you do a Google "read and write to Access Autolisp". Pretty sure its similar to Excel uses row and columns. I can provide read write for Excel which should work with Access. https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/getting-data-from-an-access-database/td-p/6238062 Edited Monday at 11:57 PM by BIGAL Quote
SLW210 Posted Tuesday at 11:37 AM Posted Tuesday at 11:37 AM In the future please place your code in code tags. (<> in the editor toolbar) Quote
GLAVCVS Posted Wednesday at 05:36 PM Posted Wednesday at 05:36 PM (edited) On 7/7/2025 at 11:55 PM, PGia said: Hi, Sorry for not replying earlier. I've been traveling for several days. @BlackBox: I don't understand what's so special about implementing a Lisp function that returns the privileges with which another application, controlled by AutoCAD, was launched. Do you need my code? Here it is: (setq Access (vl-catch-all-apply 'vlax-get-object '("Access.Application"))) (if (vl-catch-all-error-p Access) (progn (setq privileges (adminP "acad")) (setq msg (strcat "\nThere is no current instance of Access\nA new one will open with the same privileges as AutoCAD: " privileges)) (alert msg) (setq Access (vl-catch-all-apply 'vlax-create-object '("Access.Application"))) (if (vl-catch-all-error-p Access) (princ "\nIt was not possible to open a new instance of Access") (progn (vlax-put-property Access 'Visible :vlax-true) (princ "\nConnection successful") ) ) ) (progn (setq privileges (adminP "access")) (setq msg (strcat "\nAn instance of Microsoft Access was found with the folowing privileges: " privileges "\nConnection successful")) (alert msg) ) ) Where adminP is the function I need. It's something I found somewhere and I'm trying to adapt it to my needs. This code will be used on 3 PCs. Currently, in all cases, AutoCAD is configured to start as Administrator. Therefore, any application launched from AutoCAD should inherit the same privileges, as far as I understand. However, I would also like to cover the case where AutoCAD controls an already running instance of Access, as you mentioned. So I tried to add something to the code to take that possibility into account. Is it possible to create a Lisp function that returns whether an already opened instance of Access has Administrator privileges or not? Maybe I'm wrong, but I don't think you can control a previously opened Access instance with AutoCAD. Does anyone know if this is actually possible? As for the code to check if any open application in Windows (controlled or not from AutoCAD) is running with Administrator privileges, another trick could be used: ask PowerShell. You should keep in mind that this code requires AutoCAD to be running as admin to work. Therefore, you may want to run 'acAdmin' first to ensure the response from 'aplicAdmin' is valid. It's not very fast, but it works. (defun aplicAdmin? (nbreAplic / arch shell ruta ruta1 f r) (if (setq arch (open (setq ruta (strcat (getenv "TEMP") "\\ea.ps1")) "w")) (progn (write-line (strcat "Add-Type @\" using System; using System.Runtime.InteropServices; public class Advapi32 { [DllImport(\"advapi32.dll\", SetLastError=true)] public static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, ref IntPtr TokenHandle); [DllImport(\"advapi32.dll\", SetLastError=true)] public static extern bool GetTokenInformation(IntPtr TokenHandle, int TokenInformationClass, byte[] TokenInformation, int TokenInformationLength, ref int ReturnLength); } \"@ param([string]$procName = \"" nbreAplic "\") # Obtiene el proceso $proc = Get-Process -Name $procName -ErrorAction SilentlyContinue if ($proc) { # Intenta abrir el token del proceso $handle = $proc.Handle $token = [System.IntPtr]::Zero $TOKEN_QUERY = 0x0008 $TokenElevation = 20 $tokenInfo = New-Object byte[] 4 $returnLength = 0 $r1 = [Advapi32]::OpenProcessToken($handle, $TOKEN_QUERY, [ref]$token) $r2 = [Advapi32]::GetTokenInformation($token, $TokenElevation, $tokenInfo, $tokenInfo.Length, [ref]$returnLength) if ($r1 -and $r2) { $elevado = [BitConverter]::ToInt32($tokenInfo, 0) if ($elevado -eq 1) { \"SI\" | Out-file \"$env:TEMP\\esAdmin.txt\" -encoding ASCII } else { \"NO\" | Out-file \"$env:TEMP\\esAdmin.txt\" -encoding ASCII } } else { \"ERROR\" | Out-file \"$env:TEMP\\esAdmin.txt\" -encoding ASCII } } else { \"NOEXISTE\" | Out-file \"$env:TEMP\\esAdmin.txt\" -encoding ASCII } exit" ) arch ) (close arch) (setq shell (vlax-create-object "WScript.Shell")) (vlax-invoke shell 'Run (strcat "powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden -File \"" ruta "\"") 0 :vlax-true); Ejecuta PowerShell en segundo plano (vlax-release-object shell) (if (findfile (setq ruta1 (strcat (getenv "TEMP") "\\esAdmin.txt"))) (if (setq f (open ruta1 "r")) (progn (setq r (= (read-line f) "SI")) (close f) (vl-file-delete ruta) (vl-file-delete ruta1) r ) ) ) ) ) ) However, maybe someone knows a better way. Edited Wednesday at 05:43 PM by GLAVCVS Quote
GLAVCVS Posted Wednesday at 05:44 PM Posted Wednesday at 05:44 PM 6 minutes ago, GLAVCVS said: Maybe I'm wrong, but I don't think you can control a previously opened Access instance with AutoCAD. Does anyone know if this is actually possible? As for the code to check if any open application in Windows (controlled or not from AutoCAD) is running with Administrator privileges, another trick could be used: ask PowerShell. You should keep in mind that this code requires AutoCAD to be running as admin to work. Therefore, you may want to run 'acAdmin' first to ensure the response from 'aplicAdmin' is valid. It's not very fast, but it works. (defun aplicAdmin? (nbreAplic / arch shell ruta ruta1 f r) (if (setq arch (open (setq ruta (strcat (getenv "TEMP") "\\ea.ps1")) "w")) (progn (write-line (strcat "Add-Type @\" using System; using System.Runtime.InteropServices; public class Advapi32 { [DllImport(\"advapi32.dll\", SetLastError=true)] public static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, ref IntPtr TokenHandle); [DllImport(\"advapi32.dll\", SetLastError=true)] public static extern bool GetTokenInformation(IntPtr TokenHandle, int TokenInformationClass, byte[] TokenInformation, int TokenInformationLength, ref int ReturnLength); } \"@ param([string]$procName = \"" nbreAplic "\") # Obtiene el proceso $proc = Get-Process -Name $procName -ErrorAction SilentlyContinue if ($proc) { # Intenta abrir el token del proceso $handle = $proc.Handle $token = [System.IntPtr]::Zero $TOKEN_QUERY = 0x0008 $TokenElevation = 20 $tokenInfo = New-Object byte[] 4 $returnLength = 0 $r1 = [Advapi32]::OpenProcessToken($handle, $TOKEN_QUERY, [ref]$token) $r2 = [Advapi32]::GetTokenInformation($token, $TokenElevation, $tokenInfo, $tokenInfo.Length, [ref]$returnLength) if ($r1 -and $r2) { $elevado = [BitConverter]::ToInt32($tokenInfo, 0) if ($elevado -eq 1) { \"SI\" | Out-file \"$env:TEMP\\esAdmin.txt\" -encoding ASCII } else { \"NO\" | Out-file \"$env:TEMP\\esAdmin.txt\" -encoding ASCII } } else { \"ERROR\" | Out-file \"$env:TEMP\\esAdmin.txt\" -encoding ASCII } } else { \"NOEXISTE\" | Out-file \"$env:TEMP\\esAdmin.txt\" -encoding ASCII } exit" ) arch ) (close arch) (setq shell (vlax-create-object "WScript.Shell")) (vlax-invoke shell 'Run (strcat "powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden -File \"" ruta "\"") 0 :vlax-true); Ejecuta PowerShell en segundo plano (vlax-release-object shell) (if (findfile (setq ruta1 (strcat (getenv "TEMP") "\\esAdmin.txt"))) (if (setq f (open ruta1 "r")) (progn (setq r (= (read-line f) "SI")) (close f) (vl-file-delete ruta) (vl-file-delete ruta1) r ) ) ) ) ) ) However, maybe someone knows a better way. P.S.: You must make sure to accompany 'aplicAdmin' with the correct argument: the name of the process. This means that it won't always be the same as the application. For example: for AutoCAD it's 'acad', but for Paint it's 'mspaint'. Therefore, make sure you correctly identify the name of the process you want to check before writing it into your code. Quote
BlackBox Posted Wednesday at 06:33 PM Posted Wednesday at 06:33 PM (edited) On 7/7/2025 at 5:55 PM, PGia said: Hi, Sorry for not replying earlier. I've been traveling for several days. @BlackBox: I don't understand what's so special about implementing a Lisp function that returns the privileges with which another application, controlled by AutoCAD, was launched. Do you need my code? Here it is: (setq Access (vl-catch-all-apply 'vlax-get-object '("Access.Application"))) (if (vl-catch-all-error-p Access) (progn (setq privileges (adminP "acad")) (setq msg (strcat "\nThere is no current instance of Access\nA new one will open with the same privileges as AutoCAD: " privileges)) (alert msg) (setq Access (vl-catch-all-apply 'vlax-create-object '("Access.Application"))) (if (vl-catch-all-error-p Access) (princ "\nIt was not possible to open a new instance of Access") (progn (vlax-put-property Access 'Visible :vlax-true) (princ "\nConnection successful") ) ) ) (progn (setq privileges (adminP "access")) (setq msg (strcat "\nAn instance of Microsoft Access was found with the folowing privileges: " privileges "\nConnection successful")) (alert msg) ) ) Where adminP is the function I need. It's something I found somewhere and I'm trying to adapt it to my needs. This code will be used on 3 PCs. Currently, in all cases, AutoCAD is configured to start as Administrator. Therefore, any application launched from AutoCAD should inherit the same privileges, as far as I understand. However, I would also like to cover the case where AutoCAD controls an already running instance of Access, as you mentioned. So I tried to add something to the code to take that possibility into account. Is it possible to create a Lisp function that returns whether an already opened instance of Access has Administrator privileges or not? Hi @PGia - just getting back from a long weekend. Thanks for the reply, but I'm still not seeing a post that explains why you need another user's administrator privilege? To do what (remotely)? Cheers Edited Wednesday at 06:34 PM by BlackBox Quote
BIGAL Posted Thursday at 12:45 AM Posted Thursday at 12:45 AM (edited) I should have read the code by PGia closer (setq Access (vl-catch-all-apply 'vlax-create-object '("Access.Application"))) Instead use (setq Access (vl-catch-all-apply 'vlax-get-or-create-object '("Access.Application"))) The get or create means if it is open then make application, if it is not open it will open Access. I have never had a problem opening Word or Excel with lisp. Same with are they open already. @PGia its your turn to respond, The code should work. Edited Thursday at 12:46 AM by BIGAL 1 Quote
Danielm103 Posted Thursday at 02:27 AM Posted Thursday at 02:27 AM I think vlax-get-or-create-object will get the instance, if the process was created by the same user, so I don’t think you can start an application as admin, then connect to it from another user. I also don’t think you can use vlax-get-or-create-object in an attempt to elevate privileges To me the whole thread goes not make sense. If you want to connect to a database, use SQL express and assign connection rights from the server. Use a file based server like SQLite Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.