Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Executing External Process from Windows 8 Metro Application Using Native Proxy

0.00/5 (No votes)
17 Jul 2012 1  
This is probably the best solution I could think of for executing external process from Windows 8 metro application by using proxy application running as native application.

Downloads

ExecutingExternalProcessfromWindows8MetroApplicationUsingNativeProxy-noexe.zip

Introduction

This is probably the best solution I could think of for executing external process from Windows 8 metro application by using proxy application running as native application. But take note, this is not for production because you will be asking your clients to download an external application to be able to use your Metro application. What I done here is for a Proof of Concept only.

Background

The trick here is simple and basic

  1. Metro create a text file with some sort of command
  2. Proxy monitors the file changes
  3. Once changed, proxy reads that file and process it
  4. Then proxy executes the file needed to run.

So how's that possible?

We will be using 2 Visual Studio version here.

  1. Visual Studio for creating Metro application
  2. and your VS IDE where you can create a Windows Forms Application

Let's take a look at this code written for Metro application

public async void CreateTextCommand(string file_to_run)
{
    file = await KnownFolders.DocumentsLibrary.CreateFileAsync("proxyfile.txt", CreationCollisionOption.ReplaceExisting);
 
    // we added Ticks to act as applications UID
    // and to make sure that it doesn't spawn and run only one instance per click
    // check MetroProxy solution.
    string command = string.Format("run={0},{1}", file_to_run, DateTime.Now.Ticks);
 
    await FileIO.WriteTextAsync(file, command);
}

This method writes a file in your Documents folder called "proxyfile.txt" that contains 1 line of command.

run=<file_to_execute>

Then we let our proxy application process and execute that file once there are changed made from our Metro application. Monitoring the file changes is done via FileSystemWatcher.

void ProcessCommand()
{
    // pause for 100 millisecond for Windows to properly write the contents of the
    // proxyfile.txt
    System.Threading.Thread.Sleep(100);
 
    string file_to_run = string.Empty;
    string UID = string.Empty;
 
    string filename = Path.Combine(this.path, this.file);
 
    if (!File.Exists(filename))
    {
        MessageBox.Show("proxyfile.txt is missing!");
    }
 
    using (StreamReader reader = new StreamReader(filename))
    {
        string data = reader.ReadToEnd();
        string[] cmd2 = data.Split('=')[1].Split(',');
 
        file_to_run = cmd2[0];
        UID = cmd2[1];
    }
 
    if (!this.running_apps.Contains(file_to_run + UID))
    {
        RunOnce(file_to_run, UID);
    }
    else
    {
        Debug.WriteLine(file_to_run + " is already running");
    }
}
 
void RunOnce(string fullpath, string UID)
{
    ProcessStartInfo psi = new ProcessStartInfo()
    {
        FileName = fullpath,
        UseShellExecute = true
    };
 
    Process.Start(psi);
 
    // add to our ran list to make sure it does
    // not spawn a new instance each time we click on LeLaunch app buttons
    this.running_apps.Add(fullpath + UID);
 
    /*
     * Our NotifyFilter has
     * NotifyFilter = NotifyFilters.LastWrite which FileSystemWatcher monitors
     * so everytime we click the button on LeLaunch Metro application buttons
     * FileSystemWatcher.Changed is triggered.
     * 
     * but the problem was FileSystemWatcher.Changed is triggered 5 times for each
     * click on the button. so we have to filter this out by using UID
    */
} 

That's just it. Now you can execute any external application or file from your Metro application. If you want to put more complex commands, then you can use JSON

Points of Interest

FileSystemWatcher's job is to monitor the last changes made in the file that we are monitoring "proxyfile.txt" so we set our NotifyFilter to LastWrite

FileSystemWatcher.NotifyFilter = NotifyFilters.LastWrite 

So everytime we click the button on LeLaunch Metro application buttons, FileSystemWatcher.Changed is triggered.

but the problem was FileSystemWatcher.Changed is triggered 5 times for each click on the button. so we have to filter this out by using UID.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here