I have seen mentions in other places to a -regserver argument to cscript or wscript - but can't find any info that precisely defines what this option does or really clarifies when you'd want/need to use it.
Even the built-in help does not mention it:
λ cscript /?
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.
Usage: CScript scriptname.extension [option...] [arguments...]
Options:
//B Batch mode: Suppresses script errors and prompts from displaying
//D Enable Active Debugging
//E:engine Use engine for executing script
//H:CScript Changes the default script host to CScript.exe
//H:WScript Changes the default script host to WScript.exe (default)
//I Interactive mode (default, opposite of //B)
//Job:xxxx Execute a WSF job
//Logo Display logo (default)
//Nologo Prevent logo display: No banner will be shown at execution time
//S Save current command line options for this user
//T:nn Time out in seconds: Maximum time a script is permitted to run
//X Execute script in debugger
//U Use Unicode for redirected I/O from the console
and nor does Microsoft's documentation.
Note - I gather from some of the external articles I linked to that this option can be used to recover from some bugs in Windows XP and maybe also Vista. But that doesn't actually explain what this option DOES or why it exists. I don't think Microsoft added it after the fact as a FIX, but rather people could take advantage of it to address whatever those problems were in XP/Vista.
EDIT: Just because two questions have same/similar answers does not make them duplicates. The same information can answer multiple different questions. The question referred to as a potential duplicate doesn't have anything to do with the scripting executables. The value of THIS question is that someone using those tools can actually search and find an answer. They will not readily find the other one (as I did not when extensively searching/Googling before I posted this).
These are not actually unique arguments to cscript or wscript; rather they are standard arguments in Windows to any EXE which can act as a COM server.
See this related question for more details of how they operate: https://superuser.com/questions/1164298/what-actually-happens-during-regserver-unregserver
This is at least partly documented here:
If the server is packaged in an EXE module, the application wishing to
register the server launches the EXE server with the command-line
argument /RegServer or -RegServer (case-insensitive). If the
application wishes to unregister the server, it launches the EXE with
the command-line argument /UnregServer or -UnregServer.
The
self-registering EXE detects these command-line arguments and invokes
the same operations as a DLL would within DllRegisterServer and
DllUnregisterServer, respectively, registering its module path under
LocalServer32 instead of InprocServer32 or InprocHandler32.
Related
I am a beginner in VBScript. I googled it & got to know that we can run VBScript from command line by executing below command:
For Example my vbscript name is Converter.vbs & it's present in folder D:\VBS.
I can run it through following methods:
CScript "D:\VBS\Converter.vbs"
OR
WScript "D:\VBS\Converter.vbs"
Now I would like to execute above VBScript without Cscript or Wscript command by simply typing the name of VBscript name i.e. Converter.
I DON'T WANT TO SPECIFY THE FULL PATH OF VBSCRIPT EVERYTIME.
Can anyone please guide me on how to do that ?
I'll break this down in to several distinct parts, as each part can be done individually. (I see the similar answer, but I'm going to give a more detailed explanation here..)
First part, in order to avoid typing "CScript" (or "WScript"), you need to tell Windows how to launch a * .vbs script file. In My Windows 8 (I cannot be sure all these commands work exactly as shown here in older Windows, but the process is the same, even if you have to change the commands slightly), launch a console window (aka "command prompt", or aka [incorrectly] "dos prompt") and type "assoc .vbs". That should result in a response such as:
C:\Windows\System32>assoc .vbs
.vbs=VBSFile
Using that, you then type "ftype VBSFile", which should result in a response of:
C:\Windows\System32>ftype VBSFile
vbsfile="%SystemRoot%\System32\WScript.exe" "%1" %*
-OR-
C:\Windows\System32>ftype VBSFile
vbsfile="%SystemRoot%\System32\CScript.exe" "%1" %*
If these two are already defined as above, your Windows' is already set up to know how to launch a * .vbs file. (BTW, WScript and CScript are the same program, using different names. WScript launches the script as if it were a GUI program, and CScript launches it as if it were a command line program. See other sites and/or documentation for these details and caveats.)
If either of the commands did not respond as above (or similar responses, if the file type reported by assoc and/or the command executed as reported by ftype have different names or locations), you can enter them yourself:
C:\Windows\System32>assoc .vbs=VBSFile
-and/or-
C:\Windows\System32>ftype vbsfile="%SystemRoot%\System32\WScript.exe" "%1" %*
You can also type "help assoc" or "help ftype" for additional information on these commands, which are often handy when you want to automatically run certain programs by simply typing a filename with a specific extension. (Be careful though, as some file extensions are specially set up by Windows or programs you may have installed so they operate correctly. Always check the currently assigned values reported by assoc/ftype and save them in a text file somewhere in case you have to restore them.)
Second part, avoiding typing the file extension when typing the command from the console window.. Understanding how Windows (and the CMD.EXE program) finds commands you type is useful for this (and the next) part. When you type a command, let's use "querty" as an example command, the system will first try to find the command in it's internal list of commands (via settings in the Windows' registry for the system itself, or programmed in in the case of CMD.EXE). Since there is no such command, it will then try to find the command in the current %PATH% environment variable. In older versions of DOS/Windows, CMD.EXE (and/or COMMAND.COM) would automatically add the file extensions ".bat", ".exe", ".com" and possibly ".cmd" to the command name you typed, unless you explicitly typed an extension (such as "querty.bat" to avoid running "querty.exe" by mistake). In more modern Windows, it will try the extensions listed in the %PATHEXT% environment variable. So all you have to do is add .vbs to %PATHEXT%. For example, here's my %PATHEXT%:
C:\Windows\System32>set pathext
PATHEXT=.PLX;.PLW;.PL;.BAT;.CMD;.VBS;.COM;.EXE;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.PY
Notice that the extensions MUST include the ".", are separated by ";", and that .VBS is listed AFTER .CMD, but BEFORE .COM. This means that if the command processor (CMD.EXE) finds more than one match, it'll use the first one listed. That is, if I have query.cmd, querty.vbs and querty.com, it'll use querty.cmd.
Now, if you want to do this all the time without having to keep setting %PATHEXT%, you'll have to modify the system environment. Typing it in a console window only changes it for that console window session. I'll leave this process as an exercise for the reader. :-P
Third part, getting the script to run without always typing the full path. This part, in relation to the second part, has been around since the days of DOS. Simply make sure the file is in one of the directories (folders, for you Windows' folk!) listed in the %PATH% environment variable. My suggestion is to make your own directory to store various files and programs you create or use often from the console window/command prompt (that is, don't worry about doing this for programs you run from the start menu or any other method.. only the console window. Don't mess with programs that are installed by Windows or an automated installer unless you know what you're doing).
Personally, I always create a "C:\sys\bat" directory for batch files, a "C:\sys\bin" directory for * .exe and * .com files (for example, if you download something like "md5sum", a MD5 checksum utility), a "C:\sys\wsh" directory for VBScripts (and JScripts, named "wsh" because both are executed using the "Windows Scripting Host", or "wsh" program), and so on. I then add these to my system %PATH% variable (Control Panel -> Advanced System Settings -> Advanced tab -> Environment Variables button), so Windows can always find them when I type them.
Combining all three parts will result in configuring your Windows system so that anywhere you can type in a command-line command, you can launch your VBScript by just typing it's base file name. You can do the same for just about any file type/extension; As you probably saw in my %PATHEXT% output, my system is set up to run Perl scripts (.PLX;.PLW;.PL) and Python (.PY) scripts as well. (I also put "C:\sys\bat;C:\sys\scripts;C:\sys\wsh;C:\sys\bin" at the front of my %PATH%, and put various batch files, script files, et cetera, in these directories, so Windows can always find them. This is also handy if you want to "override" some commands: Putting the * .bat files first in the path makes the system find them before the * .exe files, for example, and then the * .bat file can launch the actual program by giving the full path to the actual *. exe file. Check out the various sites on "batch file programming" for details and other examples of the power of the command line.. It isn't dead yet!)
One final note: DO check out some of the other sites for various warnings and caveats. This question posed a script named "converter.vbs", which is dangerously close to the command "convert.exe", which is a Windows program to convert your hard drive from a FAT file system to a NTFS file system.. Something that can clobber your hard drive if you make a typing mistake!
On the other hand, using the above techniques you can insulate yourself from such mistakes, too. Using CONVERT.EXE as an example.. Rename it to something like "REAL_CONVERT.EXE", then create a file like "C:\sys\bat\convert.bat" which contains:
#ECHO OFF
ECHO !DANGER! !DANGER! !DANGER! !DANGER, WILL ROBINSON!
ECHO This command will convert your hard drive to NTFS! DO YOU REALLY WANT TO DO THIS?!
ECHO PRESS CONTROL-C TO ABORT, otherwise..
REM "PAUSE" will pause the batch file with the message "Press any key to continue...",
REM and also allow the user to press CONTROL-C which will prompt the user to abort or
REM continue running the batch file.
PAUSE
ECHO Okay, if you're really determined to do this, type this command:
ECHO. %SystemRoot%\SYSTEM32\REAL_CONVERT.EXE
ECHO to run the real CONVERT.EXE program. Have a nice day!
You can also use CHOICE.EXE in modern Windows to make the user type "y" or "n" if they really want to continue, and so on.. Again, the power of batch (and scripting) files!
Here's some links to some good resources on how to use all this power:
http://ss64.com/
http://www.computerhope.com/batch.htm
http://commandwindows.com/batch.htm
http://www.robvanderwoude.com/batchfiles.php
Most of these sites are geared towards batch files, but most of the information in them applies to running any kind of batch (* .bat) file, command (* .cmd) file, and scripting (* .vbs, * .js, * .pl, * .py, and so on) files.
When entering the script's full file spec or its filename on the command line, the shell will use information accessibly by
assoc | grep -i vbs
.vbs=VBSFile
ftype | grep -i vbs
VBSFile=%SystemRoot%\System32\CScript.exe "%1" %*
to decide which program to run for the script. In my case it's cscript.exe, in yours it will be wscript.exe - that explains why your WScript.Echos result in MsgBoxes.
As
cscript /?
Usage: CScript scriptname.extension [option...] [arguments...]
Options:
//B Batch mode: Suppresses script errors and prompts from displaying
//D Enable Active Debugging
//E:engine Use engine for executing script
//H:CScript Changes the default script host to CScript.exe
//H:WScript Changes the default script host to WScript.exe (default)
//I Interactive mode (default, opposite of //B)
//Job:xxxx Execute a WSF job
//Logo Display logo (default)
//Nologo Prevent logo display: No banner will be shown at execution time
//S Save current command line options for this user
//T:nn Time out in seconds: Maximum time a script is permitted to run
//X Execute script in debugger
//U Use Unicode for redirected I/O from the console
shows, you can use //E and //S to permanently switch your default host to cscript.exe.
If you are so lazy that you don't even want to type the extension, make sure that the PATHEXT environment variable
set | grep -i vbs
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.py;.pyw;.tcl;.PSC1
contains .VBS and there is no Converter.cmd (that converts your harddisk into a washing machine) in your path.
Update wrt comment:
If you 'don't want to specify the full path of my vbscript everytime' you may:
put your CONVERTER.VBS in a folder that is included in the PATH environment variable; the shell will then search all pathes - if necessary taking the PATHEXT and the ftype/assoc info into account - for a matching 'executable'.
put a CONVERTER.BAT/.CMD into a path directory that contains a line like cscript p:\ath\to\CONVERTER.VBS
In both cases I would type out the extension to avoid (nasty) surprises.
I am wondering why you cannot put this in a batch file. Example:
cd D:\VBS\
WSCript Converter.vbs
Put the above code in a text file and save the text file with .bat extension. Now you have to simply run this .bat file.
Why don't you just stash the vbscript in a batch/vbscript file hybrid. Name the batch hybrid Converter.bat and you can execute it directly as Converter from the cmd line. Sure you can default ALL scripts to run from Cscript or Wscript, but if you want to execute your vbs as a windows script rather than a console script, this could cause some confusion later on. So just set your code to a batch file and run it directly.
Check the answer -> Here
And here is an example:
Converter.bat
::' VBS/Batch Hybrid
::' --- Batch portion ---------
rem^ &#echo off
rem^ &call :'sub
rem^ &exit /b
:'sub
rem^ &echo begin batch
rem^ &cscript //nologo //e:vbscript "%~f0"
rem^ &echo end batch
rem^ &exit /b
'----- VBS portion -----
Dim tester
tester = "Convert data here"
Msgbox tester
You may follow the following steps:
Open your CMD(Command Prompt)
Type 'D:' and hit Enter. Example: C:\Users\[Your User Name]>D:
Type 'CD VBS' and hit Enter. Example: D:>CD VBS
Type 'Converter.vbs' or 'start Converter.vbs' and hit Enter. Example: D:\VBS>Converter.vbs Or D:\VBS>start Converter.vbs
I am running Windows 7x64 and Excel 2010x32. I call 32bit dos programs (written in Fortran) via vba using ExecCmd (a Microsoft function that waits for a command prompt process to finish). I send a command line to this function that explicitly contains the program path and the paths of the input file and output file.
This runs fine on my PC and also on a company PC running the same software (OS and Office) and for which I have general access to the C: drive.
On other company PCs, where there is not general access to the C: drive, this does not work - i.e. the dos programs do not produce an output file. On these PCs, I can still run the program at the command prompt manually. It is just that calling this command prompt does not work via Excel VBA.
Now the strange thing is that I can successfully run one of these programs by adding "cmd.exe /c" at the beginning of the command line. That would appear to be running a command prompt within a command prompt (!). The other program (which, incidentally, is quite a bit bigger) does not work at all via vba on these PCs. I need to be able to provide other employees with something that works.
Can anyone shed some light on what is happening here and suggest a work around? I could past some code, but I think the above should be self explanatory.
You're confusing the command shell with the console window. In this context, the distinction is critical.
Console-mode programs (aka "command-line programs") require a console window to provide input and output. When a console-mode program is launched from a GUI program, Windows automatically creates a console window for it (unless instructed otherwise).
The command shell (aka "Command Prompt") is cmd.exe, a console-mode program.
The important point here is that not every console window has an instance of cmd.exe running in it. When a console-mode program is launched from a GUI program, Windows automatically creates a console window but does not automatically create an instance of cmd.exe. If you want to pass a command to cmd.exe you have to do so yourself, or use a run-time library routine that does it for you.
ExecCmd does not do this; it runs the program directly. So passing cmd /c <command> to ExecCmd is not "running a command prompt within a command prompt" at all. Without the cmd /c you aren't running a command shell command, you're just launching an executable.
There are any number of reasons why the command you're passing might need to be given to the command shell. For example:
it might be a built-in command like dir or type which only exists within the command shell;
it might include redirection or pipelining operators, or environment variable substitution;
it might be a script rather than an executable.
There are other cases. If you show us the command line being passed to ExecCmd we may be able to provide more specific advice. (The fact that the same command line is apparently working on some machines is puzzling, but can't be addressed without more information.)
I'm trying to install a driver with a remote framework that lets me run shell commands spawned as children of the remoting/monitoring app on the remote machine, run as cmd /c "command". But the driver refuses to install due to a security feature which thinks the driver may be unsafe.
The driver also has quotes(spaces in path) so its something like
Dim command: command = "\\\\server\\driver\\folder\\Autorun.exe" /passive /norestart";
Set retVal = remote.Shell(command)
which runs
cmd /c " "\\server\driver\folder\Autorun.exe" /passive /norestart"
on the remote machine
I've tried and have had trouble using setx SEE_MASK_NOZONECHECKS 1 /m in a previous statement, I'm guessing that the subprocess don't see new global enviromental variables that weren't around when it's parent started, and won't work without a restart. I'd like to avoid a restart.
I tried running
cmd /c " set SEE_MASK_NOZONECHECKS=1 & "\\server\driver\folder\Autorun.exe" /passive /norestart"
but it doesn't seem to work. Any ideas?
You got a bit lost on the way SEE_MASK_NOZONECHECKS is used. It is not an environment variable and cannot be tinkered with from the command prompt, it is an option for ShellExecuteEx(). A winapi function that you indeed use to start programs. It isn't very clear what programming tools you have access to, using it in a batch file or VBScript isn't going to work. You'd need at least, say, VB.NET and pinvoke the function. You can get the required declarations from the pinvoke.net web site.
Let's talk about what's really going on, you might find a simpler solution. When you download a file from an Internet web site, Windows adds an extra stream to the file that indicates where the file came from. Which basically states "this file did not come from a safe place" and makes the driver installer balky. Which is rather an important feature if you think about it, your user is going to install software that can do a lot, you pretty much have free reign of the machine if you can get a driver installed.
If you right-click the file in Explorer and click Properties then you'll see this at the bottom of the window:
All that's needed is to click that Unblock button. So this is a simple way for your user to solve the problem. You could document the extra step in the install instructions. Also with the advantage that it is now the user that took responsibility of allowing potentially unsafe code to be installed.
Other ways to get the file unblocked is with PowerShell's Unblock-File command and the SysInterals' streams utility, -d option.
And you probably ought to consider the option of writing your own installer. Which will keep the driver packaged in the setup file so it won't be tinkered with by Windows. And the user gets the warning when he starts the installer instead. And it can be signed so the user has some confidence in where the file came from and that it didn't get messed with on its way to his machine. There are many utilities that help you write an installer, like InstallAware, InstallShield, NSIS, etcetera.
I beg to differ to Hans' answer:
Of course, SEE_MASK_NOZONECHECKS is as well a predefined environment variable. Changing it in a process and then starting a child process (e.g. msiexec.exe) which by defaults inherits the environment, has just the same result as using ShellExecuteEx() and providing SEE_MASK_NOZONECHECKS as a parameter to the SHELLEXECUTEINFO structure. The first method is preferred by admins or quick hacks, e.g. if you work with batch or script files which set the environment variable- or when the final call to the .msi file lying on the unsafe network drive is not done by your own code.
For example:
#echo off
set SEE_MASK_NOZONECHECKS=1
call msiexec.exe /i "\\MY_UNC_DRIVE\installs\mysetup.msi /qb /L*v "c:\logs\mysetup.log"
call "\\MY_UNC_DRIVE\installs\Just_another_setup.exe"
If you already use a ShellExecuteEx() in your code, then of course, go with the parameter as Hans mentioned, because this implementation it is more closed. (If you use CreateProcess(), think about using ShellExecuteEx() instead.
Getting back to the environment variable(s). Generally you cannot influence the environment of already started processes. You can set the default environment used by NEW processes by the "setx" command used in the question. But with "setx" you don't change the environment for your current process.This was the problem in question. For this you have to use "set" as shown. So either use both commands after each other or don't use setx at all because for running a setup on foreign machines, it is not clean to make permanent security changes without asking.
For more details on permanent changes/admin point of view, see:
https://superuser.com/questions/595211/removing-the-open-file-security-warning-in-windows-8/934283#934283
Important: As mentioned, there is no general way in Windows to influence processes which already run (only own-defined inter-process-communication maybe), so it is important to set the environment variable before starting the setup to be influenced.
One more thing: Some people think, one must use "SETLOCAL" in a batch file. Normally this is not necessary. Environment changes with "set" are not permanent, and do not incluence "other" processes- they are only inherited to subprocesses and, partly, to superprocesses. But, when the caller on first level ends, the environment is reverted to original state again.
I ended up setting "Launch applications and unsafe files" to enabled for Internet zone in Internet Explorer options under security(custom level) and then exporting the changes from HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3 to a registry file and adding it with regedit /s.
After that I can run the installer of the shared drive.
One of these days I'll pare the registry file down to the minimum I guess.
P.S. I believe this causes IE to default to a warning page on startup.
I believe you need to put everything within the same quotation:
cmd /c "set SEE_MASK_NOZONECHECKS=1 & \\server\driver\folder\Autorun.exe /passive /norestart"
You can try these and see the difference in the output:
cmd /c "echo foo & echo bar"
cmd /c "echo foo" & "echo bar"
I'm porting a Linux tool-set that makes frequent use of shell functions to provide certain functionality. These functions are automatically sourced when you start a new shell and include things like changing the working directory, which is nigh impossible with stand-alone programs because child processes can't change their parent's environment.
For example, there is a function cdbm which changes the working directory to one that was previously bookmarked. Now I want to do the same on Windows, but I'm stuck with cmd.exe. As far as I understand the scripts could be ported to jscript, vbscript or plain batch, which shouldn't be a problem. But how do I make sure they automatically get sourced on startup and live in the shell's environment?
According to help cmd:
If /D was NOT specified on the command line, then when CMD.EXE starts, it
looks for the following REG_SZ/REG_EXPAND_SZ registry variables, and if
either or both are present, they are executed first.
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\AutoRun
and/or
HKEY_CURRENT_USER\Software\Microsoft\Command Processor\AutoRun
As a test, in regedit I created a new key in the HLM branch shown above called "AutoRun" with the string value "echo Hi". When I started a new instance of cmd I got:
Microsoft Windows [Version 6.0.6000]
Copyright (c) 2006 Microsoft Corporation. All rights reserved.
Hi
C:\Users\Username>
You could put in the name of a script to run instead (I would put in a fully specified path to the script or one with a environment variable in it like "%HOMEPATH%\scripts\scriptname" (including the quotes in case there are spaces in the name).
Edit:
The registry key has some side effects. One example is help. If I have the echo command above, for example, in the AutoRun when I type help vol I get a "Hi" right above the help text. Doing vol /?, though doesn't do that.
You can set either of the following registry keys to a batch file or other executable to run that program when CMD is started:
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\AutoRun
HKEY_CURRENT_USER\Software\Microsoft\Command Processor\AutoRun
A batch file should be able to change the current directory of the executing CMD process with the CD command, as it doesn't run as a subprocess. You can disable the autorun behaviour by supplying /D as a switch to CMD.
See CMD /? for more details.
Since cmd doesn't allow you to define functions in global scope, I'm a little at a loss to understand what exactly you're trying to achieve by auto-sourcing a script at startup. I tend to include a batch file directory in my path where you can put batch files I regularly need.
Look at cygwin.
After installing the new server, I am facing an issue.
I have lot of .vbs files, all need to run in wscript, reason, I use all those command like WScript.Echo "hello"
I want to be able to see the output when I double click the VBScript file.
But when I right click on the vbs file, I see console, I want to change the default to Windows host, globally!
How can I do that?
You can change the default scripting host to wscript.exe like so:
wscript.exe //H:wscript
If you wish to set cscript as the default host, that works in the same way:
wscript.exe //H:cscript
You can execute cscript.exe with the same arguments for the same result.
You can switch the default script engine with:
wscript //H:Wscript
Good luck!
I was able to solve it by using the following steps:
selecting the VBScript file that I want to open,
right click to select default program for this,
browse to C:/windows/windows32/wscript.exe, and select this.
In command prompt (as administrator):
To set windows script host as default script host enter:
wscript.exe //H:WScript
To set command line based script host as default script host enter:
cscript.exe //H:cscript
Check the Windows Explorer settings for the filetype *.vbs (something like tools->options->file types etc.) and change the "open with" setting to cscript.
Edit: I now advise caution with the recommendations I give below. After continuing to toggle and test my settings, I find I am unable to re-establish cscript as my default script host. (Note that I also retried the procedures given by other answers to this question.)
In addition, I tried using Process Monitor (a.k.a., "ProcMon") to find the reason for my difficulties, but unfortunately have not been unsuccessful.
Finally, I also considered going back to an earlier Windows 7 restore point, but this was complicated by the fact that I just yesterday changed my domain password. So, for now, I'm going to have to put my investigation to rest as other tasks are pressing.
On last thought...I have also considered the possibility that there are network policy security settings that are thwarting my efforts.
Original Answer: Enter the following line in a Windows batch file:
ftype VBSFile="%%SystemRoot%%\System32\WScript.exe" "%%1" %%*
Then, run a Command Prompt as an Administrator and run the batch file.
I believe the above will make the change for all users on the system. To make the change for only the logged in user, do the following (on Windows 7):
Control Panel => Programs => Default Programs => Associate a file type or protocol with a program
Then, in the Name column, scroll down to .vbs and click Change program... in the upper right. Then choose one of the Recommended Programs. If you do not see Microsoft ® Windows Based Script Host, browse to the following file:
C:\Windows\System32\wscript.exe
The guy above who right-clicked to choose the default program was right, however the path should be: C:\Windows\System32\wscript.exe