none
Running an exe file form SIlverlight resource

    Question

  • Hello everyone,

    I have an exe file into the specific folder in my Silverlight project, I also seted up this file as Embedded Resource. What I'm trying to do is at Run Time, execute that exe file some way. If for some reason it's not possible, I wonder save that file in windows TEMP folder and then run it from there.

    Could anybody help me out?

    Monday, February 04, 2013 10:44 AM

Answers

  • Hi,

    I changed a little the code to write the exe in a temporal path first.

    Remember, configure your Silverlight application in this way:

    Mark in the project properties the option:

    Require elevated trust when running in-browser.

    When you do that, can run a code like this:

            private void button1_Click(object sender, RoutedEventArgs e)
            {
                if (App.Current.HasElevatedPermissions)
                {
                    WebClient myWebClient = new WebClient();
                    myWebClient.OpenReadCompleted += new OpenReadCompletedEventHandler(myWebClient_OpenReadCompleted);
                    myWebClient.OpenReadAsync(new Uri("SilverlightPruebas.xap", UriKind.RelativeOrAbsolute));
                }
            }

            void myWebClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
            {
                StreamResourceInfo streamXAP = new StreamResourceInfo(e.Result, null);

                StreamResourceInfo streamFile = Application.GetResourceStream(streamXAP,
                    new Uri("PruebaExe.exe", UriKind.Relative));

                SaveFile(@"C:\Windows\Temp", "PruebaExe.exe", ReadToEnd(streamFile.Stream));
                dynamic exeFile = AutomationFactory.CreateObject("WScript.Shell");
                exeFile.Run(@"C:\Windows\Temp\PruebaExe.exe");
       
            }

            private void SaveFile(string directoryPath, string fileName, byte[] fileBytes){
                if (!Directory.Exists(directoryPath))
                {
                    Directory.CreateDirectory(directoryPath);
                }

                // build the full filename
                var fullPath = directoryPath + @"\" + fileName;

                // write a new file
                using (FileStream fs = File.Create(fullPath))
                {
                    foreach (byte myBite in fileBytes)
                    {
                        fs.WriteByte(myBite);
                    }
                }
            }
            public static byte[] ReadToEnd(System.IO.Stream stream)
            {
                long originalPosition = 0;

                if (stream.CanSeek)
                {
                    originalPosition = stream.Position;
                    stream.Position = 0;
                }

                try
                {
                    byte[] readBuffer = new byte[4096];

                    int totalBytesRead = 0;
                    int bytesRead;

                    while ((bytesRead = stream.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0)
                    {
                        totalBytesRead += bytesRead;

                        if (totalBytesRead == readBuffer.Length)
                        {
                            int nextByte = stream.ReadByte();
                            if (nextByte != -1)
                            {
                                byte[] temp = new byte[readBuffer.Length * 2];
                                Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length);
                                Buffer.SetByte(temp, totalBytesRead, (byte)nextByte);
                                readBuffer = temp;
                                totalBytesRead++;
                            }
                        }
                    }

                    byte[] buffer = readBuffer;
                    if (readBuffer.Length != totalBytesRead)
                    {
                        buffer = new byte[totalBytesRead];
                        Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead);
                    }
                    return buffer;
                }
                finally
                {
                    if (stream.CanSeek)
                    {
                        stream.Position = originalPosition;
                    }
                }
            }

    Notes:

    1. The users of application must be the machine administrators or to have the adequate permissions to execute the exe file.

    2. My EXE PruebaExe.exe is on Silverlight application root path and its Build Action is Content.

    Please, mark as answer if this help you.

    • Marked as answer by iwpfModerator Monday, February 18, 2013 10:38 AM
    Wednesday, February 06, 2013 7:35 PM

