Lotus Notes - lotusscript: shell function: illegal function call - shell

I have a problem: I want to run a file from lotusscript code:
Dim result As Integer
result = Shell("D:\testF.dsx", 1)
And I get the following error: Illegal function call.
If I want to execute it from formula it works:
#Command([Execute]; "D:\\testF.dsx")
Thanks a lot!

I had the same problem with the shell function in lotus script with PDF files. And my workaround is to use the windows scripting host to launch the file. I am pretty sure this will solve your problem too.
Set objShell = CreateObject("WScript.Shell")
returnValue = objShell.Run("d:\testF.dsx", 3, false)enter code here

It is not possible to "Execute" a Textfile. usually there is no "run" function defined for dsx- files.
You could do it like:
Dim result as Integer
result = Shell("notepad.exe D:\testF.dsx", 1)
Or find out, which program is linked to dsx (via registry) and execute the corresponding exe with filename as Parameter. If the filename contains spaces, then it has to be enclosed:
Dim result as Integer
result = Shell({notepad.exe "D:\testF.dsx"}, 1)
And reading your last question this approach for sure is NOT the right for your request. You have to use "open" in order to process files... Like Per Hendrik told you in his response.

I had similar problems passing parameters to Outlook.
On some windows machines, this #Formula worked perfectly:
#Command([Execute]; "Outlook.exe"; "/recycle")
On Windows Terminal Servers, it caused Outlook to be unable to parse the "/recycle"
The Shell-command from LotusScript wasn't even able to locate the Outlook.exe, as it was not in the PATH.
Ralf's code helped me in this respect. The "WScript.Shell" seems able to interact with Windows registry settings. Anyway, here is the code that works for activating an open Outlook window.
Dim objShell, returnValue
Set objShell = CreateObject("WScript.Shell")
returnValue = objShell.Run("outlook.exe /recycle", 3, False)

Related

VBScript passing value by reference (VarPtr) to ActiveX function

I'm trying this:
Dim oApp
Dim iReturnedResult
Set oApp = CreateObject("Some.Application")
Set F_Ord = oApp.Documents.Open("Window 1", VarPtr(iReturnedResult))
The ActiveX control expects the second parameter to be a Long by reference.
This works perfectly well inside Excel VBA.
I can run this step by step, and see the result is returned like it should.
But, when I move this code to a VBS file and run it from the command line (CScript.exe), I get an error 800A000D, meaning it's the wrong type.
I have also tried creating an array instead, and tested with these commands, without any luck:
Set F_Ord = oApp.Documents.Open("Window 1", VarPtr(iReturnedResult(0)))
Set F_Ord = oApp.Documents.Open("Window 1", iReturnedResult(0))
Does anyone know how to pass a long variable by reference to an ActiveX control from VBScript?
The simple answer is VarPtr() is not supported by VBScript.
To my knowledge, there is no equivalent that allows you to pass a pointer to a variables memory address.
Useful Links
Visual Basic for Applications Features Not In VBScript

SAS Enterprise Guide with VBScript. Looping through SAS programs get stuck

I'm facing a random problem. When executing SAS programs with VBScript and the SASEGObjectModel.Application.7.1, looping through CodeCollection get stuck sometimes, even if the program execution was succeeded (the final data bases are correctly created in our server). The script simple doesn't go to the next program of CodeCollection (the prompt executing the script still open... ad infinitum). The SAS program It happens is random, also the frequency. I'm going with something like this:
Dim oSasApp
Set oSasApp = CreateObject("SASEGObjectModel.Application.7.1")
oSasApp.SetActiveProfile("some-profile")
Dim oSasProj
Set oSasProj = oSasApp.Open("some-project.egp", "")
Dim oProgramList
Set oProgramList = oSasProj.CodeCollection
Dim programOrder
Set programOrder = ...here I assign the SAS programs order array reading from a .txt...
For Each program in programOrder
For Each sasProgram in oProgramList
If sasProgram.Name = program Then
sasProgram.Run
sasProgram.Log.SaveAs "some-folder/" & sasProgram.Name & ".txt"
End If
Next
Next
oSasProj.Close
oSasApp.Quit
The problem is not the Log saving, as the log txt file of the stucked program is also correctly created.
Any idea? Maybe problems in our SAS server? Should I declare some kind of options?
SAS Guide version: 7.15
Windows: 10
Tks
So... for people facing the same problem. As I commented above, if I press enter on prompt the script flows again. So it is waiting for my input, for reasons I can't tell. I did 2 things to get around it. Not sure if all of them are necessary or if only one solves it, but here it goes:
First, by VBScript I turned off a list of generations and I applied a delay after the SAS program runs:
For Each program in programOrder
For Each sasProgram i oProgramList
If sasProgram.Name = program Then
sasProgram.GenSasReport = False
sasProgram.GenHTML = False
sasProgram.GenListing = False
sasProgram.GenPDF = False
sasProgram.GenRTF = False
sasProgram.Run
WScript.Sleep(2000)
sasProgram.Log.SaveAs "some-folder/" & sasProgram.Name & ".txt"
End If
Next
Next
Them, in my batch file, wich I use to call the VBScript with the "cscript" command, I set it to apply "y" to every single message the VBScript could ask:
cd ./script-folder
echo y | cscript script-file-name.vbs
And that is it.

