I developed an uninstaller windows script file for my application.
I'm trying to delete a folder from Programfiles (x86) but I'm getting this error
Microsoft VBScript runtime error '800A0046' Premission Denied
My code is below.
Dim shell, systempath
set shell = WScript.CreateObject( "WScript.Shell" )
systempath = shell.ExpandEnvironmentStrings("%SystemRoot%")
shell.Run Chr(34) & systempath & "\system32\msiexec.exe" & Chr(34) & " /x{ProductCode}"
For Each f In CreateObject("Scripting.FileSystemObject").GetFolder("C:\Program Files (x86)\XXXXX").SubFolders
If LCase(f.Name) <> "dev" Then
f.Delete
If Err Then
WScript.Echo "Error deleting:" & Name & " - " & Err.Description
Else
WScript.Echo "Deleted:" & Name
End If
On Error GoTo 0
End If
Next
WScript.Quit
The error line is "f.Delete".There is no problem when I ran this code on administrator account.But not an administrator I got the permission denied error.
How can I solve this problem?
Related
I'm looking for vbscript that do the following tasks
Script Tasks
execute on startup of the computer,
the way is being executed is via putting it in startup folder of windows in
C:\Documents and Settings\Admin\Start Menu\Programs\Startup
if output text file is exist, write down some text and exit
if the text file is not exist then it echo out full destination
the code is as provided, any help would be appreciated
'create txt.vbs
'vbscript
Set WshShell = CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
CurrentDirectory = objFSO.GetAbsolutePathName(".")
FilePath = CurrentDirectory & "\test.txt"
Existcode = objFSO.FileExists(FilePath)
' wscript.echo "FileExists code:" & Existcode
if Existcode = False then
Existcode = objFSO.FileExists(FilePath)
'for debugging
wscript.echo "file not exist" & vbCrLf _
& "FileExists code:" & Existcode
Set objFile = objFSO.CreateTextFile(FilePath,True)
strtext = "file created:" & vbCrLf & chr(34) & "New Line" & chr(34)
objFile.Write strtext & vbCrLf
objFile.Close
else
'for debugging
wscript.echo "file exist" & vbCrLf _
& "FileExists code:" & Existcode & vbCrLf & vbCrLf _
& FilePath & vbCrLf _
& CurrentDirectory & vbCrLf
end if
wscript.echo "end"
when get executed by clicking on it, either via a batch file, the script works with no errors and the output is as expected
while it's executed from startup folder by
windows, it show all echo that i set for debugging but doesn't
create the output file neither write to text in it, but also it read it as exist i'm not sure why
the vbscript cannot write text to startup folder,
however changes are the following
CurrentDirectory = objFSO.GetAbsolutePathName(".")
FilePath = CurrentDirectory & "\test.txt"
become
DesktopDirectory = WshShell.SpecialFolders("Desktop")
FilePath = DesktopDirectory & "\test.txt"
I'm using below code to delete the folder since it is used by other application I'm getting an error:
Permission denied-Cannot delete a folder
I need a code to check if the folder is in use by other application, if so kill that process and then delete that folder.
Set fso = CreateObject("Scripting.FileSystemObject")
Set folder = fso.GetFolder("C:\Users\x")
'delete all files in root folder
For Each f In folder.Files
On Error Resume Next
name = f.Name
f.Delete True
If Err Then
WScript.Echo "Error deleting:" & name & " - " & Err.Description
Else
WScript.Echo "Deleted:" & name
End If
On Error GoTo 0
Next
'delete all subfolders and files
For Each f In folder.SubFolders
On Error Resume Next
name = f.Name
f.Delete True
If Err Then
WScript.Echo "Error deleting:" & name & " - " & Err.Description
Else
WScript.Echo "Deleted:" & name
End If
On Error GoTo 0
Next
I want to execute a vbs script which provides me the size of a given folder but at the execution it returns me the error:
Microsoft VBScript runtime error: Path not found
Previously, the error was
Microsoft VBScript runtime error: Permission denied
but after these commands:
takeown /f C:\Users /r /d y
icacls C:\Users /grant administrators:F /T
it turned into "path not found". As you can see the folder that I want the size is C:\Users.
Here's my code:
'Created the 18.03.2010
'Easy script for check space folder. You need NRPE_NT daemon on win computer
'##########################################################'
'Install'
'##########################################################'
'1.copy file to c:\ for example... c:\nrpe_nt\bin\check_folder_size.vbs'
'2.set your nrpe.cfg for command for example
'command[check_foldersize]=c:\windows\system32\cscript.exe //NoLogo //T:30 c:\nrpe_nt\bin\check_folder_size.vbs c:\yourfolder 50 78
'50 70 are parameters for warning and critical value in MB'
'3.restart your nrpe_nt daemon in command prompt example.. net stop nrpe_nt and net start nrpe_nt'
'4. try from linux example.: ./check_nrpe -H yourcomputer -c check_foldersize and result can be OK:22,8 MB'
'it is all'
'##########################################################'
Dim strfolder
Dim intwarning
Dim intcritic
Dim wsh
Dim intvelkost
Dim intjednotka
'##########################################################'
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set wsh = CreateObject("WScript.Shell")
'##########################################################'
If WScript.Arguments.Count = 3 Then
strfolder = WScript.Arguments(0)
intwarning = WScript.Arguments(1)
intcritic = WScript.Arguments(2)
Set objFolder = objFSO.GetFolder(strfolder)
intjednotka = 1048576 '1MB->bytes'
intvelkost = objFolder.Size/intjednotka
If (objFolder.Size/1048576) > CInt(intwarning) Then
WScript.Echo "WARNING:" & round (objFolder.Size / 1048576,1) & " MB"
WScript.Quit(1)
ElseIf (objFolder.Size/1024000) > CInt(intcritic) Then
WScript.Echo "CRITICAL:" & Round(objFolder.Size / 1048576,1) & " MB"
WScript.Quit(2)
Else
WScript.Echo "OK:" & Round(objFolder.Size /1048576,1) & " MB"
WScript.Quit(0)
End If
Else
WScript.Echo "UNKNOWN:"& strfolder &"-" & intwarning & "-" & intcritic
WScript.Quit(3)
End If
The line of the call of the script:
check_foldersize = cscript.exe //nologo //T:60 scripts\check_folder_size.vbs C:\Users 4000 5000
Edit: One more useful point : There are no errors when I change the folder C:\Users to C:\Intel for example. So it seems to be a problem linked to the Users folder itself. Then I don't think that iis_iusrs permissions are the cause.
There is a great answer providing a batch file what will allways do it's best to run elevated and will not elevate if already elevated.
I don't want to distribute the batch file with my program though. The whole core of the answer is this VBSScript:
Set UAC = CreateObject("Shell.Application")
UAC.ShellExecute "[path to the batch file which will run elevated]", "ELEV", "", "runas", 1
Pretty simple. So just instead of the path to the batch file, I want to use the path to a jar file. But it doesn't seem to work:
Set UAC = CreateObject("Shell.Application")
UAC.ShellExecute "AutoClient.jar", "ELEV", "", "runas", 1
Set UAC = CreateObject("Shell.Application")
UAC.ShellExecute "javaw -jar AutoClient.jar", "ELEV", "", "runas", 1
Set UAC = CreateObject("Shell.Application")
UAC.ShellExecute "javaw", "ELEV", "-jar AutoClient.jar", "runas", 1
So well, how can I run the jar from the vbs file? Both files share the same directory. It's necessary that java application's working directory is that directory.
Edit:
So thanks #MCND (and this) I now know that the arguments go as follows:
path to executable to run
command line parameters sent to the program
working directory of the new process
'runas' command which invokes elevation
0 means do not show the window, 1 to show the window
And thanks to his code:
Set UAC = CreateObject("Shell.Application")
UAC.ShellExecute "javaw.exe", "-jar AutoClient.jar", "", "runas", 1
I can add another error in my collection:
The documentation states that the first parameter in the call is the file to start, leaving the arguments to the second parameter. So it should be (sorry, not tested)
Set UAC = CreateObject("Shell.Application")
UAC.ShellExecute "javaw.exe", "-jar AutoClient.jar", "", "runas", 1
So far, the only way I made this work without crazy popup errors is:
' Get the script location, the directorry where it's running
Set objShell = CreateObject("Wscript.Shell")
strPath = Wscript.ScriptFullName
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.GetFile(strPath)
strFolder = objFSO.GetParentFolderName(objFile)
' Args:
' path to executable to run
' command line parameters - first parameter of this file, which is the jar file name
' working directory (this doesn't work but I use it nevertheless)
' runas command which invokes elevation
' 0 means do not show the window. Normally, you show the window, but not this console window
' which just blinks and disappears anyway
UAC.ShellExecute "run-normally.bat", "SomeFile.jar, strFolder, "runas", 0
Because the working directory parameter doesn't work, I have following two lines in the bat file:
rem Used as a helper for the elevating VBS script. Runs the jar file
rem given as 1st argument as if the file was double clicked.
rem Make sure we're on our CURRENT directory
cd /d %~dp0
rem Run java, expecting the jar file to be given as the 1st argument
javaw -jar %1
I am not satisfied with this solution for cosmetic reasons. I want to display the UAC message for JRE, not windows command line:
I don't use Java but you aren't specifing full paths. You can't expect things to work reliably. Also whatever you are starting will need to have on it's right click menu Run As Administrator because the VBS code runs that menu command as if you clicked it. If it's not there you can't click it. EXE have it. So specify the correct paths to both Javaw and the jar file.
One issue is that the current directory is different depending on what technique you are using. ALWAYS specify full paths.
Here's a script that lists what verbs are available for an object (not we are not working with files but with objects). The graphical shell (explorer) is an object browser and has no idea what a file is apart from the fact it's an object of some type.
---------------------------
Windows Script Host
---------------------------
ShVerb
Lists or runs an explorer verb (right click menu) on a file or folder
ShVerb <filename> [verb]
Used without a verb it lists the verbs available for the file or folder
The program lists most verbs but only ones above the first separator
of the menu work when used this way
The Properties verb can be used. However the program has to keep running
to hold the properties dialog open. It keeps running by displaying
a message box.
---------------------------
OK
---------------------------
The script
HelpMsg = vbcrlf & " ShVerb" & vbcrlf & vbcrlf & " David Candy 2014" & vbcrlf & vbcrlf & " Lists or runs an explorer verb (right click menu) on a file or folder" & vbcrlf & vbcrlf & " ShVerb <filename> [verb]" & vbcrlf & vbcrlf & " Used without a verb it lists the verbs available for the file or folder" & vbcrlf & vbcrlf
HelpMsg = HelpMsg & " The program lists most verbs but only ones above the first separator" & vbcrlf & " of the menu work when used this way" & vbcrlf & vbcrlf
HelpMsg = HelpMsg & " The Properties verb can be used. However the program has to keep running" & vbcrlf & " to hold the properties dialog open. It keeps running by displaying" & vbcrlf & " a message box."
Set objShell = CreateObject("Shell.Application")
Set Ag = WScript.Arguments
set WshShell = WScript.CreateObject("WScript.Shell")
Set fso = CreateObject("Scripting.FileSystemObject")
If Ag.count = 0 then
wscript.echo " ShVerb - No file specified"
wscript.echo HelpMsg
wscript.quit
Else If Ag.count = 1 then
If LCase(Replace(Ag(0),"-", "/")) = "/h" or Replace(Ag(0),"-", "/") = "/?" then
wscript.echo HelpMsg
wscript.quit
End If
ElseIf Ag.count > 2 then
wscript.echo vbcrlf & " ShVerb - To many parameters" & vbcrlf & " Use quotes around filenames and verbs containing spaces" & vbcrlf
wscript.echo HelpMsg
wscript.quit
End If
If fso.DriveExists(Ag(0)) = True then
Set objFolder = objShell.Namespace(fso.GetFileName(Ag(0)))
' Set objFolderItem = objFolder.ParseName(fso.GetFileName(Ag(0)))
Set objFolderItem = objFolder.self
msgbox ag(0)
ElseIf fso.FolderExists(Ag(0)) = True then
Set objFolder = objShell.Namespace(fso.GetParentFolderName(Ag(0)))
Set objFolderItem = objFolder.ParseName(fso.GetFileName(Ag(0)))
ElseIf fso.fileExists(Ag(0)) = True then
Set objFolder = objShell.Namespace(fso.GetParentFolderName(Ag(0)))
Set objFolderItem = objFolder.ParseName(fso.GetFileName(Ag(0)))
Else
wscript.echo " ShVerb - " & Ag(0) & " not found"
wscript.echo HelpMsg
wscript.quit
End If
Set objVerbs = objFolderItem.Verbs
'If only one argument list verbs for that item
If Ag.count = 1 then
For Each cmd in objFolderItem.Verbs
If len(cmd) <> 0 then CmdList = CmdList & vbcrlf & replace(cmd.name, "&", "")
Next
wscript.echo mid(CmdList, 2)
'If two arguments do verbs for that item
ElseIf Ag.count = 2 then
For Each cmd in objFolderItem.Verbs
If lcase(replace(cmd, "&", "")) = LCase(Ag(1)) then
wscript.echo(Cmd.doit)
Exit For
End If
Next
'Properties is special cased. Script has to stay running for Properties dialog to show.
If Lcase(Ag(1)) = "properties" then
WSHShell.AppActivate(ObjFolderItem.Name & " Properties")
msgbox "This message box has to stay open to keep the " & ObjFolderItem.Name & " Properties dialog open."
End If
End If
End If
We run Dynamics GP. Because of the way it stores forms/reports, I need to have some install scripts that copy a .SET file into the program directory. This can be done manually, but it's much quicker to just have a user run an installer script which installs the proper files for them.
I've been building a VBScript installer that copies the necessary files around. The tricky part is that some clients are running Windows XP, and some are running Windows 7 (or even 8). UAC is enabled, so permissions come into play.
The way I've tried to do it is by blindly attempting to copy the files, and if a permission error is detected, it relaunches the script with administrator permissions. Where we've run into problems is some (all?) Windows 7 machines have virtualized file/registry writes enabled, so when the script tries to copy files into C:\Program Files\Microsoft Dynamics\GP2010, it silently fails and copies them to the user's AppData\Local\VirtualStore directory. This doesn't work properly with GP.
So what I need to do is have the script copy the files to C:\Program Files (not the VirtualStore directory), and elevate permissions only if necessary. If I have it elevate across the board, this causes the Windows XP machines to simply pop up a cryptic "Run As" dialog box when launching the script.
Here's what I have so far:
Dim WSHShell, FSO, Desktop, DesktopPath
Set FSO = CreateObject("Scripting.FileSystemObject")
Set WSHShell = CreateObject("WScript.Shell")
Desktop = WSHShell.SpecialFolders("Desktop")
DesktopPath = FSO.GetAbsolutePathName(Desktop)
'Set working directory to directory the script is in.
'This ends up being C:\Windows\System32 if the script is
'started from ShellExecute, or a link in an email, thus breaking
'relative paths.
WSHShell.CurrentDirectory = FSO.GetFile(WScript.ScriptFullName).ParentFolder
On Error Resume Next
If FSO.FolderExists("C:\Program Files (x86)") Then
WScript.Echo "Installing 64-bit."
FSO.CopyFile "64-bit\*.set", "C:\Program Files (x86)\Microsoft Dynamics\GP2010\", True
FSO.CopyFile "64-bit\*.lnk", DesktopPath, True
ElseIf FSO.FolderExists("C:\Program Files\Microsoft Dynamics\GP2010\Mekorma MICR") Then
WScript.Echo "Installing 32-bit (with MICR)."
FSO.CopyFile "32-bit MICR\*.set", "C:\Program Files\Microsoft Dynamics\GP2010\", True
FSO.CopyFile "32-bit MICR\*.lnk", DesktopPath, True
Else
WScript.Echo "Installing 32-bit."
FSO.CopyFile "32-bit\*.SET", "C:\Program Files\Microsoft Dynamics\GP2010\", True
FSO.CopyFile "32-bit\*.lnk", DesktopPath, True
End If
If Err.Number = 70 Then
CreateObject("Shell.Application").ShellExecute "wscript.exe", """" & WScript.ScriptFullName & """" , "", "runas", 1
WScript.Quit
ElseIf Err.Number <> 0 Then
MsgBox "Error " & Err.Number & vbCrLf & Err.Source & vbCrLf & Err.Description
Else
MsgBox "Installed successfully."
End If
In summary: How do I have a VBScript elevate permissions without causing XP to stall at a "Run As" dialog box, and without causing Windows 7 to copy the files to AppData\Local\VirtualStore instead?
Improved on #db2 answer:
real elevation testing, without depending on passed arguments
passes all original arguments to the elevated script
uses the same host of the initial script: wscript.exe, cscript.exe, whatever
Code:
Set OSList = GetObject("winmgmts:").InstancesOf("Win32_OperatingSystem")
For Each OS In OSList
If InStr(1, OS.Caption, "XP") = 0 And InStr(1, OS.Caption, "Server 2003") = 0 Then
With CreateObject("WScript.Shell")
IsElevated = .Run("cmd.exe /c ""whoami /groups|findstr S-1-16-12288""", 0, true) = 0
If Not IsElevated Then
Dim AllArgs
For Each Arg In WScript.Arguments
If InStr( Arg, " " ) Then Arg = """" & Arg & """"
AllArgs = AllArgs & " " & Arg
Next
Command = """" & WScript.ScriptFullName & """" & AllArgs
With CreateObject("Shell.Application")
.ShellExecute WScript.FullName, " //nologo " & Command, "", "runas", 1
WScript.Echo WScript.FullName & " //nologo " & Command
End With
WScript.Quit
End If
End With
End If
Next
' Place code to run elevated here
Seems like this is the simplest way to do it.
Check OS version.
If it's not XP or 2003 (I don't anticipate this running on anything older), re-execute with elevation.
Here's the code block I added to the beginning of the script:
Dim OSList, OS, UAC
UAC = False
If WScript.Arguments.Count >= 1 Then
If WScript.Arguments.Item(0) = "elevated" Then UAC = True
End If
If Not(UAC) Then
Set OSList = GetObject("winmgmts:").InstancesOf("Win32_OperatingSystem")
For Each OS In OSList
If InStr(1, OS.Caption, "XP") = 0 And InStr(1, OS.Caption, "Server 2003") = 0 Then
CreateObject("Shell.Application").ShellExecute "wscript.exe", """" & WScript.ScriptFullName & """ elevated" , "", "runas", 1
WScript.Quit
End If
Next
End If