Build your own SAS client app with Microsoft .NET

48

As part of my follow-up to SAS Global Forum 2013, I've posted a few articles about how to create your own client apps with SAS Integration Technologies. This article shows how to use Microsoft .NET -- the same approach used for SAS Enterprise Guide and SAS Add-In for Microsoft Office -- to assemble a powerful client application.

About Microsoft .NET

Microsoft .NET, when accessed through Microsoft Visual Studio, offers a full application development platform. You can download Express editions of Microsoft Visual C# or Visual Basic .NET for free from the Microsoft website. However, if you want the best productivity with the tool, consider investing in one of the professional editions. If you're just getting started with Microsoft .NET, check out the many resources that Microsoft offers.

How to reference SAS Integration Technologies from Microsoft .NET

To create a Microsoft .NET project that can connect to a SAS environment with SAS Integration Technologies, follow these steps in Microsoft Visual Studio:

  1. Create a new project of any type, appropriate for your objective (for example, a Windows Forms application, Console application, or Windows Presentation Foundation application).
  2. In your Visual Studio project, add references to the following DLL files:
    • SASOManInterop.dll (for SAS Object Manager classes)
    • SASInterop.dll (for SAS Workspace classes)
    • SASOMIInterop.dll (for SAS Metadata Server classes)
    • SASIOMCommonInterop.dll (supports SASInterop.dll and SASOMIInterop.dll; not used directly in these examples)

    You can find these files in the installation folder for the SAS Integration Technologies client. For example: C:/Program Files/SAS/Shared Files/Integration Technologies or C:/Program Files/SASHome/x86/Integration Technologies.

Here's a screenshot of a Visual Studio project that contains these references:

About the sample application

As a companion to my SAS Global Forum paper, I have prepared a full sample application with these features:

  • connects to a SAS Workspace session using a server that you define in a dialog box.
  • allows you to connect to a local instance of SAS – no configuration required.
  • features three windows: a Program Editor, a log viewer, and a listing viewer. (Does that seem familiar?)
  • allows you to run a SAS program on a background thread, keeping the main user interface responsive.
  • retrieves the SAS log and listing output, and colors each line of output as appropriate (errors, warnings, notes, page boundaries).
  • Provides a simple data table viewer that supports filters.

Here is a screen capture of the application, named SAS Program Harness. It shows a program, the SAS log, and the listing output:

The sample application was built using Microsoft Visual Studio 2012. You can also use Microsoft Visual C# Express (which is free) to view, modify, and build the project. See the GitHub repository to download the project files: source code and ready-to-run binaries.

In future articles I'll focus on some implementation details such as connecting to servers, submitting programs, and viewing data. However, you don't have to wait! You can review the details within the paper right now, and examine the source code on GitHub.

Share

About Author

Chris Hemedinger

Senior Manager, SAS Online Communities

+Chris Hemedinger is the manager of SAS Online Communities. Since 1993, Chris has worked for SAS as an author, a software developer, an R&D manager and a consultant. Inexplicably, Chris is still coasting on the limited fame he earned as an author of SAS For Dummies.  He also hosts the SAS Tech Talk webcasts each year from SAS Global Forum, connecting viewers with smart people from SAS R&D and the impressive work that they do.