Need Assistance with VBSCRIPT to capture screenshots of user's desktop

I am a novice when it comes to object oriented program. That said, I have been trying to construct a vbscript that will capture a screenshot of the desktop and immediately save it to a folder I specify. Here is the code I have so far:
' START
Dim screenSize
screenSize = New screenSize.Size(Screen.PrimaryScreen.Bounds.X,Screen.PrimaryScreen.Bounds.Y)
Dim screenGrab
screenGrab = New screenGrab.Bitmap(My.Computer.Screen.Bounds.Width, my.Computer.Screen.Bounds.Height)
Dim g
g = g.System.Drawing.Graphics.FromImage(screenGrab)
dim copyS
copyS = Graphics.CopyPixels4.PaintEventArgs
dim copyS2
copyS2 = copyS.Graphics.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation)
dim saveTo
saveTo = screenGrab.Save("C:\temp\screenGrab.bmp")
' END
I prefer to keep this in VBSCRIPT as this script will be incorporated into an existing vbscript I created. I currently get an error at line 3 stating "class not defined 'screensize". I am also concerned that even if I fix the error at line 3 I may run into other syntax issues afterward. The overall intent of the script is to 1) get the screen dimensons ; 2) perform the screenshot ; 3) and save the file to a destination. I am open to any suggestions to make this work.
I appreciate any help I can get at this point. Thank you.
It seems like you have messed VB.NET with VBScript.
screenSize, screenGrab, System.Drawing.Graphics - there are no such classes in VBScript by default.
What I'd suggest is to use some screen capture ActiveX (google it).
Or create your own ActiveX with VB6 by using code like this. Create new ActiveX project in VB6, add that module and compile.
And remember to run regsvr32.exe youractivex.ocx before using it in your script.

How to set "Run as administrator" flag on shortcut created by MSI installer

