0

I'm trying to figure out the quickest way to get data from the MS Band 2 into a Unity standalone Windows build with VR support. I'm able to build and run the SDK sample apps on my Win10 laptop, and they work.

I've tried various things, ranging from importing the Microsoft.Band.DLL into Unity as a managed plugin, to trying to wrap the Band DLL in a native plugin. However, I have not found a way to make this work. I'm starting to suspect that I simply will not be able to get the Band DLL to work with a standalone Windows build, for a number of reasons.

When I try to use the Band DLL as a managed plugin, Unity doesn't support C# 4 which is required by the Band DLL. When I try to create a native DLL, I can't figure out how to create a project in VS2015 that will work with the Band SDK, and I can't change the sample projects to output a DLL instead of an app. When I try a new project that can output a DLL, and try to install the Microsoft.Band NuGet package, it tells me that my project targets 'native,Version=v0.0' even though the SDK version is 10.*.

Ideally, there would be a way to include required DLLs with the Band DLL in Unity, and I could access it as a managed plugin. But I'd even be happy with wrapping a C++ file in extern "C" and making a separate function to return each piece of data from the Band.

I simply am not familiar enough with the Universal Windows concept to know if there is a way to make it work with a Unity standalone Windows build, or if it is intentionally prevented from working that way. Since they both run on the same machine, it seems like this should be possible.

My fallback plan is to write a Universal Windows app that reads the device data, and have that connect to the Unity standalone Windows app to give access to it. Whether that's through a local file, network connection, or remote server is another problem altogether.

1 Answers1

2

The best way of doing this is to use C++ to make a wrapper around the MS Band but that is not an option in this case because Microsoft does not have a C++ API for MS Band and their website is full of requests from programmers asking for C++ support since late 2015, which they ignored. You still have 4 other options that may or may not work.

  1. Try Unity C# 5.0 and 6.0 Integration https://bitbucket.org/alexzzzz/unity-c-5.0-and-6.0-integration/src This will let you use C# >4 with Unity. How to Set it up is on the page.

  2. Use Local Interprocess Communication. Make a console plugin with C# and build the project as C# with Visual Studio instead of Unity. Compile it to exe instead of DLL and call it MSBandLIC.exe. Write all your code that communicates with the MS Band in this program.

    Start the MSBandLIC.exe program from your Unity program.

    You can then use Anonymous Pipes to communicate with the MSBandLIC.exe from Unity. The code is long but easy to write. Here is a link from Microsoft on how or do this. https://msdn.microsoft.com/en-us/library/bb546102.aspx

  3. TCP Console Plugin

    Make a console plugin with C# and build the project as C# with Visual Studio instead of Unity. Compile it to exe instead of DLL and call it MSBandTCP.exe.

    Start the MSBandTCP.exe program from your Unity program.Write all your code communicates with the MS Band in this program then create a TCP server listening to port 5550.

    On Unity side, use TCP to connect to your local machine with port 5550 and there you can communicate and receive information from MS Band.

  4. Reverse-Engineer the API and make your simple API with the functions you need to access from the MS Band. It looks like MS Band communicates with computer/mobile phones through Bluetooth. Bluefruit LE Sniffer and Wireshark should help you accomplish this.

    How do this:

    Choose a functions that you need from the MS Band API. Write a C# App without Unity that sends a message to the MS Band in while loop everything 2 seconds. Use Bluefruit LE Sniffer and Wireshark to see what message is going from Windows to the MS Band. MS Band should respond, if it does but what it sent is encrypted, use JustDecompile to de-compile the DLL part of the API and figure out how the API de-compiles bytes it receives from the MS Band. You can then reconstruct your own API from what information you gathered.

