MQRC_HOST_NOT_AVAILABLE when connecting to MQ Queue Manager - c#

I'm getting this error message, MQRC_HOST_NOT_AVAILABLE, when connecting to IBMMQ.
I'm relatively new to working with IBMMQ, but have been handed this project and need to get our .NET WCF code talking to MQ.
Our code currently looks like this:
Hashtable queueManagerProps = new Hashtable();
queueManagerProps.Add(MQC.HOST_NAME_PROPERTY, mqhost);
queueManagerProps.Add(MQC.CHANNEL_PROPERTY, mqchannel);
queueManagerProps.Add(MQC.PORT_PROPERTY, ConfigurationManager.AppSettings["MQPort"].ToString());
queueManagerProps.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED);
try
{
mqQMgr = new MQQueueManager(qmname, queueManagerProps);
}
catch (Exception ex)
{
throw new Exception(String.Format("Failed to connect to MQ Queue Manager {0}, channel {1} on host {2} on port {3}. Check inner exception for root cause.", qmname, mqchannel, mqhost, ConfigurationManager.AppSettings["MQPort"].ToString()), ex);
}
I have confirmed that (1) all the properties contain values, and (2) the values match the setup of our MQ server.
I also looked in the AMQERR01.LOG log file and there have been no entries since we set up the queue earlier this month.
Why is my new MQQueueManager() called throwing this exception? Is there any chance this could be a permissions issue, or is it definitely network / connectivity / configuration related?

Found the problem. I had the host name misspelt.
The moral of the story is don't overlook the fundamentals, even when working with a technology you don't understand.
Admins: please feel free to delete this question if you don't find it useful.

Related

Randomly getting Renci.SshNet.SftpClient.Connect throwing SshConnectionException

I've seen other threads about this error, but I am having this error randomly. Out of 30 connects, 12 got this error. Trying to understand why this is, and what possible solutions are.
using (SftpClient client = new SftpClient(sftpHost, sftpPort, sftpUser, sftpPassword))
{
client.Connect();
}
throws this exception:
Renci.SshNet.Common.SshConnectionException: Server response does not contain SSH protocol identification
This might sound trivial, but I have tried the Renci.SshNet.Async package and it worked with out any issue. The following could be a reason/s for the problem with solution or alternative solution.
Renci.SshNet.Async might have bug or issues that appears in specific environment or in specific combination. Some mentioned same problems here, no solution https://github.com/sshnet/SSH.NET/issues/377
Some has experienced same problem and mentioned a solutions, one is to retry n number of times Renci.SshNet : "server response does not contain ssh protocol identification"
The problem is not with your client but more or less with your Host. It can be many things or issues.
Finally I would try using WinSCP which is also well recognized library for .net (nuget). I have tried it my self as well and have never experienced any issues so far. I suggest you to get it and try it as alternative to your current solution, and see if it helps. If WinSCP works then point 1 is valid, if you experience same issue with WinSCP then point 3 is valid. This way we can make conclusions and narrow down to the problem.
Here examples provided by WinSCP https://winscp.net/eng/docs/library_examples.
My Test example is:
This is just playground example to see if things are running, when used in production, please modify it. Further more thanks to #MartinPrikry adding this note: If you have set SshHostKeyFingerprint correctly, then do not set GiveUpSecurityAndAcceptAnySshHostKey.
public static int WinSCPListDirectory()
{
try
{
var sessionOptions = new SessionOptions
{
Protocol = Protocol.Sftp,
HostName = "xxx.xxx.xxx.xxx",
UserName = "username",
Password = "password",
SshHostKeyFingerprint = "ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx",
GiveUpSecurityAndAcceptAnySshHostKey = true
};
using (var session = new Session())
{
session.Open(sessionOptions);
var directory = session.ListDirectory("/var/www");
foreach (RemoteFileInfo fileInfo in directory.Files)
{
Console.WriteLine(
"{0} with size {1}, permissions {2} and last modification at {3}",
fileInfo.Name, fileInfo.Length, fileInfo.FilePermissions,
fileInfo.LastWriteTime);
}
}
return 0;
}
catch (Exception e)
{
Console.WriteLine("Error: {0}", e);
return 1;
}
}
This example should return a list of directories
Related links:
https://winscp.net/eng/docs/library_session_listdirectory
OpenSource .NET library for connecting to SFTP server?
No one knows the exact cause for this behavior to be honest.
As a possible fix, Some people suggest creating a counter loop for retrying to connect, suggesting it solved their problem:
int attempts = 0;
do
{
try
{
client.Connect();
}
catch (Renci.SshNet.Common.SshConnectionException e)
{
attempts++;
}
} while (attempts < _connectiontRetryAttempts && !client.IsConnected);
Another suggestion is to add the IP address into the hosts.allow file on the server, so you could check in that direction as well.
As I said, there is no possible explanation for the behavior altogether.