All replies

  • Hi Leo_PQD, you cannot do that. Silverlight runs on client machine. For security reason you cannot run a local program via Silverlight.

    My 2 cents.

    Regards


    - Chris.

    Monday, February 04, 2013 6:30 PM
  • Hi,

    Starting in Silverlight 5, is posible to mark in project properties:

    Require elevated trust when running in-browser.

    When you do that, can run a code like this:

            private void button1_Click(object sender, RoutedEventArgs e)
            {
                if (App.Current.HasElevatedPermissions)
                {
                    dynamic exeFile = AutomationFactory.CreateObject("WScript.Shell");
                    exeFile.Run(@"C:\Windows\Temp\PruebaExe.exe");
                }
            }

    And that works.

    Please, mark as answer if this help you.

    Note: The users of application must be the machine administrators or to have the adequate permissions to execute the exe file.


    Monday, February 04, 2013 7:24 PM
  • Hi César,

    nice answer, but I still in doubt.

    In your sample you wrote a fixed path where the .exe file suppose to be ("C:\Windows\Temp\PruebaExe.exe"), so far so good, but in my case

    my .exe file is inside of my project, into the XAP, i created a file called Assets in my  SL project and puted the file there as a Resource. What I need is run your

    code sample above, but find the .exe file into the Assets folther in my XAP instead of a fixed path.

    Can I get this?

    Monday, February 04, 2013 8:08 PM
  • Leo_PQD you can run .exe if your silverlight project runs on out-of-the-browser only.

    You cannot run your .exe from the way you want.

    Best regards.


    - Chris.

    Tuesday, February 05, 2013 1:11 PM
  • Christian, thank you for replay,
    I understand your point, but at least the path of my current running solution, suppose I should be able to get, right?

    The problem is: I already tried all the samples below and no one worked.

    "var dfgh = System.Reflection.Assembly.GetExecutingAssembly().GetAssemblyName();" -> This, brings me empty sting.

    I tried all the methods showed in this link:

    "http://www.dotnetfunda.com/codes/code2471-how-to-get-the-pathdirectory-for-the-current-assembly.aspx"

    No Success.

    Any Idea?

    Thanks!


    • Edited by Leo_PQD Tuesday, February 05, 2013 4:37 PM
    Tuesday, February 05, 2013 1:43 PM
  • Hi,

    I changed a little the code to write the exe in a temporal path first.

    Remember, configure your Silverlight application in this way:

    Mark in the project properties the option:

    Require elevated trust when running in-browser.

    When you do that, can run a code like this:

            private void button1_Click(object sender, RoutedEventArgs e)
            {
                if (App.Current.HasElevatedPermissions)
                {
                    WebClient myWebClient = new WebClient();
                    myWebClient.OpenReadCompleted += new OpenReadCompletedEventHandler(myWebClient_OpenReadCompleted);
                    myWebClient.OpenReadAsync(new Uri("SilverlightPruebas.xap", UriKind.RelativeOrAbsolute));
                }
            }

            void myWebClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
            {
                StreamResourceInfo streamXAP = new StreamResourceInfo(e.Result, null);

                StreamResourceInfo streamFile = Application.GetResourceStream(streamXAP,
                    new Uri("PruebaExe.exe", UriKind.Relative));

                SaveFile(@"C:\Windows\Temp", "PruebaExe.exe", ReadToEnd(streamFile.Stream));
                dynamic exeFile = AutomationFactory.CreateObject("WScript.Shell");
                exeFile.Run(@"C:\Windows\Temp\PruebaExe.exe");
       
            }

            private void SaveFile(string directoryPath, string fileName, byte[] fileBytes){
                if (!Directory.Exists(directoryPath))
                {
                    Directory.CreateDirectory(directoryPath);
                }

                // build the full filename
                var fullPath = directoryPath + @"\" + fileName;

                // write a new file
                using (FileStream fs = File.Create(fullPath))
                {
                    foreach (byte myBite in fileBytes)
                    {
                        fs.WriteByte(myBite);
                    }
                }
            }
            public static byte[] ReadToEnd(System.IO.Stream stream)
            {
                long originalPosition = 0;

                if (stream.CanSeek)
                {
                    originalPosition = stream.Position;
                    stream.Position = 0;
                }

                try
                {
                    byte[] readBuffer = new byte[4096];

                    int totalBytesRead = 0;
                    int bytesRead;

                    while ((bytesRead = stream.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0)
                    {
                        totalBytesRead += bytesRead;

                        if (totalBytesRead == readBuffer.Length)
                        {
                            int nextByte = stream.ReadByte();
                            if (nextByte != -1)
                            {
                                byte[] temp = new byte[readBuffer.Length * 2];
                                Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length);
                                Buffer.SetByte(temp, totalBytesRead, (byte)nextByte);
                                readBuffer = temp;
                                totalBytesRead++;
                            }
                        }
                    }

                    byte[] buffer = readBuffer;
                    if (readBuffer.Length != totalBytesRead)
                    {
                        buffer = new byte[totalBytesRead];
                        Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead);
                    }
                    return buffer;
                }
                finally
                {
                    if (stream.CanSeek)
                    {
                        stream.Position = originalPosition;
                    }
                }
            }

    Notes:

    1. The users of application must be the machine administrators or to have the adequate permissions to execute the exe file.

    2. My EXE PruebaExe.exe is on Silverlight application root path and its Build Action is Content.

    Please, mark as answer if this help you.

    • Marked as answer by iwpfModerator Monday, February 18, 2013 10:38 AM
    Wednesday, February 06, 2013 7:35 PM
  • can u send me whole project plz i want to try something else on it ...

    my email ID

    kalpesh.mapelkar@ves.ac.in

    Wednesday, April 01, 2015 7:54 AM
  • plz send me all  project file related to this topic . my emailID :- kalpesh.mapelkar@ves.ac.in 
    Wednesday, April 01, 2015 7:57 AM
  • This solution worked for my test application. Thanks.

    In my actual application, service & client were in the same solution and having multiple startup projects. Hence reading via web client didn't work. 

    To resolve that problem, I added that executable as embedded resource & created a stream object using reflection and used remaining things as mentioned above. That worked fine.


    if (App.Current.HasElevatedPermissions)
                {
                    string output = "";

                    try
                    {
                        var stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(@"SLTest.MyConsoleApp.exe");
                        StreamResourceInfo streamXAP = new StreamResourceInfo(stream, null);
                        
                        string appPath = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "MyConsoleApp.exe");
                        SaveFile(System.IO.Path.GetTempPath(), "MyConsoleApp.exe", ReadToEnd(streamXAP.Stream));
                        dynamic shell = AutomationFactory.CreateObject("WScript.Shell");
                        string exeParams = "some parameters";
                        string executeCommand = string.Format(@"{0} {1}""", appPath, exeParams);
                        dynamic resul = null;

                        resul = shell.Exec(executeCommand);
                        while (!resul.StdOut.AtEndOfStream)
                        {
                            output += resul.StdOut.ReadLine() + "\r\n";
                        }
                    }
                    catch (Exception ex)
                    {
                        output = ex.Message;
                        if (null != ex.InnerException)
                            output += "\n" + ex.InnerException.Message;
                    }

                    MessageBox.Show(output);
                }


    Wednesday, January 18, 2017 5:22 PM
  • I know it's very old post but still, i am replying because it would help someone else....

    You have to give embedded resource name along with namespace like below.

    var stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(@"SLTest.MyConsoleApp.exe");

    Thursday, January 19, 2017 8:26 PM