update task using Task Scheduler Managed Wrapper? - c#

Here's the library I'm using:
http://taskscheduler.codeplex.com/wikipage?title=Install&referringTitle=Documentation
Here's the code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32.TaskScheduler;
namespace ConsoleApplication1 {
class Program {
static void Main(string[] args) {
var p = new Program();
p.EnumAllTasks();
}
void EnumAllTasks() {
using (TaskService ts = new TaskService())
EnumFolderTasks(ts,ts.RootFolder);
}
void EnumFolderTasks(TaskService ts, TaskFolder fld) {
var tasks = fld.Tasks.Where(t => t.Name.Equals("test-task", StringComparison.OrdinalIgnoreCase));
foreach (Task task in tasks)
ActOnTask(ts, task);
}
void ActOnTask(TaskService ts, Task t) {
//ea.Path
Console.WriteLine(t.Name);
Console.WriteLine(t.Path);
Console.WriteLine(((ExecAction)t.Definition.Actions.First()).Path);
var ea = (ExecAction)t.Definition.Actions.First();
ea.Path = ea.Path + ".coolio/test.exe";
UpdateFirstAction(t, new ExecAction(ea.Path+".coolio/test.exe",ea.Arguments,ea.WorkingDirectory));
//ts.s
// Do something interesting here
}
void UpdateFirstAction(Task t, Microsoft.Win32.TaskScheduler.Action action) {
if (t.TaskService.HighestSupportedVersion >= new Version(1, 2)) {
Console.WriteLine("HERE");
t.Definition.Actions.RemoveAt(0);
}
t.Definition.Actions.Add(action);
}
}
}
I added the 'UpdateFirstAction' method based upon the following: https://taskscheduler.codeplex.com/discussions/203704
I want to be able to update the path that's getting executed, and the above link seems to imply that updating the collection is enough.
How do I actually save the changes? All of the documentation I've read seems to describe how to read things only.

You can omit the UpdateFirstAction method. The library since version 1.6.1 has fixed the bug from that discussion item. The code is correct on how to edit the Path property. To update the task with the changed Path, you only need to call t.RegisterChanges() at the point you are calling UpdateFirstAction.

Related

CefSharp how to rename and embed BrowserSubProcess.exe

