Connecting to the MQ Server using CCDT - c#

I'm trying to connect to the MQ using the information present in the CCDT file. I can currently connect to the MQ using all the details, and get and put messages from and to the queue.
After extensive googling, I've been unable to find any sample code which allows me to connect using the CCDT file.
One of my colleagues forwarded me his JMS connection code, but I've been unable to port it to C#.
The JAVA code is as follows -
public class MQTest {
public static void main(String[] args) {
MQQueueManager queueManager = null;
URL ccdtFileUrl = null;
MQMessage mqMessage = null;
//MQPutMessageOptions myPMO = null
try {
String QM = "IB9QMGR";
String QUEUE1 = "TEST";
System.out.println("Starting MQClient Put Program: ");
ccdtFileUrl = new URL("file:///D:/AMQCLCHL.TAB") ;
ccdtFileUrl.openConnection();
queueManager = new MQQueueManager("SDCQMGR.T1", ccdtFileUrl);
System.out.println("Connected to QMGR ");
int openOptions = MQC.MQOO_OUTPUT;
MQQueue InQueue = queueManager.accessQueue(QUEUE1,openOptions,null,null,null);
MQMessage inMessage = new MQMessage();
inMessage.writeString("###Testing####");
InQueue.put(inMessage);
System.out.println("Message Id is :" + inMessage.messageId);
System.out.println(inMessage.toString());
InQueue.close();
queueManager.disconnect() ;
}
catch(MQException ex){
System.out.println("MQ Error - Reason code :" + ex.reasonCode);
}
catch (Exception e){
System.out.println("Error : " + e);
}
}
}
Instead of URL, I used the URI (in C#) to set file location. (This may be wrongly used. Not sure what else to use though.)
Uri ccdtFileUrl = new Uri("file:///D:/AMQCLCHL.TAB") ;
but I can't use openConnection() on a URI. Also,
queueManager = new MQQueueManager("SDCQMGR.T1",ccdtFileUrl);
gives an argument overload exception. As URI is not supported in C#.
I've tried looking up samples but I've found some JMS samples and thats it. Looking for some sample code to connect in C#.

You will need to set MQCHLLIB and MQCHLTAB environment variables to use CCDT. You can set these two variables either from command prompt,app.config or code in the application itself.
Following example demonstrates usage of CCDT:
MQQueueManager qm = null;
System.Environment.SetEnvironmentVariable("MQCHLLIB", "C:\\ProgramData\\IBM\\MQ\\qmgrs\\QM1\\#ipcc");
System.Environment.SetEnvironmentVariable("MQCHLTAB", "AMQCLCHL.TAB");
try
{
**Hashtable props = new Hashtable();
props.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_CLIENT);
qm = new MQQueueManager("QM1",props);**
MQQueue queue1 = qm.AccessQueue("SYSTEM.DEFAULT.LOCAL.QUEUE", MQC.MQOO_OUTPUT | MQC.MQOO_FAIL_IF_QUIESCING);
MQMessage msg = new MQMessage();
msg.WriteUTF("Hello this message is from .net client");
queue1.Put(msg);
queue1.Close();
qm.Disconnect();
}
catch (Exception ex)
{
Console.Write(ex);
}

Related

Getting the "path" of connected/disconnected USB HID devices in C#

