Control goes to next statement immediately after running a command using Run method - command-line

I have script to uninstall a package say pkg_1 using it's uninstallstring (i.e. setup.exe -remove). After that it is trying to remove another package say pkg_2. The uninstallation of pkg_1 takes around 1 to 2 minutes. the script looks like as below
rc = shellobj.Run("cmd /C " & uninstall_string_1 & " /silent",0, true)
rc1 = shellobj.Run("cmd /C " & uninstall_string_2 & " /silent",0, true)
Here what's my problem is, if you place WScript.sleep(120000) between above two statements, both packages are getting removed successfully. Otherwise, uninstaaltion of pkg_1 is halted and uninstallation of pkg_2 begins immediately. As a result only pkg_2 is getting removed(without sleep).
How can i do the uninstallation of two packages without using sleep method?
FYI
If you run uninstall_string_1 from command prompt, new prompt will be opned after 0-5 seconds and uninstallation proceeds in background

Arjun, I read this in another forum :
When we use scripts to install or uninstall packages, it depends very much on the implementation of the package. Let's say setup.exe itself run as process A. Process A does some nominal verification then spawns a process B, the real installation engine, then close itself out. In this case, the bWaitOnReturn(which you have set to true in your code) has done its work and the control will hand to the next statement. However, the process B is still running. That is out of the control of the bWaitOnReturn. So your 2nd package will start before your 1rst package is actually completed. Maybe your 1rst package is not actually halted, it might be taking time and executing in the background. Thats just a guess anyways.
If that is not the case, can you also try this :
Set obj0 = CreateObject("WScript.Shell")
Set objExec = obj0.Exec("your package../../")
' We will set a loop until finished
Do While objExec.Status <> 1
WScript.Sleep 100
Loop
So every 100ms, script will check if your package has completed execution. And if it has, it will move to next statement.

Try this one:
strCmd = uninstall_string_1 & " & " & uninstall_string_2
rc = shellObj.Run("cmd /C " & strCmd, 0, True)

Related

Calling Powershell from MATLAB does not move to next line in MATLAB

I have a command that calls powershell using !powershell . it works fine but, the first command will execute a publishing of data action from an external program and does not proceed to next line of code in MATLAB until there is a subscriber to the published data. the problem is that the next line of code is the one that subscribes to the published data so it just runs for ever waiting for the data. any ideas how to make the code continue? I have tried the continue statement but since I have called powershell, it stays there and MATLAB commands do not get executed. Also, I have tried to run the commands backwards, so subscriber first and publisher after but get same issue. Any ideas?
pubPath = 'powershell -inputformat none cd path' ;
subPath = 'powershell -inputformat none cd path2';
[status_one,publish] = system(pubPath);
[status_two,subscribe] = system(subPath);
You need to start the job in the background, such that PowerShell returns immediately before the job finishes. Note that it is PowerShell that waits for the job to finish, not MATLAB.
End the PowerShell command with an ampersand (&) to run it in the background:
[status_one,publish] = system('powershell -inputformat none cd path &');

When calling Win32 ShellExecute within ANY language, how can I stop program execution until ShellExecute is done?

