Queued Components called from a Web Service
-
2012年2月8日 下午 07:37
Hello All,
I seem to be having a problem with COM+ that has me stumped. I'm developing a Queued Component on an x64 Windows 7 box (but I've found the same issue on W2K8R2) with no success. The component is (supposed to be) instatiated by a web service, but Marshal.GetActiveObject returns null. I've combed through all the COM+ application settings and the Event Viewer with no luck.
Here is the code for the web service:
using WCF = global::System.ServiceModel;
namespace WCFService1.ServiceImplementation
{
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Processor;
using WCFService1.DataContracts;
using WCFService1.MessageContracts;
/// <summary>
/// Service Class - Service1
/// </summary>
[WCF::ServiceBehavior(Name = "Service1",
Namespace = "http://MSMQDemoR2.Model/2012/ServiceContractDsl1",
InstanceContextMode = WCF::InstanceContextMode.PerSession,
ConcurrencyMode = WCF::ConcurrencyMode.Single)]
public abstract class Service1Base : ServiceContracts.IServiceContract1
{
#region ServiceContract1 Members
public virtual MessageContracts.XsdMessage1 Operation1(MessageContracts.Message1 request)
{
return null;
}
#endregion ServiceContract1 Members
}
public partial class Service1 : Service1Base
{
public override MessageContracts.XsdMessage1 Operation1(MessageContracts.Message1 request)
{
var res = new XsdMessage1();
var tRoot = new root() { ExtensionData = null, msg = "sent" };
try
{
var iQc = Marshal.GetActiveObject("queue:/new:{67F00E61-E75E-317E-BAE5-46C76A3F1C73}") as IQComponent; // THIS RETURNS NULL
// iQc.DisplayMessage(messageToSend.Text);
Debug.Assert(iQc != null, "iQc != null");
iQc.ProcessQueue(msg: "test");
Marshal.ReleaseComObject(o: iQc);
tRoot.err = "good";
}
catch (Exception ex)
{
tRoot.err = ex.ToString();
}
res.Root = tRoot;
return res;
}
}
}Here is the Queued COM Component:
using System;
using System.Data;
using System.Diagnostics;
using System.EnterpriseServices;
using System.Messaging;
using System.Reflection;
using System.Runtime.InteropServices;
using Microsoft.Practices.EnterpriseLibrary.Data;
using Microsoft.Practices.EnterpriseLibrary.Data.Sql;
[assembly: ApplicationName(name: "QueueProcessor")]
[assembly: AssemblyKeyFile(keyFile: "keyPair.snk")]
[assembly: CLSCompliant(true)]
[assembly: ApplicationActivation(ActivationOption.Server)]
[assembly: ApplicationQueuing(Enabled = true, QueueListenerEnabled = true)]
[assembly: ApplicationAccessControl(false)]
namespace Processor
{
[ComVisible(true)]
[CLSCompliant(true)]
[InterfaceQueuing(Enabled = true)]
public interface IQComponent
{
void ProcessQueue(string msg);
}
[ComVisible(true)]
[CLSCompliant(true)]
[InterfaceQueuing(Interface = "IQComponent")]
public class MainClass1 : ServicedComponent, IQComponent
{
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
[ComVisible(true)]
[CLSCompliant(true)]
public void ProcessQueue(string msg)
{
Debug.Assert(Log != null, "log != null");
Log.Info(message: "Application [ProcessQueue] Start");
Log.Debug(message: string.Format(format: "msg:{0}", arg0: msg));
string tres = string.Empty;
try
{
Log.Debug(message: "starting SQL run");
Database db = new SqlDatabase("Data Source=PCSOFFDGG;Initial Catalog=testdb;Integrated Security=True");
db.ExecuteNonQuery(CommandType.Text,
"INSERT INTO results(st,name) SELECT a.st,b.name FROM people b INNER JOIN states AS a ON a.id=b.id");
using (var tdb = db.ExecuteReader(CommandType.Text, "SELECT * FROM results"))
while (tdb.Read())
{
tres += string.Format("{0}:{1}:{2}", tdb[0], tdb[1], tdb[2]);
Log.Debug(message: string.Format(format: "tres:{0}", arg0: tres));
}
}
catch (Exception ex)
{
Log.Error(message: ex);
}
Log.Debug(message: "finished SQL run");
Log.Debug(message: "starting MSMQ run");
try
{
using (var tMessageQueue = new MessageQueue(@".\private$\testa"))
tMessageQueue.Send(obj: tres);
Log.Debug(message: "MSMQ good");
}
catch (Exception ex)
{
Log.Error(message: ex);
}
Log.Debug(message: "end MSMQ run");
Log.Info("Application [ProcessQueue] End");
}
[CLSCompliant(isCompliant: true)]
public MainClass1()
{
Log.Debug("Application [ProcessQueue] Constructor");
}
}
}Thanks in advance for any ideas.
Geoff
所有回覆
-
2012年2月8日 下午 08:32
Just a quick follow up: I originally tried Marshal.BindToMoniker before trying Marshal.GetActiveObjectGeoffrey J Gowey

