I'm looking to run some powershell scripts via automation. Something like:
IList errors;
Collection<PSObject> res = null;
using (RunspaceInvoke rsi = new RunspaceInvoke())
{
try
{
res = rsi.Invoke(commandline, null, out errors);
}
catch (Exception ex)
{
LastErrorMessage = ex.ToString();
Debug.WriteLine(LastErrorMessage);
return 1;
}
}
the problem I'm facing is that if my script uses cmdlets such as write-host the above throws an System.Management.Automation.CmdletInvocationException -
Cannot invoke this function because
the current host does not implement
it.
What are some good options for getting around this problem?
One option is to create a write-host function and inject that into your runspace. The function will take precedence over a cmdlet with the same name. In this function, you could do nothing or perhaps use [console]::writeline() if your app is a console app, or if your app is a GUI app, inject some object into the PowerShell session that the function can write the output to (look at Runspace.SessionStateProxy.SetVariable).
Another (bit more complicated) option is to implement the PowerShell hosting interfaces in your app.
Related
I need to execute workflow from command line that is already created using UI.
Already I have tried to invoke workflow by creating workflow instance.
the code shown below which is i was tried
XmlTextReader reader = new XmlTextReader("Workflow1.xml");
Console.WriteLine("Waiting for Workflow completion..");
WorkflowRuntime runtime = new WorkflowRuntime();
WorkflowInstance instance = runtime.CreateWorkflow(reader);
instance.Start();
but it shows the error message "xml tag is not framed well".
I have fully copied the workflow xaml content and pasted in Workflow1.xml file.
is there any other possibilities to achieve this.
Thanks in Advance.
It looks like you are using Windows Workflow 4, but you are trying to use the Windows Workflow 3 runtime to execute the workflow. I've got a white paper [1] on WF 4 that might be useful, but here's a snippet from that article that might be helpful. It uses the workflowInvoker class to execute the workflow. You can also use WorkflowApplication if you have long running workflows that need bookmarking capabilities.
Activity mathWF;
using (Stream mathXaml = File.OpenRead("Math.xaml"))
{
mathWF = ActivityXamlServices.Load(mathXaml);
}
var outputs = WorkflowInvoker.Invoke(mathWF,
new Dictionary<string, object> {
{ "operand1", 5 },
{ "operand2", 10 },
{ "operation", "add" } });
Assert.AreEqual<int>(15, (int)outputs["result"], "Incorrect result returned");
Developer's Introduction to Windows Workflow
I have a simple dotnet application which i want to execute from powershell. but while i am passing the arguments in powershell my dotnet application is not able to catch those value.
I am not sure where the error is. is it in dotnet side or in powershell.
dotnet winform
private void Form1_load(object sender, EventArgs e)
{
string[] passedArgs = Environment.GetCommandLineArgs();
foreach(string s in passedArgs)
{
textBox1.Text = s.ToString();
}
}
powershell script
PS C:\Users\528741> Start-Process 'D:\MVC\PowershellTest\PowershellTest\bin\Debug\PowershellTest.exe' -ArgumentList '/hello'
Thanks,
Rosalini
It's difficult to tell without seeing the rest of the application what might be going wrong, as what you've shown us is pretty straightforward. Things to try:
textbox1.Text = "Does a string literal work?";
If the textbox doesn't display your string literal, the issue is in your C# or in the design of your winforms application. Maybe textbox1 isn't visible anymore and you have some other textbox object displayed? Maybe the Form1_load() method isn't being called when you think it is. Did a name get changed somewhere? If that's the case I would suggest recreating the form and pasting your code for the Form1_load() method into there and try again.
If it does display as expected, then I would suspect something with Powershell. Have you tried without Start-Process? Like:
& "D:\MVC\PowershellTest\PowershellTest\bin\Debug\PowershellTest.exe" "I'm argument 1" "This is argument 2" "3rd argument here!"
Also, as your code looks simple enough, are you sure this is the correct path to your executable? Have you rebuilt your solution after making your changes to the code? Simple oversights like this are often the issue.
I'm trying to call an async method on a .Net object instantiated in Powershell :
Add-Type -Path 'my.dll'
$myobj = new-object mynamespace.MyObj()
$res = $myobj.MyAsyncMethod("arg").Result
Write-Host "Result : " $res
When executing the script, the shell doesn't seem to wait for MyAsyncMethod().Result and displays nothing, although inspecting the return value indicates it is the correct type (Task<T>). Various other attempts, such as intermediary variables, Wait(), etc. gave no results.
Most of the stuff I found on the web is about asynchronously calling a Powershell script from C#. I want the reverse, but nobody seems to be interested in doing that. Is that even possible and if not, why ?
I know this is a very old thread, but it might be that you were actually getting an error from the async method but it was being swallowed because you were using .Result.
Try using .GetAwaiter().GetResult() instead of .Result and that will cause any exceptions to be bubbled up.
For long running methods, use the PSRunspacedDelegate module, which will enable you to run the task asynchronously:
$task = $myobj.MyAsyncMethod("arg");
$continuation = New-RunspacedDelegate ( [Action[System.Threading.Tasks.Task[object]]] {
param($t)
# do something with $t.Result here
} );
$task.ContinueWith($continuation);
See documentation on GitHub. (Disclaimer: I wrote it).
This works for me.
Add-Type -AssemblyName 'System.Net.Http'
$myobj = new-object System.Net.Http.HttpClient
$res = $myobj.GetStringAsync("https://google.com").Result
Write-Host "Result : " $res
Perhaps check that PowerShell is configured to use .NET 4:
How can I run PowerShell with the .NET 4 runtime?
I have a C# program which build me a TFS build definition. I want to do the same code in a powershell script. So far, I have been able code the script which will create me a new build definition in TFS. However, I have trouble setting Process section of the build definition. I need to convert the below code in C# to powershell and all attemps I have made did not work.
//Set process parameters
var process = WorkflowHelpers.DeserializeProcessParameters(buildDefinition.ProcessParameters);
//Set BuildSettings properties
BuildSettings settings = new BuildSettings();
settings.ProjectsToBuild = new StringList("$/Templates/Main/Service/application1");
settings.PlatformConfigurations = new PlatformConfigurationList();
settings.PlatformConfigurations.Add(new PlatformConfiguration("Any CPU", "Debug"));
process.Add("BuildSettings", settings);
buildDefinition.ProcessParameters = WorkflowHelpers.SerializeProcessParameters(process);
First I loaded the assemblies I need to work with TFS. When I want to replicate the same C# code as,
var process = WorkflowHelpers.DeserializeProcessParameters(buildDefinition.ProcessParameters);
I did following in PowerShell
$process = New-Object Microsoft.TeamFoundation.Build.Workflow.WorkflowHelpers.
Above gave me an error saying "Constructor not found. Cannot find an appropriate constructor for type Microsoft.TeamFoundation.Build.Workflow.WorkflowHelpers"
I checked and there are no constructors for that. My question is what I am I doing wrong in writing the PowerShell script to achieve the same functionality as c# code. I am sure it's syntax error that I am doing and not aware of the correct way of doing it in PowerShell.
It would appear from your code snippet (and confirmed via MSDN) that the DeserializeProcessParameters is a static method on the WorkflowHelpers class. You would need to invoke it with the following syntax in PowerShell:
$process = [Microsoft.TeamFoundation.Build.Workflow.WorkflowHelpers]::DeserializeProcessParameters($buildDefinition.ProcessParameters)
It looks like the buildDefinition variable is declared earlier - so I just stuck a $ character on it to make it a legit PowerShell variable. Same thing with the process variable. I hope this helps!
Hello everyone i am new in wpf. so i have got problems with it. if you help me, i will be so pleased. thanks everyone in advance.
My problem is, can not insert into name inside database in wpf. how can i fix it? my codes as follows;
private void button1_Click(object sender, RoutedEventArgs e)
{
try
{
string SqlString = "Insert Into UserInformation(name) Values (?)";
using (OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|Cell.mdb;Persist Security Info=True"))
{
using (OleDbCommand cmd = new OleDbCommand(SqlString, conn))
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("name", textBox1.Text);
conn.Open();
cmd.ExecuteNonQuery();
}
}
}
catch (Exception ex)
{ }
}
Try to use cmd.Parameters.AddWithValue("#name", textBox1.Text);
Is it opening the right database file? As people have suggested in the comments, set Visual Studio to break on first-chance exceptions, or remove the exception handling. The database file needs to exist, and you need the appropriate JET drivers.
I've tried your code and it works without any problems here (in a WPF application or otherwise). Using named parameters instead of a question mark was a good suggestion, but it doesn't appear to be the problem. (I have Office 2007 and .NET 3.5 SP1 installed, but I doubt that matters).
Are you using a WPF browser application (cbap)? Because you won't be able to access the local file system (and thus the database) if you are. WPF browser applications run with isolated permissions, much like a Silverlight browser application.
The problem here seams to be the parameter. In the command text you don't specify its name, but when you add it, it has a name. Change command text to :
Insert Into UserInformation(name) Values (#name)
In line:
cmd.Parameters.AddWithValue("name", textBox1.Text);
the parameter name should stay without # .