I once needed to use C# to call into the Citrix Fast Connect API. This is how I did it. 

I used the authmanager SDK to enumerate apps.

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Net;
using System.Runtime.ConstrainedExecution;

using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Security.Policy;
using System.Text;
using System.Xml;
using Microsoft.Win32.SafeHandles;
using Citrix.DeliveryServices.Clients.AuthManager;


namespace UseCtxCredApi
{
  class Program
  {
    static void Main( string[] args )
    {

      // Pass credentials securely to fast connect

      MSV1_0_INTERACTIVE_LOGON logon = new MSV1_0_INTERACTIVE_LOGON();

      logon.LogonDomainName = FastConnectWrapper.InitLsaString("imp");
      logon.MessageType = MSV1_0_LOGON_SUBMIT_TYPE.MsV1_0InteractiveLogon;
      logon.Password = FastConnectWrapper.InitLsaString( "Citrix1" );
      logon.UserName = FastConnectWrapper.InitLsaString( "user1" );

      FastConnectWrapper m = new FastConnectWrapper();
      
      int result = 100;
      LOGONSSOUSER_ERROR_CODE transmittionErrorCode = m.MyLogonSsoUser( ref logon, 1, 1,ref result );

      if(transmittionErrorCode != LOGONSSOUSER_ERROR_CODE.LOGONSSOUSER_OK)
        Console.WriteLine("There was a problem trasmitting the credentials to the single sign-on compoment.");

      // Now enumerate applications

      try
      {
        ConnectionManager.Initialize();

      }
      catch (Exception ex)
      {
        System.Console.WriteLine(ex.Message);
        throw;
      }
      
      int authResult = 0;
      try
      {

        Connection pConnection = ConnectionManager.CreateConnection("HTTP API C++ test");
        LogonStatus loggedOnStatus = pConnection.GetLogonStatus("http://imp-xd1.imp.net/Citrix/Authentication/auth/v1/token");
        if (loggedOnStatus != LogonStatus.LoggedOn)
        {
          Console.WriteLine("Not Logged in");
          return;
        }
        Console.WriteLine( "Logged in" );
       

        string enumeration_result;

        // Now everything is initialised, do some tasks.
        // These may or may not throw, but as good practice expect an AuthManagerException from anything using the SDK.
        
        //enumeration_result = DoResourceAccess();
        enumeration_result = DoResourceAccess_GetSilent();
        if (String.IsNullOrEmpty(enumeration_result))
          return;

        // get first ica launch resource in the enumeration results.
        XmlDocument doc = new XmlDocument();
        doc.Load( new System.IO.StringReader( enumeration_result ) );
        
        XmlNode firstApp = doc.SelectSingleNode("//*[local-name()='launchica'][1]");
        if( firstApp != null)
          PostData( firstApp.InnerText );
      }
      catch (AuthManagerException ex)
      {
        authResult = 2;
      }

      try
      {
        ConnectionManager.Uninitialize();
      }
      catch (AuthManagerException ex)
      {
        authResult = 3;
      }

      if( authResult != 0)
          Console.WriteLine("Problem using the AuthManager SDK.");

      Console.WriteLine("Press any key to perform fast connect Logoff");
      Console.ReadKey();
      m.MyLogoffSsoUser(0);
    }

