My question is similar to Running a CMD or BAT in silent mode, but with one additional constraint.
If you use WshScript.Run in vbscript, you lose access to the standard in/error/out streams of the process. WshScript.Exec gives you access to the standard streams, but you can't hide your windows. How can you have your cake (hide the windows) and eat it too (have direct access to the console streams)?
I'm currently thinking about a C++ executable which creates a new Windows Station and Desktop, (see MSDN) and runs a specified script within that new Desktop (I'm not yet an expert on Window Stations and Desktops, so this idea may be retarded).
This idea is based loosely on Condor's USE_VISIBLE_DESKTOP feature, which, if disabled, runs Condor jobs in a non-visible Desktop. I haven't quite figured out if this requires elevated priveledge.
The tradeoff of this approach is that your script can disappear into limbo if it blocks on user input.
Does anyone have any additional ideas? Or feedback on the approach outlined above?
Edit:
Also, the purpose of our script is to set up the user environment, so running as another user, or as a system scheduled task isn't really an option (unless there are clever tricks I don't know about).
I didn't have any luck with the VBScript fragment above - the windows would still pop up. However I did find a tool called hstart, which looks like about what I need. Unfortunately it isn't open source, or free for commercial use.
Cygwin (http://www.cygwin.com/) comes with a utility named run.exe which does what you are asking for a generic process. You could use this to wrap your call to cscript. Cygwin is GNU so free for commercial or personal use.
I only tested this a little bit, so YMMV...
Put the following code into a .vbs file (I called mine HideWindow.vbs):
Const HIDDEN_WINDOW = 12
computer = "."
Set oWmiService = GetObject("winmgmts:" & _
"{impersonationLevel=impersonate}!\\" & _
computer & "\root\cimv2")
Set oStartup = oWmiService.Get("Win32_ProcessStartup")
Set oConfig = oStartup.SpawnInstance_
oConfig.ShowWindow = HIDDEN_WINDOW
Set oProcess = GetObject("winmgmts:root\cimv2:Win32_Process")
ret = oProcess.Create("cmd.exe /c C:\Scripts\test.cmd", null, oConfig, pid)
Call it from a batch file or command line like this:
CSCRIPT HideWindow.vbs
Whatever you put in test.cmd will run without displaying a window. This could be improved in several ways, but especially by parameterizing the program that gets called by oProcess.Create.
You could use Exec, a freeware tool I wrote that provides a command-line interface for the CreateProcess Windows API call. The GUI version doesn't have a console itself, and you can use it to start a shell script (batch file) in a hidden window.
Bill
Related
I have created bat file for automatic build. It's create installer of my product. But problem is that before run automatic build script I have to change product code manually from install shield. So, is there any way to change product code automatically ? because everything is automatic except product code.
As Phil says you can do this via the COM automation interface for Installshield, but there are also other ways as explained here: Installshield Build Automation.
Essentially:
The link above shows a small sample of how to use the standalone build executable ISCmdBld.exe - which you might already be using.
Something like: "[PATHHERE]ISCmdBld.exe" -p "MyInstaller.ism" -r SingleImage -y "1.0.0.13" -z ProductCode=%guid%.
Do check the above link out - I have never used ISCmdBld.exe opting for COM automation instead.
The linked answer also explains how to use msbuild, read Urman's answer.
Finally you can use the COM automation interface and a VBScript (or Javascript?), and I have added a small sample below for how this can work.
I don't have Installshield 2013 available, but here is a very rough sketch of how you can automate the latest version 2016 via COM automation using a VBScript:
' On Error Resume Next
Set isproject = CreateObject("ISWiAuto23.ISWiProject")
isproject.OpenProject "C:\InstallShield 2016 Projects\TestProject.ism", False
Set isproductconfig = isproject.AddProductConfig("MyNewProduct_1.0.16")
isproductconfig.ProductName = "MyNewProduct_1.0.16"
isproductconfig.ProductVersion = "1.0.16"
isproductconfig.ProductCode = isproject.GenerateGUID
' lots of properties to set, the above should normally suffice I think...
Set isrelease = isproductconfig.AddRelease("MyNewRelease_1.0.16")
isrelease.Compressed = True
isrelease.SetupEXE = True
' lots of properties to set...
' Save and build project
isproject.SaveProject ' For some reason the project won't save properly after it is built
isrelease.Build
isproject.SaveProject
' Report error status
WScript.Echo "Number of Build Errors: " & CStr(isrelease.BuildErrorCount)
WScript.Echo "Number of Build Warnings: " & CStr(isrelease.BuildWarningCount)
isproject.CloseProject
This script wasn't tested that thoroughly, and weirdly, the new product configuration and release are not saved unless you save before triggering the build. It might be something simple I have mixed up - or it might be a bug in the tool (it wouldn't be the first one).
Take it for what it is, let's hope it gets you going to work out the wilburys on your own (bugs). I think it might run if you change ISWiAuto23.ISWiProject to IswiAuto20.ISWiProject to match the Installshield 2013 COM server version.
Crucially, you must run the VBScript from a 32-bit CScript.exe / WScript.exe (don't ask me why). Just put a shortcut to C:\Windows\SysWOW64\cscript.exe on your desktop for testing, and drag and drop your script onto it, or better yet, open a command prompt and go to C:\Windows\SysWOW64 (believe it or not this is the 32-bit folder - and the System32 folder is 64 bit (!) - only in Windows!) and then type cscript.exe [FullPathToVBScript]. Obviously remember to close your ISM file in the Installshield GUI before running the script.
I like the fact that you can save the new release and product config inside the *.ism file so you have a record of compiled releases. I am not sure what ISCmdBld.exe does.
I think you are supposed to use the InstallShield automation for this kind of thing, such as the ISWiProductConfig object that exposes the ProductCode of the MSI you're building.
I work with multiple Explorer windows that use different user credentials and I was wondering if there is a way to set a static title for each window to be able to determine which one uses which user credentials, like window A title set to "user abc" - since the titles change to the currently opened directory which is rather confusing sometimes with multiple windows open
I'm looking for as simple solution as possible, batch, VBScript, etc., something that can be easily ran from either a command line or a script file that doesnt need any compilation, conversion or specific software installed, for example:
open explorer.exe title="custom title"
So far I wasn't able to find any scripts that could handle that - 3rd party applications are out of the question.
Not sure if it's even possible, tried to find anything for few days now to no avail.
According to here its possible to do it for iexplorer (internet explorer)
so by a blind guess it might be possible to do it the same way for explorer
windows>run>regedit.exe
HKEY_CURRENT_USER > Software > Microsoft > Windows > CurrentVersion > Explorer and a new data with string as value type and window title as value name
And by changing theme it is possible to achieve a same or maybe similar objective, everything explained here could be done with a batch script
There are some registry keys that are owned by System, and I can't edit them unless I run as System. I want to be able to edit these keys from my VB application. Any tutorials I've found suggest using PSTools, the now deprecated At command, or schtasks. PSTools seems great, but its license seems to restrictive (about redistributing). At and schtasks are too messy, and require scheduling delays.
This is related to my previous question. I want to take what I discovered, and implement it via VB.
Modify audit policy (group policy)
I also found this, but am getting error 1314. I realized despite running VS2010 "requireAdministrator", and even Running my EXE as Administrator, it still says my username in Task Manager (running as me, not Administrator). I logged in as Administrator, and got Error 5 instead. Even after ensuring I had the rights set, as suggested by this post (CreateProcessAsUser error 1314), it still gave me Error 5.
Using a vb.net application running as SYSTEM, how do I start a detached process for each logged on user?
I changed the example to "TokenAccessLevels.Read and Duplicate" rather than MaximumAllowed.
If Not DuplicateTokenEx(hToken.DangerousGetHandle,
TokenAccessLevels.Read & TokenAccessLevels.Duplicate,
Nothing,
SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
TOKEN_TYPE.TokenPrimary,
phNewToken) Then
I get Error 5 from CreateProcessAsUser. This is while running VS2010 as Administrator.
http://forum.sysinternals.com/tip-run-process-in-system-account-scexe_topic16714.html
This post was the best I could do. Basically, install a service, run it, then delete it. According to the OP, this is his explanation.
So how does it work?
The & symbol tells cmd.exe to parse treat the text that follows as if it were a new line in a batch file (It basically is a new line
delimiter which allows multiple commands to be combined into 1 line)
To break it down: Create Service - sc create -- binPath= "cmd /c start
calc" type= own type= interact Start Service net start -- (This could
also be done with: sc start --) Delete Service sc delete --
Variables
Service Name: --
App to run: calc
Variables:
How it works:
cmd /c - allows us to pass in parameters to cmd (Without this initial
part, it will work if you copy & paste in cmd.exe, but not in the Run
Dialog. So this fixes it) sc create binPath= - Since cmd.exe does not
respond to service commands, when the SCM runs the app in binPath (Reg
= ImagePath) then it will terminate it, when not responding in a timely fasion, therefore cmd.exe cannot be used. It has to call
something else which in this case is calc.exe sc create type= This one
took a while to figure out. The inital problem is the Window Station
in which cmd.exe is launched in (which in turn is inherited by
calc.exe (its child process)). Luckily after reading Mark's Windows
Internals e4, I was able to solve it by specifying the service as
being Interactive. (Experimenting, it actually has to be BOTH
interactive(256) and own(16) (256|16 = 272) . Basically what this
allows is for the windows to run in \WinSta0\Default (The current
user's desktop, allowing the window to be displayed.) After some
research from being frustrated that sc would not accept type
=own|interact, I found out that it allows us to specify it again, and instead of overwriting Type (dword) it bitwise-ORs it (Adds it).
Problems Solved! net start - start the service (probably calls
StartService) cmd.exe runs with the command line (CL) of start [File]
in which start probably calls ShellExecute (Its ashame that MS didn't
allow start to specify a SW_* commands (like hide). Although it does
allowing us to min/max windows. cmd.exe opens the app/file, the SCM
terminates cmd.exe for not responding in a timely fashion to its
commands, and the window is now shown to the user. sc delete - Finally
we clean up our path by removing the service
For me, this worked.
cmd /c sc create -- binPath= "cmd /c start app.exe" type= own type= interact & net start -- & sc delete --
Now, I had trouble with getting absolute paths to work. I had to put my .EXE in System32 and SysWOW64, so I didn't have to use an absolute path. According to the site, this is supposed to allow absolute paths to work.
cmd /c sc create -- binPath= "cmd /c start \"\" \"C:\windows\regedit.exe\" " type= own type= interact & net start -- & sc delete --
It never worked for me, as it would hang for some time and never start the app. It should almost instantly complete.
I have a small VB .Net application that, among other things, attempts to substitute system wide typed text by the user(hotstrings concept). To achieve that, I have deployed 'ahk2exe' and 'AutoHotkeySC.bin' with my application and did the following:
When a user assignes a new 'hotstring':
Kill 'hotstring' exe script file if running
Append new hotstring to the script file (if non exist then create a new one)
Convert edited/new script file to exe (using ahk2exe)
Run the newly converted script exe
(somewhere there I also check if the hotstring has been already assigned)
However, I am not totally satisfied with this method for the following two main reasons:
The extra resources deployed with the application.
Lag: The time it takes for the system to kill the process and then restart it takes a minimum of 5 seconds on my fast computer and more on other computers. That amount of time is much more than the time it takes the user to assign the hotstring, minimize/close the window and then test his/her new hotstring. When the user does so initially with no success they will think the process failed. So this method is not very good for user experience.
So, I am looking for a different method or implementation. May be using keyboard hooks? Or maybe adding a .dll library that achieves the same. Are there any resources you know about that might help (free or commercial)? What is the best way to achieve my desired goal?
Many thanks for your help.
Implementing what Autohotkey does would be a pretty non trivial task.
But I'm pretty sure that AHK supports an "autoreload" option for scripts
googling "autohotkey auto reload" turned up several pages discussing that very concept. IF that worked, all you'd have to do is update the script file and that's it, AHK should automatically reload the script.
This isn't strictly a programming question, but hopefully someone here has the knowledge to help me.
Running Vista x64, the "Open File With" dialog takes forever to appear when trying to open a file with unknown type.
To be specific, the prompt giving the choice between "Use the web service to find the correct program" and "Select a program from a list of installed programs" appears immediately, but there is about a 10 second delay between pressing OK here and the next window (with a list of installed programs) appearing.
The same delay is present when I run "rundll32 shell32.dll,OpenAs_RunDLL" from a command line.
I'm guessing that this is not common behaviour, because I find it incredibly annoying, and I couldn't find any mention of it anywhere.
So..does anyone have any ideas what it might be? Or what I could do to try and find out?
VonC could be correct.
Read this article:
http://blogs.technet.com/markrussinovich/archive/2005/08/28/the-case-of-the-intermittent-and-annoying-explorer-hangs.aspx
You should use process explorer to watch the stack when you initiate the action. You should be able to tell what sort of operation is timing out.
Download process explorer here:
http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx
You could check if you do not have have network connection declared (net use), or more generally any network paths which may be used by your list of program listed to "Open File With".
If a network path is unavailable, a 'timeout' delay can affect the GUI responsiveness, especially if that GUI must explore/list those paths.