Enumerated Types in VBScript - vbscript

I want to script creating a scheduled task with VBScript.
I need to use the Enumerated Types of the Task Scheduler object to set the task to run with "Highest Privileges".
Anyone know how I set this?
Thanks,
Ben

I guess you're using the Task Scheduler 2.0 Scripting API, right?
The easiest solution is to manually define any constants needed in your script:
Const TASK_RUNLEVEL_LUA = 0
Const TASK_RUNLEVEL_HIGHEST = 1
Alternatively, you can try the following: wrap your VBScript code in a Windows Script (.wsf) file and use the <reference> tag to import the Task Scheduler type library, so that your script has access to constants defined in that type library. Your .wsf script would look something like this:
<job>
<reference object="Schedule.Service" />
<script language="VBScript">
WScript.Echo TASK_RUNLEVEL_HIGHEST
</script>
</job>
You can find more info on Windows script files here: Using Windows Script Files (.wsf).

Related

Include some kind of "header"-file to VBScript [duplicate]

VBScript doesn't appear to have a way to include a common file of functions.
Is there a way to achieve this?
You can create a (relatively) small function in each file that you want to include other files into, as follows:
sub includeFile (fSpec)
dim fileSys, file, fileData
set fileSys = createObject ("Scripting.FileSystemObject")
set file = fileSys.openTextFile (fSpec)
fileData = file.readAll ()
file.close
executeGlobal fileData
set file = nothing
set fileSys = nothing
end sub
and then use it to include specific files - these are executed as if they were inline.
includeFile "commonapi.vbi"
includeFile "dbcalls.vbi"
It basically opens the file, reads the entire contents into a string, then executes that string. There's no error handling on the I/O calls since this sort of stuff is usually done once on program start, and you want to fail if there's a problem including it.
Note that the includeFile function can be compressed to:
Sub includeFile(fSpec)
With CreateObject("Scripting.FileSystemObject")
executeGlobal .openTextFile(fSpec).readAll()
End With
End Sub
Or even to (if you're not adverse to long lines):
Sub includeFile(fSpec)
executeGlobal CreateObject("Scripting.FileSystemObject").openTextFile(fSpec).readAll()
End Sub
The "Windows Script Host" framework (if ya want to call it that), offers an XML wrapper document that adds functionality over regular vbs files. One of which is the ability to include external script files of both the VBscript and Jscript flavors. I never got very deep into it, but I think it would do what you're wanting to do.
http://msdn.microsoft.com/en-us/library/15x4407c(VS.85).aspx
You can include JavaScript, VBScript, or modules of other WScript script languages.
Example WSF file:
<job id="IncludeExample">
<script language="JavaScript" src="sprintf.js"/>
<script language="VBScript" src="logging.vbs"/>
<script language="VBScript" src="iis-queryScriptMaps.vbs"/>
</job>
If the above file is called "iis-scriptmaps.wsf", run it this way with cscript.exe:
cscript.exe iis-scriptmaps.wsf
I know this is an old thread but I post my answer anyway so others can learn what I have learnt about VBS and WSF files by "trial and error" :
So to have the same functionality as in other languages you can create one WSF file and include all of your VBS libs there, including the main program.
Something like this :
<job id="MainProg">
<script language="VBScript" src="Constants.vbs"/>
<script language="VBScript" src="FileFunctions.vbs"/>
<script language="VBScript" src="SendMail.vbs"/>
<script language="VBScript" src="LoggingFunctions.vbs"/>
<script language="VBScript" src="MainProgram.vbs"/>
<script language="VBScript">
' Here we call the main program
MainProgram()
</script>
</job>
In Constants.vbs collect all constants you want to use later and in the other VBS files define your functions. In your main program file MainProgram.vbs, create a sub called MainProgram() and write your program there.
In this subroutine, you can use all of the constants and functions defined in the other VBS files.
For example :
sub MainProgram()
' Local variables
Dim strMessage, strSendTo, strSubject
' OpenFile is a function from FileFunctions.vbs
strMessage = OpenFile("C:\Msg\message.html")
strSendTo = "email.address#yourdomain.com"
strSubject = "Daily report - " & date
' SendMessage is a function from SendMail.vbs
' cFrom and cServer are constants from Constants.vbs
SendMessage(cFrom, strSendTo, strSubject, strMessage, cServer)
' Logger is a function from LoggingFunctions.vbs
Logger("Daily report sent - " & now())
end sub
Hope you get the idea and I could help some people write better VBS apps :)
Building on the accepted answer, here's an include sub procedure which takes a path relative to the script location instead of the working directory:
Sub include( relativeFilePath )
Set fso = CreateObject("Scripting.FileSystemObject")
thisFolder = fso.GetParentFolderName( WScript.ScriptFullName )
absFilePath = fso.BuildPath( thisFolder, relativeFilePath )
executeGlobal fso.openTextFile( absFilePath ).readAll()
End Sub
Note the you can additionally use . and .. parts in your path to include files in parent folders, etc. and it will not matter where you launch the script from. Example:
include "..\Lib\StringUtilities.vbs"
Is this VBScript being used locally, or served classic ASP style?
If its classic ASP, you can use SSI todo it:
<!-- #include virtual="/PathTo/MyFile.vbs" -->
You can use the ExecuteGlobal function to run arbitrary VBS code in the global namespace. An example can be found here : http://www.source-code.biz/snippets/vbscript/5.htm
IIS 5 and up also allow a script tag for including other files from an ASP file. (Is your VBScript an ASP page or a Windows script?) Here's an example:
<script language="VBScript" runat="server" src="include.asp"></script>
The behavior and rules are a bit different from server-side includes. Note: I have never actually tried using this syntax from classic ASP.
you can definately use the WSF script tag in cscript:
<script language="VBScript" src="ADOVBS.INC"/>
If you use ADOVBS.inc for an ADODB access make sure to remove the
<% %>
tags from ADOVBS.INC.

