title: Problem interfacing C++ POS controls with the .NET POS SDK
body: <p>We're trying implement a .NET Service Object that supports a COM interface to emulate a POSPrinter but still be compatible with the older technologies. </p>
  
  <p>We have our interface and class object in the following class.. </p>
  
  <pre><code>using [...]
  
  namespace yRPOSPrinterDotNet
  {
      [Guid("2D570F11-4BD8-40e7-BF14-38772063AAF0")]
      [InterfaceType(ComInterfaceType.InterfaceIsDual)]
      public interface yRPosPrinterCOM
      {
  
          long Open(String DeviceName);
          long PrintNormal(long Station, String Data);
  
      }
  
      [Guid("478176F4-5105-435c-8EBC-D4CB90B7B1C7")]
      [ClassInterface(ClassInterfaceType.None)]
      //[ProgId("yRPOSPrinterDotNet.POSPrinter")] //will be set automatically as the progid &lt;namespace&gt;&lt;clsid&gt;
      public class POSPrinter : yRPosPrinterCOM
      {
  
          #region yRPosPrinterCOM Members
          public long Open()
          {
              return 0;
          }
  
          public long Open(String DeviceName)
          {
              Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));
              FileStream objStream = new FileStream("C:\\yRPOSLog.txt", FileMode.OpenOrCreate);
              TextWriterTraceListener objTraceListener = new TextWriterTraceListener(objStream);
              Trace.Listeners.Add(objTraceListener);
              Trace.AutoFlush = true;
              Trace.Indent();
              Trace.WriteLine("Entering Main");
              Debug.WriteLine("How does this one do??");
              Console.WriteLine("Hello World.");
              Trace.WriteLine("Exiting Main");
              Trace.Unindent();
              return 0;
          }
  
  
          public long PrintNormal(long Station, string Data)
          {
              throw new NotImplementedException();
          }
  
          #endregion
      }
  
  }
  </code></pre>
  
  <p>And put inside <code>HKEY_LOCAL_MACHINE\SOFTWARE\OLEforRetail\ServiceOPOS\POSPrinter\yReceipts</code> our ProgID of yRPosPrinterDotNet.POSPrinter</p>
  
  <p><code>HKEY_CLASSES_ROOT\CLSID\{478176F4-5105-435C-8EBC-D4CB90B7B1C7}</code> has our ProgID correctly after building (yRPosPrinterDotNet.POSPrinter)</p>
  
  <p>We can call the DLL through a test class as follow (finding the ProgID) using this class</p>
  
  <pre><code>using [...]
  
  namespace TestYRPosPrinterDotNet
  {
      /// &lt;summary&gt;
      /// Summary description for UnitTest1
      /// &lt;/summary&gt;
      [TestClass]
      public class UnitTest1
      {
          public UnitTest1()
          {
  
          }
  
          private TestContext testContextInstance;
  
          /// &lt;summary&gt;
          ///Gets or sets the test context which provides
          ///information about and functionality for the current test run.
          ///&lt;/summary&gt;
          public TestContext TestContext
          {
              get
              {
                  return testContextInstance;
              }
              set
              {
                  testContextInstance = value;
              }
          }
  
          [TestMethod]
          public void TestMethod1()
          {
              String sProgID = "yRPosPrinterDotNet.POSPrinter";
              // We get the type using just the ProgID
              Type oType = Type.GetTypeFromProgID(sProgID);
              if (oType != null)
              {
                 POSPrinter pp = (POSPrinter)Activator.CreateInstance(oType);
                 long retVal = pp.Open("Nothing");
              }
  
          }
      }
  }
  </code></pre>
  
  <p>But when we try calling through sample TestApp (it does show up as a serviceObject) </p>
  
  <pre><code>{"Method Open threw an exception.  The service object does not support one or more of the methods required by its release."} System.Exception {Microsoft.PointOfService.PosControlException}
  </code></pre>
  
  <p>Through a Sample C++ Control Object we receive a 104 defined in opos.h as <code>(const LONG OPOS_E_NOSERVICE = 4 + OPOSERR;)</code> with the following stack trace </p>
  
  <pre><code>----------------------------------- Doesn't work --------------------------------------------------------
  
   POSPrinterExample.exe!COleDispatchDriver::InvokeHelperV(long dwDispID=37, unsigned short wFlags=1, unsigned short vtRet=3, void * pvRet=0x0012f1e0, const unsigned char * pbParamInfo=0x00702014, char * argList=0x0012f110)  Line 
  
  397 C++
   POSPrinterExample.exe!COleControlSite::InvokeHelperV(long dwDispID=37, unsigned short wFlags=1, unsigned short vtRet=3, void * pvRet=0x0012f1e0, const unsigned char * pbParamInfo=0x00702014, char * argList=0x0012f10c)  Line 1093 
  
  C++
    POSPrinterExample.exe!CWnd::InvokeHelper(long dwDispID=37, unsigned short wFlags=1, unsigned short vtRet=3, void * pvRet=0x0012f1e0, const unsigned char * pbParamInfo=0x00702014, ...)  Line 382 C++
    POSPrinterExample.exe!COPOSPOSPrinter::Open(const char * DeviceName=0x00271f00)  Line 192 + 0x1c bytes C++
  </code></pre>