Running into an issue where I can't figure out how to tell this to check if the definition or shared parameter exists before adding. I've tried combinations of if else statements as well as coalescing. There is still a lot that I am learning so any help would be greatly appreciated. ` public Autodesk.Revit.UI.Result Execute(
ExternalCommandData commandData, ref string message, Autodesk.Revit.DB.ElementSet elements)
{
Transaction transaction = new Transaction(commandData.Application.ActiveUIDocument.Document, "External Tool");
try
{
transaction.Start();
//Create a clear file as parameter file.
String path = Assembly.GetExecutingAssembly().Location;
int index = path.LastIndexOf("\\");
String newPath = path.Substring(0, index);
newPath += "\\TPMechanicalRevitParameters.txt";
if (File.Exists(newPath))
{
File.Delete(newPath);
}
FileStream fs = File.Create(newPath);
fs.Close();
//cache application handle
Application revitApp = commandData.Application.Application;
//prepare shared parameter file
commandData.Application.Application.SharedParametersFilename = newPath;
//Open shared parameter file
DefinitionFile parafile = revitApp.OpenSharedParameterFile();
//get Fabricaation Pipe category
Category TpCat = commandData.Application.ActiveUIDocument.Document.Settings.Categories.get_Item(BuiltInCategory.OST_FabricationPipework);
CategorySet categories = revitApp.Create.NewCategorySet();
categories.Insert(TpCat);
InstanceBinding binding = revitApp.Create.NewInstanceBinding(categories);
//Create a group
DefinitionGroup apiGroup = parafile.Groups.Create("TpFabricationPipe");
//Create a visible "VisibleParam" of text type.
ExternalDefinitionCreationOptions ExternalDefinitionCreationOptions1 = new ExternalDefinitionCreationOptions("FullFabricationServiceName", ParameterType.Text);
Definition visibleParamDef = apiGroup.Definitions.Create
(ExternalDefinitionCreationOptions1);
BindingMap bindingMap = commandData.Application.ActiveUIDocument.Document.ParameterBindings;
bindingMap.Insert(visibleParamDef, binding);
//Create a invisible "InvisibleParam" of text type.
ExternalDefinitionCreationOptions ExternalDefinitionCreationOptions2 = new ExternalDefinitionCreationOptions("InvisibleParam", ParameterType.Text);
Definition invisibleParamDef = apiGroup.Definitions.Create
(ExternalDefinitionCreationOptions2);
bindingMap.Insert(invisibleParamDef, binding);
}
catch (Exception e)
{
transaction.RollBack();
message = e.ToString();
return Autodesk.Revit.UI.Result.Cancelled;
}
finally
{
transaction.Commit();
}
return Autodesk.Revit.UI.Result.Succeeded;
}`
Think I've found a solution. I just changed it to see if the file exists instead of the definition & it worked. If there is a better way to achieve this let me know.
Related
need to change default ringtone with xamarin
i use android.net.parse with path string and return null, then i use the bellow code where i find online and again return null anybody can help?
var ring1 = ("file:////storage/emulated/0/Ringtones/" + item.ringtone);
ContentValues values = new ContentValues();
values.Put(MediaStore.IMediaColumns.Data, ring1);
values.Put(MediaStore.Audio.Media.InterfaceConsts.IsRingtone, true);
values.Put(MediaStore.IMediaColumns.MimeType, "audio/mp3");
var uri = MediaStore.Audio.Media.GetContentUriForPath(path: ring1);
Android.Net.Uri newUri = this.ContentResolver.Insert(uri, values);
RingtoneManager.SetActualDefaultRingtoneUri(Android.App.Application.Context,RingtoneType.Ringtone, newUri);
"uri" and "values" in debugging have values but parameter newUri is null
the problem was in write permisions i use the code below to check if the file exist ask for permision and change the ringtone and work
var newuri3 = Android.Net.Uri.Parse("file:///storage/emulated/0/Ringtones/" + item.ringtone);
var newuri = newuri3;
bool b = false;
if (null != newuri)
{
try
{
var inputStream = Android.App.Application.Context.ContentResolver.OpenInputStream(newuri);
inputStream.Close();
Console.WriteLine("file exist");
b = true;
}
catch (Exception e)
{
Console.WriteLine("File corresponding to the uri does not exist " + newuri.ToString());
}
}
var bi = Settings.System.CanWrite(Android.App.Application.Context);
if (bi)
{
Console.WriteLine("it haw write permision");
}
else
{
Console.WriteLine("doenst have permision");
Intent intent = new Intent(Settings.ActionManageWriteSettings);
intent.SetData(Android.Net.Uri.Parse($"package:{Android.App.Application.Context.PackageName}"));
intent.AddFlags(ActivityFlags.NewTask);
Android.App.Application.Context.StartActivity(intent);
}
RingtoneManager.SetActualDefaultRingtoneUri(Android.App.Application.Context, RingtoneType.Ringtone, newuri);
where item.ringtone is the file name for example music.mp3
You need to recheck the path of ring1.
I use the file in download folder for reference. It works.
var ring1 = System.IO.Path.Combine(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath, Android.OS.Environment.DirectoryDownloads, "sample.mp3");
If you want to use the default Uri of Ringtone, you could use the code below instead.
RingtoneManager.GetDefaultUri(RingtoneType.Ringtone)
I'm working on an ASP.NET Core 5 project. I have this action method:
public async Task<IActionResult> CreateV3EnterCheckFile(IFormFile MarksFile)
{
var filesCount = Directory.GetFiles("Uploads").Length;
string path = Path.Combine("Uploads", filesCount + 1 + ".xlsx");
await MarksFile.SaveToAsync(path);
var xlImporter = new XLImporter();
var importedData = await xlImporter.ImportSheetAsync(path, 0);
var r = (from x in importedData select new { ID = x[0], StudentId = x[1] }).ToList();
System.IO.File.Delete(path);
return View();
}
I tried to get IFormFile uploaded file by the user to save it on the server and querying it using one of my projects (that uses LinqToExcel library).
I am querying the data and everything is perfect I still have just one problem it is this line of code:
System.IO.File.Delete(path);
It throws an exception and the message is I can't delete that file because it is still being used by another process.
I'm very sure that the process is related to the LinqToExcel library.
More details :
SaveToAsync is an extension method created by me that is its definition
public static Task SaveToAsync(this IFormFile file, string pathToSaveTo)
{
return Task.Factory.StartNew(() =>
{
using (Stream fileStream = File.Open(pathToSaveTo, FileMode.Create, FileAccess.ReadWrite, FileShare.None))
{
file.CopyTo(fileStream);
}
});
}
Please - is there any way or method or solution to delete this file even if it is being used by another process?
Massive thanks in advance.
Based on the source code of ExcelQueryFactory (https://github.com/paulyoder/LinqToExcel/blob/master/src/LinqToExcel/ExcelQueryFactory.cs) I would try the following:
ExcelQueryFactory has a ReadOnly Property. For read only access (if applicable) I would set it to true when creating the instance.
More important: IExcelQueryFactory implements IDisposable, so you can (should) use a using block:
using (var excelFile = new ExcelQueryFactory(pathToExcelFile) {ReadOnly = true})
{
// Do your work.
}
Of course you can use using var ..., but if you need a more reduced scope, the "old" using syntax allows more control.
I assumed that your Uploads folder is under webroot.
You can try this:-
public YourControllerName(IHostingEnvironment he) //input parameter
{
_he = he;
}
public async Task<IActionResult> CreateV3EnterCheckFile(IFormFile MarksFile)
{
try
{
var filesCount = Directory.GetFiles("Uploads").Length;
string contentRootPath = _he.ContentRootPath;
string path = Path.Combine(contentRootPath +"\\Uploads", filesCount + 1 + ".xlsx");
await MarksFile.SaveToAsync(path);
var xlImporter = new XLImporter();
var importedData = await xlImporter.ImportSheetAsync(path, 0);
var r = (from x in importedData select new { ID = x[0], StudentId = x[1] }).ToList();
//System.IO.File.Delete(path);
if (File.Exists(path))
{
File.Delete(path);
}
else
{
Debug.WriteLine("File does not exist.");
}
return View();
}
catch(Exception e)
{
Console.WriteLine(e);
}
Or you can try another process:-
try
{
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
System.IO.File.Delete(path);
}
catch(Exception e){
}
}
Or this:-
if (System.IO.File.Exists(path))
{
try
{
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
System.IO.File.Delete(path);
}
catch (Exception e) { }
}
it should resolve your issue I hope. by the way, if your Upload folder is not under the webroot path. you can find your path using your process.
I am using the elency solutions CSV library for C# to save and load some data from a file.
My code saves and loads correctly, but when I load and then try to save an error occurs, saying that another process is using the file.
The load method is this:
private void loadfile(string name)
{
int key = 696969;
CsvReader read = new CsvReader("data.csv");
try
{
do
{
read.ReadNextRecord();
} while (name != read.Fields[0]);
int decAgain = int.Parse(read.Fields[1], System.Globalization.NumberStyles.HexNumber); //convert to int
int dec = decAgain ^ key;
MessageBox.Show(dec.ToString());
}
catch (Exception)
{
MessageBox.Show("Not Found");
}
read = null;
}
As you can see, I am sort of disposing the "read" object.
Here is the save method:
private void savefile(string encrypted, string name)
{
CsvFile file = new CsvFile();
CsvRecord rec = new CsvRecord();
CsvWriter write = new CsvWriter();
rec.Fields.Add(name);
rec.Fields.Add(encrypted);
file.Records.Add(rec);
write.AppendCsv(file, "data.csv");
file = null;
rec = null;
write = null;
}
It always gets stuck on append csv.
I do understand the problem. The reader is not being closed successfully. How can I correctly close the file?
NB: I have tried read.Dispose() but it is not working.
Can you please help me out?
Regards
Use using to automatically dispose object. It may solve your issue.
private void savefile(string encrypted, string name)
{
using(CsvFile file = new CsvFile())
{
using(CsvRecord rec = new CsvRecord())
{
using(CsvWriter write = new CsvWriter())
{
rec.Fields.Add(name);
rec.Fields.Add(encrypted);
file.Records.Add(rec);
write.AppendCsv(file, "data.csv");
}
}
}
}
I'm coding an application in c# using EC4 SP2 SDK.
I want to publish my file to a media server publishing point. I've searched and found 2 examples regarding seting up and auth on publishing points, but either are from older sdk's or do not work (and are for console). basicly my application doesn't encode nothing, as if it had nothing to encode.
When in degub mode checkpont i can see the correct properties for the source file and for the server.
The encoding process takes 0secs to process. I checked the logs on the server events and i get a warning "the security system has received and auth request that could not be decoded". I just havo no knowledge to break up further than this. Any help would be appreciated.
this is the piece of code:
private void broadcastSourceFileToMediaServer2()
{
using (LiveJob job = new LiveJob())
{
String filetoencode = #"c:\temp\niceday.wmv";
LiveFileSource filesource = job.AddFileSource(filetoencode);
filesource.PlaybackMode = FileSourcePlaybackMode.Loop;
job.ActivateSource(filesource);
job.ApplyPreset(LivePresets.VC1Broadband4x3);
//don't know which one is good to use
job.AcquireCredentials += new EventHandler<AcquireCredentialsEventArgs>(job_AcquireCredentials);
_myUserName = "indes";
_pw = PullPW("indes");
Uri url = new Uri("http://192.168.1.74:8080/live");
PushBroadcastPublishFormat pubpoint = new PushBroadcastPublishFormat();
pubpoint.PublishingPoint = url;
pubpoint.UserName = _myUserName;
pubpoint.Password = _pw;
job.PublishFormats.Add(pubpoint);
job.PreConnectPublishingPoint();
job.StartEncoding();
statusBox.Text = job.NumberOfEncodedSamples.ToString();
job.StopEncoding();
job.Dispose();
}
}
public static string _myUserName { get; set; }
public static SecureString _pw { get; set; }
//codificação de Password a enviar
private static SecureString PullPW(string pw)
{
SecureString s = new SecureString();
foreach (char c in pw) s.AppendChar(c);
return s;
}
static void job_AcquireCredentials(object sender, AcquireCredentialsEventArgs e)
{
e.UserName = _myUserName;
e.Password = _pw;
e.Modes = AcquireCredentialModes.None;
}
Progresses:
I managed to authenticate (at least get a positive audit event) on the server.
I changed from this:
//don't know which one is good to use
job.AcquireCredentials += new EventHandler<AcquireCredentialsEventArgs>(job_AcquireCredentials);
_myUserName = "indes";
_pw = PullPW("indes");
Uri url = new Uri("http://192.168.1.74:8080/live");
PushBroadcastPublishFormat pubpoint = new PushBroadcastPublishFormat();
pubpoint.PublishingPoint = url;
pubpoint.UserName = _myUserName;
pubpoint.Password = _pw;
To this:
job.AcquireCredentials += new EventHandler<AcquireCredentialsEventArgs>(job_AcquireCredentials);
_myUserName = #"mediaservername\user";
_pw = PullPW("user_password");
Uri url = new Uri("http://192.168.1.74:8080/live");
PushBroadcastPublishFormat pubpoint = new PushBroadcastPublishFormat();
pubpoint.PublishingPoint = url;
If you see on one side if had to include the domain (either domain or computername) before username. this changed the failed audit events on the server, so i could eliminate the manual credentials pubpoint.username and pubpoint.Password.
Now I'm just dealing with a lack of output format exception. On to it.
How about using SMOOTH Streaming, I managed to get my project going but I didn't get much more beyond Look below, to the part that has the PUBLISH switch type. ignore the file portion
internal bool StartStream()
{
Busy = true;
// Instantiates a new job for encoding
//
//***************************************Live Stream Archive******************************
if (blnRecordFromFile)
{
// Sets up publishing format for file archival type
FileArchivePublishFormat fileOut = new FileArchivePublishFormat();
// job.ApplyPreset(LivePresets.VC1512kDSL16x9);
// Gets timestamp and edits it for filename
string timeStamp = DateTime.Now.ToString();
timeStamp = timeStamp.Replace("/", "-");
timeStamp = timeStamp.Replace(":", ".");
// Sets file path and name
string path = "C:\\output\\";
string filename = "Capture" + timeStamp + ".ismv";
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
fileOut.OutputFileName = Path.Combine(path, filename);
// Adds the format to the job. You can add additional formats as well such as
// Publishing streams or broadcasting from a port
job.PublishFormats.Add(fileOut);
}
//******************************END OF Stream PORTION****************************************
////////////////////////////////////////////////////////////////////////////////////////////////////
//*************************************** Process Files or Live Stream******************************
if (blnRecordFromFile)
{
job.ApplyPreset(LivePresets.VC1IISSmoothStreaming720pWidescreen);
job = new LiveJob();
// Verifies all information is entered
if (string.IsNullOrWhiteSpace(sourcePath) || string.IsNullOrWhiteSpace(destinationPath))
return false;
job.Status += new EventHandler<EncodeStatusEventArgs>(StreamStatus);
LiveFileSource fileSource;
try
{
// Sets file to active source and checks if it is valid
fileSource = job.AddFileSource(sourcePath);
}
catch (InvalidMediaFileException)
{
return false;
}
// Sets to loop media for streaming
// fileSource.PlaybackMode = FileSourcePlaybackMode.Loop;
// Makes this file the active source. Multiple files can be added
// and cued to move to each other at their ends
job.ActivateSource(fileSource);
}
//******************************END OF FILE PORTION****************************************
// Sets up variable for fomat data
switch (publishType)
{
case Output.Archive:
// Verifies destination path exists and if not creates it
try
{
if (!Directory.Exists(destinationPath))
Directory.CreateDirectory(destinationPath);
}
catch (IOException)
{
return false;
}
FileArchivePublishFormat archiveFormat = new FileArchivePublishFormat();
// Gets the location of the old extention and removes it
string filename = Path.GetFileNameWithoutExtension(sourcePath);
// Sets the archive path and file name
archiveFormat.OutputFileName = Path.Combine(destinationPath, filename + ".ismv");
job.PublishFormats.Add(archiveFormat);
break;
case Output.Publish:
// Setups streaming of media to publishing point
job = new LiveJob();
// Aquires audio and video devices
Collection<EncoderDevice> devices = EncoderDevices.FindDevices(EncoderDeviceType.Video);
EncoderDevice video = devices.Count > 0 ? devices[0] : null;
for (int i = 0; i < devices.Count; ++i)
// devices[i].Dispose();
devices.Clear();
devices = EncoderDevices.FindDevices(EncoderDeviceType.Audio);
EncoderDevice audio = devices.Count > 0 ? devices[0] : null;
for (int i = 1; i < devices.Count; ++i)
devices[i].Dispose();
devices.Clear();
// Checks for a/v devices
if (video != null && audio != null)
{
//job.ApplyPreset(Preset.FromFile(#"C:\Tempura\LivePreset3.xml"));
job.ApplyPreset(LivePresets.H264IISSmoothStreamingLowBandwidthStandard);
job.OutputFormat.VideoProfile.SmoothStreaming = true;
deviceSource = job.AddDeviceSource(video, audio);
// Make this source the active one
job.ActivateSource(deviceSource);
}
else
{
error = true;
}
PushBroadcastPublishFormat publishFormat = new PushBroadcastPublishFormat();
try
{
// checks the path for a valid publishing point
publishFormat.PublishingPoint = new Uri(destinationPath);
}
catch (UriFormatException)
{
return false;
}
// Adds the publishing format to the job
try
{
// job.ApplyPreset(LivePresets.VC1IISSmoothStreaming480pWidescreen);
job.PublishFormats.Add(publishFormat);
job.PreConnectPublishingPoint();
}
catch (Exception e)
{
MessageBox.Show(e.StackTrace.ToString());
}
break;
default:
return false;
}
job.StartEncoding();
return true;
}
Sadly I dont have enough rep to comment, so I have to write it as an answer.
Due to you are starting a live job, in order to stream you should not call job.StopEncoding() right after StartEncoding. I think usually you would use an event to stop the encoding. If you start encoding and immediately stop it, it is only logical you have no, or only a very small output.
I changed your code to the following and it seems work well. I guess your problem is that you disposed the instance of LiveJob class. You have to keep the instance alive before it finished encoding the whole stream. So change the using part and remove the StopEncoding and Dispose will be OK.
private void broadcastSourceFileToMediaServer2()
{
LiveJob job = new LiveJob();
String filetoencode = #"c:\temp\niceday.wmv";
LiveFileSource filesource = job.AddFileSource(filetoencode);
filesource.PlaybackMode = FileSourcePlaybackMode.Loop;
job.ActivateSource(filesource);
job.ApplyPreset(LivePresets.VC1Broadband4x3);
//don't know which one is good to use
job.AcquireCredentials += new EventHandler<AcquireCredentialsEventArgs>(job_AcquireCredentials);
_myUserName = "indes";
_pw = PullPW("indes");
Uri url = new Uri("http://192.168.1.74:8080/live");
PushBroadcastPublishFormat pubpoint = new PushBroadcastPublishFormat();
pubpoint.PublishingPoint = url;
pubpoint.UserName = _myUserName;
pubpoint.Password = _pw;
job.PublishFormats.Add(pubpoint);
job.PreConnectPublishingPoint();
job.StartEncoding();
statusBox.Text = job.NumberOfEncodedSamples.ToString();
}
public static string _myUserName { get; set; }
public static SecureString _pw { get; set; }
//codificação de Password a enviar
private static SecureString PullPW(string pw)
{
SecureString s = new SecureString();
foreach (char c in pw) s.AppendChar(c);
return s;
}
static void job_AcquireCredentials(object sender, AcquireCredentialsEventArgs e)
{
e.UserName = _myUserName;
e.Password = _pw;
e.Modes = AcquireCredentialModes.None;
}
I was wondering if there is a way to programmatically check how many messages are in a private or public MSMQ using C#? I have code that checks if a queue is empty or not using the peek method wrapped in a try/catch, but I've never seen anything about showing the number of messages in the queue. This would be very helpful for monitoring if a queue is getting backed up.
You can read the Performance Counter value for the queue directly from .NET:
using System.Diagnostics;
// ...
var queueCounter = new PerformanceCounter(
"MSMQ Queue",
"Messages in Queue",
#"machinename\private$\testqueue2");
Console.WriteLine( "Queue contains {0} messages",
queueCounter.NextValue().ToString());
There is no API available, but you can use GetMessageEnumerator2 which is fast enough. Sample:
MessageQueue q = new MessageQueue(...);
int count = q.Count();
Implementation
public static class MsmqEx
{
public static int Count(this MessageQueue queue)
{
int count = 0;
var enumerator = queue.GetMessageEnumerator2();
while (enumerator.MoveNext())
count++;
return count;
}
}
I also tried other options, but each has some downsides
Performance counter may throw exception "Instance '...' does not exist in the specified Category."
Reading all messages and then taking count is really slow, it also removes the messages from queue
There seems to be a problem with Peek method which throws an exception
If you need a fast method (25k calls/second on my box), I recommend Ayende's version based on MQMgmtGetInfo() and PROPID_MGMT_QUEUE_MESSAGE_COUNT:
for C#
https://github.com/hibernating-rhinos/rhino-esb/blob/master/Rhino.ServiceBus/Msmq/MsmqExtensions.cs
for VB
https://gist.github.com/Lercher/5e1af6a2ba193b38be29
The origin was probably http://functionalflow.co.uk/blog/2008/08/27/counting-the-number-of-messages-in-a-message-queue-in/ but I'm not convinced that this implementation from 2008 works any more.
We use the MSMQ Interop. Depending on your needs you can probably simplify this:
public int? CountQueue(MessageQueue queue, bool isPrivate)
{
int? Result = null;
try
{
//MSMQ.MSMQManagement mgmt = new MSMQ.MSMQManagement();
var mgmt = new MSMQ.MSMQManagementClass();
try
{
String host = queue.MachineName;
Object hostObject = (Object)host;
String pathName = (isPrivate) ? queue.FormatName : null;
Object pathNameObject = (Object)pathName;
String formatName = (isPrivate) ? null : queue.Path;
Object formatNameObject = (Object)formatName;
mgmt.Init(ref hostObject, ref formatNameObject, ref pathNameObject);
Result = mgmt.MessageCount;
}
finally
{
mgmt = null;
}
}
catch (Exception exc)
{
if (!exc.Message.Equals("Exception from HRESULT: 0xC00E0004", StringComparison.InvariantCultureIgnoreCase))
{
if (log.IsErrorEnabled) { log.Error("Error in CountQueue(). Queue was [" + queue.MachineName + "\\" + queue.QueueName + "]", exc); }
}
Result = null;
}
return Result;
}
//here queue is msmq queue which you have to find count.
int index = 0;
MSMQManagement msmq = new MSMQManagement() ;
object machine = queue.MachineName;
object path = null;
object formate=queue.FormatName;
msmq.Init(ref machine, ref path,ref formate);
long count = msmq.MessageCount();
This is faster than you selected one.
You get MSMQManagement class refferance inside "C:\Program Files (x86)\Microsoft SDKs\Windows" just brows in this address you will get it. for more details you can visit http://msdn.microsoft.com/en-us/library/ms711378%28VS.85%29.aspx.
I had real trouble getting the accepted answer working because of the xxx does not exist in the specified Category error. None of the solutions above worked for me.
However, simply specifying the machine name as below seems to fix it.
private long GetQueueCount()
{
try
{
var queueCounter = new PerformanceCounter("MSMQ Queue", "Messages in Queue", #"machineName\private$\stream")
{
MachineName = "machineName"
};
return (long)queueCounter.NextValue();
}
catch (Exception e)
{
return 0;
}
}
The fastest method I have found to retrieve a message queue count is to use the peek method from the following site:
protected Message PeekWithoutTimeout(MessageQueue q, Cursor cursor, PeekAction action)
{
Message ret = null;
try
{
ret = q.Peek(new TimeSpan(1), cursor, action);
}
catch (MessageQueueException mqe)
{
if (!mqe.Message.ToLower().Contains("timeout"))
{
throw;
}
}
return ret;
}
protected int GetMessageCount(MessageQueue q)
{
int count = 0;
Cursor cursor = q.CreateCursor();
Message m = PeekWithoutTimeout(q, cursor, PeekAction.Current);
{
count = 1;
while ((m = PeekWithoutTimeout(q, cursor, PeekAction.Next)) != null)
{
count++;
}
}
return count;
}
This worked for me. Using a Enumarator to make sure the queue is empty first.
Dim qMsg As Message ' instance of the message to be picked
Dim privateQ As New MessageQueue(svrName & "\Private$\" & svrQName) 'variable svrnme = server name ; svrQName = Server Queue Name
privateQ.Formatter = New XmlMessageFormatter(New Type() {GetType(String)}) 'Formating the message to be readable the body tyep
Dim t As MessageEnumerator 'declared a enumarater to enable to count the queue
t = privateQ.GetMessageEnumerator2() 'counts the queues
If t.MoveNext() = True Then 'check whether the queue is empty before reading message. otherwise it will wait forever
qMsg = privateQ.Receive
Return qMsg.Body.ToString
End If
If you want a Count of a private queue, you can do this using WMI.
This is the code for this:
// You can change this query to a more specific queue name or to get all queues
private const string WmiQuery = #"SELECT Name,MessagesinQueue FROM Win32_PerfRawdata_MSMQ_MSMQQueue WHERE Name LIKE 'private%myqueue'";
public int GetCount()
{
using (ManagementObjectSearcher wmiSearch = new ManagementObjectSearcher(WmiQuery))
{
ManagementObjectCollection wmiCollection = wmiSearch.Get();
foreach (ManagementBaseObject wmiObject in wmiCollection)
{
foreach (PropertyData wmiProperty in wmiObject.Properties)
{
if (wmiProperty.Name.Equals("MessagesinQueue", StringComparison.InvariantCultureIgnoreCase))
{
return int.Parse(wmiProperty.Value.ToString());
}
}
}
}
}
Thanks to the Microsoft.Windows.Compatibility package this also works in netcore/netstandard.
The message count in the queue can be found using the following code.
MessageQueue messageQueue = new MessageQueue(".\\private$\\TestQueue");
var noOFMessages = messageQueue.GetAllMessages().LongCount();