I'm writing this:
using System.Diagnostics;
Process.Start("C:\\CodeProjects\\C#\\WindowsPowerShell\\v1.0\\powershell_ise.exe", "-File .\\mp4_to_flac.ps1");
All this does is open up the script in Windows PowerShell ISE. But I also want it to RUN! So what other arguments do I have to pass in so that it executes?
Process.Start method Reference
You don't want to run powershell_ise.exe but powershell.exe. From a dos command prompt you can just prefix your command or script with #powershell, but for a process you're going to want to use something like
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
(that's mine on Win 8.1), yours should be somewhere near there if you're on a different version.
The chocolatey guys throw in these switches
-NoProfile -ExecutionPolicy unrestricted
when executing powershell from the command prompt, you might have to do that also depending on how your execution policy is set.
You could call it like so:
Process.Start(".\\mp4_to_flac.ps1");
and make sure all your windows settings are correct, so a double click on the file will execute it.
Related
I wanted to execute the following shell script commands '.sh' from either c# or through command prompt (which I can further execute it via c#)
I usually use the following commands to execute my .sh file .
The commands I do it manually are
a) Open cygwin (which inturn calls C:\cygwin\bin\mintty.exe -i /Cygwin-Terminal.ico -). This will open cygwin console
b) Go to the working directory where I need to execute the .sh file using
cd <dir in unix format>
c) execute the .sh script file
sh <path to my .sh file in unix format>
But, I would like to automate these steps using command line/ c#
(i.e to execute without opening console/apps like mintty.exe or bash.exe)
Note : The examples provided in How do i start Mintty and run a script file? didnt help me since they just close after opening without executing my commands.
If you want also the mintty window (useful when using vt100 escape sequences), you could use a batch wrapper file.
#echo off
setlocal EnableDelayedExpansion
set "script=%~1"
set "cygwin=C:\cygwin64\bin"
set "path=!cygwin!;!path!"
mode con lines=80 cols=120
REM C:\cygwin\bin\mintty
start "cygwin window" !cygwin!\mintty.exe -i /cygdrive/c/Windows/System32/compstui.dll,53 --exec "!script!"
You should prefix (at least) the cygwin/bin directory to the path variable, else you get strange results
The -i ...compstui.dll,53 is only for changing the icon in the taskbar/window
You can run a script directly with bash, using C:\cygwin\bash.
example: c:\cygwin\bin\bash --login "C:\foo.bsh"
I'm working on an application that will run as a windows service, and I'm trying to get it to update itself automatically.
My current approach is to to execute a powershell script, which will stop the service, run a msi installer, and then restart the service.
This is what the powershell script looks like at this time
Start-Sleep -s 10
Write-Host "update start"
Stop-Service ServiceName1
msiexec /i c:\ProgramData\ProgramName\Install\ServiceName.Setup.msi /passive /l*v C:\ProgramData\ProgramName\Install\log.txt | Out-Null
Start-Service ServiceName1
Write-Host "update finished"
This is how I'm running it from the app
Process.Start("Powershell", #"C:\ProgramData\ProgramName\Install\UpdateApp.ps1");
What happens, is the service stops and restarts, but it doesn't update. It's as though the msi never gets run. The log file doesn't even appear.
When I run the Service as a command line app from an elevated command prompt it works as expected and the app gets updated, so My current theory is that the service isn't running the powershell script with administrator privileges.
Other questions suggest that I set up the log on settings for the service to use an administrator account, so I set the service to run as the account that I was currently logged in under, who was able to open an elevated command prompt and/or manually run the installer, but doing that didn't change anything.
Is there any way to do what I'm trying to do?
I'm currently not committed to any particular automatic update strategy, but I do know that I want this service to update itself. So if I'm doing something completely wrong, I'm 100% open to attempting a different approach.
UPDATE:
I made the following change to log the error and output for msiexecc
Try{
c:\windows\system32\msiexec.exe /i c:\ProgramData\ProgramName\Install\ServiceName.msi /passive /l*v C:\ProgramData\ProgramName\Install\log.txt | Out-File -filepath C:\ProgramData\ProgramName\Install\output.txt
}
Catch {
$_ | Out-File C:\ProgramData\ProgramName\Install\errors.txt -Append
}
After running that script, I found the following error:
The term 'msiexec' is not recognized as the name of a cmdlet, function, script file, or operable program..
It looks like the call to msiexec isn't actually targeting c:\windows\system32\msiexec.exe
As per this question it seems that Powershell does not use the standard PATH environment variable, but has its own scheme, which perhaps doesn't work as expected in the context of a system service.
The simplest resolution, as you say, is to specify the full path, which is probably c:\windows\system32\msiexec.exe.
However, in production, it would probably be wise to avoid the use of a hardcoded path, since you might run into problems with localization, operating system changes, and so on. You could perhaps use SearchPath or a .NET equivalent from your service and either write out the Powershell script in real time or pass the path to msiexec as a command-line option, or there may be a sensible Powershell solution.
I'm calling a powershell script from my C# application using:
System.Diagnostics.Process.Start("powershell.exe", " -executionpolicy unrestricted -file myscript.ps1");
Within this script is a call to Java (which relies on the CLASSPATH & PATH system variables). This is where the script fails and reports that:
java is not recognized as an internal command or external command
I believe this is because the system variables for PATH are not being used when I'm executing Powershell from C#. Any help ?
FYI, if I open Powershell manually and run the command it works correctly.
I'm trying to get a batch script to run a silent install of my program. Here's the line that's causing trouble:
runas /user:domain\admin /savecred start "" "%temp%\MyProgram - 4.6.0.0\Setup.exe" /silent >> %userprofile%\Desktop\BatchLog.txt
A few notes:
"" before the file location is there to avoid issues with spaces in the location of Setup.exe
/silent is a parameter passed into Setup.exe to run a silent installation
>> %userprofile%\Desktop\BatchLog.txt pipes the output to a log file
When run as part of a batch script, Setup.exe isn't running as domain\admin. For the SharePoint savvy, SPFarm.Local is throwing a null ref (it's written in C#), indicating that the running user doesn't have DB access. Can you spot anything wrong with my use of runas here?
Running that line from the command line just pulls up the runas help screen. I'd like to find out why that's happening as well.
If I just manually run (double-click) Setup.exe (logged in as domain\admin) I don't get that null ref, indicating that my program is running properly as domain\admin.
How can I fix this line to execute my program as domain\admin?
Think that the whole command needs to be in quotes as runas only takes 1 "program" parameter. Also, the start command doesn't seem compatible with runas. Try this:
runas /user:domain\admin /savecred "\"%temp%\MyProgram - 4.6.0.0\Setup.exe\" /silent >> \"%userprofile%\Desktop\BatchLog.txt\""
(See end for solution)
I didn't think this was going to be hard. I have a commmand file, d:\a.cmd which contains:
copy /b d:\7zS.sfx + d:\config.txt + d:\files.7z d:\setup.exe
But these lines of C# won't execute it:
Process.Start("d:\\a.cmd");
Process.Start("cmd", "/c d:\\a.cmd");
Throws Win32Exception: "%1 is not a valid Win32 application."
Process.Start opens .pdf files...why not execute command files?
This works if I type it in a cmd window:
cmd /c d:\a.cmd
Windows XP, MS Visual Studio 2008.
Thanks in advance,
Jim
SOLUTION
I'm only SLIGHTLY embarrassed :( There was a file named cmd.exe, size zero in my app's dir. I have no idea how it got there but it is now toast and both of the above C# statements now work. I'm off to find a Harry Potter book so I can get some self-punishment ideas from Dobby...
I've got four things for you that you can try out:
(1) Try providing the full path for cmd.exe (e.g. on my machine: C:\WINDOWS\SYSTEM32\CMD.EXE).
(2) Try adding call to the command to be executed:
Process.Start(#"C:\WINDOWS\SYSTEM32\CMD.EXE", #"/c call D:\a.cmd");
(3) Besides that, I can only guess where the %1 in the Win32Exception is coming from. Maybe your file associations are set-up incorrectly.
If you type the following on the command-line:
> assoc .cmd
You will likely get a mention of cmdfile. If you then look up this token with:
> ftype cmdfile
You might get an answer along the lines of:
cmdfile="%1" %*
Those settings are stored in the registry, and this is how the command-line interpreter knows how to execute files with custom extensions. (You can find out how a PDF document is started by executing the above two statements for the .pdf extension.)
(4) If you start to suspect that your machine might be mis-configured, start regedit (the registry editor) and locate the key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor.
On my Windows XP machine (and your Process.Start example works on my machine, with different filenames though), I've got the following values stored in there:
// Name Type Value
// -----------------------------------------------
// (standard) REG_SZ (not set)
// AutoRun REG_SZ
// CompletionChar REG_DWORD 0x00000040 (64)
// DefaultColor REG_DWORD 0x00000000 (0)
// EnableExtensions REG_DWORD 0x00000001 (1)
// PathCompletionChar REG_DWORD 0x00000040 (64)
Of those, the AutoRun value might be of some interest. I think it corresponds to the /d command-line switch of cmd.exe, which controls whether cmd.exe attempts to start files with custom extensions. Usually, this is enabled. Maybe, on your machine, it isn't?
Or you can do a .bat file, then call this file through System.Diagnostics.Process.Start(). It won't redirect output to Console Application, but it would certainly execute the commands inside.
You need to specify the process full name (cmd.exe).
You should try
Environment.GetFolderPath(Environment.SpecialFolder.System) + "cmd.exe"
So you can be sure to execute the right file even if a cmd.exe is in your applications directory.
It looks like something wrong with your computer. Try running this on another machine. This should work. Process.Start(string) uses ShellExecuteEx to launch the file, so it's pretty much the same thing as double-clicking the file in Explorer, as you supposed.
A simple test worked for me.
B:\foo.cmd:
#echo Hello from foo.cmd!
#pause
Program.cs:
class Program{
static void Main(){
System.Diagnostics.Process.Start("B:\\foo.cmd");
}
}
This works as expected.
Your error message is suspicious, "%1 is not a valid Win32 application." The value in my registry at HKCR\cmdfile\shell\open\command is
"%1" %*
The %1 gets replaced by the file name, and the %* can be ignored here (it indicates that any further command-line arguments should be passed along, but we're not concerned with that right now).
The fact that the file itself is launched to handle this type of file indicates that Windows itself knows how to launch this type of file. On a normal installation of Windows, the following extensions should be set up similarly:
.exe Windows and DOS executable files
.com DOS "command" files
.bat Windows and DOS batch files
.cmd Windows NT batch files
.pif Windows shortcuts to DOS executable files
If you go to HKCR\.xxx (where xxx is any of the above), the "(Default)" value should be xxxfile. If you then go to HKCR\xxxfile\shell\open\command, the "(Default)" value should be "%1" %*. Also the "(Default)" value of HKCR\xxxfile\shell should be either not set or open.
If you have anything else in any of these values, then some program has attempted to insert itself into the execution process. Viruses sometimes do this (Sircam, for example).
Have you tried executing cmd.exe, and passing the .cmd file to it as an argument?
hmm try:
System.Diagnostics.Process myproc = new System.Diagnostics.Process();
myproc.EnableRaisingEvents=false;
myproc.StartInfo.FileName="d:\\a.cmd";
myproc.Start();
MessageBox.Show("did the command");
Have you tested your batch file in the directory, context it's going to run? The error message with %1 looks like the problem may be in there?