how to get connect with ibm websphere mq by using c#.net - c#

can any one guide me on, to get connect with ibm websphere mq by using c#.net, reason was i am trying to push the message in to MQ, kindly can any give me suggestion to connect by using c#.net

There is an IBM supplied dll (since v5.3 Fixpack8) on Windows called amqmdnet.dll, which is a .NET assembly providing an IBM supported model for MQSeries. (Reference) It is usually located in C:\Program Files\IBM\WebSphere MQ\bin\amqmdnet.dll
If you need more direction, there are several examples on how to communicate with MQ from .NET on CodeProject:
http://www.codeproject.com/Articles/12198/IBM-WebSphere-MQ-with-C-GUI-application-that-is-bo
http://www.codeproject.com/Articles/37807/How-to-Setup-a-Websphere-MQ-with-C-NET-GUI-to-Put
http://www.codeproject.com/Articles/6212/C-and-WebSphere-MQ-formerly-MQSeries-Client-Server
Also, there's this walkthrough that could be helpful: http://www.c-sharpcorner.com/UploadFile/pk_khuman/AquickstartCsharpWebsphereMQ07112006024017AM/AquickstartCsharpWebsphereMQ.aspx

You can connect using the .NET libraries provided by IBM; however, they require you to install the WebSphere MQ Client on every server you deploy your solution to. (lame)
If using WebSphere MQ, the machine used to run the XMS application
must be installed with the WebSphere MQ Client V7.0.1.0 or later
You can avoid this by converting a few Java libraries using IKVM (www.ikvm.net).
The whole process should only take about 15 minutes.
You'll still need to download and install the client on your development box so that you can get the JAR files. After you convert them, you can uninstall the client.
Here are the steps
1) Get JARs
Download WebSphere MQ V7.5 Client: http://www-304.ibm.com/support/docview.wss?uid=swg24032744
Install the MQ client: You only need to install the "Java and .Net Messaging and Web Services".
2) Convert JARs
Download IKVM: www.ikvm.net
Extract the IKVM files (e.g. c:\tools\IKVM).
Open Win command prompt
Execute command: set path=%path%;c:\tools\IKVM\bin
Execute command: cd C:\Program Files (x86)\IBM\WebSphere MQ\java\lib
Execute command: ikvmc -target:library -sharedclassloader { com.ibm.mq.jmqi.jar } { com.ibm.mqjms.jar } { dhbcore.jar } { jms.jar }
3) Copy JARs
Open windows explorer.
Navigate to: C:\Program Files (x86)\IBM\WebSphere MQ\java\lib
Copy the following files:
**com.ibm.mq.jmqi.dll
com.ibm.mqjms.dll
jms.dll**
Navigate to: c:\tools\IKVM\bin
Copy the following files:
**IKVM.Runtime.dll
IKVM.OpenJDK.Core.dll**
Move the copied files to a 3rd Party folder in your project/solution.
4) References JARs
Reference the copied JARs. Please note that you can skip the previous Copy JARs step above and simply reference the libraries directly, if you like. The objective was to show that there were no other resources needed for proper execution.
The following is a very simple example of how you can use the libraries.
using com.ibm.msg.client.jms;
using com.ibm.msg.client.wmq.common;
using javax.jms;
using System;
class Program
{
static void Main(string[] args)
{
var ff = JmsFactoryFactory.getInstance(JmsConstants.__Fields.WMQ_PROVIDER);
var cf = ff.createConnectionFactory() as JmsConnectionFactory;
cf.setIntProperty(CommonConstants.__Fields.WMQ_CONNECTION_MODE, CommonConstants.__Fields.WMQ_CM_CLIENT);
cf.setStringProperty(CommonConstants.__Fields.WMQ_HOST_NAME, "<YOUR INFO>");
cf.setIntProperty(CommonConstants.__Fields.WMQ_PORT, 1414);
cf.setStringProperty(CommonConstants.__Fields.WMQ_CHANNEL, "<YOUR INFO>");
cf.setStringProperty(CommonConstants.__Fields.WMQ_QUEUE_MANAGER, "<YOUR INFO>");
var connection = cf.createConnection();
var session = connection.createSession(false, Session.__Fields.AUTO_ACKNOWLEDGE);
var queue = session.createQueue("queue:///<YOUR INFO>");
var producer = session.createProducer(queue);
var msg = session.createTextMessage();
msg.setStringProperty("JMSXGroupID", Guid.NewGuid().ToString());
msg.setIntProperty("JMSXGroupSeq", 1);
msg.setBooleanProperty("JMS_IBM_Last_Msg_In_Group", true);
msg.setText("Hello World");
connection.start();
producer.send(msg);
producer.close();
session.close();
connection.close();
}
}