iam quite desperate here. I couldn't find any example code for this in C#.
I want to rename BrowserSubProcess.exe and i want it to embed my main exe, if possible.
I am aware of this solution;
https://github.com/cefsharp/CefSharp/issues/1149#issuecomment-225547869
Rename CefSharp.BrowserSubprocess winforms
but i couldn't implemented it. I need sample program or code to understand. I hope #amaitland will see this and helps me.
I embed the BrowserSubProcess Program.cs to my Program.cs so it is embedded now.
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
if (args.Count() < 5)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new LoginForm());
}
else
{
MyBrowserSubProcess(args);
}
}
static int MyBrowserSubProcess(string[] args)
{
Debug.WriteLine("BrowserSubprocess starting up with command line: " + String.Join("\n", args));
SubProcess.EnableHighDPISupport();
int result;
var type = args.GetArgumentValue(CefSharpArguments.SubProcessTypeArgument);
var parentProcessId = -1;
// The Crashpad Handler doesn't have any HostProcessIdArgument, so we must not try to
// parse it lest we want an ArgumentNullException.
if (type != "crashpad-handler")
{
parentProcessId = int.Parse(args.GetArgumentValue(CefSharpArguments.HostProcessIdArgument));
if (args.HasArgument(CefSharpArguments.ExitIfParentProcessClosed))
{
Task.Factory.StartNew(() => AwaitParentProcessExit(parentProcessId), TaskCreationOptions.LongRunning);
}
}
// Use our custom subProcess provides features like EvaluateJavascript
if (type == "renderer")
{
var wcfEnabled = args.HasArgument(CefSharpArguments.WcfEnabledArgument);
var subProcess = wcfEnabled ? new WcfEnabledSubProcess(parentProcessId, args) : new SubProcess(args);
using (subProcess)
{
result = subProcess.Run();
}
}
else
{
result = SubProcess.ExecuteProcess();
}
Debug.WriteLine("BrowserSubprocess shutting down.");
return result;
}
private static async void AwaitParentProcessExit(int parentProcessId)
{
try
{
var parentProcess = Process.GetProcessById(parentProcessId);
parentProcess.WaitForExit();
}
catch (Exception e)
{
//main process probably died already
Debug.WriteLine(e);
}
await Task.Delay(1000); //wait a bit before exiting
Debug.WriteLine("BrowserSubprocess shutting down forcibly.");
Environment.Exit(0);
}
}
And my BrowserSubprocessPath is my main exe.
settings.BrowserSubprocessPath = System.AppDomain.CurrentDomain.FriendlyName;
I finally managed to rename this sub process! Haven't found any solution how to do it through the CefSharp API, but found my own worked solution.
So, In your code that uses CefSharp add one setting to the Cef Settings, before Cef.Initialize()
using CefSharp;
using CefSharp.Wpf;
using System.IO;
using System.Reflection;
using System.Windows;
public App()
{
var settings = new CefSettings
{
BrowserSubprocessPath = Path.Combine(GetAppPath(), $#"runtimes\win-x64\native{ GetAppName() }.exe")
};
Cef.InitializeAsync(settings);
}
private static string GetAppPath()
{
return new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName;
}
private static string GetAppName()
{
return Assembly.GetExecutingAssembly().GetName().Name;
}
After this go to the bin\Debug\net6.0-windows\runtimes\win-x64\native\ and rename CefSharp.BrowserSubprocess.exe to Name you want to use.
Done. Now it will use this file with custom name you need.
P.S. For the auto name set you can always use Post-Build event with command to rename the file after project built and set the name same as your assembly name. I use this approach for my needs.

Define Entry Point of a BackgroundTask for UWP

I want to know how can I declarate in the EntryPoint of a Declaration in the manifest file the location of the code to execute as a background task.
I have my code set in a folder called "Models" inside the project, But I don't know how to reffer to this code.
Here you have a picture of it:
Just in case, here is my code inside the cs:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.ApplicationModel.Background;
using Windows.UI.Popups;
namespace Universal_in_C.Models
{
public sealed class ExampleBackgroundTask : IBackgroundTask
{
public async Task ExampleMethodAsync()
{
Debug.WriteLine("Done Exe");
var dialog = new MessageDialog("TESTING, TESTING LIKE THERE IS NO TOMORROW.");
await dialog.ShowAsync();
}
public async void Run(IBackgroundTaskInstance taskInstance)
{
BackgroundTaskDeferral _deferral = taskInstance.GetDeferral();
await ExampleMethodAsync();
_deferral.Complete();
}
}
}
And how I call it(I know that I need to change the entry here too);
private void button6_Click(object sender, RoutedEventArgs e)
{
var taskRegistered = false;
var exampleTaskName = "BackgroundTask";
foreach (var task in BackgroundTaskRegistration.AllTasks)
{
if (task.Value.Name == exampleTaskName)
{
taskRegistered = true;
break;
}
}
if (taskRegistered)
{
Debug.WriteLine("Already Exist");
}
else
{
var builder = new BackgroundTaskBuilder();
Debug.WriteLine("Started to Exist");
builder.Name = exampleTaskName;
builder.TaskEntryPoint = "exampleTaskName";
builder.SetTrigger(new SystemTrigger(SystemTriggerType.InternetAvailable, true));
builder.AddCondition(new SystemCondition(SystemConditionType.UserPresent));
builder.Register();
}
}
Thanks!
From what I understand, you are having problems declaring the background task on the manifest file. Based on this, my answer.
You need to create a new project that will contain your background tasks. This is necessary in order to correctly debug them later on.
Reference the project on your application.
Create the task by implementing the IBackgroundTask interface.
Register it via code.
Register it on the manifest.
At step number 5, the entry point is always the {project namespace}.{background task name}, so for example if you created a project names BackgroundTasks with a task ExampleTask, the entry point will be: BackgroundTasks.ExampleTask
I'll leave for future references a link to the guidelines and tutorial on how to implement them.

Error 1 The name 'WriteAt' does not exist in the current context

I'm trying to write a game in C# that runs on my cmd on Windows and I need to be able to write to any part of the box to do that. I found WriteAt used extensively for this purpose, however it doesn't seem to work in VS 2010. I get the error: "The name WriteAt does not exist in the current context"
I have the default:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
at the top of my code. So why can't I use WriteAt?
Here's my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GamePCL
{
class Program
{
static void Main(string[] args)
{
Console.Clear();
for (int x = 0; x < 24; x += 2)
{
WriteAt("█", x, 0);
WriteAt("█", x, 30);
}
}
}
}
When you call a method without an object or type prefix, as in this case WriteAt() (as opposed to for example Console.WriteLine(), which is called on the Console type), the method must exist in the current context, i.e. in the current class.
You copied that code from MSDN without copying the relevant method:
protected static void WriteAt(string s, int x, int y)
{
try
{
Console.SetCursorPosition(origCol+x, origRow+y);
Console.Write(s);
}
catch (ArgumentOutOfRangeException e)
{
Console.Clear();
Console.WriteLine(e.Message);
}
}

Handling collection events with MongoDB C# driver (v2.0)

Playing with the new MongoDB driver (v2.0) has been quite challenging. Most of the examples you find on the web still refer to the legacy driver. The reference manual for v2.0 on the official Mongo site is "terse", to say the least.
I'm attempting to do a simple thing: detect when a collection has been changed in order to forward a C# event to my server application.
For doing so, I've found the following C# example (see below) that I'm trying to convert to the new API.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
namespace TestTailableCursor {
public static class Program {
public static void Main(string[] args) {
try {
var server = MongoServer.Create("mongodb://localhost/?safe=true");
var database = server["test"];
if (database.CollectionExists("capped")) {
database.DropCollection("capped");
}
var collectionOptions = CollectionOptions.SetCapped(true).SetMaxDocuments(5).SetMaxSize(10000);
var commandResult = database.CreateCollection("capped", collectionOptions);
var collection = database["capped"];
// to test the tailable cursor manually insert documents into the test.capped collection
// while this program is running and verify that they are echoed to the console window
// see: http://www.mongodb.org/display/DOCS/Tailable+Cursors for C++ version of this loop
BsonValue lastId = BsonMinKey.Value;
while (true) {
var query = Query.GT("_id", lastId);
var cursor = collection.Find(query)
.SetFlags(QueryFlags.TailableCursor | QueryFlags.AwaitData)
.SetSortOrder("$natural");
using (var enumerator = (MongoCursorEnumerator<BsonDocument>) cursor.GetEnumerator()) {
while (true) {
if (enumerator.MoveNext()) {
var document = enumerator.Current;
lastId = document["_id"];
ProcessDocument(document);
} else {
if (enumerator.IsDead) {
break;
}
if (!enumerator.IsServerAwaitCapable) {
Thread.Sleep(TimeSpan.FromMilliseconds(100));
}
}
}
}
}
} catch (Exception ex) {
Console.WriteLine("Unhandled exception:");
Console.WriteLine(ex);
}
Console.WriteLine("Press Enter to continue");
Console.ReadLine();
}
private static void ProcessDocument(BsonDocument document)
{
Console.WriteLine(document.ToJson());
}
}
}
A few (related) questions:
Is that the right approach with the new driver?
If so, how do I set collection options (like SetCap in the example above). The new API includes something called "CollectionSettings", which seems totally
unrelated.
Is my only option to rely on the legacy driver?
Thanks for your help.
Is my only option to rely on the legacy driver?
No.
[...] how do I set collection options (like SetCap in the example above). The new API includes something called "CollectionSettings", which seems totally unrelated.
There's CreateCollectionSettings now. CollectionSettings is a setting for the driver, i.e. a way to specify default behavior per-collection. CreateCollectionOptions can be used like this:
db.CreateCollectionAsync("capped", new CreateCollectionOptions
{ Capped = true, MaxDocuments = 5, MaxSize = 10000 }).Wait();
Is that the right approach with the new driver?
I think so, tailable cursors are a feature of the database, and avoiding polling always makes sense.
I converted the gist of the code and it appears to work on my machine™:
Be careful when using .Result and .Wait() in a web or UI application.
private static void ProcessDocument<T>(T document)where T : class
{
Console.WriteLine(document.ToJson());
}
static async Task Watch<T>(IMongoCollection<T> collection) where T: class
{
try {
BsonValue lastId = BsonMinKey.Value;
while (true) {
var query = Builders<T>.Filter.Gt("_id", lastId);
using (var cursor = await collection.FindAsync(query, new FindOptions<T> {
CursorType = CursorType.TailableAwait,
Sort = Builders<T>.Sort.Ascending("$natural") }))
{
while (await cursor.MoveNextAsync())
{
var batch = cursor.Current;
foreach (var document in batch)
{
lastId = document.ToBsonDocument()["_id"];
ProcessDocument(document);
}
}
}
}
}
catch (Exception ex) {
Console.WriteLine("Unhandled exception:");
Console.WriteLine(ex);
}
}

Trying to learn about the new async features in c#

I copied this example from here
I have seen many similar examples. Most of them say they're using the Async CTP. I'm using Visual Studio 11 on Windows 8 though so that does not apply. As shown, the error says TaskEx doesn't exist. I assume I'm missing a reference but don't know which one.
This page is http://users.zoominternet.net/~charleswatson/pic.png.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static Random rnd = new Random();
static void Main(string[] args)
{
//Do some other heavy duty background task in this thread
StartHotel();
Console.WriteLine("StartHotel called..");
Console.ReadLine();
}
static void StartHotel()
{
Console.WriteLine("Starting Hotel..");
for (int i = 0; i < 10; i++)
{
string name = "Chef" + i;
CookDish(name, "Dish" + i);
Console.WriteLine("Asked {0} to start cooking at {1}", name, DateTime.Now.ToString());
}
}
static async void CookDish(string chefName, string dish)
{
//Induce a random delay
int delay = rnd.Next(1000, 4000);
//Cook is cooking - Task
await TaskEx.Delay(delay);
//Write the result - StuffAfterAwait
Console.WriteLine("Chef {0} Finished at {1}", chefName, DateTime.Now.ToString());
}
}
}
In the CTP we were unable to add new features to the Task type so we did the pragmatic thing and just made a new TaskEx type. In the final release there will be no such type; those methods will just be on Task like you'd expect.
Replace TaskEx with Task. At the top of the .cs file, you'll need:
using System.Threading.Tasks;
Much of the sample code I've seen refers to TaskEx, and the estimable Mr. Lippert seems to be indicating that's an artifact of their development process. If you're using the Developer Preview, calls like Run, WhenAll, and Delay are already methods of the class Task rather than of TaskEx. The release tools should be the same.

Categories