I had an HTML button with id=submit so using Selenium IDE I selected the command "Click" with target as id=submit but selenium IDE pass this line as if it is executed but without the button really clicked so the form is not submitted !! what is wrong ?
Here is the C# code I exported. Problem is in driver.FindElement(By.Name("submit")).Click();
using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Support.UI;
namespace SeleniumTests
{
[TestFixture]
public class Web
{
private IWebDriver driver;
private StringBuilder verificationErrors;
private string baseURL;
private bool acceptNextAlert = true;
[SetUp]
public void SetupTest()
{
driver = new FirefoxDriver();
baseURL = "I cannot share url";
verificationErrors = new StringBuilder();
}
[TearDown]
public void TeardownTest()
{
try
{
driver.Quit();
}
catch (Exception)
{
// Ignore errors if unable to close the browser
}
Assert.AreEqual("", verificationErrors.ToString());
}
[Test]
public void TheWebTest()
{
driver.Navigate().GoToUrl("I cannot share url");
driver.FindElement(By.Id("submit")).Click();
for (int second = 0;; second++) {
if (second >= 60) Assert.Fail("timeout");
try
{
if ("All Campaigns" == driver.FindElement(By.CssSelector("#CampaignsTable > div.box > div.title")).Text) break;
}
catch (Exception)
{}
Thread.Sleep(1000);
}
for (int second = 0;; second++) {
if (second >= 60) Assert.Fail("timeout");
try
{
if ("Last" == driver.FindElement(By.Id("cloaker_last")).Text) break;
}
catch (Exception)
{}
Thread.Sleep(1000);
}
driver.FindElement(By.XPath("(//img[#alt='Click to edit the rotator settings'])[1]")).Click();
driver.FindElement(By.Id("addNewUrl_0_geo_0_url_to_cloak")).Clear();
driver.FindElement(By.Id("addNewUrl_0_geo_0_url_to_cloak")).SendKeys("dghfghf");
driver.FindElement(By.Id("addNewUrl_0_geo_0_mobile_url")).Click();
driver.FindElement(By.Id("submit")).Click();
driver.FindElement(By.Id("submit")).Click();
for (int second = 0;; second++) {
if (second >= 60) Assert.Fail("timeout");
try
{
if ("Success" == driver.FindElement(By.CssSelector("div.message.green > span > b")).Text) break;
}
catch (Exception)
{}
Thread.Sleep(1000);
}
driver.FindElement(By.XPath("(//img[#alt='Click to edit the rotator settings'])[2]")).Click();
driver.FindElement(By.Id("addNewUrl_0_geo_0_url_to_cloak")).Clear();
driver.FindElement(By.Id("addNewUrl_0_geo_0_url_to_cloak")).SendKeys("tyujghghj");
driver.FindElement(By.Name("submit")).Click();
driver.FindElement(By.XPath("(//img[#alt='Click to edit the rotator settings'])[3]")).Click();
driver.FindElement(By.Id("addNewUrl_0_geo_0_url_to_cloak")).Clear();
driver.FindElement(By.Id("addNewUrl_0_geo_0_url_to_cloak")).SendKeys("gfhjghjgh");
driver.FindElement(By.Name("submit")).Click();
driver.FindElement(By.XPath("(//img[#alt='Click to edit the rotator settings'])[4]")).Click();
driver.FindElement(By.Id("addNewUrl_0_geo_0_url_to_cloak")).Clear();
driver.FindElement(By.Id("addNewUrl_0_geo_0_url_to_cloak")).SendKeys("ghghkghk");
driver.FindElement(By.Id("addNewUrl_0_geo_0_mobile_url")).Click();
driver.FindElement(By.Name("submit")).Click();
}
private bool IsElementPresent(By by)
{
try
{
driver.FindElement(by);
return true;
}
catch (NoSuchElementException)
{
return false;
}
}
private bool IsAlertPresent()
{
try
{
driver.SwitchTo().Alert();
return true;
}
catch (NoAlertPresentException)
{
return false;
}
}
private string CloseAlertAndGetItsText() {
try {
IAlert alert = driver.SwitchTo().Alert();
string alertText = alert.Text;
if (acceptNextAlert) {
alert.Accept();
} else {
alert.Dismiss();
}
return alertText;
} finally {
acceptNextAlert = true;
}
}
}
}
Perhaps if you shared existing code, the URL you are trying to reference, etc. we could be more helpful.
It's very hard to answer a question without enough information.
You haven't shared the code so It is hard to analyze your problem. This might help you -
just change your command click to clickAt and then try.
Related
I decompiled a .NET Application to write my own Injection Software. A Thread Error don't want to get removed. I tried everything but it keeps telling me that something is wrong...
Code (Screenshot)
{
using System;
using System.IO;
using System.IO.Pipes;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;
internal class NamedPipes
{
public static string luapipename = "IDUNNOPIPE123";
public static void LuaPipe(string script)
{
if (NamedPipeExist(luapipename))
{
new Thread (delegate {
try
{
using (NamedPipeClientStream stream = new NamedPipeClientStream(".", luapipename, PipeDirection.Out))
{
stream.Connect();
using (StreamWriter writer = new StreamWriter(stream, Encoding.Default, 0xf423f))
{
writer.Write(script);
writer.Dispose();
}
stream.Dispose();
}
}
catch (IOException)
{
MessageBox.Show("Error occured connecting to the pipe.", "Connection Failed!", MessageBoxButtons.OK, MessageBoxIcon.Hand);
}
catch (Exception exception1)
{
MessageBox.Show(exception1.Message.ToString());
}
}).Start();
}
else
{
MessageBox.Show("Please Inject " + Functions.exploitdllname + " before Using this!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
public static bool NamedPipeExist(string pipeName)
{
bool flag;
try
{
int timeout = 0;
if (!WaitNamedPipe(Path.GetFullPath($"\\\\.\\pipe\\{pipeName}"), timeout))
{
bool flag4;
int num2 = Marshal.GetLastWin32Error();
if (num2 != 0)
{
if (num2 != 2)
{
goto TR_0005;
}
else
{
flag4 = false;
}
}
else
{
flag4 = false;
}
return flag4;
}
TR_0005:
flag = true;
}
catch (Exception)
{
flag = false;
}
return flag;
}
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)]
private static extern bool WaitNamedPipe(string name, int timeout);
}
}
I think you are getting the The call is ambiguous between the following methods or properties: 'Thread.Thread(ThreadStart)' and 'Thread.Thread(ParameterizedThreadStart)' error with this.
As you correctly noted, the compiler can't distinguish what type the Thread constructor parameter is. ParameterizedThreadStart is used if you pass a parameter to your delegate when calling the Thread.Start method. Your code does not do this. Thus, you need a ThreadStart delegate here. Its syntax is
public delegate void ThreadStart();
I.e. it does not accept any parameter and does not return a value. So, you can just pass a lambda function that does the same.
new Thread(() => {
// ...
}).Start();
I'm pretty new at C#. But have experience in C, Python etc.
here is my question.
I have a GUI which has 2 forms.
the First form asks for a serial number of the unit and the second one is where the main test occurs.
In the 2nd form, there is a stage when I wait for the controller (DUT) to boot up so that I can get the bootup information.
I got most of the code working, but here the issue.
I disable the "Next" button until the user powercycles the unit. But, even with the button disabled, the click event occurs (when the user clicks the disabled button) and based on the number of click he does, the SW validates the clicks and skips the next stage/s.
how can I sort this out? Or, is there another better way to code this?
here is my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WIFI_DMX_TEST
{
public partial class form_test : Form
{
int x = 0;
int MAX_TEST_STATES = 15; //Set the number of test states.
string Rx_String;
test_instructions test_intsructions = new test_instructions(); //Create a new instance of the class test_instructions
public form_test()
{
InitializeComponent();
but_test_next_Click(null, null); //Call the but_test_next_Click event
Serial_INIT();
}
public void but_test_next_Click(object sender, EventArgs e)
{
if ((x <= MAX_TEST_STATES) && (but_test_next.Enabled == true))
{
if (x == 0)
{
textBox1.Text = test_intsructions.check_unit;
//load picture here showing unit
}
else if (x == 1)
{
textBox1.Text = test_intsructions.connect_cables;
//load picture here showing cables to connect
}
else if (x == 2)
{
textBox1.Text = test_intsructions.powerup_unit;
//load picture here showing unit powerup
}
else if (x == 3)
{
but_test_next.Enabled = false; //Disable the Next button
if (Rx_String == null) //check if the Rs232 info is empty
{
MessageBox.Show("No DUT info available. Please powercycle the unit", "Error: No data", MessageBoxButtons.OK, MessageBoxIcon.Error);
while (Rx_String == null) ; //Sit here doing nothing and wait till info is available
but_test_next.Enabled = true;
}
textBox1.Text = test_intsructions.program_unit; //Show next instruction.
//put programming function here.
//Put info here showing the unit has been programmed successfully or not.
//if failed, then log this error and WIFI controller info in the Log file.
}
else if (x == 4)
{
textBox1.Text = test_intsructions.reset_unit;
//if failed, then log this error and WIFI controller info in the Log file.
}
else if (x == 5)
{
textBox1.Text = test_intsructions.query_colour_R;
//if failed, then log this error and WIFI controller info in the Log file.
}
else if (x == 6)
{
textBox1.Text = test_intsructions.query_colour_G;
//if failed, then log this error and WIFI controller info in the Log file.
}
else if (x == 7)
{
textBox1.Text = test_intsructions.query_colour_B;
//if failed, then log this error and WIFI controller info in the Log file.
}
else if (x == 8)
{
textBox1.Text = test_intsructions.query_colour_W;
//if failed, then log this error and WIFI controller info in the Log file.
}
else if (x == 9)
{
textBox1.Text = test_intsructions.acclerometer_mode;
//if failed, then log this error and WIFI controller info in the Log file.
}
else if (x == 10)
{
textBox1.Text = test_intsructions.STL_mode_Sens_Low;
//if failed, then log this error and WIFI controller info in the Log file.
}
else if (x == 11)
{
textBox1.Text = test_intsructions.STL_mode_Sens_High;
//if failed, then log this error and WIFI controller info in the Log file.
}
else if (x == 12)
{
textBox1.Text = test_intsructions.test_mode;
//if failed, then log this error and WIFI controller info in the Log file.
}
else if (x == 13)
{
textBox1.Text = test_intsructions.control_output;
//if failed, then log this error and WIFI controller info in the Log file.
}
else if (x == 14)
{
textBox1.Text = test_intsructions.powerdown_unit;
}
else if (x == 15)
{
textBox1.Text = test_intsructions.disconnect_cables;
}
//x++;
if (!((x == 3) && (but_test_next.Enabled == false)))
{
x++;
//but_test_next.Enabled = true;
}
//but_test_next.Enabled = true;
}
}
private void but_test_exit_Click_1(object sender, EventArgs e)
{
Serial_Close();
this.Close();
this.Hide();
form_startup f1 = new form_startup();
f1.ShowDialog();
}
private void program_unit()
{
}
class test_instructions
{
public string check_unit
{
get { return "Check DUT for any obvious faults"; }
set { }
}
public string connect_cables
{
get {return "Connect cables to the DUT";}
set {}
}
public string powerup_unit
{
get { return "Powerup the DUT"; }
set {}
}
public string program_unit
{
get { return "Programming the DUT"; }
set { }
}
public string reset_unit
{
get {return "Reset the unit";}
set {}
}
public string query_colour_R
{
get { return "Is the LED RED ON?"; }
set {}
}
public string query_colour_G
{
get {return "Is the LED GREEN ON?";}
set {}
}
public string query_colour_B
{
get {return "Is the LED BLUE ON?";}
set {}
}
public string query_colour_W
{
get {return "Is the LED WHITE ON?";}
set {}
}
public string acclerometer_mode
{
get { return "Accelerometer mode: Move the unit and check if the Lights change colour" ;}
set { }
}
public string STL_mode_Sens_Low
{
get { return "Set sensitivity to Low"; }
set { }
}
public string STL_mode_Sens_High
{
get { return "Set sensitivity to High"; }
set { }
}
public string test_mode
{
get { return "Press the test mode and check if lights are moving between R,G,B and W"; }
set { }
}
public string control_output
{
get { return "Check if Control output is working as expected."; }
set { }
}
public string powerdown_unit
{
get { return "Switch OFF the jig"; }
set { }
}
public string disconnect_cables
{
get { return "Disconnect cables and remove DUT"; }
set { }
}
}
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
Rx_String = serialPort1.ReadExisting();
this.Invoke(new EventHandler(DisplayText));
}
private void DisplayText(object sender, EventArgs e)
{
textBox2.AppendText(Rx_String);
}
private void Serial_INIT ()
{
serialPort1.PortName = "COM3";
serialPort1.BaudRate = 9600;
serialPort1.Open();
}
private void Serial_Close()
{
serialPort1.Close();
}
private void form_test_FormClosing(object sender, FormClosingEventArgs e)
{
Serial_Close();
}
}
}
cheers,
Mat
I didn't fully understand what you mean by disabling the button.
if you did the following it should work:
NextBtn.IsEnabled = false;
NextBtn.Visibility = Visibility.Collapsed;
Otherwise, you can simply disable the method by creating a bool:
bool hasOccured;
Private void Reason_Occured(EventArgs)
{
hasOccured = true;
}
private void NextBtn_Click(Args)
{
if(hasOccured) return;
//code chunk
}
Sorry for the late reply.
I managed to fix this issue. Seems like I had to use a Switch, Case statement rather than If statements.
Cheers for all your help
Mat
:D
I have created two projects in MS Visual C# 2010 Express. The first project has a class SugarcrmLogin with the method TheSugarCrmLoginTest().
The second project has a class Sugarcrm with the method Main. This project has a reference to the project dll of the first project.
In the method Main I have instantiated the class SugarcrmLogin and called the SugarCrmLoginTest() method.
Here the code of the Main method in the second project, where I instantiate the class and call the method:
public static void Main()
{
SugarcrmLogin Login;
Login = new SugarcrmLogin();
Login.TheSugarcrmLoginTest();
}
Both projects build succesfully in MS Visual C#, but when I try to run the project dll of the second project with Nunit, I get the error 'Object reference not set to an instance of an object' with a reference to TheSugarCrmLoginTest() method in the first project.
First project
using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.IE;
using OpenQA.Selenium.Support.UI;
namespace SeleniumTests
{
[TestFixture]
public class SugarcrmLogin
{
private IWebDriver driver;
private StringBuilder verificationErrors;
private string baseURL;
private bool acceptNextAlert = true;
[SetUp]
public void SetupTest()
{
//driver = new FirefoxDriver();
driver = new InternetExplorerDriver();
baseURL = "http://127.0.0.1/";
verificationErrors = new StringBuilder();
}
[TearDown]
public void TeardownTest()
{
try
{
driver.Quit();
}
catch (Exception)
{
// Ignore errors if unable to close the browser
}
Assert.AreEqual("", verificationErrors.ToString());
}
[Test]
public void TheSugarcrmLoginTest()
{
driver.Navigate().GoToUrl(baseURL + "/sugarcrm/index.php?module=Users&action=Login");
driver.FindElement(By.Id("user_name")).Clear();
driver.FindElement(By.Id("user_name")).SendKeys("admin");
driver.FindElement(By.Id("user_password")).Clear();
driver.FindElement(By.Id("user_password")).SendKeys("admin");
driver.FindElement(By.Id("login_button")).Click();
}
private bool IsElementPresent(By by)
{
try
{
driver.FindElement(by);
return true;
}
catch (NoSuchElementException)
{
return false;
}
}
private bool IsAlertPresent()
{
try
{
driver.SwitchTo().Alert();
return true;
}
catch (NoAlertPresentException)
{
return false;
}
}
private string CloseAlertAndGetItsText()
{
try
{
IAlert alert = driver.SwitchTo().Alert();
string alertText = alert.Text;
if (acceptNextAlert)
{
alert.Accept();
}
else
{
alert.Dismiss();
}
return alertText;
}
finally
{
acceptNextAlert = true;
}
}
}
}
Second project:
using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.IE;
using OpenQA.Selenium.Support.UI;
namespace SeleniumTests
{
[TestFixture]
public class Sugarcrm
{
public IWebDriver driver;
private StringBuilder verificationErrors;
public string baseURL;
private bool acceptNextAlert = true;
[SetUp]
public void SetupTest()
{
//driver = new FirefoxDriver();
driver = new InternetExplorerDriver();
baseURL = "http://127.0.0.1/";
verificationErrors = new StringBuilder();
}
[TearDown]
public void TeardownTest()
{
try
{
driver.Quit();
}
catch (Exception)
{
// Ignore errors if unable to close the browser
}
Assert.AreEqual("", verificationErrors.ToString());
}
[Test]
public static void Main()
{
SugarcrmLogin Login;
Login = new SugarcrmLogin();
Login.TheSugarcrmLoginTest();
}
private bool IsElementPresent(By by)
{
try
{
driver.FindElement(by);
return true;
}
catch (NoSuchElementException)
{
return false;
}
}
private bool IsAlertPresent()
{
try
{
driver.SwitchTo().Alert();
return true;
}
catch (NoAlertPresentException)
{
return false;
}
}
private string CloseAlertAndGetItsText()
{
try
{
IAlert alert = driver.SwitchTo().Alert();
string alertText = alert.Text;
if (acceptNextAlert)
{
alert.Accept();
}
else
{
alert.Dismiss();
}
return alertText;
}
finally
{
acceptNextAlert = true;
}
}
}
}
With the edit that shows the code: driver is null. The constructor does not assign it, and you do not call the SetupTest() method which does.
Frankly, though, your Sugarcrm unit test shouldn't be instantiating and calling-into another (SugarcrmLogin) unit test like that, IMO. This seems like "using your unit test framework incorrectly".
My question is all about URL Protocols.
I have registered a URL Protocol called mcm, but I noticed that everytime I run it from any web browser, t creates a new instance of the application. Is there any way to handle the protocol request in an already running instance?
For example, when uTorrent is using the torrent protocol It handles the request immediately without running the app again. I couldn't really find anything interesting about it, so I am asking here...
Here is the code I use to register the protocol:
private static void RegisterUrlProtocol()
{
UnregisterUrlProtocol();
RegistryKey rKey = Registry.ClassesRoot.OpenSubKey(UrlProtocol, true);
if (rKey == null)
{
rKey = Registry.ClassesRoot.CreateSubKey(UrlProtocol);
rKey.SetValue("", "URL: MazCraft Protocol");
rKey.SetValue("URL Protocol", "");
rKey = rKey.CreateSubKey(#"shell\open\command");
rKey.SetValue("", "\"" + Application.ExecutablePath + "\" %1");
}
if (rKey != null)
{
rKey.Close();
}
}
And the code to read the arguments:
private static bool CheckForProtocolMessage()
{
string[] arguments = Environment.GetCommandLineArgs();
if (arguments.Length > 1)
{
string[] args = arguments[1].Split(':');
args[1] = args[1].Replace("//", "");
if (args[0].Trim().ToUpper() == "MCM" && args.Length > 1)
{
string[] actionDetail = args[1].Split('=');
if (actionDetail[0].Trim().ToUpper() == "INSTALL" && actionDetail.Length > 1)
{
string id = actionDetail[1].Trim().Replace("/", "");
Funcs.ID = id;
return true;
}
}
}
return false;
}
Any help would be greatly appreciated :)
Greetings.
You could use a Mutex to detect an instance of the application that is already running and send the data over to the existing instance via Named Pipes.
Hope the following example helps.
you can swap out the named pipes object (in this case string) for whatever serializable object you like.
NamedPipe.cs
namespace SingleInstanceNP
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Pipes;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;
using System.IO;
public class NamedPipe<T> : IDisposable
{
#region Attribute and Properties
private string _pipeName;
private NamedPipeServerStream _pipeServer;
private bool _disposed;
private Thread _thread;
private bool _started;
#endregion
#region Constructors
public NamedPipe(NameTypes pipeType)
{
_disposed = false;
_started = false;
_pipeName = pipeType.ToString();
_thread = new Thread(Main);
_thread.SetApartmentState(ApartmentState.STA);
_thread.Name = "NamePipe: " + pipeType.ToString() + " Thread";
_thread.IsBackground = true;
}
~NamedPipe()
{
Dispose();
}
#endregion
#region Events
public delegate void Request(T t);
public event Request OnRequest;
#endregion
#region Public Methods
public static void Send(NameTypes pipeType, T t)
{
using (var npc = new NamedPipeClientStream(".", pipeType.ToString(), PipeDirection.Out))
{
var bf = new BinaryFormatter();
npc.Connect();
bf.Serialize(npc, t);
}
}
public static T Recieve(NameTypes pipeType)
{
using (var nps = new NamedPipeServerStream(pipeType.ToString(), PipeDirection.In))
{
return Recieve(nps);
}
}
public void Start()
{
if (!_disposed && !_started)
{
_started = true;
_thread.Start();
}
}
public void Stop()
{
_started = false;
if (_pipeServer != null)
{
_pipeServer.Close();
// disposing will occur on thread
}
}
public void Dispose()
{
_disposed = true;
Stop();
if (OnRequest != null)
OnRequest = null;
}
#endregion
private void Main()
{
while (_started && !_disposed)
{
try
{
using (_pipeServer = new NamedPipeServerStream(_pipeName))
{
T t = Recieve(_pipeServer);
if (OnRequest != null && _started)
OnRequest(t);
}
}
catch (ThreadAbortException)
{ }
catch (System.IO.IOException iox)
{
Console.WriteLine("ERROR: {0}", iox.Message);
Thread.Sleep(TimeSpan.FromSeconds(30));
}
catch (Exception ex)
{
Console.WriteLine("ERROR: {0}", ex.Message);
return;
}
}
}
private static T Recieve(NamedPipeServerStream nps)
{
var bf = new BinaryFormatter();
try
{
nps.WaitForConnection();
var obj = bf.Deserialize(nps);
if (obj is T)
return (T)obj;
}
// Catch the IOException that is raised if the pipe is
// broken or disconnected.
catch (IOException e)
{
Console.WriteLine("ERROR: {0}", e.Message);
}
return default(T);
}
#region Enums
public enum NameTypes
{
PipeType1
}
#endregion
}
}
Program.cs
Please give credit for the APP GUID to What is a good pattern for using a Global Mutex in C#?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Threading;
namespace SingleInstanceNP
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
// get application GUID as defined in AssemblyInfo.cs
string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value.ToString();
// unique id for global mutex - Global prefix means it is global to the machine
string mutexId = string.Format("Global\\{{{0}}}", appGuid);
using (var mutex = new Mutex(false, mutexId))
{
try
{
if (!mutex.WaitOne(0, false))
{
//signal existing app via named pipes
NamedPipe<string>.Send(NamedPipe<string>.NameTypes.PipeType1, "test");
Environment.Exit(0);
}
else
{
// handle protocol with this instance
Application.Run(new Form1());
}
}
finally
{
mutex.ReleaseMutex();
}
}
}
}
}
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace SingleInstanceNP
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// start listening for named pipe connections
var namedPipeString = new NamedPipe<string>(NamedPipe<string>.NameTypes.PipeType1);
namedPipeString.OnRequest += new NamedPipe<string>.Request(namedPipeString_OnRequest);
namedPipeString.Start();
}
void namedPipeString_OnRequest(string t)
{
MessageBox.Show(t);
}
}
}
I created this simple sample Form with the close button.
Everything is working as expected when NOT using the Interop.WMPLib.dll
I've seen other applications using this without problems but why isn't the Form process closed when I just add the line:
SoundPlayer myPlayer = new SoundPlayer();
and of course dispose it:
if (myPlayer != null)
{
myPlayer.Dispose();
myPlayer = null;
}
The Form closes but the debugger VS2008 is still active. The Form project and the dll are still active.
If you send me an email to xdasleepsense#gmail.com, I can send you the zipped project.
Below is the class for the dll:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;
using WMPLib;
namespace WindowsMobile.Utilities
{
public delegate void SoundPlayerStateChanged(SoundPlayer sender, SoundPlayerState newState);
public enum SoundPlayerState
{
Stopped,
Playing,
Paused,
}
public class SoundPlayer : IDisposable
{
[DllImport("coredll")]
public extern static int waveOutSetVolume(int hwo, uint dwVolume);
[DllImport("coredll")]
public extern static int waveOutGetVolume(int hwo, out uint dwVolume);
WindowsMediaPlayer myPlayer = new WindowsMediaPlayer();
public SoundPlayer()
{
myPlayer.uiMode = "invisible";
myPlayer.settings.volume = 100;
}
string mySoundLocation = string.Empty;
public string SoundLocation
{
get { return mySoundLocation; }
set { mySoundLocation = value; }
}
public void Pause()
{
myPlayer.controls.pause();
}
public void PlayLooping()
{
Stop();
myPlayer.URL = mySoundLocation;
myPlayer.settings.setMode("loop", true);
}
public int Volume
{
get { return myPlayer.settings.volume; }
set { myPlayer.settings.volume = value; }
}
public void Play()
{
Stop();
myPlayer.URL = mySoundLocation;
myPlayer.controls.play();
}
public void Stop()
{
myPlayer.controls.stop();
myPlayer.close();
}
#region IDisposable Members
public void Dispose()
{
try
{
Stop();
}
catch (Exception)
{
}
// need this otherwise the process won't exit?!
try
{
int ret = Marshal.FinalReleaseComObject(myPlayer);
}
catch (Exception)
{
}
myPlayer = null;
GC.Collect();
}
#endregion
}
}
A MessageBox or Below solved it. Thx.
public void Dispose()
{
try
{
Stop();
}
catch (Exception)
{
}
// need this otherwise the process won't exit?!
try
{
int ret = Marshal.FinalReleaseComObject(myPlayer);
}
catch (Exception)
{
}
myPlayer = null;
GC.Collect();
//If you don't do this, it will not quit
//http://www.eggheadcafe.com/software/aspnet/31363254/media-player-freezing-app.aspx
for (int s = 0; s < 100; s++)
{
Application.DoEvents();
Thread.Sleep(1);
}
GC.WaitForPendingFinalizers();
//MessageBox.Show("Application Exiting");
}
I just found from this link: http://software.itags.org/pocketpc-developer/163455/
a hint...
So I added a messagebox:
public void Dispose()
{
try
{
Stop();
}
catch (Exception)
{
}
// need this otherwise the process won't exit?!
try
{
int ret = Marshal.FinalReleaseComObject(myPlayer);
}
catch (Exception)
{
}
myPlayer = null;
GC.Collect();
**MessageBox.Show("Application Exiting");**
}
once I click OK, the debugger also thinks it's finished. Of course I can't have the user click OK.
So what's happening here?