Trouble opening QB

I am a long time c# developer but brand new to QBFC. I have downloaded the samples and was actually able to add an invoice to my file with it, but I am a little confused. I have trouble connecting unless QB is up and running. I was trying to follow the code in the sample, but it is difficult. I need this app to add invoices and bills to the file even if QB is not open. They only have one file so there won't be an instance where another file is already open. Also, the environment is simple as everything runs on the same computer.
My basic questions are:
How to select the correct QB file and provide credentials to allow access?
Is there a decent simple example using QBFC? Everything I have found is using XML which seems overly complicated compared to QBFC.
I cannot seem to get QB to open automatically. I have tried the code below and I get an error that states "Could not start QuickBooks".
Any pointers are greatly appreciated.
QBSessionManager qbSession = new QBSessionManager();
qbSession.OpenConnection("", "Lumber Management System");
try
{
qbSession.BeginSession("C:\\Users\\Jerry\\Documents\\QuickBooks\\Company Files\\MRJ Tecnology, LLC", ENOpenMode.omDontCare);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + '\n' + ex.StackTrace, "Error opening QB");
}
There are a couple of things that you need in order for this to work. The first time that you request access to a company file, QuickBooks must be opened and the Admin must be logged in. The Admin will then be given a dialog to grant permission to your application to access QuickBooks. In the permission dialog, it will ask the Admin if they want to allow the application to read and modify the company file with four options:
No
Yes, prompt each time
Yes, whenever this QuickBooks company file is open
Yes, always; allow access even if QuickBooks is not running
The admin must choose the fourth option to allow your app to launch QuickBooks without running.
I would also suggest that you use OpenConnection2 instead of OpenConnection, and use a unique ID as the first parameter. You will also need to specify the connection type, which should be ENConnectionType.ctLocalQBD.
It also appears that the filename you are passing in the BeginSession call does not include the .qbw extension. Here is a basic sample:
QBSessionManager SessionManager = null;
try
{
SessionManager = new QBSessionManager();
SessionManager.OpenConnection2("UniqueAppID", "Lumber Management System", ENConnectionType.ctLocalQBD);
SessionManager.BeginSession("C:\\Users\\Jerry\\Documents\\QuickBooks\\Company Files\\MRJ Tecnology, LLC.qbw", ENOpenMode.omSingleUser);
// CODE TO SEND TO QB GOES HERE
}
catch(Exception ex)
{
MessageBox.Show("Error opening QB:" + ex.ToString());
}
finally
{
if(SessionManager != null)
{
SessionManager.EndSession();
SessionManager.CloseConnection();
}
}

Post Journal Entries to EPICOR 905 using C#

