Loren on the Art of MATLAB

Using Microsoft .NET to Expand MATLAB Capabilities 16

Posted by Loren Shure,

Ken Atwell in the MATLAB product management group is guest blogging this week about his recent experiences using Microsoft .NET® and how it can used to expand the breadth of capabilities in MATLAB, especially in situations where you need a facility that MATLAB does not directly supply.

Contents

Microsoft .NET is a software framework for developing applications on Microsoft Windows. Notably, it includes a comprehensive library for all kinds of general-purpose programming tasks, from networking and security, to file parsing. Since R2009a, MATLAB has been able to call into the .NET library, but personally being a newbie to .NET, it was only very recently that I had enough motivation to invest it learning about it. It was a very positive experience, so I thought I’d share my story in this blog post.

Introducing the problem to solve

The other day, I was experimenting with the MATLAB function REGMATLABSERVER. It registers MATLAB as an Automation server, so that it can be controlled by other applications. For instance, this is used by Spreadsheet Link EX to enable live data transfer from Microsoft Excel to MATLAB (Even if you don’t know or care about what these things are, bear with me, as much of what we’re discussing is generally applicable). Under Windows 7 or Windows Vista, registering is an Administrator-level operation that will cause User Account Control (UAC) to bring up a dialog box prompting the user to confirm the action. As it turns out, REGMATLABSERVER in its current form does not invoke UAC and will simply fail to register MATLAB. The work-around is easy enough -- run MATLAB as an Administrator (right-click on the MATLAB Start Menu icon) and register from within that privileged MATLAB. But, it got me wondering, is there a way to invoke UAC from within MATLAB, avoiding the need to run MATLAB as a whole as an Administrator?

Examining the implementation of REGMATLABSERVER shows that it works by simply invoking a second instance of MATLAB with a special command line switch. These are the relevant commands in REGMATLABSERVER:

  command = sprintf('"%s" /wait /regserver /r quit', ...
            fullfile(matlabroot,'bin','matlab'));
  [s,msg] = system(command);

Finding a C#/.NET solution

So, all I really needed to figure out was how to invoke a process as an Administrator. I knew of no way to do this in MATLAB, so like anyone, I used Google to find programmatic ways to start a process as an Administrator. I quickly learned that .NET provides facilities to do this, and found source code in C#/.NET (on the English-language Wikipedia page for UAC, of all places) that demonstrates how to do it. At first, this gave me some pause, as I’d never used C# or .NET in any meaningful way. But, the code was very readable, so I decided to drop the code into MATLAB and see if I could make it work. The C# code from Wikipedia was:

  System.Diagnostics.Process proc = new System.Diagnostics.Process();
  proc.StartInfo.FileName = "C:\\Windows\\system32\\notepad.exe";
  proc.StartInfo.Verb = "runas"; // Elevate the application
  proc.Start();

Porting the code to MATLAB