This question is similar to most about ShellExecute, with one exception: I want to use ShellExecute because it's simple to use and it can be called with a few lines from within many programming languages including the now sunsetted Visual FoxPro.
Most existing solutions rely on doing stuff with threads, looking for processes (not reliable if it's a common process name) or ShellExecuteEx which is much more complicated to use. I was not satisfied with other solutions out there.
The issue is that I have a file operation that takes a few seconds to complete: unzipping an archive. How do I know that I am done?
The solution is to create a semaphore from within the command being executed. This can be done by running a batch file, but if that is not desired, there is another way to handle it with a one-liner using cmd.exe:
ShellExecute(0, 'open', 'cmd.exe', '/c 7z.exe e Invoices.zip | find "Everything is Ok" > semaphore.txt', workingDirectory, 1)
This one-liner uses CMD to pipe the output of 7zip to Find, which looks for the line of text that indicates completion. Of course, this fails if there's an error.
If you don't have output you to wait for (for piping into FIND), you can use & echo thusly:
... & echo > semaphore.txt
This waits until ... is done, then echos a newline to semaphore.txt.
At the end, you'll have a semaphore.txt file inside your working directory. All you have to do is look for this file to appear, and you know that execution is done. Delete this file and continue with your program.

TFS Build vNext - start process after successful build

On our build server, we have a running process that, among other things, are necessary for running integration tests, to gain access to a database.
This piece of software can be changed in our repository, and I have therefore created a CI build that builds the changes. What I would then like to do, is to restart the process with the new compiled version upon successful build, but that part I can not seem to get to work.
I have no issue killing the running process, and deploying the result to specific location on the build server, but seemingly no matter what I try, the process I spawn is killed as soon as the running build ends.
I have tried the following:
With PowerShell
Start-Process <path to file>
With CMD
with 'cmd' as tool and the following arguments:
<path to file>
start <path to file>
/c start <path to file>
cmd <path to file>
cmd start <path to file>
cmd /c start <path to file>
I have also tried simply supplying the .exe path as the tool name, and no arguments, no luck either.
How well did it work?
Well, for most of the above approaches, an extra step with the PS command Get-Process <exe name>* I got the result that the process was running. The same step yielded no results after a step that stopped the process, so a new updated one could be started. So I am positive it works, vNext build simply kills it all after the build ends.
Other solutions
I have got 2 solutions left that I can think of should work, but both solutions are too complicated for my liking, in that I am introducing quite the complexity to the build process that then might go wrong, but here goes:
Setup the build server as a valid target for deployments. Then I am guessing that I can use the "PowerShell on Target Machines" step, even though I am targeting itself. I would assume that it would then act as separate processes. That requires all sorts of configurations to get that in place though, plus writing the remote PowerShell script for the task.
Writing a small windows service that is callable with as e.g. REST, which could then start the process, so the new windows service becomes the owning thread. - that just introduces a new layer that also might need to be updated. This could then perhaps be updated manually instead of automatic.
Again, I would rather not use any of the 2 solutions, if a better exists. :)
At the moment I ended up fixing it by installing AutoIt, and added this simple script to the "deploy" folder:
While 1 ; Opens up a WHILE loop, with 1 as a constant, so it is infinite
If Not ProcessExists("DelphiDebug.exe") Then Run("DelphiDebug.exe") ; if the process of DelphiDebug.exe doesn't exist, it starts it
Sleep (10) ; Puts the script to sleep for 10 milliseconds so it doesn't chew CPU power
WEnd ; Closes the loop, tells it to go back to the beginning
Credit goes to this forum entry where a notepad example was made.
I have then made a PowerShell script that renames the current version, copies the newly build version to "deploy" folder, stops the running instance, and deletes the renamed version:
# CONSTANTS AND CALCULATED VARIABLES
[string]$deploymentFolder = 'C:\Deployment-folder-on-local-machine'
[string]$deploymentPath = "$deploymentFolder\my-program.exe"
[string]$searchPathExistingVersion = $deploymentPath + '*' # The star is important so Get-Item does not throw an error
[string]$toDeleteExeName = 'please-delete.exe'
[string]$newCompiledVersionFullPath = "$env:BUILD_SOURCESDIRECTORY\sub-path-to-bin-folder\my-program.exe"
[string]$processName = 'my-program'
[string]$searchPathToDeleteVersion = "$deploymentFolder\$toDeleteExeName*" # The star is important so Get-Item does not throw an error
# EXECUTION
Write-Verbose "Search path: $searchPathExistingVersion"
$existingVersion = Get-Item $searchPathExistingVersion;
if ($existingVersion) {
Write-Debug "Match found: $existingVersion"
Rename-Item $existingVersion.FullName $toDeleteExeName
} else {
Write-Debug 'No existing file found'
}
Write-Verbose "Copy new version from path: $newCompiledVersionFullPath"
Copy-Item $newCompiledVersionFullPath $deploymentPath
Write-Verbose 'Stopping running processes'
Get-Process ($processName + '*') | Stop-Process # The new version is auto started with a running AutoIt script in the deployment folder.
Write-Verbose "Deleting old versions with search path: $searchPathToDeleteVersion"
$toDeleteVersion = Get-Item $searchPathToDeleteVersion
if ($toDeleteVersion) {
Write-Debug "Match found: $toDeleteVersion"
Remove-Item $toDeleteVersion -ErrorAction SilentlyContinue # Deletion is not critical. Next time the build runs, it will attempt another cleanup.
} else {
Write-Debug 'No file found to delete'
}
Again, this solution added another complexity to the server, so I am keeping the question open for a few days, to see if there are simpler solutions. :)
Instead of starting a process during the build I think you need to install the process as a Windows Service and start it. It makes sense that any process you start in the context of the build would stop at the completion of the build. You can use the commandline to install/update/start a Windows service:
sc create [service name] [binPath= ]
https://ozansafi.wordpress.com/2009/01/14/create-delete-start-stop-a-service-from-command-line/

