case
18Mar/0957

Communicate betwen C# and an embeded Flash application


The External API allows an ActionScript developer to easily interact with the container program that is hosting Flash Player 8 and vice versa. The majority of the time, this will most likely be a Web browser, but this does not always have to be the case.

As many C# developers know, it is easy to house an ActiveX control (the IE version of Flash Player) in a .NET Windows application. This means we can now load an SWF in our Windows application and easily send data back and forth. Keep in mind that the keyword in this statement is "easily;" although possible before, it was not nearly as simple as the External API makes it now!

C# to ActionScript Communication

As I said before, communication between Flash Player and its container has been made extremely easy. The new class that makes this process so easy is the ExternalInterface. We will begin in the ActionScript. First, we need to import this new class so we can use it (as2 only, in as3 it will work without the import):

import flash.external.ExternalInterface;

Next, we have to register any function we want to make available externally:

ExternalInterface.addCallback("addText", addText);

Basically, the code above will allow us to call the addText function (which I will show in a minute) from the C# application.
The addText function is as below. Basically, it takes a string input and appends it to a text box

function addText(val:String):void
{
	inTxt.appendText(val + "\n"); // append text recieved from c#
}

That's it from the ActionScript side. Now all we need to do is call the function from C#. First, I add an instance of the Flash Player ActiveX control to my form and load the SWF we created in the form's constructor:

private AxShockwaveFlash player;
 
public DemoForm ()
{
     ...
     player.LoadMovie(0, Application.StartupPath + "\\EITest.swf");
     player.Play();
     ...
}

Next, all we have to do is call the externalized method when desired. In my case, it is in response to the user clicking the send button:

private void sendBtn_Click(object sender, EventArgs e)
{
    player.CallFunction("" + outTxt.Text + "");
}

ActionScript to C# Communication

Again, you will need to use the ExternalInterface in the ActionScript:

function send(evt : Event):void
{
	ExternalInterface.call("sendText", outTxt.text); // function to call and it's parameters
	outTxt.text = ""; // reset text box
}

As you can see, I am calling a method sendText and passing the input string as a parameter. Now to receive the message in C#, we first have to subscribe to the FlashCall event. You can do this in the constructor or from the activex properties panel on events tab.

Now the call made in ActionScript will be received in the request property of the event argument. For my particular call, the XML will look like this:

<invoke name="sendText" returntype="xml">
<arguments>
<string>some text message here</string>
</arguments>
</invoke>

So now all we have to do is parse the XML in the event handler and invoke the C# function locally:

private void player_FlashCall(object sender, _IShockwaveFlashEvents_FlashCallEvent e)
{
    // message is in xml format so we need to parse it
    XmlDocument document = new XmlDocument();
    document.LoadXml(e.request);
    // get attributes to see which command flash is trying to call
    XmlAttributeCollection attributes = document.FirstChild.Attributes;
    String command = attributes.Item(0).InnerText;
    // get parameters
    XmlNodeList list = document.GetElementsByTagName("arguments");
    // Interpret command
    switch (command)
    {
        case "sendText" : resultTxt.Text = list[0].InnerText; break;
        case "Some_Other_Command" : break;
    }
}

Viola!

c# to flash activex demo

I have made the simple example discussed available here.


