Multiple AxWindowsMediaPlayer controls exception: System.Runtime.InteropServices.COMException' in AxInterop.WMPLib.dll - c#

Developing a winforms C# 4.5 on Win10 that creates multiple AxWindowsMediaPlayer control objects dynamically on Form1 (the only form). Relative code segments look like this:
axWMPn[zi] = new AxWindowsMediaPlayer();
((ISupportInitialize)(axWMPn[zi])).BeginInit();
axWMPn[zi].Name = "Zone " + zi; //Zone name + index
axWMPn[zi].Tag = "Z" + zi; // "Z" + Zone index
axWMPn[zi].Location = loc;
axWMPn[zi].Size = sz;
Controls.Add(axWMPn[zi]);
((ISupportInitialize)(axWMPn[zi])).EndInit();
axWMPn[zi].uiMode = "none";
axWmpDisplayZones.Add(axWMPn[zi].Tag.ToString(), axWMPn[zi]);
axWMPn[zi].StatusChange += axWMPx_StatusChange;
axWMPn[zi].PlayStateChange += axWMPx_PlayStateChange;
I create 6 zones - 3 are assigned static JPEG images and the other 3 are used for video (*.avi and *.mov). The video files are assigned like this:
private void playVideo(string file)
{
int tc6 = 0;
axWMPn[0].URL = file;
axWMPn[4].URL = file;
axWMPn[5].URL = file;
axWMPn[6].URL = "C:/test/AmexDonut.mov";
}
This all works - playVideo is called from another process and the first time all videos run without errors; however when I call playVideo a second time I intermittently get a COMException error:
Exception thrown: 'System.Runtime.InteropServices.COMException' in AxInterop.WMPLib.dll -- Message: The message filter indicated that the application is busy. (Exception from HRESULT: 0x8001010A (RPC_E_SERVERCALL_RETRYLATER)).
Notes:
1. If I just do 2 axWMPn[x].URL=file it always works no COMException; if I had a third axWMPn[x].URL=file it mostly works with a COMException once every few dozen calls to playVideo. Adding the 4th awWMPn[x].URL=file almost always causes the COMException but not every single time.
So I did following to see more about what was going on:
private void playVideo(string file)
{
int tc6 = 0;
try
{
axWMPn[0].URL = file;
}
catch (System.Runtime.InteropServices.COMException comEx)
{
Console.WriteLine("playVideo COMException 0: " + comEx.Source + " -- " + comEx.Message);
}
try
{
axWMPn[4].URL = file;
}
catch (System.Runtime.InteropServices.COMException comEx)
{
Console.WriteLine("playVideo COMException 4: " + comEx.Source + " -- " + comEx.Message);
}
try
{
axWMPn[5].URL = file;
}
catch (System.Runtime.InteropServices.COMException comEx)
{
Console.WriteLine("playVideo COMException 5: " + comEx.Source + " -- " + comEx.Message);
}
Again:
try
{
axWMPn[6].URL = "C:/test/AmexDonut.mov";
}
catch (System.Runtime.InteropServices.COMException comEx)
{
tc6++;
Console.WriteLine("playVideo COMException 6: try again count = " + tc6 + " - " + comEx.Source + " -- " + comEx.Message);
goto Again;
}
The COMException "busy" when it occurs always occurs in axWMPn[6].URL=file and putting the goto Again in works - tc6 will always just be 1. So merely trying one more time to assign axWMPn[6].URL=file always works. It never takes more than 1 additional try (tc6 never goes beyond 1).
I could leave it this way - I have run it dozens of times and it works just fine; but it sure seems like a bad hack. Does anybody have any thoughts or ideas?
Thanks for any input

Related

Value assigned more than once in single assignment

I made script task that's downloading and saving on disk two spreadsheets from Google Drive using file ID and prepared URL address.
This is main() from my C# code, there are no things outside of it:
public void Main()
{
string m_FileId = Dts.Variables["User::varFileId"].Value.ToString();
string m_RemoteUrl = "https://docs.google.com/spreadsheets/d/" + m_FileId + "/export?format=xlsx";
string m_FilePath = null;
WebClient client = new WebClient();
try
{
m_FilePath = Dts.Variables["User::varFilePath"].Value.ToString() + Dts.Variables["User::varFileName"].Value.ToString();
client.DownloadFile(new System.Uri(m_RemoteUrl), m_FilePath);
m_FilePath = "";
m_FileId = Dts.Variables["User::varFileId2"].Value.ToString();
m_RemoteUrl = "https://docs.google.com/spreadsheets/d/" + m_FileId + "/export?format=xlsx";
m_FilePath = Dts.Variables["User::varFilePath"].Value.ToString() + Dts.Variables["User::varFileName2"].Value.ToString();
client.DownloadFile(new System.Uri(m_RemoteUrl), m_FilePath);
}
catch(Exception e)
{
Dts.Events.FireError(0, "FileDownload", e.Message
+ "\r" + e.StackTrace
+ " \rUrl: " + m_RemoteUrl
+ " \rFilePath: " + m_FilePath
+ " \rPath: " + Dts.Variables["User::varFilePath"].Value.ToString()
+ " \rFileName2: " + Dts.Variables["User::varFileName2"].Value.ToString()
, string.Empty, 0);
Dts.TaskResult = (int)ScriptResults.Failure;
}
Dts.TaskResult = (int)ScriptResults.Success;
}
Problem occurs exactly on every second time I run this code and I don't know how to get rid of it. There's just exception in my script task. I'm printing all variables that are used in this code, and as you can see there's something wrong with m_FilePath, it's like multiplied despite of being printed just once.
[FileDownload] Error: An exception occurred during a WebClient request.
at System.Net.WebClient.DownloadFile(Uri address, String fileName)
at ST_84b63d1593dd449886eb2b32dff40b2d.ScriptMain.Main()
Url: https://docs.google.com/spreadsheets/d/----------/export?format=xlsx
FilePath: C:\Google Drive extract\ga_manual_cost_file.xlsxC:\Google Drive extract\ga_manual_cost_file.xlsx
Path: C:\Google Drive extract\ga_manual_cost_file.xlsx
FileName2: ga_manual_cost_file.xlsx
SSIS variables that I'm using are ReadOnly, and are used only in this script task(I tried running only this part of control flow), and their values are as follows:

OrientDB Query works sometimes and at other times throws FormatException

I'm having a problem with this query below. I'm connecting to OrientDB using the C# driver and running the query in my c# code. All this code is in a loop and the queries in the try block works for a number of iterations and afterwards fails throwing a FormatException. At the point it fails I copy out the query and run it in the orientDB web interface and it returns the expect records so I'm sure it's not the input. So I'm so confused as to why it succeeds sometimes and fails at other times even when the input string is correct. Has anyone encountered a similar problem? Someone please help.
string origin = route[i].Trim();
string destination = route[i + 1].Trim();
List<ODocument> document = new List<ODocument>();
try
{
document = database.Query("select from (traverse out_Connects from " + origin + ") where in = " + destination);
//document = database.Query("select from Connects where (out = " + origin + " and in = " + destination + ")");
}
catch (Exception e)
{
//document = database.Query("select from Connects where (out = " + origin + " and in = " + destination + ")");
}

c# windows service Object reference not set to an instance of an object [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 9 years ago.
I have a service that checks other services and reports information on them.
The error is:
Object reference not set to an instance of an object.
at ServiceControl.ServiceCore.CheckServiceStatus(List`1 myservices)
Code Block
protected void CheckServiceStatus(List<ServiceConfig> myservices)
{
if (!restarting)
{
for (int i = 0; i < myservices.Count; i++)
{
string emailBody = "";
try
{
if (myservices[i].service.Status == ServiceControllerStatus.Running)
{
serviceName = myservices[i].service.DisplayName;
try
{
foreach (ManagementObject obj in searcher.Get())
{
uint processId = (uint)obj["ProcessId"];
Process process = null;
process = Process.GetProcessById((int)processId);
//Assign memory to service for later use
myservices[i].memoryUsage = process.WorkingSet64;
//Check process memory vs threshold
if (myservices[i].memoryUsage > myservices[i].memoryThreshold)
{
//report if memory exceeds threshold
emailBody = myservices[i].serviceName + " has exceeded its memory threshold of " + myservices[i].memoryThreshold + "\n"
+ "Current memory usage: " + Convert.ToString(myservices[i].memoryUsage);
EmailReport(emailBody, false);
//extend memory threshold by %
myservices[i].memoryThreshold *= myservices[i].memoryThresholdIncPercentage;
}
}
}
catch (Exception ex)
{
EventLog.WriteEntry(ex.Message);
emailBody = "Could not find process for " + myservices[i].serviceName;
EmailReport(emailBody, true);
}
}
}
catch (Exception ex)
{
EventLog.WriteEntry(ex.Message + "\n" + ex.StackTrace + "\n memory");
}
try
{
if (myservices[i].service.Status != myservices[i].status)
{
//Report change in service, includes last saved memory
emailBody = myservices[i].serviceName + " has changed status" + "\n" +
"from: " + Convert.ToString(myservices[i].status) + " to: " + Convert.ToString(myservices[i].service.Status) + "\n" +
"Memory Usage: " + Convert.ToString(myservices[i].memoryUsage);
EmailReport(emailBody, false);
}
}
catch (Exception ex)
{
EventLog.WriteEntry(ex.Message + "\n" + ex.StackTrace + "\n status");
}
}
}
if (lastDate != DateTime.Today)
{
restarting = true;
RestartServices();
}
}
I have done a fair amount of debugging and my results are:
myservices is not Null,
it contains exactly 1 item in this instance.
I have also tried making a localized list within the block
to consume myservices and work of the local list. this did not work.
I have tried passing myservices[i] to a local var and use the far, this did not work.
Any help would be much appreciated
Every time, those errors mean that you're referencing something that isn't instantiated. Therefore if your myservices[i] instance is NOT NULL, a property you're trying to reference for it MUST be.
Have you checked all properties of the myservices[i] objext?

Best practice error handling in Global asax

I have code below in global asax now, I want to store exception log in database, is this good practice? because if sql error happens there, I want to log it too. So I am thinking changing the code below to write text log instead email, then on sql error, write text log.
void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
string testEnvironment = ConfigurationSettings.AppSettings["isTestEnvironment"];
if (testEnvironment == "0")
{
Exception ex = Server.GetLastError();
if (ex is HttpException && ex.InnerException is ViewStateException)
{
Response.Redirect(Request.Url.AbsoluteUri)
return
}
StringBuilder theBody = new StringBuilder();
theBody.Append("URL: " + Request.Url + "\n");
theBody.Append("Referer: " + Request.ServerVariables["HTTP_REFERER"] + "\n");
theBody.Append("IP: " + Request.ServerVariables["REMOTE_HOST"] + "\n");
theBody.Append("Error Message: " + ex.ToString() + "\n");
if (User.Identity.IsAuthenticated)
theBody.Append("User: " + User.Identity.Name + "\n");
else
theBody.Append("User is not logged in." + "\n");
theBody.Append("Form Values: " + "\n");
foreach (string s in Request.Form.AllKeys)
{
if (s != "__VIEWSTATE")
theBody.Append(s + ":" + Request.Form[s] + "\n");
}
theBody.Append("Session Values: " + "\n");
foreach (string s in Session.Keys)
theBody.Append(s + ":" + Session[s] + "\n");
System.Net.Mail.MailMessage email = new System.Net.Mail.MailMessage();
email.IsBodyHtml = false;
email.From = new System.Net.Mail.MailAddress("errors#karpach.com", "ErrorManager");
email.To.Add(new System.Net.Mail.MailAddress("errornotification#karpach.com", "Developer"));
email.Subject = Request.Url.ToString().Split('/')[2] + " has ASP.NET error";
email.Body = theBody.ToString();
try
{
System.Net.Mail.SmtpClient emailProvider = new System.Net.Mail.SmtpClient();
emailProvider.Send(email);
}
catch (Exception anException)
{
}
finally
{
if (Request.Url.Segments[Request.Url.Segments.Length - 1].ToLower() != "error.aspx")
Response.Redirect("~/error.aspx?msg=4");
else
{
Response.Write(#"We encountered an internal error. We apologize for any inconvenience
but know that our staff gets emailed EVERY error that occurs so that we can solve it promptly.");
Response.End();
}
}
}
}
You could log it to the EventLog. System admins can setup monitoring to see when new events are added and be alerted to potential problems.
Here's an example from MSDN for the EventLog class:
if(!EventLog.SourceExists("MySource"))
{
//An event log source should not be created and immediately used.
//There is a latency time to enable the source, it should be created
//prior to executing the application that uses the source.
//Execute this sample a second time to use the new source.
EventLog.CreateEventSource("MySource", "MyNewLog");
Console.WriteLine("CreatedEventSource");
Console.WriteLine("Exiting, execute the application a second time to use the source.");
// The source is created. Exit the application to allow it to be registered.
return;
}
// Create an EventLog instance and assign its source.
EventLog myLog = new EventLog();
myLog.Source = "MySource";
// Write an informational entry to the event log.
myLog.WriteEntry("Writing to event log.");

C# WinForms App - Debug Error - Length can not be less than zero. Parameter Name: Length

In debug mode, while running the C# WinForms App, I successfully select multiple files through the OpenFileDialog, which is then displayed in the logging window, these files are copied to a temp directory and I believe I get the error when trying to convert the excel files to csv. I get the following runtime debug error:
Error: You may not have permission to read the file or it may be corrupt.
Reported Error: Length Can not be less than zero.
Parameter Name: Length.
How do I fix this error?
Here's my code on MainForm.cs
// Consolidate Button Click Commands that executes if there are no user input errors
void ExecuteConsolidate()
{
string consolidatedFolder = targetFolderBrowserDialog.SelectedPath;
string tempfolder = targetFolderBrowserDialog.SelectedPath + "\\tempDirectory";
string sFile = "";
//create a temporary directory to store selected excel and csv files
if (!Directory.Exists(tempfolder))
{
Directory.CreateDirectory(tempfolder);
}
try
{
for (int i = 0; i < listBoxSourceFiles.Items.Count; i++)
{
sFile = listBoxSourceFiles.Items[i].ToString();
// Copy each selected xlsx files into the specified Temporary Folder
System.IO.File.Copy(textBoxSourceDir.Text + "\\" + sFile, tempfolder + #"\" + System.IO.Path.GetFileName(sFile), true);
Log("File " + sFile + " has been copied to " + tempfolder + #"\" + System.IO.Path.GetFileName(sFile));
} // ends foreach
Process convertFilesProcess = new Process();
// remove xlsx extension from filename so that we can add the .csv extension
string csvFileName = sourceFileOpenFileDialog.FileName.Substring(0, sourceFileOpenFileDialog.FileName.Length - 3);
// command prompt execution for converting xlsx files to csv
convertFilesProcess.StartInfo.WorkingDirectory = "I:\\CommissisionReconciliation\\App\\ConvertExcel\\";
convertFilesProcess.StartInfo.FileName = "ConvertExcelTo.exe";
convertFilesProcess.StartInfo.Arguments = " ^ " + targetFolderBrowserDialog.SelectedPath + "^" + csvFileName + ".csv";
convertFilesProcess.StartInfo.UseShellExecute = true;
convertFilesProcess.StartInfo.CreateNoWindow = true;
convertFilesProcess.StartInfo.RedirectStandardOutput = true;
convertFilesProcess.StartInfo.RedirectStandardError = true;
convertFilesProcess.Start();
//Process that creates all the xlsx files in temp folder to csv files.
Process consolidateFilesProcess = new Process();
// command prompt execution for CSV File Consolidation
consolidateFilesProcess.StartInfo.WorkingDirectory = targetFolderBrowserDialog.SelectedPath;
consolidateFilesProcess.StartInfo.Arguments = "Copy *.csv ^" + csvFileName + ".csv";
consolidateFilesProcess.StartInfo.UseShellExecute = false;
consolidateFilesProcess.StartInfo.CreateNoWindow = true;
consolidateFilesProcess.StartInfo.RedirectStandardOutput = true;
consolidateFilesProcess.StartInfo.RedirectStandardError = true;
consolidateFilesProcess.Start();
Log("All Files at " + tempfolder + " has been converted to a csv file");
Thread.Sleep(2000);
StreamReader sOut = consolidateFilesProcess.StandardOutput;
sOut.Close();
}
catch (SecurityException ex)
{
// The user lacks appropriate permissions to read files, discover paths, etc.
MessageBox.Show("Security error. The user lacks appropriate permissions to read files, discover paths, etc. Please contact your administrator for details.\n\n" +
"Error message: " + ex.Message + "\n\n");
}
catch (Exception ex)
{
// Could not load the image - probably related to Windows file system permissions.
MessageBox.Show("You may not have permission to read the file, or " +
"it may be corrupt.\n\nReported error: " + ex.Message);
}
try
{
if (Directory.Exists(tempfolder))
{
Directory.Delete(tempfolder, true);
}
}
catch (SecurityException ex)
{
// The user lacks appropriate permissions to read files, discover paths, etc.
MessageBox.Show("Security error. The user lacks appropriate permissions to read files, discover paths, etc. Please contact your administrator for details.\n\n" +
"Error message: " + ex.Message + "\n\n");
}
catch (Exception ex)
{
// Could not load the image - probably related to Windows file system permissions.
MessageBox.Show("You may not have permission to read the file, or " +
"it may be corrupt.\n\nReported error: " + ex.Message);
}
finally
{
// reset events
m_EventStopThread.Reset();
m_EventThreadStopped.Reset();
// create worker thread instance;
m_WorkerThread = new Thread(new ThreadStart(this.WorkerThreadFunction));
m_WorkerThread.Start();
}
} // ends void ExecuteConsolidate()
Thanks for looking! :)
All helpful answers will receive up-votes! :)
If you need more information like the workerThread method or the app.config code, let me know!
It is most likely this line that is causing your problem:
string csvFileName = sourceFileOpenFileDialog.FileName.Substring(0, sourceFileOpenFileDialog.FileName.Length - 3);
Why not use Path.GetFileNameWithoutExtension to get the filename without extension?
I suppose it dies here:
string csvFileName = sourceFileOpenFileDialog.FileName.Substring(0,
sourceFileOpenFileDialog.FileName.Length - 3);
Write it like this and see if it helps:
string selectedFile = sourceFileOpenFileDialog.FileName;
string csvFileName = Path.Combine(Path.GetDirectoryName(selectedFile),
Path.GetFileNameWithoutExtension(selectedFile));
This is the translation of your line.
But I think, you really wanted to just have the filename without path:
string csvFileName =
Path.GetFileNameWithoutExtension(sourceFileOpenFileDialog.FileName);
And to break on All Errors:
Go to "Debug" -> Exceptions (or CTRL+ALT+E)
Tick "Thrown" on Common Language Runtime Exceptions
Once done with you fix, dont forget to reset it (Reset All button)

Categories