The first thing I needed to do was make some small syntax changes to turn this C# program into a MATLAB program. With the help of the MATLAB Code Analyzer (those wavy red and orange lines in the editor), I was able to get to valid MATLAB code in maybe a minute. I needed to do three things:

  • The first line creates a variable of type System.Diagnostics.Process. I was not sure what that meant exactly, but I didn’t really need to know. MATLAB is implicitly typed, so the type name is not needed in the variable declaration (that is, the left side of the =). Further, the C# new keyword is not needed.
  • The second and third lines needed their strings surrounded by single quotes instead of double quotes.
  • The comment on the third line needed to be preceded with % and not //.
  • This resulted in the following MATLAB code:

      proc = System.Diagnostics.Process();
      proc.StartInfo.FileName = 'C:\\Windows\\system32\\notepad.exe';
      proc.StartInfo.Verb = 'runas'; % Elevate the application
      proc.Start();

    Neat! With very little effort, I had a script which launches the Notepad application as an Administrator, triggering UAC prompts as necessary. My next step was to use this as a starting point for what I actually want to do, namely start MATLAB as an Administrator with extra command-line arguments (as we saw in the implementation of REGMATLABSERVER above). Given that I now knew the name of the .NET class I needed (System.Diagnostics.Process), I was able to get to the MSDN reference page (again, Google is your friend). Between this reference page and tab completion in MATLAB (type proc. , then press the Tab key), I was able to poke around and specify the bits I needed:

      proc = System.Diagnostics.Process;
      % EXE to run
      proc.StartInfo.FileName = fullfile(matlabroot,'bin','matlab');
      % Arguments to the EXE
      proc.StartInfo.Arguments = '/wait /regserver /r quit';
      % Run-as admin
      proc.StartInfo.Verb = 'runas';
      proc.Start(); % Start

    Refining the solution

    It was now working, but there were two things I didn’t like:

  • After spawning the process, control was immediately returned to MATLAB, but I wanted MATLAB to block until the spawned process finished so I could examine the exit code.
  • There was an empty Command Prompt window visible on the screen for a couple of seconds. Cosmetic, to be sure, but ugly.
  • Another several more minutes of experimentation and iteration, and I got to a more satisfying implementation:

      proc = System.Diagnostics.Process;
      % EXE to run
      proc.StartInfo.FileName = fullfile(matlabroot,'bin','matlab');
      % Arguments to the EXE
      proc.StartInfo.Arguments = '/wait /regserver /r quit';
      % Run-as admin
      proc.StartInfo.Verb = 'runas';
      proc.StartInfo.WindowStyle = ...
            System.Diagnostics.ProcessWindowStyle.Hidden;
      proc.Start(); % Start
      proc.WaitForExit(); % Wait for the process to end
      proc.ExitCode %Display exit code

    Not bad! Knowing next-to-nothing about .NET, it took me about a half-hour to create my first MATLAB script that leverages .NET. Granted, this is a trivial program, but it does something new and useful. I know this sounds corny, but it was something of a revelatory moment for me and I won’t hesitate to leverage .NET when the situation next arises.

    A second experiment

    For a second experiment, I recalled hearing somewhere that .NET includes a speech synthesizer. I thought this might be a “fun” example, so I Google searched “.NET speech synthesis” and found a nice article on the subject, with code in C++, C#, and VB. Reading through the short article, it said something about needing to “reference the System.Speech assembly”. I was not quite sure what that meant, so I moved on. The C# code looked closest to MATLAB code, so I started with it:

      using System.Speech.Synthesis;
      SpeechSynthesizer speaker = new SpeechSynthesizer();
      speaker.Rate = 1;
      speaker.Volume = 100;
      speaker.Speak("Hello world.");

    As before, I tweaked things a tiny bit to make the syntax agreeable to MATLAB:

      using System.Speech.Synthesis;
      speaker = SpeechSynthesizer();
      speaker.Rate = 1;
      speaker.Volume = 100;
      speaker.Speak('Hello world.');

    Here, MATLAB (perhaps unsurprisingly) generated an error on the using keyword. Being a past C++ programmer, I recognized the using statement as a way to bring a namespace into scope; stated more pragmatically, it is a mechanism to save keystrokes later in your code. I could avoid the need for a using statement by simply specifying the full “path” to SpeechSynthesizer instead:

      speaker = System.Speech.Synthesis.SpeechSynthesizer();
      speaker.Rate = 1;
      speaker.Volume = 100;
      speaker.Speak('Hello world.');

    But, that still didn’t work, as I triggered an error about an undefined variable or class. Hmm… guess I needed to pay attention earlier when the article advised me to add a reference to the System.Speech assembly. I did not know how to do this in MATLAB, so I Google searched “MATLAB add reference to .NET assembly”. For me, the first couple of results were from mathworks.com. The first result was an index of functions; the second was the topic Getting Started with .NET. Reading through the first few paragraphs of the introduction, I learned that in MATLAB I need to use NET.addAssembly to load an assembly. It is analogous to using JAVAADDPATH to make Java classes visible to MATLAB. As it turns out, a few particularly useful assemblies are loaded by default, which explains why I did not need to bother with this in the first example (basically, I got lucky!).

    Armed with this information, I inserted a line of code to add the assembly before using its classes:

      NET.addAssembly('System.Speech');
      speaker = System.Speech.Synthesis.SpeechSynthesizer();
      speaker.Rate = 1;
      speaker.Volume = 100;
      speaker.Speak('Hello world.');

    And voilà! My computer was now saying “Hello world” to me. Since I was having fun, I changed the message to tell me the day of the week:

      NET.addAssembly('System.Speech');
      speaker = System.Speech.Synthesis.SpeechSynthesizer();
      speaker.Rate = 1;
      speaker.Volume = 100;
      [~,S]=weekday(date, 'long');
      speaker.Speak(['Today is ' S]);

    I now had my second MATLAB program using .NET. This one was a touch more complex, as I need to understand NET.addAssembly, but that was a hurdle I was able to get over with little fuss.

    Conclusion

    Bottom line: When you’re looking to solve a problem that is outside the normal purview of MATLAB, don’t underestimate the power of the .NET Framework you have at your fingertips (or, on the off chance .NET is not already installed, it is freely available for download from Microsoft). Further, don’t be daunted by .NET if you’ve never used it, as starting points (code fragments) are easy to come by and C# and other languages can often easily be ported into MATLAB.

    I’m curious to hear if any readers have had experiences with .NET in MATLAB. What kinds of problems do you solve? Chime in below!


    Get the MATLAB code

    Published with MATLAB® 7.11

    16 CommentsOldest to Newest

    1) Sending messages to the windows system log.
    2) Encrypting strings
    3) Generating GUIDs
    4) Sending and retrieving info from a database
    5) Utilizing Google’s .Net API
    6) Writing and reading XML files. (I find this easier to do then Java’s)
    7) Sending email with authentication
    8) Using Log4Net

    Most of these could be accomplished with the JVM, but many times I compile application without JVM support because the start up is significantly faster. This is due to the virus checker and the JVM.

    Like Ken, I’m also ‘.NET-illiterate’ but have used Speech Recognition functions of .NET framework to listen to spoken numbers and input them in a Sudoku Solver program successfully. For cosmetic effects, some messages are also spoken to the user using SpeechSynthesizer exactly as shown in this post. (A demo is available here.)
    I was surprised when the first example worked without the use of NET.addAssembly() function but calmed down when second example did not work at first!
    I relied on MATLAB’s Help (& MSDN library, obviously) rather than Google (for once!) to get both speaking (½ hour) & listening (1 hour) set up.

    Yair — Thanks for the kind words. I follow your own blog and learn much from it. :)

    StephenLL — That’s a great list, thanks for sharing.

    jkmsmkj — Thanks for the link to the YouTube video. Any chance you can put the source code up on the MATLAB Central File Exchange?

    Aslak — Thanks for asking, but you’re right — Mono is not currently supported.

    I’m sure these sorts of libraries (as many others too, in C etc) could be useful sometimes, particularly when needing rapid exchange of data back and forward with matlab. But it always strikes me how superior the command-based approach (rather than linking-to-libraries) is for user-efficiency for the common cases, such as the examples in this article, where speed is not critical.

    Instead of learning several details of another language and how to call it, one could run (under *nix) another matlab process as another user, from an existing matlab, as:
    !su -c username matlab [options]
    or
    !sudo matlab [options]
    (except that one wouldn’t need to, as it shouldn’t have had the problem for which this was a work-around).

    Likewise, outputting matlab results as speech would be as difficult as
    system(‘echo “%s” | festival –tts’, string);
    or other possible incantations involving a temp-file.

    Some things, such as some suggested by StephenLL, would not be suitable for such treatment; but where it does work, the many-small-commands concept is remarkably quick and simple. Sadly, it’s almost unconsidered nowadays, when so much is either a GUI or a separate ‘library’.

    We have used the MATLAB .NET interface to create a domain specific scripting language. The .NET objects of the domain are wrapped into MATLAB objects and subsref and subsasgn have been overwritten to suit the specific needs. The users of the language have all the features of the Matlab Desktop and integrated help available. The language has been put into production and is currently used by 20 users in their daily work. So the Matlab .NET interface works excellent not just for small helper functions.

    I’ve utilized the ‘System.IO.FileSystemWatcher’ to create a “directory watcher” class. I use this to monitor specific directories for various changes in the filesystem (both change, create, delete etc. for both directories and files), very handy.

    I ran into one shortcoming of the -NET Matlab implementation though;
    It’s not possible to OR enumerated .NET values togheter. I noticed this one when trying to set up the ‘NotifyFilter’ for the ‘FileSystemWatcher’ class. The OR’ing of enumerated values are commonly used in function calls in .NET.
    (this was confirmed as a shortcoming by Mathworks support)

    @Aurélien, we do reuse materials in different media since people prefer to learn in different ways. In this case, I was aware that speech synthesis is possible in .NET, but I was unaware (or had forgotten) that it was included in the R2009a video. I did not consult the video in preparing this blog.

    @Ken, I’ve been thinking of doing that but haven’t quite gotten around to do that yet. For now, third & fourth para of this blogpost should do the job, I guess!

    I have NEVER used .NET from within MATLAB. However I am currently developing a C#/WPF application using a fair amount of .NET under the bonnet.

    I had no idea that this was possible.

    I have previously used hand made Java classes for Socket IO (http://iheartmatlab.blogspot.com/2010/06/non-blocking-output-socket.html). Although that means you have to lug a .class file around with you. And while Java is OK, I think .NET certainly has the legs in terms of updates.

    Thanks for this very useful blog post. I’ll have to keep an eye out for where I can use this (sadly I am doing minimal MATLAB development these days).

    Rod

    MATLAB allows us to call a .NET object within MATLAB codes and MATLAB also allows us to create .NET components from MATLAB programs.

    So what would be the preferred approach? Let me use an example to illustrate my question. I can develop a MATLAB calculator that call a .NET object to retrieve data or use MATLAB Builder to compile this MATLAB calculator into a .NET component and then pass data to this .NET component from a C# program.

    Which one would be better?

    These postings are the author's and don't necessarily represent the opinions of MathWorks.