There are number of samples that come with MQ product install. Refer Nmqsput.cs for your case. When creating a new project you will need to add amqmdnet.dll as reference.
Not sure what version of MQ you are using. I am assuming you are using MQ v701. You can find the samples under tools folder of your MQ installation.
If are looking for JMS style of messaging in C#, then XMS .NET is worth looking at. You can find the samples of XMS .NET in the same folder as MQ samples. XMS .NET reference is here

Already converted (java to c#) mq-client -
nuget,
github
c# example:
var ff = JmsFactoryFactory.getInstance(JmsConstants.__Fields.WMQ_PROVIDER);
var cf = ff.createConnectionFactory();
cf.setIntProperty(CommonConstants.__Fields.WMQ_CONNECTION_MODE, CommonConstants.__Fields.WMQ_CM_CLIENT);
cf.setStringProperty(CommonConstants.__Fields.WMQ_HOST_NAME, "127.0.0.1");
cf.setIntProperty(CommonConstants.__Fields.WMQ_PORT, 8010);
cf.setStringProperty(CommonConstants.__Fields.WMQ_CHANNEL, "EXAMPLE.CHANNEL.ONE");
cf.setStringProperty(CommonConstants.__Fields.WMQ_QUEUE_MANAGER, "EXAMPLE_QUEUE_MANAGER");
cf.setStringProperty(CommonConstants.__Fields.WMQ_APPLICATIONNAME, "JMS EXAMPLE");
cf.setStringProperty(CommonConstants.USERID, "EXAMPLE_USER");
using (var context = cf.createContext())
{
var queue = context.createQueue("queue:///EXAMPLE_QUEUE_NAME");
var producer = context.createProducer();
producer.send(queue, "Hello World");
}

Related

How to instantiate a ComVisible class in a .NET Core assembly from .NET Framework application?

We have a software product that is currently released that is a .NET Framework 4.7.2 application (the "legacy" app). The legacy client-server implementation is built on System.Runtime.Remoting, which is not supported in .NET 5 and later, so the .NET 5 implementation is gRPC.
It is necessary to instantiate each of the two COM servers in turn because the legacy and the .NET 5 COM servers can only connect to the comm (not COM) server application that implements the same communications framework, which are System.Runtime.Remoting and gRPC, respectively.
The COM servers are used by third party applications to interface with the comm server application, so I am currently working on creating a static class that returns the interface from the COM server that can connect to the currently running instance of the comm server.
I have a .NET 5 WPF implementation of the product almost complete, but I've hit a roadblock in that, I am unable to register the .NET COM server.
I found these two articles:
Exposing .NET Core Components to COM
GitHub Issue
I have now been able to:
Create a Type Library
I found a comment from #SimonMourier suggesting copying the .NET 5 COM server code into a .NET Framework project and use RegAsm to export the type library to be used in the .NET 5 project. The type library was added to the .NET 5 COM server project folder and "" was added to an ItemGroup in the .csproj file per the first referenced article.
Register the .NET 5 COM server
This required using the "dotnet publish -r win-x64 -c Debug" command in the project folder from the Visual Studio Developer Command Line. I was then able to use regsvr32 to register the WinCalRemoting.comhost.dll in the "bin\Debug\net5.0\win-x64\publish" project directory.
Create an Instance of the COM Class
After registering the COM server, I am now able to create an instance of the COM class, but haven't been successful at getting the interface from it:
public static IWinCalClient LoadCompatibleRemotingClient(bool useClientEventWindow, string serverName, int serverPort, bool connectToServer = true)
{
UseClientEventWindow = useClientEventWindow;
WinCalServerName = serverName;
WinCalServerPort = serverPort;
ClassIdList = new Guid[]
{
LegacyWinCalClientClsId, // CAN'T GET INTERFACE FROM THIS COM SERVER
//WinCal5ClientClsId // THE .NET 5 COM SERVER WORKS
};
if (RemotingClassObject != null)
{
UnloadClient();
}
foreach (Guid clsId in ClassIdList)
{
try
{
RemotingClassObject = Activator.CreateInstance(Type.GetTypeFromCLSID(clsId, true));
}
catch (Exception e)
{
continue;
}
if (RemotingClassObject != null)
{
RemotingInterface = (IWinCalClient)RemotingClassObject;
if (RemotingInterface == null)
{
UnloadClient();
continue;
}
if (CanClientConnect(_RemotingInterface, connectToServer))
{
break;
}
}
if (Marshal.IsComObject(RemotingClassObject))
{
Marshal.FinalReleaseComObject(RemotingClassObject);
}
RemotingClassObject = null;
}
return RemotingInterface;
}
Update on the exception
After correcting the "bitness" of the test COM Client application that #SimonMourier clued me to, I am able to get the interface from the .NET 5 COM server. I have updated the code from the method.
HOWEVER, I'm now struggling with getting the interface from the .NET Framework COM server in the same way I get it from the .NET 5 COM server. I successfully register it using RegAsm.exe, but I get the following exception:
System.InvalidCastException: 'Unable to cast object of type 'CMI.WinCalRemoting.cWinCalClient' to type 'CMI.WinCalRemoting.IWinCalClient'.'.
I've done an exhaustive search to try to find out how to fix the .NET Framework COM project so that it can be used in the same way that the .NET 5 COM server is used so that it doesn't matter whether the COM client is a .NET Framework or a .NET Core assembly.
I added a .NET Framework COM server project to the shared directory below to replicate what I'm seeing. With the .NET Framework COM server.
I also switched the test application to be 32-bit to replicate how our sister application will be using the COM servers.
All of the projects are located here:
.NET 5 COM Interop
Unable to Add .NET Framework COM Type Library Reference
For a .NET Framework client assembly, I've attempted to add a reference to the .NET Framework COM server that was registered with regasm.exe, but that fails with the following message:

Transactional IBM MQ 9.0.0.3 .NET Monitor sample crashes with AMQ8377

I'm trying to get the transactional .NET monitor sample to work from the IBM WebSphere 9.0 documentation (see Using the .NET monitor, page 675 of the folowing document: ftp://public.dhe.ibm.com/software/integration/wmq/docs/V9.0/PDFs/mq90.develop.pdf)
I managed to compile everything ok (targetting .NET 2.0), but when running the monitor with runmqdnm as follows, I get an exception:
runmqdnm -m myqmgr -q myqueue -a TransactionalMonitor.dll -c TransactionalMonitor.Monitor
5724-H72 (C) Copyright IBM Corp. 1994, 2017.
AMQ8377: Unexpected error 2354 was received by the application.
I'm running the sample directly on my MQ server, which is a Windows Server 2012 R2 machine with IBM MQ 9.0.0.3 server installed.
For reference, the code I implemented:
using System.EnterpriseServices;
using IBM.WMQ;
using IBM.WMQMonitor;
[assembly: ApplicationName("TransactionalMonitor")]
namespace TransactionalMonitor
{
[Transaction(TransactionOption.Required)]
public class Monitor : ServicedComponent, IMQObjectTrigger
{
[AutoComplete(true)]
public void Execute(MQQueueManager qmgr, MQQueue queue, MQMessage message, string param)
{
System.Console.WriteLine("SETTING COMMIT");
ContextUtil.SetComplete();
}
}
}
When removing the transactional stuff the sample works OK.
What am I doing wrong?
You don't say what release of IBM MQ you are actually using (you mention MQ V9 documentation).
I would compile your exit with the OLDEST release of .NET that you have. People try and use the latest & greatest but most times it will not work.
i.e. For 64-bit DLL
C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727\csc.exe /nologo /t:library /platform:x64 /r:System.dll /r:"%MQ_FILE_PATH%\bin\amqmdnet.dll" /out:TransactionalMonitor.dll TransactionalMonitor.cs
Just for reference:
Problem is fixed after upgrading to version 9.0.5.
Also make sure that the MSRPC & MSDTC ports are not blocked by a firewall.
See this blog post for more info on the that.

Visual Studio Team Services API Example Throwing System.Net.Http Error

I'm trying to write an application that communicates with Visual Studio Team Services, using the Nuget packages listed here.
The example code is directly from Microsoft's official documentation, on same same page the packages are listed, under "Pattern for use". My test code is in a console application, set to version 4.7 of the .net framework (compiled by Visual Studio 2017 15.2(26430.16) Release, but I don't think that matters). The code is identical to Microsoft's example, other than changing the connection url, project, and repo name.
The only Nuget package directly installed (about 30 others are installed as dependencies) is Microsoft.TeamFoundationServer.ExtendedClient.
Install-Package Microsoft.TeamFoundationServer.ExtendedClient
using System;
using Microsoft.VisualStudio.Services.Common;
using Microsoft.VisualStudio.Services.Client;
using Microsoft.TeamFoundation.SourceControl.WebApi;
using Microsoft.VisualStudio.Services.WebApi;
namespace vssApiTest
{
class Program
{
const String c_collectionUri = "https://[[redacted]].visualstudio.com/DefaultCollection";
const String c_projectName = "Inspections";
const String c_repoName = "Src";
static void Main(string[] args)
{
// Interactively ask the user for credentials, caching them so the user isn't constantly prompted
VssCredentials creds = new VssClientCredentials();
creds.Storage = new VssClientCredentialStorage();
// Connect to VSTS
VssConnection connection = new VssConnection(new Uri(c_collectionUri), creds);
// Get a GitHttpClient to talk to the Git endpoints
GitHttpClient gitClient = connection.GetClient<GitHttpClient>();
// Get data about a specific repository
var repo = gitClient.GetRepositoryAsync(c_projectName, c_repoName).Result;
}
}
}
On the line VssConnection connection = new VssConnection(new Uri(c_collectionUri), creds);, a TypeLoadException is thrown (at run-time) with the message:
Inheritance security rules violated by type:
'System.Net.Http.WebRequestHandler'. Derived types must either match
the security accessibility of the base type or be less accessible.
None of the Google search variants I've tried on this error message have returned anything helpful.
Am I doing something wrong, is the example code I'm following wrong, or is there some other issue going on?
The problem was due to a bug introduced in version 4.1.0 of the System.Net.Http Nuget package, as discussed here.
The solution was to update that Nuget package to the latest version (4.3.2 at this time, it may have been fixed in earlier versions also).

