error when run PowerShell command from cmd c# - c#

i want to execute this commands from c#:
#echo off
PowerShell "ForEach($v in (Get-Command -Name \"Set-ProcessMitigation\").Parameters[\"Disable\"].Attributes.ValidValues){Set-ProcessMitigation -System -Disable $v.ToString() -ErrorAction SilentlyContinue}"
pause
i put the it in cmd file and run it using :
Process.Start(CMDFilePath);
but error occurre:
C:\Users\New-hwid\Desktop\Debug2>PowerShell "ForEach($v in (Get-Command -Name \"Set-ProcessMitigation\").Parameters[\"Disable\"].Attributes.ValidValues){Set-ProcessMitigation -System -Disable $v.ToString() -ErrorAction SilentlyContinue}"
Get-Command : The term 'Set-ProcessMitigation' is not recognized as the name of a cmdlet, function, script file, or
operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try
again.
At line:1 char:16
+ ForEach($v in (Get-Command -Name "Set-ProcessMitigation").Parameters[ ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Set-ProcessMitigation:String) [Get-Command], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException,Microsoft.PowerShell.Commands.GetCommandCommand
Cannot index into a null array.
At line:1 char:15
+ ... rEach($v in (Get-Command -Name "Set-ProcessMitigation").Parameters["D ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
when i open cmd file normally it worked fine , but when i run it via Process.Start(...) this error happen, my OS is windows 10 64 bit, how to run CMD file without error? Thanks

from this answer , The issue that you're seeing is because of the File System Redirector which is occurring because you're running your program as 32-bit on your 64-bit OS. Therefore, you're executing %windir%\SysWOW64\SystemPropertiesProtection.exe (ex: C:\Windows\SysWOW64\SystemPropertiesProtection.exe).
so i add In app.manifest, and replace
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
with
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
and modified the code to work with powershell:
public static void OpenPowerShell(string Command)
{
try
{
string filename = System.IO.Path.Combine(Environment.GetEnvironmentVariable("windir"), "System32", "WindowsPowerShell","v1.0","powershell.exe");
//environment variable windir has the same value as SystemRoot
//use 'Sysnative' to access 64-bit files (in System32) if program is running as 32-bit process
//use 'SysWow64' to access 32-bit files on 64-bit OS
if (Environment.Is64BitOperatingSystem && !Environment.Is64BitProcess)
{
//filename = System.IO.Path.Combine(Environment.GetEnvironmentVariable("windir"), "SysNative", "PowerShell.exe");
filename =System.IO.Path.Combine(Environment.GetEnvironmentVariable("windir"), "SysNative", "WindowsPowerShell", "v1.0", "powershell.exe");
}
ProcessStartInfo startInfo = new ProcessStartInfo(filename);
startInfo.UseShellExecute = true;
startInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(filename);
startInfo.Arguments = "-NoExit "+Command ;
Process.Start(startInfo);
}
catch (Exception ex)
{
FRM_MSG f = new FRM_MSG();
f.ShowDLG(" ",
ex.Message + "\n" + ex.StackTrace.ToString(),
FRM_MSG.MSGIcon.Error,
FRM_MSG.BTNS.One,
new string[] { "Ok" });
throw ex;
}
}

Related

Powershell Error when Running process

I am working in C# working on a program to clean up the windows 10 start menu and assign a custom layout. To do so I need to run a single command from powershell and am getting an error when running it.
How I am trying to accomplish the task.
I am starting C:\.\.\powershell.exe and passing the -command arguments of: Import-StartLayout -LayoutPath C:\StartMenu.xml -MountPath C:\
Process process = new Process();
process.StartInfo.FileName = #"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe";
process.StartInfo.Arguments = #" -command Import-StartLayout -LayoutPath C:\StartMenu.xml -MountPath C:\";
process.Start();
Here is the error I am receiving:
Import-StartLayout : The term 'Import-StartLayout' is not recognized as the name of a cmdlet, function, script file,
or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and
try again.
At line:1 char:1
+ Import-StartLayout -LayoutPath C:\StartMenu.xml -MountPath C:\; Start ...
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Import-StartLayout:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Any ideas why cmd or powershell will not take the external cmdlet of Import-StartLayout??
Import-StartLayout does not exist on windows 7 and earlier if you know that, continue.
You could try using System.Diagnostics.Process like the following:
Process powerShell = new Process()
{
StartInfo =
{
Arguments = "Import-StartLayout -LayoutPath C:\\StartMenu.xml -MountPath C:\\",
FileName = "powershell"
}
};
powerShell.Start();
Another way would be to use System.Management.Automation which is not an official supported package by Microsoft.
using (Runspace runSpace = RunspaceFactory.CreateRunspace())
{
runSpace.Open();
using (Pipeline pipeline = runSpace.CreatePipeline())
{
Command importStartLayout = new Command("Import-StartLayout");
importStartLayout.Parameters.Add("LayoutPath", "C:\\StartMenu.xml");
importStartLayout.Parameters.Add("MountPath", "C:\\");
pipeline.Commands.Add(importStartLayout);
Collection<PSObject> resultsObjects = pipeline.Invoke();
StringBuilder resultString = new StringBuilder();
foreach (PSObject obj in resultsObjects)
{
resultString.AppendLine(obj.ToString());
}
}
}

"You cannot call a method on a null-valued expression" when passing parameters to powershell

I'm trying to parse some parameters to a script I'm running in powershell.
But I'm getting errors while executing the script saying they are empty.
Im starting the process like this:
string input1 = "Powershell.exe -File " + Config.Directory + "/ICS.ps1" + " -toggle '" + toggle + "' -par1 '" +
par1 + "' -par2 '" + par2 + "' -connectionInterface '" + connectionInterface + "'";
//(for readability) input1 will look something like this:
//Powershell.exe -File map/to/ICS.ps1 -toggle 'EnableSharing' -par1 '0' -par2 '1' -connectionInterface 'Ethernet'
string[] output = CmdProcess.Exec(input1);
CmdProcess.Exec is a method i created to quickly run a cmd process.
it works like this
public static string[] Exec(params string[] parameters)
{
Process cmd = new Process
{
StartInfo =
{
UseShellExecute = false,
Verb = "runas",
FileName = #"cmd.exe",
RedirectStandardInput = true,
RedirectStandardOutput = true,
CreateNoWindow = true,
}
};
cmd.Start();
foreach (string parameter in parameters)
{
cmd.StandardInput.WriteLine(parameter);
}
cmd.StandardInput.WriteLine("exit");
return Regex.Split(cmd.StandardOutput.ReadToEnd(), "\r\n");
}
the reason i use cmd to execute powershell is because i tried it with a powershell instance* but that crashed for an unknown reason on really fast computers (while it runs normally if you run it manually).
*System.Management.Automation.Powershell
in the script i wrote this: (At the beginning of the script)
Param( [string]$toggle, [string]$par1, [string]$par2, [string]$connectionInterface )
But it gives an error the params are null :
You cannot call a method on a null-valued expression.
At C:\Users\Jeremy\AppData\Roaming\HotspotLauncher\ICS.ps1:10 char:1
+ $config.$toggle($par1)
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
I get error's like this with all the params. not just $toggle or $par1.
I tried running Powershell.exe and -File ..... seperatly but that caused my thread to hang.
Also I'm 100% sure toggle, par1 and the rest (In the C# code) arent null themselves
I also tried adding [CmdletBinding()] before the params in the script but that did nothing :
[CmdletBinding()]Param( [string]$toggle, [string]$par1, [string]$par2, [string]$connectionInterface )
Here is the powershell script:
[CmdletBinding()]Param( [string]$toggle, [string]$par1, [string]$par2, [string]$connectionInterface )
regsvr32 hnetcfg.dll /s
$m = New-Object -ComObject HNetCfg.HNetShare
$m.EnumEveryConnection |% { $m.NetConnectionProps.Invoke($_) }
$c = $m.EnumEveryConnection |? { $m.NetConnectionProps.Invoke($_).Name -eq $connectionInterface }
$config = $m.INetSharingConfigurationForINetConnection.Invoke($c)
Write-Output $config.SharingEnabled
Write-Output $config.SharingConnectionType
$config.$toggle($par1)
$m2 = New-Object -ComObject HNetCfg.HNetShare
$m2.EnumEveryConnection |% { $m2.NetConnectionProps.Invoke($_) }
$c2 = $m2.EnumEveryConnection |? { $m2.NetConnectionProps.Invoke($_).DeviceName -Match 'Microsoft Hosted Network Virtual Adapter' }
$config2 = $m2.INetSharingConfigurationForINetConnection.Invoke($c2)
Write-Output $config2.SharingEnabled
Write-Output $config2.SharingConnectionType
$config2.$toggle($par2)
This script enables/disables Internet sharing for the $connectionInterface which could be something like Ethernet or Wifi, and set it to public ($par1) / or nothing if it has to be disabled.
and does the same for microsoft hostednetwork and set it to private ($par2).
Don't fork a new process with powershell.exe - use the API instead:
using System.Collections.ObjectModel;
using System.IO;
using System.Management.Automation;
//...
using(PowerShell ps = PowerShell.Create())
{
ps.AddScript(Path.Combine(Config.Directory, "ICS.ps1"))
.AddParameter("toggle", toggle)
.AddParameter("par1", par1)
.AddParameter("par2", par2)
.AddParameter("connectionInterface", connectionInterface);
Collection<PSObject> results = ps.Invoke();
}
Remember to add a reference to the System.Management.Automation.dll assembly to your project

Use MSBuild to Update a Program

We use a MSBuild do create a Setup.exe. This Setup.exe will be uploaded on a Server and the programm use this file to reinstall the new Version of the program. My task is to speed up this process.
I would like to write a MSBuild which compiles the exe. So the customer don't need to download the whole 40mb but rather it updates his program.
Is that possible with MSBuild or is there another (better) solution.
I created patches.
I just want to give a short answer. It will probably be superficial.
So, everything is generated with a build.msbuild file.
Create folders with all the versions of the program (1.0.0.0, 1.0.1.0,…). Each folders also contains a .wixpdb file. This file is needed to generate the patches.
I created a msbuild-Task in C# to automate the patch generation. It looks like that:
…
foreach directory
…
if (!startTool("candle","\""+wurzel + "\\Setup\\MSI\\Patch.wxs\" -o \""+wurzel+"\\Setup\\MSI\\Patch.wixobj\""))
return false;
if (!startTool("light","\"" + wurzel + "\\Setup\\MSI\\Patch.wixobj\" -o \"" + wurzel + "\\Setup\\MSI\\Patch.wixmsp\""))
return false;
if (!startTool("torch", " -p -xi \"" + older.wixpdb + "\" \"" + newer.wixpdb + "\" -out \"" + wurzel + "\\Setup\\MSI\\Patch.wixmst\""))
return false;
if (!startTool("cmd", "/c cd /d \""+wurzel+"\\Setup\\MSI\" && pyro Patch.wixmsp -t MyPatch Patch.wixmst -out \"" + wurzel + "..\\Release\\Patches\\Patch_" + kvp.Value + "-" + versionNrS + ".msp\""))
return false;
…
The program automatically downloads the right patch and installs it with this command:
"msiexec /qb /p " + fd.Directory.FullName + "\\"+currentFtp.FileName + " REINSTALL=ALL REINSTALLMODE=a”

Process to export svn files hangs with Process.Start()

I try to execute a .cmd to export files from SVN, it works manually and in my local machine(WS2003 SP2 IIS Identiy: Local System), but it fails in the execution server (same configuration).
The script I execute is:
echo.%Date%-%Time%- Username %username%>>c:\vpcheckcode\logsvn.txt
svn export %svnUrl% %srcFolder% --force --username %usr% --password %psw%
If I try simply to copy a file, no svn, it works.
When I execute it manually it logs my user and it exports the files.
On develop PC it doesn't log the user but it works, in execution server it doesn't log the user and it doesn't works.
I try to execute the .cmd in this way:
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
startInfo.FileName = strFileName;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.Arguments = svnUrl + " " + srcFolder+ " " + usr+" "+psw;
using (Process exeProcess = Process.Start(startInfo))
{
pid = exeProcess.Id;
EventLog.WriteEntry("VPCheckCodeSrvDll.ExecuteScriptSVN", "avviato pid svn: " + pid.ToString(), EventLogEntryType.Warning);
if (!exeProcess.WaitForExit((int)_svnExportTimeout))
{
exeProcess.Kill();
The process hangs untill it has been killed.
C:\Documents and Settings\myuser>tlist 4980
4980 cmd.exe
CWD: c:\windows\system32\inetsrv\
CmdLine: cmd /c ""C:\ANALISI\000000-xx-v90\SVN\svnExport.cmd" https://svn.mysite.local/repos/HA/branches/H
VirtualSize: 11332 KB PeakVirtualSize: 15492 KB
WorkingSetSize: 1832 KB PeakWorkingSetSize: 1848 KB
NumberOfThreads: 1
2704 Win32StartAddr:0x4ad07670 LastErr:0x000000cb State:Waiting
5.2.3790.3959 shp 0x4AD00000 cmd.exe
5.2.3790.4937 shp 0x7C800000 ntdll.dll
5.2.3790.5069 shp 0x77E40000 kernel32.dll
7.0.3790.3959 shp 0x77BA0000 msvcrt.dll
5.2.3790.4455 shp 0x7D1E0000 ADVAPI32.dll
5.2.3790.4759 shp 0x77C50000 RPCRT4.dll
5.2.3790.4455 shp 0x76F50000 Secur32.dll
5.2.3790.4033 shp 0x77380000 USER32.dll
5.2.3790.4396 shp 0x77C00000 GDI32.dll
5.2.3790.3959 shp 0x71BD0000 MPR.dll
5.2.3790.3959 shp 0x76290000 IMM32.DLL
Any suggestion?
I did something similar. Try the following:
Change : startInfo.Arguments = svnUrl + " " + srcFolder+ " " + usr+" "+psw;
to : startInfo.Arguments = String.Format("{0} \"{1}\" --username {2} --password {3}", svnUrl, srcFolder, usr, psw);
I am making the assumption that your usr and psw variables do not contain the parameter information for subversion. Also, my destination included the file name (I can't see your full command line as it is cut off) and also contained spaces, so I had to enclose it within quotes. Your svnUrl should have "%20" in place of spaces if you have any (again, the full URL is not visible).

Using Drush Site-Install in C#

I'm trying to do a Drupal site install using Drush in C# as part of a full Windows Server site installation using MSI.
The Drush commmand I am using is the following one.
C:\ProgramData\Drush\Drush.bat -y si application_name --db-url=sqlsrv://admin_name:password(local)\SQLEXPRESS:/database_name --account-name=admin --account-mail=name#test.com --account-pass=Password1234 --site-mail="admin#company.com" --site-name="Site Name" install_configure_form.site_default_country=GB install_configure_form.date_default_timezone="Europe/London"
And this works perfectly when run from cmd.exe when in the working directory (inetpub\application_name).
The issue arises when the above is put into code and executed during an installation and always results in the following error (with a different file name each time).
Unable to decompress C:\ProgramData\Drush\lib\druFD63.tmp.gz
The C# code being used to execute the command is as follows:
public static ActionResult Drush_Configuration(Session session)
{
string strArgs = "-y si application_name --db-url=sqlsrv://admin_name:password(local)\SQLEXPRESS:/database_name --account-name=admin --account-mail=name#test.com --account-pass=Password1234 --site-mail="admin#company.com" --site-name="Site Name" install_configure_form.site_default_country=GB install_configure_form.date_default_timezone="Europe/London";
string strExeCmd = #"C:\ProgramData\Drush\Drush.bat ";
strExeCmd = strExeCmd + strArgs;
string strLocation = #"C:\inetpub\application_name";
session.Log("Starting Drush Configuration");
session.Log("Command line is: " + strExeCmd + " " + strArgs);
int exitCode;
ProcessStartInfo processInfo;
Process process;
try
{
processInfo = new ProcessStartInfo("cmd.exe", "/c " + strExeCmd);
processInfo.WorkingDirectory = strLocation;
processInfo.WindowStyle = ProcessWindowStyle.Normal;
processInfo.CreateNoWindow = true;
processInfo.UseShellExecute = false;
// *** Redirect the output ***
processInfo.RedirectStandardError = true;
processInfo.RedirectStandardOutput = true;
process = Process.Start(processInfo);
process.WaitForExit();
// *** Read the streams ***
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
exitCode = process.ExitCode;
session.Log("output>>" + (String.IsNullOrEmpty(output) ? "(none)" : output));
session.Log("error>>" + (String.IsNullOrEmpty(error) ? "(none)" : error));
session.Log("ExitCode: " + exitCode.ToString(), "ExecuteCommand");
process.Close();
}
catch (Exception e)
{
session.Log("Error: " + e);
return ActionResult.Failure;
}
session.Log("Drush Configuration completed successfully");
return ActionResult.Success;
}
And as stated above, this always results in the "unable to decompress" error.
Has anyone ever used c# to run Site-Install in Drush? Does anyone know why this might fail when executed in this way?
Any thoughts or advice would be greatly appreciated.
I am using Drush-5.8-2012-12-10-Installer-v1.0.20, Drupal 7, and Windows Server 2008 R2 x64.
The cause of this issue was the Environment Variables. The Drush MSI installer sets up User Path Environment Variables which are not recognized in an MSI machine context.
So, by adding System Path Variables for Drush, GnuWin32 and PHP to the site-install MSI the site can be programmatically installed.

Categories