Embed a bash shell script in an AppleScriptObjC application with Xcode

I have attempted to follow the instructions on this post but I am falling short of understanding how some of the posters instructions work.
I want to be able to package the app with a prewritten bash script and then execute it, but don't follow from Step 4 onwards.
Post writes:
4. Also in your AppleScriptObjC script, add the following where appropriate:
property pathToResources : "NSString" -- works if added before script command
5. Where appropriate, also add the following in your AppleScriptObjC script:
set yourScript to pathToResources & "/yourScriptFile.sh"
-- gives the complete unix path
-- if needed, you can convert this to the Apple style path:
set yourScriptPath to (((yourScript as text) as POSIX file) as alias)`
6. As an aside, you could then open the file for read using
tell application "Finder"
open yourScriptPath
end tell
Questions:
Where do I add the line:
property pathToResources : "NSString"
Do I add which of the following, and where?
set yourScript to pathToResources & "/yourScriptFile.sh"
OR
set yourScriptPath to (((yourScript as text) as POSIX file) as alias)
How is it possible to execute the script itself? The mention As an aside, you could then open the file for read using only covers the Apple style path, it does not cover using the aforementioned style.
Can anyone shed a bit more light on this for me, or post a static copy of a AppDelegate.applescript file that shows how the original poster required the base code to be used? I have tried his method and looked across the internet for the past 3 weeks to no avail. I don't want to have to convert all my code for specific tools from bash scripts into AppleScript, as this would take a lot of work.
I only need to know how to reference to the script file (for example myBashScript.sh) in my app, which would reside in the application and be included by Xcode at time of compilation.
I think you should use the command path to resource <specifiedResource>.
See Standard Additions, path to resource.
You could set it by set myVariableName to path to resource "myBashScript.sh" or just use the command instead of your property so it points always to the right place (a user could move your app while running... lol).
ADDITION:
I did it that way in my AppleScript-Application:
on run_scriptfile(this_scriptfile)
try
set the script_file to path to resource this_scriptfile
return (run script script_file)
end try
return false
end run_scriptfile
Whenever I want to run a script that is bundled within my app I do this:
if my run_scriptfile("TestScript.scpt") is false then error number -128
run_scriptfile(this_scriptfile) returns true when everything worked.
I ended up bringing all the information together and now have a solution.
This takes into consideration the following facts:
firstScript = variable name that points to a script called scriptNumberOne.sh
scriptNumberOne.sh = the script that I have embedded into my application to run
ButtonHandlerRunScript_ = the name of the Received Action in Xcode
pathToResources = variable that points to the internal Resources folder of my application, regardless of it's current location
Using this information, below is a copy of a vanilla AppDelegate.applescript in my AppleScriptObjC Xcode project:
script AppDelegate
property parent : class "NSObject"
property pathToResources : "NSString"
on applicationWillFinishLaunching_(aNotification)
set pathToResources to (current application's class "NSBundle"'s mainBundle()'s resourcePath()) as string
end applicationWillFinishLaunching_
on ButtonHandlerRunScript_(sender)
set firstScript to pathToResources & "/scriptNumberOne.sh"
do shell script firstScript
end ButtonHandlerRunScript_
on applicationShouldTerminate_(sender)
-- Insert code here to do any housekeeping before your application quits
return current application's NSTerminateNow
end applicationShouldTerminate_
end script

IsFile, IsDirectory Test Windows

I'm trying to convert a program from Linux to use on Windows, and it calls test -f, or test -d on Linux. I need it to do the same thing on Windows. Is there a built-in command, or another program I can use to do the same thing?
I'm programming using FreeBASIC (horrible, but it's what I got).
EDIT: An external program is the best option here. I've looked at the API, and it's not good.
Never heard of FreeBasic before but looking at the help there's a DIR command that supports using fbDirectory as one of the attribute patterns to filter for.
And looking slightly further down on that page I just saw that they have a sample for checking if the objects found are files or directories. Just look here, look at the second example on that page.
Not sure what exactly those test commands do, but if you want to test if a specific object is a directory you should be able to call Dir("exactname", fbDirectory, something) I'd thought. And then you could test for a file by putting a Not in somewhere (assuming that FreeBasic supports that).
Edit: To make your own tool, here's a sample that shows a tiny C++ app that could easily be changed to look for directories or not. Look for the FindFirstFile in the sample and shortly after that it checks if it's readonly, which could be changed for FILE_ATTRIBUTE_DIRECTORY.
http://unxutils.sourceforge.net/
you can use test.exe just like under linux
Not sure about FreeBASIC, have you looked into vbscript? You could use the FileSystemObject
Dim fso, msg
Set fso = CreateObject("Scripting.FileSystemObject")
If (fso.FolderExists(fldr)) Then
'Do Something here
Else
'Do Something
End If
If (fso.FileExists(filespec)) Then
'Do Something here
Else
'Do Something
End If
You can also use Kiwi for FreeBasic in order to check if a path leads to a file or directory. You can find Kiwi on Github (https://github.com/nsiatras/kiwi)
#include once "kiwi\kiwi.bi"
#include once "kiwi\io.bi"
' Declare a new file
Dim myFile as File = File("C:\Users\nsiat\Desktop\Test.txt")
' Check if file exists, is a File or is a Directory
print "File exists: " & myFile.exists()
print "Is file: " & myFile.isFile()
print "Is Directory: " & myFile.isDirectory()

How do I include a common file in VBScript (similar to C #include)?

VBScript doesn't appear to have a way to include a common file of functions.
Is there a way to achieve this?
You can create a (relatively) small function in each file that you want to include other files into, as follows:
sub includeFile (fSpec)
dim fileSys, file, fileData
set fileSys = createObject ("Scripting.FileSystemObject")
set file = fileSys.openTextFile (fSpec)
fileData = file.readAll ()
file.close
executeGlobal fileData
set file = nothing
set fileSys = nothing
end sub
and then use it to include specific files - these are executed as if they were inline.
includeFile "commonapi.vbi"
includeFile "dbcalls.vbi"
It basically opens the file, reads the entire contents into a string, then executes that string. There's no error handling on the I/O calls since this sort of stuff is usually done once on program start, and you want to fail if there's a problem including it.
Note that the includeFile function can be compressed to:
Sub includeFile(fSpec)
With CreateObject("Scripting.FileSystemObject")
executeGlobal .openTextFile(fSpec).readAll()
End With
End Sub
Or even to (if you're not adverse to long lines):
Sub includeFile(fSpec)
executeGlobal CreateObject("Scripting.FileSystemObject").openTextFile(fSpec).readAll()
End Sub
The "Windows Script Host" framework (if ya want to call it that), offers an XML wrapper document that adds functionality over regular vbs files. One of which is the ability to include external script files of both the VBscript and Jscript flavors. I never got very deep into it, but I think it would do what you're wanting to do.
http://msdn.microsoft.com/en-us/library/15x4407c(VS.85).aspx
You can include JavaScript, VBScript, or modules of other WScript script languages.
Example WSF file:
<job id="IncludeExample">
<script language="JavaScript" src="sprintf.js"/>
<script language="VBScript" src="logging.vbs"/>
<script language="VBScript" src="iis-queryScriptMaps.vbs"/>
</job>
If the above file is called "iis-scriptmaps.wsf", run it this way with cscript.exe:
cscript.exe iis-scriptmaps.wsf
I know this is an old thread but I post my answer anyway so others can learn what I have learnt about VBS and WSF files by "trial and error" :
So to have the same functionality as in other languages you can create one WSF file and include all of your VBS libs there, including the main program.
Something like this :
<job id="MainProg">
<script language="VBScript" src="Constants.vbs"/>
<script language="VBScript" src="FileFunctions.vbs"/>
<script language="VBScript" src="SendMail.vbs"/>
<script language="VBScript" src="LoggingFunctions.vbs"/>
<script language="VBScript" src="MainProgram.vbs"/>
<script language="VBScript">
' Here we call the main program
MainProgram()
</script>
</job>
In Constants.vbs collect all constants you want to use later and in the other VBS files define your functions. In your main program file MainProgram.vbs, create a sub called MainProgram() and write your program there.
In this subroutine, you can use all of the constants and functions defined in the other VBS files.
For example :
sub MainProgram()
' Local variables
Dim strMessage, strSendTo, strSubject
' OpenFile is a function from FileFunctions.vbs
strMessage = OpenFile("C:\Msg\message.html")
strSendTo = "email.address#yourdomain.com"
strSubject = "Daily report - " & date
' SendMessage is a function from SendMail.vbs
' cFrom and cServer are constants from Constants.vbs
SendMessage(cFrom, strSendTo, strSubject, strMessage, cServer)
' Logger is a function from LoggingFunctions.vbs
Logger("Daily report sent - " & now())
end sub
Hope you get the idea and I could help some people write better VBS apps :)
Building on the accepted answer, here's an include sub procedure which takes a path relative to the script location instead of the working directory:
Sub include( relativeFilePath )
Set fso = CreateObject("Scripting.FileSystemObject")
thisFolder = fso.GetParentFolderName( WScript.ScriptFullName )
absFilePath = fso.BuildPath( thisFolder, relativeFilePath )
executeGlobal fso.openTextFile( absFilePath ).readAll()
End Sub
Note the you can additionally use . and .. parts in your path to include files in parent folders, etc. and it will not matter where you launch the script from. Example:
include "..\Lib\StringUtilities.vbs"
Is this VBScript being used locally, or served classic ASP style?
If its classic ASP, you can use SSI todo it:
<!-- #include virtual="/PathTo/MyFile.vbs" -->
You can use the ExecuteGlobal function to run arbitrary VBS code in the global namespace. An example can be found here : http://www.source-code.biz/snippets/vbscript/5.htm
IIS 5 and up also allow a script tag for including other files from an ASP file. (Is your VBScript an ASP page or a Windows script?) Here's an example:
<script language="VBScript" runat="server" src="include.asp"></script>
The behavior and rules are a bit different from server-side includes. Note: I have never actually tried using this syntax from classic ASP.
you can definately use the WSF script tag in cscript:
<script language="VBScript" src="ADOVBS.INC"/>
If you use ADOVBS.inc for an ADODB access make sure to remove the
<% %>
tags from ADOVBS.INC.

Any good PowerShell MSBuild tasks?

Anyone know of any good MSBuild tasks that will execute a PowerShell script and pass it different parameters?
I was able to find B# .NET Blog: Invoking PowerShell scripts from MSBuild, but I'm hoping for something that is a little more polished.
If I can't find anything I will of course just go ahead and polish my own using that blog post as a starter.
One could use http://powershellmsbuild.codeplex.com/ for 3.5. It'd be nice if there was a NuGet package for it that one could leverage via NuGet package restore.
4.0 has a Windows Powershell Task Factory which you can get in the code gallery has been rolled into
MSBuild Extension Pack (one of the top task libraries - 400+ Tasks & recommended in Inside MSBuild) has PowerShellTaskFactory (download the help file from the download section of this example release to have a peek).
You might also want to look at Psake - a PowerShell based build environment.
Duplicate Question and Answer I Posted, here for posterity for when it has been vote to closed. The key difference is that this question was constrained to being OOTB and my self-answer stays within that constraint.
Question
Powershell doesn't seem to have an easy way to trigger it with an arbitrary command and then bubble up parse and execution errors in a way that correctly interoperates with callers that are not PowerShell - e.g., cmd.exe, TeamCity etc.
My question is simple. What's the best way for me with OOTB MSBuild v4 and PowerShell v3 (open to suggestions-wouldnt rule out a suitably production ready MSBuild Task, but it would need to be a bit stronger than suggesting "it's easy - taking the PowerShell Task Factory sample and tweak it and/or becoming it's maintainer/parent") to run a command (either a small script segment, or (most commonly) an invocation of a .ps1 script.
I'm thinking it should be something normal like:
<Exec
IgnoreStandardErrorWarningFormat="true"
Command="PowerShell "$(ThingToDo)"" />
That sadly doesn't work:-
if ThingToDo fails to parse, it fails silently
if ThingToDo is a script invocation that doesn't exist, it fails
if you want to propagate an ERRORLEVEL based .cmd result, it gets hairy
if you want to embed " quotes in the ThingToDo, it won't work
So, what is the bullet proof way of running PowerShell from MSBuild supposed to be? Is there something I can PsGet to make everything OK?
Answer
Weeeeelll, you could use something long winded like this until you find a better way:-
<PropertyGroup>
<__PsInvokeCommand>powershell "Invoke-Command</__PsInvokeCommand>
<__BlockBegin>-ScriptBlock { $errorActionPreference='Stop';</__BlockBegin>
<__BlockEnd>; exit $LASTEXITCODE }</__BlockEnd>
<_PsCmdStart>$(__PsInvokeCommand) $(__BlockBegin)</_PsCmdStart>
<_PsCmdEnd>$(__BlockEnd)"</_PsCmdEnd>
</PropertyGroup>
And then 'all' you need to do is:
<Exec
IgnoreStandardErrorWarningFormat="true"
Command="$(_PsCmdStart)$(ThingToDo)$(_PsCmdEnd)" />
The single redeeming feature of this (other than trapping all error types I could think of), is that it works OOTB with any PowerShell version and any MSBuild version.
I'll get my coat.
With a bit of fun, I managed to come up with a fairly clean way of making this work:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- #1 Place this line at the top of any msbuild script (ie, csproj, etc) -->
<PropertyGroup><PowerShell># 2>nul || type %~df0|find /v "setlocal"|find /v "errorlevel"|powershell.exe -noninteractive -& exit %errorlevel% || #</PowerShell></PropertyGroup>
<!-- #2 in any target you want to run a script -->
<Target Name="default" >
<PropertyGroup> <!-- #3 prefix your powershell script with the $(PowerShell) variable, then code as normal! -->
<myscript>$(PowerShell)
#
# powershell script can do whatever you need.
#
dir ".\*.cs" -recurse |% {
write-host Examining file named: $_.FullName
# do other stuff here...
}
$answer = 2+5
write-host Answer is $answer !
</myscript>
</PropertyGroup>
<!-- #4 and execute the script like this -->
<Exec Command="$(myscript)" EchoOff="true" />
</Target>
</Project>
Notes:
You can still use the standard Exec Task features! (see: https://msdn.microsoft.com/en-us/library/x8zx72cd.aspx)
if your powershell script needs to use < > or & characters, just place the contents in a CDATA wrapper:
<script2><![CDATA[ $(PowerShell)
# your powershell code goes here!
write-host "<<Hi mom!>>"
]]></script2>
if you want return items to the msbuild script you can get them:
<script3>$(PowerShell)
# your powershell code goes here!
(dir "*.cs" -recurse).FullName
</script3>
<Exec Command="$(script3)" EchoOff="true" ConsoleToMSBuild="true">
<Output TaskParameter="ConsoleOutput" PropertyName="items" />
</Exec>
<Touch Files="$(items)" />
See! then you can use those items with another msbuild Task :D

Resources