    // This sample demonstrates making a POST request for an ICA launch
    // allowing authentication prompts,
    // and prints all the HTTP response data to the console if successful.
    static void PostData(string launchuri)
{
    try
    {
        // Create a connection. This object can be reused for the lifetime of this task.
        Connection pConnection = ConnectionManager.CreateConnection("HTTP API C++ test");

        // Create a request. A client must create a new request for each attempt
        // to access resources. (i.e. GetResponse is valid for only one call.)
      using (IAMHttpRequest request = pConnection.CreateAMHttpRequest())
      {
         // Set up the request parameters
        //request.Uri = new Uri( "http://sf3.xd.local/Citrix/SF3/resources/v2/Q29udHJvbGxlci5Ob3RlcGFk/launch/ica" );
        request.Uri = new Uri( launchuri );
        // Set method and upload data
        request.Method = "POST";
        const string requestBody = "<?xml version=\"1.0\" encoding=\"utf-8\"?><q1:launchparams xmlns:q1=\"http://citrix.com/delivery-services/1-0/launchparams\"></q1:launchparams>";
        request.Body = Encoding.UTF8.GetBytes(requestBody);
        // Add any required headers.
        // Note that User-Agent and Connection headers are reserved.
        request.AddHeader("Content-Type","application/vnd.citrix.launchparams+xml");
        request.AddHeader("Accept","*/*");

        // Send the request and get a response
        // Send the request and get a response. This may throw an HttpException or HttpsTrustException
        IAMHttpResponse response = request.GetResponse();
        // Do something with the response data, e.g. Send to std::wcout.
        // Print the HTTP status info.
          System.Console.WriteLine("HTTP "+ response.StatusCode + " " + response.ReasonPhrase);
        
        // Print all headers
        var headers = response.Headers;
        foreach (string header in headers)
        {
          Console.WriteLine(header);
        }

        // Print the response body.
        // This example assumes the response is purely narrow characters
        // (and that sizeof(char) == sizeof(AMByte)), and copies the data
        // straight into to a string.
    
          using (MemoryStream ms = new MemoryStream())
          {
            byte[] buffer = new byte[16*1024];
            
            Stream stream = response.GetResponseBodyStream();
            int r = stream.Read(buffer, 0, buffer.Length);
            while (r > 0)
            {
              ms.Write(buffer, 0, r);
              r = stream.Read(buffer, 0, buffer.Length);
            }
            string icafile = System.Text.Encoding.UTF8.GetString(ms.ToArray());
            System.Console.WriteLine( icafile );
          }
      }

    }
    catch(AuthManagerException ex)
    {
        if(ex.Result == AuthManagerResult.AuthCancelledByUser)
        {
          Console.WriteLine("Cancelled");
        }
        else if(ex.Result == AuthManagerResult.Aborted)
        {
          Console.WriteLine("Aborted");
        }
        else
        {
            // Deal with errors, either from the request or the Auth Manager connection
            Console.WriteLine("Error: " + ex.Message);
        }
    }
}

    
    private static string DoResourceAccess()
    {
      string data = String.Empty;
      try
      {

        // Typically, a client creates and re-uses a single connection object for a task.
        Connection pConnection = ConnectionManager.CreateConnection("HTTP API C++ test");
        LogonStatus a = pConnection.GetLogonStatus( "http://imp-xd1.imp.net/Citrix/Authentication/auth/v1/token" );
        // Create a request. A client must create a new request for each attempt
        // to access resources. (i.e. GetResponse is valid for only one call.)

        using (IAMHttpRequest request = pConnection.CreateAMHttpRequest())
        {
          // Set up the request parameters.
          //request.Uri = new Uri( "http://sf3.xd.local/Citrix/SF3/resources/v2" );
          request.Uri = new Uri( "http://imp-xd1.imp.net/citrix/store/resources/v2" );
          
          // Optionally set the reference URL if the resource URL above
        // is not for a store in Receiver's service records.
          //request.ReferenceUri = new Uri( "http://sf3.xd.local/Citrix/SF3" );
          request.ReferenceUri = new Uri( "http://imp-xd1.imp.net/citrix/store" );
        // Set flags to allow interactive logon if authentication is required.
          request.AuthenticationFlags = AuthenticationFlags.AllowLogon | AuthenticationFlags.Interactive;
        // Optionally set string to append to user agent if needed to identify
        // the Receiver component making the request.
          request.UserAgentSuffix = "AuthManCppSdkSample/5.0";
        // GET is the default method so this next line is not actually required.
        request.Method = "GET";
        // Add any required headers.
        // Note that User-Agent and Connection headers are reserved.
        request.AddHeader("Accept","*/*");
        
        // Send the request and get a response. This may throw an HttpException or HttpsTrustException
        IAMHttpResponse response = request.GetResponse();

        // Do something with the response data, e.g. Send to std::wcout.
        // Print the HTTP status info.
          System.Console.WriteLine("HTTP "+ response.StatusCode + " " + response.ReasonPhrase);
        
        // Print all headers
        var headers = response.Headers;
        foreach (string header in headers)
        {
          Console.WriteLine(header);
        }

        // Print the response body.
        // This example assumes the response is purely narrow characters
        // (and that sizeof(char) == sizeof(AMByte)), and copies the data
        // straight into to a string.
    
          using (MemoryStream ms = new MemoryStream())
          {
            byte[] buffer = new byte[16*1024];
            
            Stream stream = response.GetResponseBodyStream();
            int r = stream.Read(buffer, 0, buffer.Length);
            while (r > 0)
            {
              ms.Write(buffer, 0, r);
              r = stream.Read(buffer, 0, buffer.Length);
            }
            data = System.Text.Encoding.UTF8.GetString(ms.ToArray());
            System.Console.WriteLine(data);
            
          }

        var certificate = response.ServerCertificate;
      }
    }
    catch(AuthenticationException ex)
    {
        // Deal with authentication errors.
        // Alternatively this could be handled by catching just the base
        // AuthManagerException which exposes the same data but may also contain
        // non-authentication error codes. This is shown in the samples below.
        if(ex.Result == AuthManagerResult.AuthCancelledByUser )
        {
          Console.WriteLine("Cancelled");
        }
        else
        {
          Console.WriteLine("Authentication failed: " + ex.Message);
        }
    }
    catch(HttpsTrustException trustEx)
    {
        // There is a trust problem such as an invalid, revoked or expired server certificate.
        Console.WriteLine("A server certificate trust problem occurred: " + trustEx.Message);
        throw;
    }
    catch(HttpException httpEx)
    {
        // There are network problems such as DNS problems or failure to open a connection to the server.
        Console.WriteLine("An HTTP layer problem occurred: " + httpEx.Message);
        throw;
    }
    catch(AuthManagerException ex)
    {
        // Deal with errors, either from the request or the Auth Manager connection
        if(ex.Result == AuthManagerResult.Aborted)
        {
          Console.WriteLine("Aborted");
        }
        else
        {
            Console.WriteLine("Error: " + ex.Message);
        }
    }
      return data;
    }