Update Matlab Standalone while executing that standalone

I've distributed a working standalone to different users. When they are connected to a share drive I would like to have a check if there is an update available of this standalone.
I've got this working, it will download the new install package to the directory where the standalone is located. However I can not install it as the standalone is already running (your not allowed to overwrite running applications)
Is there any way to make this update go automatically?
In code:
copyfile(name,CurrentDirectory); % Download the new package [this works]
system([CurrentDirectory,name,' -o']); % Can't overwrite the .exe file (this code will just run the package of the standalone)
Thanks in advance for the help,
It seems like you try to use some program to update itself. This sounds rather problematic, here is what you can do:
Run mainProgram to get the package that you need
Let mainProgram start a second program updater
Let updater kill mainProgram and update the program
Let updater start your mainProgram and terminate itself
It will require the programs to have some rights, but I hope it gets the job done for you.
Here is a script that I use to kill all Excel instances for your my user. I suppose this can be changed to deal with mainProgram instead.
[~, computer] = system('hostname');
[~, user] = system('whoami');
[~, alltask] = system(['tasklist /S ', computer, ' /U ', user]);
excelPID = regexp(alltask, 'EXCEL.EXE\s*(\d+)\s', 'tokens');
for i = 1 : length(excelPID)
killPID = cell2mat(excelPID{i});
system(['taskkill /f /pid ', killPID]);
end
This is what I use under windows, not sure if this works on other OS but it should not be hard to find how to kill a process in other operating systems.

Windows Scheduled task succeeds but returns result 0x1