As a flightsim enthusiast, I'm making my own cockpit hardware. I interface this hardware with my computer(s) using the USB HID interface (HW based on PIC microcontrollers). All hardware has the same VID/PID, and the Product Descriptor string is "FMGS HW Device" (fyi: FMGS is the name of the Airbus A320 simulator software I'm using).
On startup, my application scans all the USB devices and only puts the ones with my "VID/PID/Product Descriptor" combination in a Dictionary. As key, I'm using the "DevicePath" that I retrieve via the PSP_DEVICE_INTERFACE_DETAIL_DATA structure with a call to SetupDiGetDeviceInterfaceDetail (setupapi.dll).
Below is a small code extract that shows the core of this operation - just so you get the idea:
// Retrieving the detailDataBuffer
SetupApi.SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref deviceInterfaceData, detailDataBuffer, bufferSize, ref bufferSize, IntPtr.Zero);
// Skip over cbsize (4 bytes) to get the address of the devicePathName
var pDevicePath = new IntPtr(detailDataBuffer.ToInt32() + 4);
// Get the String containing the devicePath
AddDevice(Marshal.PtrToStringAuto(pDevicePath));
This DevicePath has the following format:
\?\hid#vid_04d8&pid_003f#9&599cfdc&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
Question 1:
I can clearly see the VID/PID part (vid_04d8&pid_003f) and the HidGuid (4d1e55b2-f16f-11cf-88cb-001111000030), but what is the part with "9&599cfdc&0&0000"? Is that unique for every device? With other words, isn't there a risk that 2 of my devices have exactly the same DevicePath?
Now I also want to detect if devices are connected/disconnected while the application is running. If device are disconnected, I need to remove them from my Dictionary. If devices are connected, I need to put them in my Dictionary and start communicating with them.
I'm using the "WMI method" (I know there is also a WM_DEVICECHANGE method in WndProc, not sure what is better?). Below is the code (not finished, but works so far).
private void DeviceInsertedEvent(object sender, EventArrivedEventArgs e)
{
Debug.WriteLine($"DeviceInsertEvent");
ManagementBaseObject instance = (ManagementBaseObject)e.NewEvent["TargetInstance"];
foreach(PropertyData p in instance.Properties )
{
Debug.WriteLine($"{p.Name} = {p.Value }");
}
Debug.WriteLine($"{instance.Properties["Dependent"].Value }");
}
private void DeviceRemovedEvent(object sender, EventArrivedEventArgs e)
{
Debug.WriteLine($"DeviceRemovedEvent");
ManagementBaseObject instance = (ManagementBaseObject)e.NewEvent["TargetInstance"];
foreach (PropertyData p in instance.Properties)
{
Debug.WriteLine($"{p.Name} = {p.Value }");
}
Debug.WriteLine($"{instance.Properties["Dependent"].Value}");
}
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
var scope = new ManagementScope("root\\CIMV2");
scope.Options.EnablePrivileges = true;
try
{
WqlEventQuery insertQuery = new WqlEventQuery();
insertQuery.EventClassName = "__InstanceCreationEvent";
insertQuery.WithinInterval = new TimeSpan(0, 0, 1);
insertQuery.Condition = #"TargetInstance ISA 'Win32_USBControllerdevice'";
ManagementEventWatcher insertWatcher = new ManagementEventWatcher(insertQuery);
insertWatcher.EventArrived += new EventArrivedEventHandler(DeviceInsertedEvent);
insertWatcher.Start();
WqlEventQuery removeQuery = new WqlEventQuery();
removeQuery.EventClassName = "__InstanceDeletionEvent";
removeQuery.WithinInterval = new TimeSpan(0, 0, 1);
removeQuery.Condition = #"TargetInstance ISA 'Win32_USBControllerdevice'";
ManagementEventWatcher removeWatcher = new ManagementEventWatcher(removeQuery);
removeWatcher.EventArrived += new EventArrivedEventHandler(DeviceRemovedEvent);
removeWatcher.Start();
}
catch (Exception ex)
{
Debug.WriteLine($"backgroundWorker_DoWork Exception: {ex}");
}
while (true) ;
}
I am not a WMI expert, so I have honestly no clue what I'm doing (still learning) - just got the code from several google searches. I discovered that "instance.Properties["Dependent"].Value" gives me also some kind of DevicePath, with the below format.
\DESKTOP-HANS\root\cimv2:Win32_PnPEntity.DeviceID="HID\VID_04D8&PID_003F\9&2E7AE93E&0&0000"
I see the same VID/PID combination, and the unknown "9&2E7AE93E&0&0000" part that I asked for in Question 1. So basically, with some string-manipulations, I could reconstruct the same DevicePath that I'm using as the key in my Dictionary.
Question 2:
Is there another way to discover device connect/disconnect events that give me the same DevicePath as returned by SetupDiGetDeviceInterfaceDetail?
I have been continuing with the above concept, and it works as a charm. I changed the code in the below, and now my USB devices are nicely added or removed dynamically when my application is running. The "puzzling part" is in constructing the correct DevicePath format in the DeviceCreatedEvent and DeviceRemovedEvent.
_stringHidGuid is obtained in the constructer of my UsbServer. I need it a few times, so I created a private member for it. It is a string with the format (already added the '#' and curly brackets):
#{4d1e55b2-f16f-11cf-88cb-001111000030}
I use this to "construct" the DevicePath based on the "Dependent" value I'm getting from the WMI __InstanceCreationEvent and __InstanceDeletionEvent.
_DeviceArrivedWatcher and _DeviceRemovedWatcher are another 2 private members of type ManagementEventWatcher to keep the notifiers when initializing the code. _vid and _pid contain my VID and PID.
Below is the full code extract.
private void DeviceCreatedEvent(object sender, EventArrivedEventArgs e)
{
ManagementBaseObject instance = (ManagementBaseObject)e.NewEvent["TargetInstance"];
// Describes the logical device connected to the Universal Serial Bus (USB) controller.
string path = (string)instance.Properties["Dependent"].Value;
// Check if it is our device
int start = path.IndexOf($"HID\\\\VID_{_vid:X4}&PID_{_pid:X4}");
if (start != -1)
{
// Create the DevicePath to be used in UsbServer
path = path.Substring(start, path.Length - start - 1).Replace("\\\\", "#");
path = string.Concat("\\\\?\\", path, _stringHidGuid);
Debug.WriteLine($"DeviceCreatedEvent for {path}");
AddDevice(path);
}
}
private void DeviceRemovedEvent(object sender, EventArrivedEventArgs e)
{
ManagementBaseObject instance = (ManagementBaseObject)e.NewEvent["TargetInstance"];
// Describes the logical device connected to the Universal Serial Bus (USB) controller.
string path = (string)instance.Properties["Dependent"].Value;
// Check if it is our device
int start = path.IndexOf($"HID\\\\VID_{_vid:X4}&PID_{_pid:X4}");
if (start != -1)
{
// Create the DevicePath to be used in UsbServer
path = path.Substring(start, path.Length - start - 1).Replace("\\\\", "#");
path = string.Concat("\\\\?\\", path, _stringHidGuid);
Debug.WriteLine($"DeviceRemovedEvent for {path}");
RemoveDevice(path);
}
}
private void AddDeviceArrivedHandler()
{
try
{
var scope = new ManagementScope("root\\CIMV2");
scope.Options.EnablePrivileges = true;
var q = new WqlEventQuery();
q.EventClassName = "__InstanceCreationEvent";
q.WithinInterval = new TimeSpan(0, 0, 1);
q.Condition = #"TargetInstance ISA 'Win32_USBControllerdevice'";
_deviceArrivedWatcher = new ManagementEventWatcher(scope, q);
_deviceArrivedWatcher.EventArrived += DeviceCreatedEvent;
_deviceArrivedWatcher.Start();
}
catch (Exception ex)
{
Debug.WriteLine($"AddDeviceArrivedHandler() Exception: {ex}");
if (_deviceArrivedWatcher != null)
_deviceArrivedWatcher.Stop();
}
}
private void AddDeviceRemovedHandler()
{
try
{
var scope = new ManagementScope("root\\CIMV2");
scope.Options.EnablePrivileges = true;
var q = new WqlEventQuery();
q.EventClassName = "__InstanceDeletionEvent";
q.WithinInterval = new TimeSpan(0, 0, 1);
q.Condition = #"TargetInstance ISA 'Win32_USBControllerdevice'";
_deviceRemovedWatcher = new ManagementEventWatcher(scope, q);
_deviceRemovedWatcher.EventArrived += DeviceRemovedEvent;
_deviceRemovedWatcher.Start();
}
catch (Exception ex)
{
Debug.WriteLine($"AddDeviceRemovedHandler() Exception: {ex}");
if (_deviceRemovedWatcher != null)
_deviceRemovedWatcher.Stop();
}
}
private void DeviceNotificationsStop()
{
try
{
if (_deviceArrivedWatcher != null)
_deviceArrivedWatcher.Stop();
if (_deviceRemovedWatcher != null)
_deviceRemovedWatcher.Stop();
}
catch (Exception ex)
{
Debug.WriteLine($"DeviceNotificationStop() Exception: {ex}");
throw;
}
}
For a best source of knowledge about this topic I can recommend USB Complete
The Developer's Guide book, USBView and HClient official MS samples on GitHub.
\?\hid#vid_04d8&pid_003f#9&599cfdc&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030} is a so called device interface path. Its format is not documented by MS (so could be changes at any time) and its not safe to parse it. Every device could provide several interfaces to interact with it. For example every USB HID device also have interface with GUID_DEVINTERFACE_USB_DEVICE - {A5DCBF10-6530-11D2-901F-00C04FB951ED}.
There are two main Win32 APIs exist to query for connected devices: SetupDi* (defined in SetupAPI.h) and CM_* (defined in cfgmgr32.h). You can also use WMI but I not familiar with it.
Regarding how to convert device interface path to VID/PID:
You can use CM_Get_Device_Interface_PropertyW (or SetupDiGetDevicePropertyW) with DEVPKEY_Device_InstanceId param to request "device instance identifier". After that you can open that device via CM_Locate_DevNodeW (or SetupDiGetClassDevsW) with device instance id that you got and query DEVPKEY_Device_HardwareIds (string list) property on it. And returned stuff you can parse because its documented:
Each interface has a device ID of the following form:
USB\VID_v(4)&PID_d(4)&MI_z(2)
Where:
v(4) is the 4-digit vendor code that the USB committee assigns to the vendor.
d(4) is the 4-digit product code that the vendor assigns to the device.
z(2) is the interface number that is extracted from the bInterfaceNumber field of the interface descriptor.
PS: Found WMI example code with VID/PID filtering for in a book I mentioned:
void FindDevice()
{
const String deviceIdString = #”USB\VID_0925&PID_150C”;
_deviceReady = false;
var searcher = new ManagementObjectSearcher(“root\\CIMV2”, “SELECT PNPDeviceID FROM Win32_PnPEntity”);
foreach (ManagementObject queryObj in searcher.Get()) {
if (queryObj[“PNPDeviceID”].ToString().Contains(deviceIdString)) {
_deviceReady = true;
}
}
}