    // This abbreviated sample demonstrates making a GET request to retrieve a
    // resources enumeration from StoreFront but disallows logon prompts so it's
    // suitable for a non-user initiated background activity.
    // Refer to the sample above for a more complete sample of resource access.
    static string DoResourceAccess_GetSilent()
    {
      string data = String.Empty;
      try
      {
        // Typically, a client creates and re-uses a single connection object for a task.
        Connection pConnection = ConnectionManager.CreateConnection( "HTTP API C++ test" );
        LogonStatus a = pConnection.GetLogonStatus("http://imp-xd1.imp.net/Citrix/Authentication/auth/v1/token");

        using (IAMHttpRequest request = pConnection.CreateAMHttpRequest())
        {
          // Set up the request parameters.
          //request.Uri = new Uri( "http://sf3.xd.local/Citrix/SF3/resources/v2" );
          request.Uri = new Uri( "http://imp-xd1.imp.net/citrix/store/resources/v2" );

          // Optionally set the reference URL if the resource URL above
          // is not for a store in Receiver's service records.
          request.ReferenceUri = new Uri( "http://imp-xd1.imp.net/citrix/store" );
          //request.ReferenceUri = new Uri( "http://sf3.xd.local/Citrix/SF3" );
          // The request is made 'silent' by excluding the
          // AUTHENTICATION_FLAGS_ALLOW_INTERACTIVE flag.
          request.AuthenticationFlags = AuthenticationFlags.AllowLogon;
          // Optionally set string to append to user agent if needed to identify
          // the Receiver component making the request.
          request.UserAgentSuffix = "AuthManCppSdkSample/5.0";
          // GET is the default method so this next line is not actually required.
          request.Method = "GET";
          // Add any required headers.
          // Note that User-Agent and Connection headers are reserved.
          request.AddHeader("Accept", "*/*");

          // Send the request and get a response. This may throw an HttpException or HttpsTrustException
          IAMHttpResponse response = request.GetResponse();

          // Do something with the response data, e.g. Send to std::wcout.
          // Print the HTTP status info.
          System.Console.WriteLine( "HTTP " + response.StatusCode + " " + response.ReasonPhrase );

          // Print all headers
          var headers = response.Headers;
          foreach(string header in headers)
          {
            Console.WriteLine( header );
          }

          // Print the response body.
          // This example assumes the response is purely narrow characters
          // (and that sizeof(char) == sizeof(AMByte)), and copies the data
          // straight into to a string.

          using(MemoryStream ms = new MemoryStream())
          {
            byte[] buffer = new byte[16 * 1024];

            Stream stream = response.GetResponseBodyStream();
            int r = stream.Read( buffer, 0, buffer.Length );
            while(r > 0)
            {
              ms.Write( buffer, 0, r );
              r = stream.Read( buffer, 0, buffer.Length );
            }
            data = System.Text.Encoding.UTF8.GetString( ms.ToArray() );
            System.Console.WriteLine( data );
            return data;
          }
        }
      }
      catch(HttpException httpEx)
      {
        // There are network problems or the server may be untrusted.
        Console.WriteLine("An HTTP layer problem occurred: " + httpEx.Message);
        throw;
      }
        // if interactive authentication was not required then there will be
        // a response available...
      catch(AuthManagerException ex)
      {
        // This error is expected if the silent request couldn't be
        // completed because authentication required a logon prompt to be shown.
        if (ex.Result == AuthManagerResult.AuthInteractionNotAllowed)
        {
           Console.WriteLine("Request couldn't complete silently: " + ex.Message);
        }
        else
        {
          Console.WriteLine("Authentication failed: " + ex.Message);
        }
      }
      return data;
    }
} // Program
  