I have a scheduled task on a Windows 2008 R2 server. The task includes a Start In directory entry. The task runs, and the batch file it runs does what it is supposed to do. When I run the batch file from a command prompt, I see no errors. The problem is that the "Last run result" is 0x1 (incorrect function call).
I did get this at one time with an incorrect DOS statement IF EXISTS file.txt DO (Copy file.txt file1.txt) that was corrected by dropping the DO statement. The current batch file does not show me any errors or warnings.
Why am I getting a 0x1 result?
Batch file that is run:
PUSHD \\JUKEBOX4\Archives\CallRecording
REM only move csv and wma together. wma should be created last.
IF NOT EXIST C:\CallRecording (MKDIR C:\CallRecording)
FOR /f %%f IN ('DIR /b *.wma') DO (
IF EXIST %%~nf.csv (MOVE /Y %%~nf.* C:\CallRecording\)
)
POPD
CD /D "C:\Program Files (x86)\Olim, LLC\Collybus DR Upload"
CollybusUpload.exe
POPD
Info on scheduled task setup:
Program to run: C:\Program Files (x86)\Olim, LLC\Collybus DR Upload\CallRecordingUploadFromH.cmd
Start in: C:\Program Files (x86)\Olim, LLC\Collybus DR Upload
Run whether user is logged on or not, highest privileges.
History screen, task completed entry
"Task Scheduler successfully completed task "\Call recording upload to portal from NH" , instance "{1449ad42-2210-427a-bd69-2c15e35340e6}" , action "C:\Windows\SYSTEM32\cmd.exe" with return code 1."
First screen of Task Scheduler shows "Run Result" of "Success"
It seems many users are having issues with this. Here are some fixes:
Right click on your task > "Properties" > "Actions" > "Edit" |
Put ONLY the file name under 'Program/Script', no quotes and ONLY the directory under 'Start in' as described, again no quotes.
Right click on your task > "Properties" > "General"
| Test with any/all of the following:
"Run with highest privileges" (test both options)
"Run wheter user is logged on or not" (test both options)
Check that "Configure for" is set to your machine's OS version
Make sure the user account running the program has the right permissions
I found that I have ticked "Run whether user is logged on or not" and it returns a silent failure.
When I changed tick "Run only when user is logged on" instead it works for me.
I've had the same problem. It is just a batch-file, working when manually started, but not working as a scheduled task.
there were drive-letters in the batch-file like this:
put z:\folder\file.ext
seems like you should not use drive-letters, they are bound to the user, who created them - for me this little change made it work again:
put \\server\folder\file.ext
For Powershell scripts
I have seen this problem multiple times while scheduling Powershell scripts with parameters on multiple Windows servers.
The solution has always been to use the -File parameter:
Under "Actions" --> "Program / Script" Type: "Powershell"
Under "Add arguments", instead of just typeing "C:/script/test.ps1" use -File "C:/script/test.ps1"
Happy scheduling!
Windows Task scheduler (Windows server 2008r2)
Same error for me (last run result: 0x1)
Tabs
Action: remove quotes/double-quotes in
program/script
and
start in
even if there is spaces in the path name...
General:
Run with highest privileges
and
configure for your OS...
Now it work!
last run result: The operation completed successfully
Probably not the cause of the OP's problem; for me the problem was caused by the fact that my program called a SQL function, and the service account the windows task was set up with did not have the required SQL permissions. That also gives a 0x1
This answer was originally edited into the question by the asker.
The problem was that the batch file WAS throwing a silent error. The final POPD was doing no work and was incorrectly called with no opening PUSHD.
Broken code:
CD /D "C:\Program Files (x86)\Olim, LLC\Collybus DR Upload" CALL CollybusUpload.exe POPD
Correct code:
PUSHD "C:\Program Files (x86)\Olim, LLC\Collybus DR Upload" CALL CollybusUpload.exe POPD
In my case it was an encoding issue. We wanted to start en existing batch file, and it resulted in "return code 1", and the desired action wasn't performed. I've accidentally found that the batch file was shown in Notepad as one with UTF-8 encoding (actually without any reason, as we have no special characters in the text). I saved it as ANSI, and it solved the problem for us. Might be, that it was a kind of encoding corruption in the file that prohibited Task Scheduler and cmd.exe to open the file, although it was displayed correctly in Notepad.
On our servers it was a problem with the system path. After upgrading PHP runtime (using installation directory whose name includes version number) and updating the path in system variable PATH we were getting status 0x1. System restart corrected the issue. Restarting Task Manager service might have done it, too.
I was running a PowerShell script into the task scheduller but i forgot to enable the execution-policy to unrestricted, in an elevated PowerShell console:
Set-ExecutionPolicy Unrestricted
After that, the error disappeared (0x1).
Just had the same problem here. In my case, the bat files had space " "
After getting rid of spaces from filename and change into underscore, bat file worked
sample before it wont start
"x:\Update & pull.bat"
after rename
"x:\Update_and_pull.bat"
For me the problem was the PowerShell script being ran had #Requires -RunAsAdministrator at the top, meaning it needs to run in an elevated command prompt as an Admin, but the user the Scheduled Task was set to run as wasn't an admin on the local computer. So even though Run with highest privileges was checked in the scheduled task, I still had to make the user an Administrator on the computer. Once I did that, the script ran as expected.
Since there is always more than one reason this could happen I thought I'd share some troubleshooting tips that helped me diagnose my issue.
Always adding a "start in" parameter first since thats an easy fix, even just adding the drive letter can help, e.g. C:\
If you're running "whether user is logged on or not" and it is failing it might be an issue with your user and/or user environment.
Switch the task to run only when user is logged in temporarily for
troubleshooting purposes.
Make sure you're actually logged in AS the user you're telling the task
to run as. (PATH and other environment variables are different by user
and if you see the task running on one user successfully that doesn't
necessarily mean it will run successfully for another user even if they're in the same security group.)
Add pauses or some other type of debugging to your script to give you
time to see any errors that may pop up.
Perform a manual run from the task scheduler window.
Fix any errors you see from your debugging statements. Rinse and repeat.
If it runs successfully switch back to run "whether user is logged on
or not" and try another manual run. If it works now you're all set.
If nothing has helped so far you might need to dig in deeper to your user and file privileges. My troubleshooting tips assume that you have been able to get a past task running using a specific user login already. They don't cover building a scheduled task from a fresh install necessarily. Luckily I haven't had to do that.
What solved it for me was that I was using a local administrator account instead of the domain account so I changed the "Run as" to the domain account.
It turns out that a FTP download call using winscp as last thing to do in the batch caused the problem. After inserting the echo command it works fine. Guess the problems source could be the winscp.exe which do not correctly report the end of the current task to the OS.
del "C:\_ftpcrawler\Account Export.csv" /S /Q
"C:\Program Files (x86)\WinSCP\WinSCP.exe" /console /script="C:\_isource\scripte\data.txt"
echo Download ausgeführt am %date%%time% >> C:\_isource\scripte\data.log