I'm trying to connect to Epicor905 and post a journal entry programmatically.
I found the below code which connects to Epicor. However, I am unable to locate any info on accessing the GL Journal Entry module. I'm fairly new to C# and just want someone to point me in the right direction logically/technically. I understand that the core of it is working with DLLs and the business objects. But beyond that I am clueless. Here is the code I found to connect to EPICOR:
using Ice.Core;
using Erp.Common;
try
{
Session obj = new Session("manager", "manager", Session.LicenseType.Default, #"C:\Epicor\E10Pilot.sysconfig");
if (obj != null)
{
MessageBox.Show("Sesion valida");
obj.Dispose();
obj = null;
}
}
catch (Exception error)
{
MessageBox.Show(error.Message);
}
The easiest way to identify the calls required is to start client tracing and run through the process you wish to automate in the UI. This will record the calls that the UI makes for your particular process. You should then be able to replicate them in your code.
You will need to reference the contract assembly for each BO required from your client directory.
This will take some experimentation to identify the right calls but this is exactly how the CSG team in Epicor would approach this.

PrintServerException - "...name is invalid" even though I can access the path from windows

A line similar to the following threw the above exception:
PrintServer ps = new PrintServer(#"\\prntsrv");
When I use "Run..." on Windows the address above does work and take me to the list of print jobs so why does the line of code not work?
Apparently, the address \\prntsrv was a DNS alias to \\prntserv and the PrintServer constructor was unable to deal with it. To get around this issue I used the following code (I could also use just the code in the catch block instead and it would work, but preferred not to):
try
{
// Create object to monitor the printer queue
PrintServer printServer = new PrintServer(serverPath);
mPrintQueue = printServer.GetPrintQueue(printerName);
}
catch (PrintServerException ex)
{
// If the problem might be creating the server because the name is an alias
if (ex.Message.Contains("printer name is invalid."))
{
string actualServerHostname = "\\\\" + Dns.GetHostEntry(serverPath.TrimStart('\\')).HostName;
// Create object to monitor the printer queue
PrintServer printServer = new PrintServer(actualServerHostname);
mPrintQueue = printServer.GetPrintQueue(printerName);
// Write to log about the use of a different address
}
else
{
throw;
}
}
hey i was facing similar issue, this is what i observed and made following changes, just try and let me know.
This issue was occuring due to windows feature/role "Print and Document service" is missing on the system. This role is required for managing multiple printers or print servers and migrating printers to and from other windows servers.
To add the role Go To Control Panel->Turn windows feature on or off->click on check box "Print and Document Service"->install.
See with network administrator for installing this rule if you unable to add it.
After adding the role you can able to create print server object and get the all the printqueues on respective server.

What is the Fastest way to read event log on remote machine?

I am working on an application which reads eventlogs(Application) from remote machines. I am making use of EventLog class in .net and then iterating on the Log entries but this is very slow. In some cases, some machines have 40000+ log entries and it takes hours to iterate through the entries.
what is the best way to accomplish this task? Are there any other classes in .net which are faster or in any other technology?
Man, I feel your pain. We had the exact same issue in our app.
Your solution has a branch depending on what server version you're running on and what server version your "target" machine is running on.
If you're both on Vista or Windows Server 2008, you're in luck. You should look at System.Diagnostics.Eventing.Reader.EventLogQuery and System.Diagnostics.Eventing.Reader.EventLogReader. These are new in .net 3.5.
Basically, you can build a query in XML and ship it over to run on the remote computer. Maybe you're just searching for events of a specific type, or maybe just new events from a specific point in time. The search runs on the remote machine, and then you just get back the matching events. The new classes are much faster than the old .net 2.0 way, but again, they are only supported on Vista or Windows Server 2008.
For our app when the target is NOT on Vista/Win2008, we downloaded the raw .evt file from the remote system, and then parsed the file using its binary format. There are several sources of data about the event log format for .evt files (pre-Vista), including link text and an article I recall on codeproject.com that had some c# code.
Vista and Windows Server 2008 machines use a new .evtx format that is a new format, so you can't use the same binary parsing approach across all versions. But the new EventLogQuery and EventLogReader classes are so fast that you won't have to. It's now perfectly speedy to just use the built-in classes.
Event Log Reader is horribly slow... too slow. WTF Microsoft?
Use LogParser 2.2 - Search for C# and LogParser on the Internet (or you can use the log parser commands from the command line). I don't want to duplicate the work already contributed by others.
I pull the log from the remote system by having the log exported as an EVTX file. I then copy the file from the remote system. This process is really quick - even with a network that spans the planet (I had issues with having the log exported to a network resource). Once you have it local, you can do your searches and processing.
There are multiple reasons for having the EVTX - I won't get into the reasons why we do this.
The following is a working example of the code to save a copy of the log as an EVTX:
(Notes: "device" is the network host name or IP. "LogName" is the name of the log desired: "System", "Security", or "Application". outputPathOnRemoteSystem is the path on the remote computer, such as "c:\temp\%hostname%.%LogName%.%YYYYMMDD_HH.MM%.evtx".)
static public bool DumpLog(string device, string LogName, string outputPathOnRemoteSystem, out string errMessage)
{
bool wasExported = false;
string errorMessage = "";
try
{
System.Diagnostics.Eventing.Reader.EventLogSession els = new System.Diagnostics.Eventing.Reader.EventLogSession(device);
els.ExportLogAndMessages(LogName, PathType.LogName, "*", outputPathOnRemoteSystem);
wasExported = true;
}
catch (UnauthorizedAccessException e)
{
errorMessage = "Unauthorized - Access Denied: " + e.Message;
}
catch (EventLogNotFoundException e)
{
errorMessage = "Event Log Not Found: " + e.Message;
}
catch (EventLogException e)
{
errorMessage = "Export Failed: " + e.Message + ", Log: " + LogName + ", Device: " + device;
}
errMessage = errorMessage;
return wasExported;
}
A good Explanation/Example can be found on MSDN.
EventLogSession session = new EventLogSession(Environment.MachineName);
// [System/Level=2] filters out the errors
// Where "Log" is the log you want to get data from.
EventLogQuery query = new EventLogQuery("Log", PathType.LogName, "*[System/Level=2]");
EventLogReader reader = new EventLogReader(query);
for (EventRecord eventInstance = reader.ReadEvent();
null != eventInstance;
eventInstance = reader.ReadEvent())
{
// Output or save your event data here.
}
When waiting 5-20 minutes with the old code this one does it in less than 10 seconds.
Maybe WMI can help you:
WMI with C#
Have you tried using the remoting features in powershell 2.0? They allow you to execute cmdlets (like ones to read event logs) on remote machines and return the results (as objects, of course) to the calling session.
You could place a Program at those machines that save the log to file and sends it to your webapplication i think that would be alot faster as you can do the looping local but im not sure how to do it so i cant ive you any code :(
I recently did such thing via WCF callback interface however my clients interacted with the server through WCF and adding a WCF Callback was easy in my project, full code with examples is available here
Just had the same issue and want to share my solution. It makes a search through application, system and security eventlogs from 260 seconds (using EventLog) about a 100 times faster (using EventLogQuery).
And this in a way where it is possible to check if the event message contains a pattern or any other check without the requirement of FormatDescription().
My trick is to use the same mechanism as PowerShells Get-WinEvent does and then pass it through the result check.
Here is my code to find all events within last 4 days where the event message contains a filter pattern.
string[] eventLogSources = {"Application", "System", "Security"};
var messagePattern = "*Your Message Search Pattern*";
var timeStamp = DateTime.Now.AddDays(-4);
var matchingEvents = new List<EventRecord>();
foreach (var eventLogSource in eventLogSources)
{
var i = 0;
var query = string.Format("*[System[TimeCreated[#SystemTime >= '{0}']]]",
timeStamp.ToUniversalTime().ToString("o"));
var elq = new EventLogQuery(eventLogSource, PathType.LogName, query);
var elr = new EventLogReader(elq);
EventRecord entryEventRecord;
while ((entryEventRecord = elr.ReadEvent()) != null)
{
if ((entryEventRecord.Properties)
.FirstOrDefault(x => (x.Value.ToString()).Contains(messagePattern)) != null)
{
matchingEvents.Add(entryEventRecord);
i++;
}
}
}
Maybe that the remote computers could do a little bit of computing. So this way your server would only deal with relevant information. It would be a kind of cluster using the remote computer to do some light filtering and the server would the the analysis part.

Categories

Resources