How do I enable ignite-http-rest module when using the .Net NuGet Apache Ignite package?

I have a .Net console project referencing the Apache Ignite Nuget package. I'm interested in running the ignite-rest-http module within this same process. I'm using Apache Ignite 2.0.
I'm referring to the Apache Ignite REST Api as described here:
https://apacheignite.readme.io/docs/rest-api
I've tried the "Getting Started":
To enable HTTP connectivity, make sure that ignite-rest-http module is
in classpath. With binary distribution this means copying
libs\optional\ignite-rest-http to libs\ignite-rest-http.
However, it didn't seem to work. I started my process and went to http://localhost:8080, but there was no response.
Is it appropriate to host the ignite-rest-http module within a .Net process?
If so, is there something else I need to configure in order to host the ignite-rest-http module in a .Net process?
NuGet package includes a limited set of JARs required for core functionality. Optional libs are not included (NuGet.org has 30 MB package size limit).
To enable ignite-rest-http with NuGet:
Download full binary package from https://ignite.apache.org/download.cgi#binaries
Extract libs\optional\ignite-rest-http contents somewhere, say c:\ignite-rest-http
Provide IgniteConfiguration.JvmClasspath property with ;-separated paths to all http JAR files
var cfg = new IgniteConfiguration
{
JvmClasspath = Directory.GetFiles(#"c:\ignite-rest-http")
.Aggregate((x, y) => x + ";" + y)
};
Ignition.Start(cfg);
Console.WriteLine(new WebClient().DownloadString("http://localhost:8080/ignite?cmd=version"));
There are plans to include these JARs as a separate NuGet package: https://issues.apache.org/jira/browse/IGNITE-3275

What is the minimum client footprint required to connect C# to an Oracle database?

I have successfully connected to an Oracle database (10g) from C# (Visual Studio 2008) by downloading and installing the client administration tools and Visual Studio 2008 on my laptop.
The installation footprint for Oracle Client tools was over 200Mb, and quite long winded.
Does anyone know what the minimum workable footprint is? I am hoping that it's a single DLL and a register command, but I have the feeling I need to install an oracle home, and set various environment variables.
I am using Oracle.DataAccess in my code.
You need an Oracle Client to connect to an Oracle database. The easiest way is to install the Oracle Data Access Components.
To minimize the footprint, I suggest the following :
Use the Microsoft provider for Oracle (System.Data.OracleClient), which ships with the framework.
Download the Oracle Instant Client Package - Basic Lite : this is a zip file with (almost) the bare minimum. I recommend version 10.2.0.4, which is much smaller than version 11.1.0.6.0.
Unzip the following files in a specific folder :
v10 :
oci.dll
orannzsbb10.dll
oraociicus10.dll
v11 :
oci.dll
orannzsbb11.dll
oraociei11.dll
On a x86 platform, add the CRT DLL for Visual Studio 2003 (msvcr71.dll) to this folder, as Oracle guys forgot to read this...
Add this folder to the PATH environment variable.
Use the Easy Connect Naming method in your application to get rid of the infamous TNSNAMES.ORA configuration file. It looks like this : sales-server:1521/sales.us.acme.com.
This amounts to about 19Mb (v10).
If you do not care about sharing this folder between several applications, an alternative would be to ship the above mentioned DLLs along with your application binaries, and skip the PATH setting step.
If you absolutely need to use the Oracle provider (Oracle.DataAccess), you will need :
ODP .NET 11.1.0.6.20 (the first version which allegedly works with Instant Client).
Instant Client 11.1.0.6.0, obviously.
Note that I haven't tested this latest configuration...
I use the method suggested by Pandicus above, on Windows XP, using ODAC 11.2.0.2.1. The steps are as follows:
Download the "ODAC 11.2 Release 3 (11.2.0.2.1) with Xcopy Deployment" package from oracle.com (53 MB), and extract the ZIP.
Collect the following DLLs: oci.dll (1 MB), oraociei11.dll (130 MB!), OraOps11w.dll (0.4 MB), Oracle.DataAccess.dll (1 MB). The remaining stuff can be deleted, and nothing have to be installed.
Add a reference to Oracle.DataAccess.dll, add using Oracle.DataAccess.Client; to your code and now you can use types like OracleConnection, OracleCommand and OracleDataReader to access an Oracle database. See the class documentation for details. There is no need to use the tnsnames.ora configuration file, only the connection string must be set properly.
The above 4 DLLs have to be deployed along with your executable.
As of 2014, the OPD.NET, Managed Driver is the smallest footprint.
Here is a code usage comparison to the non-managed versions that previous (outdated) answers suggested:
http://docs.oracle.com/cd/E51173_01/win.122/e17732/intro005.htm#ODPNT148
You will need to download these dlls and reference Oracle.ManagedDataAccess.dll in your project:
Download the ODP.NET, Managed Driver Xcopy version only
Here is a typical foot print you will need to package with your release:
Oracle.ManagedDataAccess.dll
Oracle.ManagedDataAccessDTC.dll
all together, a whopping 6.4 MB for .Net 4.0.
This way allows you to connect with ODP.net using 5 redistributable files from oracle:
Chris's blog entry: Using the new ODP.Net to access Oracle from C# with simple deployment
Edit: In case the blog every goes down, here is a brief summary...
oci.dll
Oracle.DataAccess.dll
oraociicus11.dll
OraOps11w.dll
orannzsbb11.dll
oraocci11.dll
ociw32.dll
make sure you get ALL those DLL's from the same ODP.Net / ODAC distribution to avoid version number conflicts, and put them all in the same folder as your EXE
DevArt http://www.devart.com/, formerly CoreLab (crlab.com) supplies a pure-C# Oracle client. That's a single dll, and it works fine.
Here is an update for Oracle 11.2.0.4.0. I had success with the following procedure on Windows 7 using System.Data.OracleClient.
1. Download Instant Client Package - Basic Lite: Windows 32-Bit or 64-Bit.
2. Copy the following files to a location in your system path:
32-Bit
1,036,288 2013-10-11 oci.dll
348,160 2013-10-11 ociw32.dll
1,290,240 2013-09-21 orannzsbb11.dll
562,688 2013-10-11 oraocci11.dll
36,286,464 2013-10-11 oraociicus11.dll
64-Bit
691,712 2013-10-09 oci.dll
482,304 2013-10-09 ociw32.dll
1,603,072 2013-09-10 orannzsbb11.dll
1,235,456 2013-10-09 oraocci11.dll
45,935,104 2013-10-09 oraociicus11.dll
3. Construct a connection string that omits the need for tnsnames.ora.
(See examples in the test program below.)
4. Run this minimal C# program to test your installation:
using System;
using System.Data;
using System.Data.OracleClient;
class TestOracleInstantClient
{
static public void Main(string[] args)
{
const string host = "yourhost.yourdomain.com";
const string serviceName = "yourservice.yourdomain.com";
const string userId = "foo";
const string password = "bar";
var conn = new OracleConnection();
// Construct a connection string using Method 1 or 2.
conn.ConnectionString =
GetConnectionStringMethod1(host, serviceName, userId, password);
try
{
conn.Open();
Console.WriteLine("Connection succeeded.");
// Do something with the connection.
conn.Close();
}
catch (Exception e)
{
Console.WriteLine("Connection failed: " + e.Message);
}
}
static private string GetConnectionStringMethod1(
string host,
string serviceName,
string userId,
string password
)
{
string format =
"SERVER=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)" +
"(HOST={0})(PORT=1521))" +
"(CONNECT_DATA=(SERVER=DEDICATED)" +
"(SERVICE_NAME={1})));" +
"uid={2};" +
"pwd={3};"; // assumes port is 1521 (the default)
return String.Format(format, host, serviceName, userId, password);
}
static private string GetConnectionStringMethod2(
string host,
string serviceName,
string userId,
string password
)
{
string format =
"Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)" +
"(HOST={0})(PORT=1521))" +
"(CONNECT_DATA=(SERVER=DEDICATED)" +
"(SERVICE_NAME={1})));" +
"User Id={2};" +
"Password={3};"; // assumes port is 1521 (the default)
return String.Format(format, host, serviceName, userId, password);
}
}
Final tip: If you encounter the error "System.Data.OracleClient requires Oracle client software version 8.1.7", see this question.
ODAC xcopy will get you away with about 45MB.
http://www.oracle.com/technology/software/tech/windows/odpnet/index.html
I found this post on the Oracle forum very usefull as well:
How to setup Oracle Instant Client with Visual Studio
Remark: the ADO.NET team is deprecating System.Data.OracleClient so for future projects you should use ODP.NET
Reproduction:
Setup the following environment variables:
make sure no other oracle directory is in your PATH
set your PATH to point to your instant client
set your TNS_ADMIN to point to where you tnsnames.ora file is
located
set your NLS_LANG
set your ORACLE_HOME to your instant client
For me, I set NLS_LANG to
http://download-east.oracle.com/docs/html/A95493_01/gblsupp.htm#634282
I verified this was using the correct client software by using the sqlplus add-on to the instant client.
For me, I set:
SET NLS_LANG=AMERICAN_AMERICA.WE8MSWIN1252
Note: before you make any changes, back up your Oracle registry key (if exist) and backup the string for any environment variables.
Read the Oracle Instant Client FAQ here

Categories

Resources