Comments (57) Trackbacks (2)
  1. Thanks for the great resource

  2. It is nice work,
    I am new to Flex.
    It would be great if you can share the Action Script file as well, i.e the source code of SWF file as well.
    Thanks.
    Pankaj

  3. @Pankaj
    it’s there in the zip file under Flash Project folder

  4. Hi,
    In the Flash Project, there are two files .swf and .fla
    what I needed was some .as file or .msxml file which I can open on Flex Builder and see the code behind that flash file.

    Thanks
    Pankaj

  5. @Pankaj

    csharp.as
    ——————–
    package
    {
    import flash.external.ExternalInterface;

    public class Csharp
    {
    private var _text : TextArea;

    public function Csharp(someTextArea : TextArea)
    {
    this._text = someTextArea;
    ExternalInterface.addCallback(“addText”,addText);
    }

    // get message from c#
    private function addText(val:String):void
    {
    _text.appendText(val + “\n”);
    }

    // Send message to C#
    public function send(message : String):void
    {
    ExternalInterface.call(“sendText”, message);
    }
    }
    }

    the way to use it is

    var com : Csharp = new Csharp(responseBox); // where responseBox is a textarea where messages will be apended when recived from c#

    and if you want to send someting you do
    com.send(‘hello from flash’);

    that’s it. the code was in the article, rest of it was just…interface

  6. Hey man, this works perfect, but what if I want to send more than 1 data to C# with the same function. Do I have to put several ExternalInterface.call inside the button function o with just one I can send a lot of data ?

  7. @Lucas
    As you see, in c# there is a switch on the command function recived from flash. in the example i gave a comment ago, the function send(message:String) uses the command sendText, but you can use that as a parameter as well.

    public function send(command : String, message : String):void
    {
    ExternalInterface.call(command, message);
    }

    and in c#

    switch (command)
    {
    case “sendText” : doSometing(); break;
    case “Some_Other_Command” : doSometingElse(); break;
    case ….
    …..
    }

    • Hello, I too have found this article very helpful. But I’d also like to expand on @Lucas question. What if I wanted to send an object, that contains several properties, say 6. We’ll keep it simple, and say the properties are strings and ints. Would the Send function change as this:

      public function send(command : String, requestObj : FlashBlob):void
      {
      ExternalInterface.call(command, requestObj);
      }

      On the C# side, I was thinking of serializing the XML, but I am confused as to what it would look like.
      Like this?

      city
      42
      12
      false

      I get that going from C# to Flex requires a string, but I can deserialize FlashBlob. Just like in your source code.

      TIA

    • Whoops, that XML for my previous comment should have read:
      “”
      “”
      “city”
      “42”
      “12”
      “false”
      “”
      “”

      or will it look like:
      “”
      “”
      “city”
      “42”
      “12”
      “false”
      “”
      “”

      I’m going to click submit, so here’s to hoping the quotes kept the xml tags.

      • you should try to serialize/deserialize with JSON encoding. For Actionscript there is a class on my blog : http://blog.another-d-mention.ro/stuff/Serializer.as

        this will make your object look something like this “{city:’cityiname’, zipcode:1234}” and so on. This json encoded object can be passed with ExternalInterface because is a string. Once the object is sent you can deserialize it on the other side and cast it to a regular object.

        But there are numerous ways in which you can encode your object. you can use binary stuff, or csv like structure, or a base64 encoded bytearray where you can place whatever you want. And yes. you can serialize it to a xml and pass that around. but plain code object will not do. arguments are string only

        • Excellent suggestion. Thank you. So the XML coming from ActionScript to C# would look more like this: (assume tags)

          invoke name=sendText returntype=xml
          arguments
          string-{city:cityiname, zipcode:1234}-string (with braces?)
          arguments
          invoke

          I believe I can handle that in C#. Would it be acceptable to use your Serializer.as?

          Thanks again for the suggestion.

  8. Hi,

    This is my first interaction with flex.
    Can i use flex to carry out memory dump of flash application without using ShockwaveFlash COM object?

    Thanks.

  9. Hi,

    Thank you for this very useful article. Do you have idea, how can I extend this to give back a return value at AS->C# call ?
    Because now AS->C# is a simple procedure, not a function call and in a lot case return value is needed…

  10. Any way to do this with Flash Lite?

  11. @Scott
    Flash Lite has no equivalent api feature like the AS3 ExternalInterface api. One potential way to send data from Flash to another local application is with fscommand(). Another common approach is to build the native application as a local server and use xml sockets as a way to send data back and forth.

  12. great Work!Really Helpful.

  13. thank you !
    it was really helpfull !
    sample on adobe site is horror !
    this is awsome !

    KISS ! ( keep it simple & stupid )

  14. hi all;
    i wrote this code in flash as3:

    ExternalInterface.addCallback(“mySong”, playSong);

    function playSong(path:String):void
    {
    var snd:Sound = new Sound();
    snd.load(new URLRequest(path));
    snd.play();
    }

    and then this error was thow


    Attempting to launch and connect to Player using URL H:\Untitled-2.swf
    [SWF] H:\Untitled-2.swf – 31686 bytes after decompression
    Error: Error #2067: The ExternalInterface is not available in this container. ExternalInterface requires Internet Explorer ActiveX, Firefox, Mozilla 1.7.5 and greater, or other browsers that support NPRuntime.
    at Error$/throwError()
    at flash.external::ExternalInterface$/addCallback()
    at Untitled_fla::MainTimeline/frame1()[Untitled_fla.MainTimeline::frame1:2]
    Cannot display source code at this location.

    I ignored this error and export the file as swf, and used it in c# app by writing this code

    private void simpleButton1_Click(object sender, EventArgs e)
    {
    axShockwaveFlash1.CallFunction(@”H:01.mp3″);
    }

    and then this error was throw


    Error HRESULT E_FAIL has been returned from a call to a COM component.

    can any one help me to fix this error, i’m using windows xp sp2, vs2008, adobe flash cs5 action script 3

    • why are you calling the flash function like that ? you must hive it the function name as a string and whatever parameters you wish to send. you don’t have access to the library assets through external interface

  15. Hi all, This is really nice work. But I could not download the project files as it seems that link is broken. Can some one help me? Thanks in advance.

  16. Hi, thank for this piece of work, is very clear and helpful, what if i want to get an image or bytearray from c# wrapper into flash ? i’ve been trying using different datatype declaration, but is not working to me actually, every hint or pointing word will be appreciated, thank u 😀

  17. What instead about using flash bitmap to be composd with other c# computation, i mean how can be fastly used the bitmap of flash viewport ?

    • Depends on what are you building there ? I don’t think you can have high performance moving bitmaps around. Communication via ExternalInterface is mostly for simple method calls and such. If you need a desktop app with flash capabilities/graphics, take a look at what AIR can do. You can also compile C code into flex libraries with Alchemy but the bottleneck is the flash VM that has pretty limited performance. High performance filters and computations can be made on flash side with Pixel Bender (I never actually used it but I’ve seen some cool stuff made with it). It all goes down to what are you trying to build. So…more details.

      • well i always checked the chance about pixelbender, alchemy and c using the new AVmachine 2 from flash 10.
        What am i building ? a flash game that can handle contours on image, i can do it in several ways, i was asking something more precise:in the case i have a c# wrapper and it displays a flash, how can i use the flash layer ? i mean non using externalinterface and whatever, is there a way to get the flash displayObject bitmap to be managed into c# ?

  18. I am new to flex – I built a flex 4.0 program – when I try to host it inside the Windows form application, it won’t displayed.

    I have flash player 10 installed on my computer, but I think that the activeX runs lower flash version, so that’s why I cannot run the flex 4 script. (flex 4 requires flash player 10)

    any idea?

    • Flex 4 apps are broken down in multiple swf files. Not just 1 swf like the previous version. Maybe you copied just the app and forgot the framework files.

      • Thanks for your reply.
        I copied all the files created by the Flash Builder – still have that problem.
        also, when I open that swf file with a standalone flash player it runs properly.

        With the C# app I receive the following error:
        “VerifyError: Error #1014: Class spark.components::Application could not be found.”

        I built a flex 3.5 app – and it works fine.
        But I do want to use flex 4.0
        Best regards, alon.

        • i don’t know way to much about flex 4 but i think you can specify somewhere in the compiler properties that you want all the framework and everything embeded in your application swf. that should take care of the problem if it works. if not then you need the swc, swf or whatever extension it has that contains the spark class next to your app

  19. What changes I need if i am using AS2

  20. thats Ok!!!!!!!!
    tnx a lot.

  21. sir i need your help i tried to redo what you have done but when i did a error occurred and i really cant figure it out here’s the error

    HRESULT E_FAIL flash error

    error occurs when i send a data to flash…

    • i already figured out what seems to be the problem the program cant communicate to flash AS2 sir can you somehow try to upload the tutorial in a AS2 flash cause i am not really familiar with flash AS3

      please thanks

      • there may be 2 ways to implement it using AS2:
        – have them communicate with each other via LocalConnection. Here is a website I found where you can download some examples, but the win32 app is written in c so you need some conversion there or maybe you can find some already written layer in c# for LocalConnection (http://osflash.org/localconnection)
        – you can use SetVariable and GetVariable (http://bojordan.com/log/?p=269). I haven’t looked for more specific examples but I’m sure you can find some.

        Good luck
        admin recently posted..Pixel ProgrammingMy Profile

  22. Hi,

    I don’t know your name, but I THANK YOU for your ActionSctript to C# Comminication tutorial.
    You solved my problem.
    I would like to learn your name.
    Thanks again.

  23. dear admin pls send me as3 file or code also plszzzzzzzzzzzzzzz

  24. hello. thank you for beauty source codes

  25. hello Jacob

    you have done a great job, please tell me can we use motion sensing threw flash in flash builder.

  26. HI Jacob ,
    Great job , But i am having a problem when i deploy my Visual Studio exe it gives me error like this.
    ****************************************************************************
    System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
    at System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
    at System.Windows.Forms.NativeWindow.DefWndProc(Message& m)
    at System.Windows.Forms.Control.DefWndProc(Message& m)
    at System.Windows.Forms.Control.WndProc(Message& m)
    at System.Windows.Forms.AxHost.WndProc(Message& m)
    at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
    at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
    at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
    *******************************************************************************

    can you tell me how to solve this problem.
    Regards
    Subhash

    • Hi Subhash,
      It may be related to the flash version but I’m not really sure.
      I’ve added the ocx from my machine next to my deployed exe to make sure it uses that one instead of the one from the client machine which may not match the version I worked on and surly fail.
      Other than that, what I see from your stack trace is that c# wasn’t allowed to call the method which should be exposed by flash and this problem on Windows may be caused by many obvious or obscure reasons that I can’t really tell only from that error.

  27. Hi, thanks by this project, i got this error:

    An unhandled exception of type ‘System.BadImageFormatException’ occurred in System.Windows.Forms.dll

    Additional information: Could not load file or assembly ‘Interop.ShockwaveFlashObjects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null’ or one of its dependencies. An attempt was made to load a program with an incorrect format.

  28. Hello. I have an axshockwave object where runs a flash game in external server. I don’t have swf source.
    In wich way can I obtai text in game’s chat?

    Thanks

    • In no way unfortunately. If you login the client in your Windows app, and then serve them the flash game, then just make the chat inside the application.

  29. Hey Can anybody help me how to send continuous various data that is calculated continuously in C# to a flash variable so that a flash object will act depending on that falsh variable. I have that flash source code file and also the program that is continuously returning the integer variable. But sending the data is really challenging….. ?

  30. hey sir thank uuuuuuuuuuu so much for the course but when i open the source in visual studio 2012 get me error when i want to debug :

    Troubleshooting Exceptions: System.Runtime.InteropServices.COMException

    i know that others ask this but i really didint undrstand what should i do .
    in fact other question :

    if i want to not to use a xml file and c# ui send the data directly to swf file what should i do ?!!?!?!? i saw that someone did this but i search many in google and found nothing . do u know what shgould i do !?!?!?!!?

    • The COM exception seems to be thrown be the FlashPlayer and I don’t know why is that. Does it have a error code to it ?

      You can’t send data using External Interface without the message on c# being a xml. That xml and the way is formated is the ‘Interface’ from the ‘External Interface’.

      I think I already wrote in the comments somewhere about LocalConnection being an alternative to External Interface. But you can’t relay on these methods of communications for big data. They were not meant for this to begin with. They were meant for simple method calling with a hand full of arguments (if any).
      admin recently posted..Pure AwesomenessMy Profile

  31. This is a great resource. I have been looking for a C# solution. Would it be possible if you can share the Action Script file as well?


Leave a comment


*

CommentLuv badge