How can I solve VPN Connection Error in C#

I use a VPN class in my program. But when I try to connect, it cause the following error:
the system could not find the phone book entry for this connection
Here is the connect method:
public void VPN_Connect(string VPN_Name, string VPN_ID, string VPN_PW)
{
string path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData) + #"\Microsoft\Network\Connections\Pbk\rasphone.pbk";
AllUsersPhoneBook = new RasPhoneBook();
AllUsersPhoneBook.Open(path);
if (AllUsersPhoneBook.Entries.Contains(EntryName))
{
AllUsersPhoneBook.Entries[EntryName].PhoneNumber = VPN_Name;
AllUsersPhoneBook.Entries[EntryName].Update();
}
else
{
RasEntry entry = RasEntry.CreateVpnEntry(EntryName, VPN_Name, RasVpnStrategy.Default,
RasDevice.GetDeviceByName("(PPTP)", RasDeviceType.Vpn));
entry.EncryptionType = RasEncryptionType.None;
AllUsersPhoneBook.Entries.Add(entry);
}
Dialer = new RasDialer();
Dialer.DialCompleted += new EventHandler<DialCompletedEventArgs>(Dialer_DialCompleted);
this.Dialer.EntryName = EntryName;
this.Dialer.PhoneBookPath = RasPhoneBook.GetPhoneBookPath(RasPhoneBookType.AllUsers);
try
{
this.Dialer.Credentials = new NetworkCredential(VPN_ID, VPN_PW);
this.handle = this.Dialer.DialAsync();
VPN_Status = (int)status.Defalut;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
How can I solve this problem?
I'm also using windows 10 with latest update and DotRas last version.

Sync SQL Server 2014 and SQL Server 2014 Express database in my VB based website site Issue NO such interface supported .net 4.0

I have setup my site on IIS 10 and Window10 (x64) and referenced SQL Server 2014 Express RMO libraries in my website but I'm getting an error:
Microsoft.SqlServer.Replication.Com Error Exception: 'No such interface supported'
when I call the
Microsoft.SqlServer.Replication.MergeSynchronizationAgent.Synchronize()
method. I have followed same code as defined in example
// Define the server, publication, and database names.
string subscriberName = subscriberInstance;
string publisherName = publisherInstance;
string distributorName = distributorInstance;
string publicationName = "AdvWorksSalesOrdersMerge";
string subscriptionDbName = "AdventureWorks2012Replica";
string publicationDbName = "AdventureWorks2012";
string hostname = #"adventure-works\garrett1";
string webSyncUrl = "https://" + publisherInstance + SalesOrders/replisapi.dll";
// Create a connection to the Subscriber.
ServerConnection conn = new ServerConnection(subscriberName);
MergePullSubscription subscription;
MergeSynchronizationAgent agent;
try
{
// Connect to the Subscriber.
conn.Connect();
// Define the pull subscription.
subscription = new MergePullSubscription();
subscription.ConnectionContext = conn;
subscription.DatabaseName = subscriptionDbName;
subscription.PublisherName = publisherName;
subscription.PublicationDBName = publicationDbName;
subscription.PublicationName = publicationName;
// If the pull subscription exists, then start the synchronization.
if (subscription.LoadProperties())
{
// Get the agent for the subscription.
agent = subscription.SynchronizationAgent;
// Check that we have enough metadata to start the agent.
if (agent.PublisherSecurityMode == null)
{
// Set the required properties that could not be returned
// from the MSsubscription_properties table.
agent.PublisherSecurityMode = SecurityMode.Integrated;
agent.DistributorSecurityMode = SecurityMode.Integrated;
agent.Distributor = publisherName;
agent.HostName = hostname;
// Set optional Web synchronization properties.
agent.UseWebSynchronization = true;
agent.InternetUrl = webSyncUrl;
agent.InternetSecurityMode = SecurityMode.Standard;
agent.InternetLogin = winLogin;
agent.InternetPassword = winPassword;
}
// Enable agent output to the console.
agent.OutputVerboseLevel = 1;
agent.Output = "";
// Synchronously start the Merge Agent for the subscription.
agent.Synchronize();
}
else
{
// Do something here if the pull subscription does not exist.
throw new ApplicationException(String.Format(
"A subscription to '{0}' does not exist on {1}",
publicationName, subscriberName));
}
}
catch (Exception ex)
{
// Implement appropriate error handling here.
throw new ApplicationException("The subscription could not be " +
"synchronized. Verify that the subscription has " +
"been defined correctly.", ex);
}
finally
{
conn.Disconnect();
}

Perforce Api - How to command "get revision [changelist number]"

I would like to implement the Perforce command "Get Revision [Changelist Number]" using the Perforce .NET API (C#). I currently have code that will "Get Latest Revision", but I need to modify it to get a specific changelist.
To sync the data with a changelist number, what should I do?
Source
// --------Connenct----------------
Perforce.P4.Server server = new Perforce.P4.Server(
new Perforce.P4.ServerAddress("127.0.0.1:9999"));
Perforce.P4.Repository rep = new Perforce.P4.Repository(server);
Perforce.P4.Connection con = rep.Connection;
con.UserName = m_P4ID;
string password = m_P4PASS;
Perforce.P4.Options opconnect = new Perforce.P4.Options();
opconnect.Add("-p", password);
con.Connect(opconnect);
if (con.Credential == null)
con.Login(password);
//----------Download----------
string clientPath = #"C:\P4V\";
string ws_client = clientPath;
Perforce.P4.Client client = new Perforce.P4.Client();
client.Name = ws_client;
client.Initialize(con);
con.CommandTimeout = new TimeSpan(0);
IList<Perforce.P4.FileSpec> fileList = client.SyncFiles(new Perforce.P4.Options());
//----------Disconnect------------
con.Disconnect();
con.Dispose();
Edit: Attempt 1
Perforce.P4.DepotPath depot = new Perforce.P4.DepotPath("//P4V//");
Perforce.P4.LocalPath local = new Perforce.P4.LocalPath(ws_client);
Perforce.P4.FileSpec fs = new Perforce.P4.FileSpec(depot, null, local,
Perforce.P4.VersionSpec.Head);
IList<Perforce.P4.FileSpec> listFiles = new List<Perforce.P4.FileSpec>();
listFiles.Add(fs);
IList<Perforce.P4.FileSpec> foundFiles = rep.GetDepotFiles(listFiles,
new Perforce.P4.Options(1234)); // 1234 = Changelist number
client.SyncFiles(foundFiles, null);
Error Message
Usage: files/print [-o localFile -q] files...Invalid option: -c.
I do not know the problem of any argument.
Or there will not be related to this reference source?
Edit 2
I tried to solve this problem. However, it does not solve the problem yet.
Perforce.P4.Changelist changelist = rep.GetChangelist(1234);
IList<Perforce.P4.FileMetaData> fileMeta = changelist.Files;
In this case, I could get only the files in the changelist. I would like to synchronize all files of the client at the moment of changelist 1234.
SyncFiles takes an optional FileSpec arg. You can specify a file path and a revision specifier with that FileSpec arg. Here are the relevant docs:
FileSpec object docs
SyncFiles method docs
You don't need to run GetDepotFiles() to get the FileSpec object; you can just create one directly as shown in the FileSpec object docs. The error you are getting with GetDepotFiles() is because it expects the change number to be specified as part of the FileSpec object passed into as the first argument to GetDepotFiles().
To expand further, GetDepotFiles() calls the 'p4 files' command when it talks to Perforce. new Perforce.P4.Options(1234) generates an option of '-c 1234' which 'p4 files' doesn't accept. That's why the error message is 'Usage: files/print [-o localFile -q] files...Invalid option: -c.'
I struggled with the same problem as well. Finally based on Matt's answer I got it working. Please see simple example below.
using (Connection con = rep.Connection)
{
//setting up client object with viewmap
Client client = new Client();
client.Name = "p4apinet_solution_builder_sample_application_client";
client.OwnerName = "p4username";
client.Root = "c:\\clientRootPath";
client.Options = ClientOption.AllWrite;
client.LineEnd = LineEnd.Local;
client.SubmitOptions = new ClientSubmitOptions(false, SubmitType.RevertUnchanged);
client.ViewMap = new ViewMap();
client.ViewMap.Add("//depotpath/to/your/file.txt", "//" + client.Name + "/clientpath/to/your/file.txt", MapType.Include);
//connecting to p4 and creating client on p4 server
Options options = new Options();
options["Password"] = "p4password";
con.UserName = "p4username";
con.Client = new Client();
con.Connect(options);
con.Client = rep.CreateClient(client);
//syncing all files (in this case 1) defined in client's viewmap to the changelist level of 12345
Options syncFlags = new Options(SyncFilesCmdFlags.Force, 100);
VersionSpec changeListLevel = new ChangelistIdVersion(12345);
List<FileSpec> filesToBeSynced = con.Client.ViewMap.Select<MapEntry, FileSpec>(me => new FileSpec(me.Left, changeListLevel)).ToList();
IList<FileSpec> results = con.Client.SyncFiles(filesToBeSynced, syncFlags);
}
The following code should allow you to sync a depot to a particular revision (changelist number).
string uri = "...";
string user = "...";
string workspace = "...";
string pass = "...";
int id = 12345; // the actual changelist number
string depotPath = "//depot/foo/main/...";
int maxItemsToSync = 10000;
Server server = new Server(new ServerAddress(uri));
Repository rep = new Repository(server);
server = new Server(new ServerAddress(uri));
rep = new Repository(server);
Connection con = rep.Connection;
con.UserName = user;
con.Client = new Client();
con.Client.Name = workspace;
// connect
bool connected = con.Connect(null);
if (connected)
{
try
{
// attempt a login
Perforce.P4.Credential cred = con.Login(pass);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
con.Disconnect();
connected = false;
}
if (connected)
{
// get p4 info and show successful connection
ServerMetaData info = rep.GetServerMetaData(null);
Console.WriteLine("CONNECTED TO " + info.Address.Uri);
Console.WriteLine("");
try
{
Options opts = new Options();
// uncomment below lines to only get a preview of the sync w/o updating the workspace
//SyncFilesCmdOptions syncOpts = new SyncFilesCmdOptions(SyncFilesCmdFlags.Preview, maxItemsToSync);
SyncFilesCmdOptions syncOpts = new SyncFilesCmdOptions(SyncFilesCmdFlags.None, maxItemsToSync);
VersionSpec version = new ChangelistIdVersion(id);
PathSpec path = new DepotPath(depotPath);
FileSpec depotFile = new FileSpec(path, version);
IList<FileSpec> syncedFiles = rep.Connection.Client.SyncFiles(syncOpts, depotFile);
//foreach (var file in syncedFiles)
//{
// Console.WriteLine(file.ToString());
//}
Console.WriteLine($"{syncedFiles.Count} files got synced!");
}
catch (Exception ex)
{
Console.WriteLine("");
Console.WriteLine(ex.Message);
Console.WriteLine("");
}
finally
{
con.Disconnect();
}
}
}
If you are looking for other ways to build the file spec, like for example sync only a specific list of files to "head", etc, visit this link and search for "Building a FileSpec"

Passing ids in IBM MQ client

I read the messages from one queue to another queue. However my correlation ids are not preserved.
If the correlation id is "ABC12345" for a message in the import queue, when i put it into the export queue, the value of the correlation id is different.
How do i keep the same correlation id between the 2 queues and always
have a unique message id?
Get:
mqQueue.Get(mqMsg);
string messageID = Convert.ToString(mqMsg.MessageId);
string correlationID = Convert.ToString(mqMsg.CorrelationId);
If for example if the correlation id is "000123456789", then after read, while putting it back , the value gets changed for the same message.
Put:
mqMsg.CorrelationId = System.Text.Encoding.UTF8.GetBytes(correlationID);
mqQueue.Put(mqMsg, mqPutMsgOpts);
I am using MQ PUT and GET options via MQ.NET classes.
The code snippet below preserves the correlation id when I put message to another queue. In my sample I do the following:
1) Put a message to importQ with unique correlation ID.
2) Get that message from importQ.
3) Put the received message to exportQ
public static void preserveCorreLid()
{
Hashtable mqProps = new Hashtable();
MQQueueManager qm = null;
String strCorrelId = "00123456789";
try
{
mqProps.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED);
mqProps.Add(MQC.CHANNEL_PROPERTY, "NET.CLIENT.CHL");
mqProps.Add(MQC.HOST_NAME_PROPERTY, "localhost");
mqProps.Add(MQC.PORT_PROPERTY, 2099);
qm = new MQQueueManager("QM", mqProps);
MQQueue importQ = qm.AccessQueue("IMPORTQ", MQC.MQOO_INPUT_SHARED |MQC.MQOO_OUTPUT | MQC.MQOO_FAIL_IF_QUIESCING );
MQMessage mqPutMsg = new MQMessage();
mqPutMsg.WriteString("This is an import message");
mqPutMsg.CorrelationId = System.Text.Encoding.UTF8.GetBytes(strCorrelId);
MQPutMessageOptions mqpmo = new MQPutMessageOptions();
importQ.Put(mqPutMsg,mqpmo);
MQMessage respMsg = new MQMessage();
MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.WaitInterval = 3000;
gmo.Options = MQC.MQGMO_WAIT;
try
{
importQ.Get(respMsg, gmo);
}
catch (MQException ex)
{
Console.Write(ex);
Console.WriteLine("Queue Name : " + importQ.Name + ":");
}
importQ.Close();
MQQueue exportQ = qm.AccessQueue("EXPORTQ", MQC.MQOO_OUTPUT | MQC.MQOO_FAIL_IF_QUIESCING);
exportQ.Put(respMsg);
exportQ.Close();
qm.Disconnect();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
This line of code gets me the correlation id
correlationID = System.Text.Encoding.UTF8.GetString(mqMsg.CorrelationId);

Categories

Resources