  class FastConnectWrapper
  {
    [DllImport( "CtxCredApi.dll", EntryPoint = "LogonSsoUser", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    private static extern LOGONSSOUSER_ERROR_CODE LogonSsoUser(ref MSV1_0_INTERACTIVE_LOGON pNewCredentials, 
      int bDisconnectCurrentUser, 
      int bRestartPna, 
      ref int pDwResult );

    [DllImport( "CtxCredApi.dll", EntryPoint = "LogoffSsoUser",CallingConvention = CallingConvention.Winapi)]
    private static extern UInt32 LogoffSsoUser( 
      UInt32 timeout );

    public LOGONSSOUSER_ERROR_CODE MyLogonSsoUser( ref MSV1_0_INTERACTIVE_LOGON newCredentials, 
      int disconnectCurrentUser, 
      int restartPna,
      ref int result )
    {
      return LogonSsoUser( ref newCredentials, disconnectCurrentUser, restartPna, ref result );
    }

    public UInt32 MyLogoffSsoUser( UInt32 timeout )
    {
      return LogoffSsoUser( timeout );
    }

    public static LSA_UNICODE_STRING InitLsaString( string s )
    {
      // Unicode strings max. 32KB
      if(s.Length > 0x7ffe)
        throw new ArgumentException( "String too long" );
      LSA_UNICODE_STRING lus = new LSA_UNICODE_STRING();
      lus.Buffer = s;
      lus.Length = (ushort) (s.Length * sizeof( char ));
      lus.MaximumLength = (ushort) (lus.Length + sizeof( char ));
      return lus;
    }
  }
  /// <summary>
  /// Type of SSO logon error code (Citrix)
  /// </summary>
  public enum LOGONSSOUSER_ERROR_CODE
  {
    LOGONSSOUSER_OK = 0,
    LOGONSSOUSER_UNABLE_TO_GET_PIPE_NAME = -1,
    LOGONSSOUSER_UNABLE_TO_CONNECT_TO_SSO = -2,
    LOGONSSOUSER_UNABLE_TO_SEND_REQUEST = -3,
    LOGONSSOUSER_INVALID_RESPONSE = -4
  };

  public enum MSV1_0_LOGON_SUBMIT_TYPE
  {
    MsV1_0InteractiveLogon = 2,
    MsV1_0Lm20Logon,
    MsV1_0NetworkLogon,
    MsV1_0SubAuthLogon,
    MsV1_0WorkstationUnlockLogon = 7,
    MsV1_0S4ULogon = 12,
    MsV1_0VirtualLogon = 82,
    MsV1_0NoElevationLogon = 82
  };

  /// <summary>
  /// Interactive logon structure for use with Citrix API (msdn)
  /// </summary>
  [StructLayout( LayoutKind.Sequential, Pack = 1 )]
  public struct MSV1_0_INTERACTIVE_LOGON
  {
    public MSV1_0_LOGON_SUBMIT_TYPE MessageType;
    public LSA_UNICODE_STRING LogonDomainName;
    public LSA_UNICODE_STRING UserName;
    public LSA_UNICODE_STRING Password;
  }

  [StructLayout( LayoutKind.Sequential, CharSet = CharSet.Unicode )]
  public struct LSA_UNICODE_STRING
  {
     public ushort Length;
     public ushort MaximumLength;
    [MarshalAs( UnmanagedType.LPWStr )]
     public string Buffer;
  }

  internal class FastConnectLibraryWrapper
  {
    [DllImport("FastConnectLib.dll")]
    internal static extern UInt32 LogoffSsoUser( UInt32 timeout );

    [DllImport( "FastConnectLib.dll" )]
    internal static extern LOGONSSOUSER_ERROR_CODE LogonSsoUser( ref MSV1_0_INTERACTIVE_LOGON pNewCredentials,
                                              int bDisconnectCurrentUser,
                                              int bRestartPna,
                                              ref UInt32 pDwResult );

    public UInt32 callLogoffSsoUser( UInt32 timeout )
    {
      return LogoffSsoUser( timeout );
    }

    public LOGONSSOUSER_ERROR_CODE callLogonSsoUser( ref MSV1_0_INTERACTIVE_LOGON pNewCredentials,
                                              int bDisconnectCurrentUser,
                                              int bRestartPna,
                                              ref UInt32 pDwResult )
    {
      return LogonSsoUser( ref pNewCredentials, bDisconnectCurrentUser, bRestartPna, ref pDwResult );
    }

  }

}