I have a Setup and Deployment project in Visual Studio 2010.
I would like the installer to create two shortcuts to the executable of another project in my solution. One normal shortcut that simply runs the application using current credentials and another which has the Run as administrator flag set, thereby ensuring that the user is asked for credentials with administrative rights when clicking the shortcut.
Running the application with administrative rights enables certain features that are otherwise not available.
Setting this flag doesn't seem to be possible at first glance. Can this be done directly in Visual Studio? If not, are there any other options?
Edit: If not, is it possible to modify the shortcut programmatically using a custom installer class?
I know this is quite an old question, but I needed to find an answer and I thought I could help other searchers. I wrote a small function to perform this task in VBScript (pasted below). It is easily adapted to VB.net / VB6.
Return codes from function:
0 - success, changed the shortcut.
99 - shortcut flag already set to run as administrator.
114017 - file not found
114038 - Data file format not valid (specifically the file is way too small)
All other non-zero = unexpected errors.
As mentioned by Chada in a later post, this script will not work on msi Advertised shortcuts. If you use this method to manipulate the bits in the shortcut, it must be a standard, non-advertised shortcut.
References:
MS Shortcut LNK format: http://msdn.microsoft.com/en-us/library/dd871305
Some inspiration: Read and write binary file in VBscript
Please note that the function does not check for a valid LNK shortcut. In fact you can feed it ANY file and it will alter Hex byte 15h in the file to set bit 32 to on.
If copies the original shortcut to %TEMP% before amending it.
Daz.
'# D.Collins - 12:58 03/09/2012
'# Sets a shortcut to have the RunAs flag set. Drag an LNK file onto this script to test
Option Explicit
Dim oArgs, ret
Set oArgs = WScript.Arguments
If oArgs.Count > 0 Then
ret = fSetRunAsOnLNK(oArgs(0))
MsgBox "Done, return = " & ret
Else
MsgBox "No Args"
End If
Function fSetRunAsOnLNK(sInputLNK)
Dim fso, wshShell, oFile, iSize, aInput(), ts, i
Set fso = CreateObject("Scripting.FileSystemObject")
Set wshShell = CreateObject("WScript.Shell")
If Not fso.FileExists(sInputLNK) Then fSetRunAsOnLNK = 114017 : Exit Function
Set oFile = fso.GetFile(sInputLNK)
iSize = oFile.Size
ReDim aInput(iSize)
Set ts = oFile.OpenAsTextStream()
i = 0
Do While Not ts.AtEndOfStream
aInput(i) = ts.Read(1)
i = i + 1
Loop
ts.Close
If UBound(aInput) < 50 Then fSetRunAsOnLNK = 114038 : Exit Function
If (Asc(aInput(21)) And 32) = 0 Then
aInput(21) = Chr(Asc(aInput(21)) + 32)
Else
fSetRunAsOnLNK = 99 : Exit Function
End If
fso.CopyFile sInputLNK, wshShell.ExpandEnvironmentStrings("%temp%\" & oFile.Name & "." & Hour(Now()) & "-" & Minute(Now()) & "-" & Second(Now()))
On Error Resume Next
Set ts = fso.CreateTextFile(sInputLNK, True)
If Err.Number <> 0 Then fSetRunAsOnLNK = Err.number : Exit Function
ts.Write(Join(aInput, ""))
If Err.Number <> 0 Then fSetRunAsOnLNK = Err.number : Exit Function
ts.Close
fSetRunAsOnLNK = 0
End Function
This is largely due to the fact that Windows Installer uses 'Advertised shortcuts' for the Windows Installer packages.
There is no way inherently to disable this in Visual Studio, but it is possible to modify the MSI that is produced to make sure that it does not use advertised shortcuts (or uses only one). There are 2 ways of going about this:
If your application uses a single exe or two - Use ORCA to edit the MSI. Under the shortcuts table, change the Target Entry to "[TARGETDIR]\MyExeName.exe" - where MyExeName is the name of your exe - this ensures that that particular shortcut is not advertised.
Add DISABLEADVTSHORTCUTS=1 to the the property Table of the MSI using ORCA or a post build event (using the WiRunSQL.vbs script). If you need more info on this let me know. This disables all advertised shortcuts.
it may be better to use the first approach, create 2 shortcuts and modify only one in ORCA so that you can right click and run as admin.
Hope this helps
This is not supported by Windows Installer. Elevation is usually handled by the application through its manifest.
A solution is to create a wrapper (VBScript or EXE) which uses ShellExecute with runas verb to launch your application as an Administrator. Your shortcut can then point to this wrapper instead of the actual application.
Sorry for the confusion - I now understand what you are after.
There are indeed ways to set the shortcut flag but none that I know of straight in Visual Studio. I have found a number of functions written in C++ that set the SLDF_RUNAS_USER flag on a shortcut.
Some links to such functions include:
http://blogs.msdn.com/b/oldnewthing/archive/2007/12/19/6801084.aspx
http://social.msdn.microsoft.com/Forums/en-US/windowssecurity/thread/a55aa70e-ae4d-4bf6-b179-2e3df3668989/
Another interesting discussion on the same topic was carried out at NSIS forums, the thread may be of help. There is a function listed that can be built as well as mention of a registry location which stores such shortcut settings (this seems to be the easiest way to go, if it works) - I am unable to test the registry method at the moment, but can do a bit later to see if it works.
This thread can be found here: http://forums.winamp.com/showthread.php?t=278764
If you are quite keen to do this programatically, then maybe you could adapt one of the functions above to be run as a post-install task? This would set the flag of the shortcut after your install but this once again needs to be done on Non-Advertised shortcuts so the MSI would have to be fixed as I mentioned earlier.
I'll keep looking and test out the registry setting method to see if it works and report back.
Chada
I needed to make my application to be prompted for Administator's Rights when running from Start Menu or Program Files.
I achieved this behavior after setting in \bin\Debug\my_app.exe 'Run this program as administator' checkbox to true. ( located in Properties\Compatibility section ).
While installing project, this file was copied to the Program Files (and therefore the shortcut in the Start Menu) with needed behavior.
Thanks,
Pavlo

Why doesn't 'shell' work in VBscript in VS6?

In a macro for Visual Studio 6, I wanted to run an external program, so I typed:
shell("p4 open " + ActiveDocument.FullName)
Which gave me a type mismatch runtime error. What I ended up having to type was this:
Dim wshShell
Set wshShell = CreateObject("WScript.Shell")
strResult = wshShell.Run("p4 open " + ActiveDocument.FullName)
What is going on here? Is that nonsense really necessary or have I missed something?
As lassevk pointed out, VBScript is not Visual Basic.
I believe the only built in object in VBScript is the WScript object.
WScript.Echo "Hello, World!"
From the docs
The WScript object is the root object of the Windows Script Host
object model hierarchy. It never needs to be instantiated before invoking its
properties and methods, and it is always available from any script file.
Everything else must be created via the CreateObject call. Some of those objects are listed here.
The Shell object is one of the other objects that you need to create if you want to call methods on it.
One caveat, is that RegExp is sort of built in, in that you can instantiate a RegExp object like so in VBScript:
Dim r as New RegExp
VBScript isn't Visual Basic.
Give this a try:
Shell "p4 open" & ActiveDocument.FullName
VB6 uses & to concatenate strings rather than +, and you'll want to make sure the file name is encased in quotes in case of spaces. Try it like this:
Shell "p4 open """ & ActiveDocument.FullName & """"

Resources