Programmer
  • 121,791
  • 22
  • 236
  • 328
  • 1
    a sophisticated answer :O – Fattie Mar 09 '16 at 13:29
  • 1
    Lol..There is a DLL compatibility issue, that's why the solution seem complicated but Only the #4 seem to be hard. #1 to #3 are actually easily if he google TCP or Local Interprocess Communication, he can do it. Writing how to do each of will take forever but doing it yourself wont. – Programmer Mar 09 '16 at 17:51
  • Quick update: I tried #1 and got some sample code working with the CSharp60Support package. However, when I tried to add the Band SDK to the project I got missing reference errors for System.Runtime and System.Threading.Tasks in the SDK itself, which I don't know how to fix. I then tried #2, which got me to the point of an UnauthorizedAccessException in the client. While reading up on that, I discovered that the anonymous pipes are one way from server->client, so that won't work for accessing the Band. I'm on to #3, and will report back with my results. – David Merrill Mar 09 '16 at 23:42
  • I thought you gave up because you didn't reply. Glad you didn't. You can use multiple anonymous pipes for 2-way communication but I suggest you try *named pipe* instead. Replace it with #2. http://stackoverflow.com/questions/13806153/example-of-named-pipes. Name pipes looks so easier than TCP. – Programmer Mar 10 '16 at 00:18
  • I saw a link on the anonymous pipes page that mentioned name pipes, so I'm trying that now. I simply used the sample code and created a client app, and put the server code in a Unity class. Unfortunately, Unity is crashing when I run it, so I'm going to make a standalone server app now and just make sure I can get the sample running. Once I verify that, I'll move it back into Unity and figure out why it's crashing. At least I'm learning new stuff. Whee! – David Merrill Mar 10 '16 at 00:48
  • Good for you. If you read my answer you will realize that I said the server should be the console app and the client should be unity. That's the right way to do it. So that when you open that console from unity, you can connect to it, disconnect from it, connect to it later on again and disconnect from it again. Unity is probably crashing because that needs multithreading. You should use multithreading for this. This answer is already big, just google c# multithreading and how to call a function in another thread with c# – Programmer Mar 10 '16 at 01:25
  • OK, I've tried two separate samples for named pipes. One spawns 4 threads on the server and connects to 4 separate client instances. The other is a simple single connection on the main thread with a preset string being passed. They run just fine as standalone apps. When I try to implement them in Unity, as either server or client, I get a "Win32Exception: The operation completed successfully" error. I've seen other threads online that indicate that people have gotten pipes to work in Unity, so I'm still hopeful. I'll have to continue tomorrow though, as my brain is mush right now. – David Merrill Mar 10 '16 at 01:54
  • D'oh! I wrote my comment without refreshing, so I missed your prior comment. I'll make a clean attempt tomorrow morning and let you know how it goes. Thanks for all of your assistance. – David Merrill Mar 10 '16 at 01:55
  • I started over this morning with new projects and am still not able to get named pipes working. I'm basically using the sample code from the MSDN NamedPipeServerStream/NamedPipeClientStream doc pages. It works with standalone apps, but when I put the client in Unity it fails. It will sometimes connect, but not always. I'm not getting any errors or unhandled exceptions, so I don't know what's happening with it. – David Merrill Mar 10 '16 at 20:07
  • I have used it outside Unity before and it worked very well. Probably not working because Unity uses mono for run-time. Your ONLY remaining easy option is TCP. TCP works with Unity 100% and I have used it many times with no problem. c# tcpclient and tcplistener(server) are made to be easier. Use them instead of using raw socket. Use them with thread too. Googling them should provide enough example to get started. – Programmer Mar 10 '16 at 20:18
  • Thanks again for your assistance. I just got a message transferred from an anonymous server to a client in Unity. I'm going to forge ahead with the anonymous pipe and see if I can get that to work for me. If I hit another roadblock, then I'll give the TCP approach a try. Stay tuned. – David Merrill Mar 10 '16 at 20:53
  • If it works sometimes and doesn't work sometimes then forget about. If it works all the time then go for it. Your app shouldn't work this morning and cease to function in the evening. I will stay tuned for which solution you went with. – Programmer Mar 10 '16 at 21:00
  • Well, the anonymous pipe solution looked promising until I tried to connect to the Band from the server code. I think I have to target a Universal or 8.1 app to get access to the BandClientManager, and that appears to use different pipe code, so I don't even know at this point if I can connect the two types of processes together. Looks like I'm moving onto a TCP solution. – David Merrill Mar 10 '16 at 23:34
  • I am confused on your last post. The server app is the place you write functions that connects the MS Band using the MS Band API. That is the place you can use the MS Band library. For example, getHeartRate function that uses the MS Band API to get heart rate beat. You can then write a simple relay that chooses which function to call when server receives message from client. For example, if you receive "gHR" from client(Unity), you can call getHeartRate function which uses the MS Band API to communicate with MS Band and then send the result back to client(Unity) – Programmer Mar 10 '16 at 23:51
  • You don't use pipe to directly communicate with the Band. You use pipe to communicate between Client(Unity) and Server(Console App). Inside that console, you use the MS Band Official API to communicate with MS Band not pipe. – Programmer Mar 10 '16 at 23:53
  • I created the server project as a .NET Framework 4.5.1 Console Application in VS. I added a reference to the Microsoft.Band NuGet package, and thought that would give me access to the Band SDK. After I got the anonymous pipe working between the server and Unity, I tried to add code to access the Band. That's when I realized that the project didn't contain BandClientManager and other interfaces. When I created a Blank App (Universal Windows), so that I could access the Band, I lost access to System.IO.Pipes. – David Merrill Mar 11 '16 at 00:20
  • When I looked up using pipes in Universal Windows apps, I found an entirely new set of pipe code. I'm really confused about the difference between Universal Windows apps and regular standalone Windows executables. At this point, it seems like TCP will be the easiest and most reliable solution. – David Merrill Mar 11 '16 at 00:24
  • I see. Microsoft changed their API for Universal Windows. c# tcpclient and tcplistener(server) is the only sensible option left. I suggest you check if c# tcpclient and tcplistener(server) are both available in Windows Universal Windows before going further. If they are not, then Socket should be available which you can also use to make TCP connections. – Programmer Mar 11 '16 at 00:50
  • Quick update: I'm able to make a TCP connection from a UWP app to a regular Windows executable. However, only if the UWP app is running in an emulator. I've tried connecting over localhost on 8.1 and 10, and the connection fails. I am now thinking that Microsoft blocks localhost connections between UWP and Windows apps on the same machine. My next attempt will be to run the UWP Band app on my laptop and Unity on my desktop and see if that works. Microsoft never ceases to amaze me. – David Merrill Mar 11 '16 at 18:20
  • No no reason why this shouldn't work. You can create a server and connect to it on the same machine. Unity does that when you build WebGL. Autodesk Maya uses that for communication between other software. I have done it before. So you can. Microsoft is not blocking you. Make sure that fireworks is not blocking you app. Write a simple function that gets the IP Address of your computer. Connect to that IP Address from the client. If that doesn't work try connecting to loopback address 127.0.0.1 – Programmer Mar 11 '16 at 19:38
  • Actually, Microsoft does do this. I've found proof: https://software.intel.com/en-us/articles/strategies-for-app-communication-between-windows-8-ui-and-windows-8-desktop https://msdn.microsoft.com/en-us/library/windows/apps/dn640582.aspx https://msdn.microsoft.com/en-us/library/windows/apps/Hh780593.aspx – David Merrill Mar 11 '16 at 19:43
  • I'm able to connect between my laptop and my desktop using the same code, so I'm going to attempt this approach now. Since my project is still pre-production and internally distributed, I may even attempt the local file data transfer if I have issues with routing and firewalls. I was really expecting to have this working last week, so I'm a bit exasperated at this point. Thanks once again for all of your assistance. This has been quite a learning experience. – David Merrill Mar 11 '16 at 19:47
  • Lol Microsoft is actually doing this. Its crazy but I don't think this applies to Standalone build. This only applies to windows store app builds. Build your app for standalone. – Programmer Mar 11 '16 at 20:17
  • That's the gist of my problem. I have to use UWP to access the Band, and I have to use standalone to access the Oculus Rift. On a positive note, I am able to establish a TCP connection from Unity on my Win 8.1 desktop to a Band sample app on my Win 10 laptop. Of course, the data transfer isn't working yet, but they are connecting. So, I think I may be seeing a little light at the end of this tunnel. – David Merrill Mar 11 '16 at 20:37
  • Ok. You know what you are doing – Programmer Mar 11 '16 at 20:46
  • Success! I simply needed to add a '\n' to the end of my test data. Now to package up the Band data and send it across the TCP connection. One last time, thank you so much with your help and I'll mark this question answered now. – David Merrill Mar 11 '16 at 21:02