48 Comments

  1. Hi Chris,

    Another great blog post :)

    Would it be possible to add syntax highlighting to the program editor for your app, so it looks more like the enhanced editor (for us post release 6.12 folk)? Could you 'borrow' the dll from E.G. to do this in .NET??

    regards

    David

    • Chris Hemedinger
      Chris Hemedinger on

      David,

      Unlike the SAS Integration Technologies client, the program editor is not available as a standalone component. It's installed with SAS for Windows, SAS Enterprise Guide, and a few other SAS applications -- but it isn't engineered (or licensed) as a building block for your own standalone apps. That said, it is possible to reuse the editor feature within custom tasks in EG, and my custom tasks book contains an example of that. It's on my backlog list to create a custom tasks example of this app, which I think would have some interesting uses.

  2. Hi ,

    I found your blog very good, but when i attempt to connect to a server with your client I do not even get the dialog box.

    I receive an unhandled exception?

    Does your client requires the whole SAS to be already installed on a workstation?

    Thank you

    • Chris Hemedinger
      Chris Hemedinger on

      You don't need SAS to be installed on your local PC, but you do need SAS Integration Technologies client, which installs with SAS Enterprise Guide or is available from the Downloads section on the SAS Support site. If you can share more details about the exception I might be able to help diagnose it.

  3. Hi Chris,

    I am trying to write programatically on current cursor position of SAS EG Editor progam window . I am able to write on open note window , data window but not able to write on Program editor window "FirstSasProgram.Sas". I am using below line of code

    foreach (Process p in System.Diagnostics.Process.GetProcesses())
    {
      if (p.ProcessName.ToUpper().Contains("SEGUIDE"))
      {
        this.WindowState = FormWindowState.Minimized;
        // Copy the text in the datafield to Clipboard
        Clipboard.SetText("First Sas Program", TextDataFormat.UnicodeText);
        IntPtr hWnd = p.MainWindowHandle;//FindWindow(null, "1.sas - Notepad");
        p.WaitForInputIdle();
          
        SetForegroundWindow(hWnd);
        //  ShowWindow(hWnd, ShowWindowCommands.Show);
        // SetFocus(hWnd);
        SendKeys.Send("^V");
          //return    ;
      }
    }
    

    Please help if u can on this.

    Thanks & Regards
    Mukta

    • Chris Hemedinger
      Chris Hemedinger on

      Mukta,

      The EG Editor is uses WPF, and not the traditional WinForms controls. This is probably why you cannot manipulate the cursor/characters in the way that you expect. Instead of your current approach, you might want to look at Windows UI Automation.

      Also, depending on what you are trying to do, you might be interested in AutoHotKey (a 3rd party app that you can script for keyboard commands) and the editor abbreviations and macro features, which allow you to script together hundreds of different program editor operations.

  4. Hi Chris,
    I need to find out current cursor position of SAS EG Editor progam window.
    Can you please help me how to approach for this using C#/VB.net code.

    -Hirdesh

    • Chris Hemedinger
      Chris Hemedinger on

      Hirdesh,

      The program editor is part of SAS Enterprise Guide, and is not documented (or permitted) for use in a separately distributed application. EG does provide basic tools for including the editor as part of your own custom tasks that run within SAS Enterprise Guide, but not as a separate standalone application.

      If you can provide a little more information about what you're trying to do, I'll see if I can provide some guidance.

      • Hi Chris,

        Thanks for replying.

        Actually, we are required to operate SAS EG via .Net. The program we have created is able to edit SAS EG editor data through "Toolbar --> Add Ins" after we add the .Net DLL to it. However, if the user changes the current cursor position from end-of-file to somewhere in between, it does not work. We have tried using SASEnhanced Editor for this using the SAS.EnhancedEditor.presentation() class and explored the line and column properties of the same but have been unsuccessful. We have been in the process of troubleshooting this issue for long now. Kindly help.

        Thanks,
        Hirdesh

        • Chris Hemedinger
          Chris Hemedinger on

          Hirdesh,

          Again, you're straying into an area of use that isn't completely documented/supported for customers, but...

          You might try looking at the CaretMoved event in the EnhancedEditorControl class. That would notify you when the cursor moves. I would be interested to learn more about the nature of your custom task -- its purpose, and how it's working for you.

  5. Thanks Chris for the wonderful article,

    I tried executing this code, I got the following error

    An unhandled exception of type 'System.TypeLoadException' occurred in SASIOM.exe
    Additional information: Could not load type 'SAS.LanguageServiceCarriageControl' from assembly 'DemoSASIOM, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

    Can you please advise what could be the problem.

    • Chris Hemedinger
      Chris Hemedinger on

      Dhanasekaran, it looks like you've built your own project -- and possibly you didn't copy the necessary SAS assemblies (DLLs) to where your project is running. In my project output directory, I have the following assemblies:

      04/26/2013  12:44 PM            30,720 SasHarness.exe
      04/26/2013  12:44 PM           188,416 SASInterop.dll
      04/26/2013  12:44 PM            32,768 SASIOMCommonInterop.dll
      04/26/2013  12:44 PM            49,152 SASOManInterop.dll
      

      The last three in that list are supplied with the SAS Integration Technologies client.

    • This took me 2 days to figure out. You need to make the target .net framework to 3.5 for the project. I had this error with the function activeSession.Workspace.LanguageService.FlushLogLines.

      My first thought that was that it could be a reference pointing to the wrong version but more testing showed that function Flushlines works though, so it had to had to be something else.

    • Alan Churchill on

      For others in the future who encounter this, it is not a .NET 3.5 dependency. Switch the Embed Interop Type to False on the SAS assemblies so that the assemblies are copied locally. I think this is alluded to but not specifically mentioned. Works fine in .NET 4.5 if you do that.

  6. Thanks a lot Chris for your reply.

    Infact I copied all those dlls you mentioned above in my project, but for some reason this was not getting included in the bin folder from where it picks and runs. After I change couple of options it worked fine.

  7. Chris, In the .Net+SAS application that I am developing, I am creating a singleton class to invoke SAS, so that the same instance would be available through out the session.

    The problem I am facing is, if there are any error in the SAS code, SAS will stop the processing. Even if I correct the code and submit, it is not running. Because it stopped due to an error in that session. Please advise an approach to fix this. What I am thinking is every time user hits "Run" button, I need to start a new instance of SAS.

    • Chris Hemedinger
      Chris Hemedinger on

      An error in the SAS code should not stop processing unless you have something like ABORT ABEND set, which would end the SAS session. That's not a good option for a SAS session that you want to persist. You should not need a new instance of SAS for each run -- and if you did, you would lose any WORK data or macro variable and options settings that had been set in a previous program. Plus, there is a bit of overhead in just creating a new SAS session, and you might not want your users to experience that penalty.

  8. Hi Chris,

    thanks for the code. My SAS server is setup as a Metadata Server. Do you know how I would modify your code to establish a connection with a SAS metadata server?

    Thanks
    F

    • Chris Hemedinger
      Chris Hemedinger on

      With the Metadata server it's a multi-step process. I have an example in PowerShell, similar in approach to what you would do in .NET.

      Step 1. Connect to Metadata Server
      Step 2. Query metadata for the connection information about the SAS Workspace Server
      Step 3. Use this information to make a connection to the Workspace server (where you can access data and submit code).

    • Chris Hemedinger
      Chris Hemedinger on

      I doubt that there is a difference between the 32-bit and 64-bit Interop for JMP. You can generate your own Interop DLLs with the TLBIMP tool (part of the .NET SDK). You would have to run this on the COM server DLL for JMP -- I'm not sure what file that is, off the top of my head, but if you check the Windows registry for JMP references I'm sure you'll find it.

  9. can this application handle the relative path? if in the sas editor, enter a statement
    Like this

    %include sample.sas;

    Can this file be found?

    • Chris Hemedinger
      Chris Hemedinger on

      The %INCLUDE statement will find files in your SAS environment. If you want to include a file from your local PC, you would need to modify my application to read the contents of that file and then submit it to the remote SAS session. Not difficult, but this small example app doesn't have that feature built-in right now.

  10. Hello Chris, Thanks for your great articles on automating SAS with C#.

    We are using your sample as the basis for a company article.

    Have a Base SAS vs Enterprise Guide question...

    Our SAS Team built their scripts using the Enterprise Guide flavor of SAS (I'm not a SAS pro so hopefully I didn't mangle this) and our automation code seems to be trying to run the scripts under "Base SAS 9.4"

    We get an error like: does ERROR: The value 12SEP2016 is not a valid SAS name

    The scripts run fine from the Enterprise guide itself but when launched from our automation code we get this error.

    Is there a way to force the COM Automation libraries to use EG ?

    thanks
    Rod

    • Chris Hemedinger
      Chris Hemedinger on

      Rod, here's my guess without knowing the details of your app. You need to include OPTIONS VALIDVARNAME=ANY; as a startup statement in the SAS program/process you're running. EG sets that by default, but Base SAS does not -- it uses the "V7" setting which wouldn't allow "12SEP2016" as a variable name.

      Now..."12SEP2016" is an odd variable name -- perhaps a result of a transpose process of some date/transaction records.

      • Thanks chris! Yeah the name is a bit odd. It's a filename. I'm trying to get them to rename it to be SEP122016

        • Chris Hemedinger
          Chris Hemedinger on

          If that doesn't do the trick, include a PROC OPTIONS; RUN; sequence as part of the job, and compare the (long) output between Base SAS and EG. Other SAS system options can affect behavior, and your EG environment might trigger certain options differently than your straight-on Base SAS.

          • Thanks for the help. I'm gonna chat with the SAS coders about this issue. I think it is something overriding this setting,

  11. I've tried this solution and also with SAS Ole DB driver and getting the same error below. I'm using VS 2013 Premium and I'e installed SAS Integration Technologies. I've even run the Wizard from SAS integration technologies Configuration Wizard in which I can test SAS server connection. Even there I get the same error.
    System.Runtime.InteropServices.COMException (0x80042002):

    Not enough storage is available to complete this operation.

    0x8007000e

    • Chris Hemedinger
      Chris Hemedinger on

      Sounds like something else is missing. Check that you're using the correct port to connect to the SAS workspace. And is there encryption involved? Make sure that you also have the SAS/Secure client installed as well, if that's the case.

  12. Very cool... I'm fairly new to SAS but virtually every interesting thought I've had thus far has been mostly resolved by one of your many blogs or papers. So, thanks! I was also wondering if you know of an easy way to implement a .Net client of, say, a scoring engine deployed as a REST service? (e.g. by providing a Swagger contract or something along those lines)?

  13. I get a "Class not registered" exception when attempting to utilize any of the COM .dll's in Visual Studio C#. Is there a simple way to register these classes?

    (regsvr32.exe didn't like them: "The module SASInterop.dll was loaded but the entry-point DllRegisterServer was not found.")

    • Chris Hemedinger
      Chris Hemedinger on

      You don't register that Interop DLL. The SAS Integration Technologies client does have components that are registered when you install the client bundle, and by using these Interop DLLs in your .NET project, you don't need to know where those registered components are. If your .NET app can't find the components, it's probably because they either aren't installed OR because the version that is installed is a different bitness (example: you built a 64-bit SASHarness app but you have only the 32-bit SAS Int Tech client installed.) You can install both the 32- and 64-bit versions of the SAS IntTech client.

  14. Hi,

    I want to read a SAS file with visual studio .net c#, and insert the SAS file content into SQL table
    Is that possible?

  15. Very cool. while I was exploring,I tried to use SAS System Options under Windows such as "-config",Is it possible for me to use the powerful options?
    Thanks.

    • Chris Hemedinger
      Chris Hemedinger on

      You cannot add startup options via this interface. If using this tool with local SAS, the SAS config options are determined by the "registered SAS command" in the Windows registry.

      For remote SAS workspace connections, the startup options are determined by the SAS Workspace Server definition in the SAS Metadata Server. It's typically an admin task to modify/maintain these.

      For any options that aren't strictly startup options, you can change these with the OPTIONS statement in a line of code.

      • Thanks a lot!
        I want to use different encoding methods to deal with different projects.
        By use sas.exe I can spacial -config "C:\Program Files\SASHome\SASFoundation\9.4\nls\zh\sasv9.cfg" to realize my needs.
        Is it possible to change the encoding via this interface?
        Or if there have another available interface to achieve my needs?

        • Chris Hemedinger
          Chris Hemedinger on

          No, ENCODING is a startup option and you can't change it from here. That has to be done at the SAS command line or in the config file chain. I guess you can't just use ENCODING UTF8 for your projects?

Leave A Reply

Back to Top