I'm in face on the following problem: An application developed on Microsoft Visual Studio 2013 in .NET 4.5, needs to work in Window XP Platforms. I'm rebuild the software using .NET 4.0 and make some modifications to add compatibility, but when i click in a button the app crash and don't show a clear error message and the Trace resource don't log anything. On application start i had a little window that ask user to put your name, and this feature works fine. Anybody have any suggestion of what can i do ?
EDIT 1:
The follow code is the root of problems, this code was compiled using .NET 4.0:
SerialManager.cs
using System;
using System.Windows;
using TestSat;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO.Ports;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Text.RegularExpressions;
using System.Diagnostics;
namespace TestSat.DataModel
{
/// <summary>
///
/// </summary>
public class SerialManager : INotifyPropertyChanged
{
#region Events
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
///
/// </summary>
/// <param name="propertyName"></param>
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
/* [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)]
public sealed class CallerMemberNameAttribute : Attribute
{
}*/
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="field"></param>
/// <param name="value"></param>
/// <param name="propertyName"></param>
/// <returns></returns>
protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}
#endregion
#region Private Fields
private static SerialPort PortaSerial;
private ObservableCollection<String> mPorts;
private String mSelectedPort;
private int mBaudRate = 115200;
private int mDataBits = 8;
#endregion
#region Public Fields
public StringBuilder logText;
#endregion
#region Properties
/// <summary>
///
/// </summary>
public ObservableCollection<String> COMPorts
{
get { return mPorts; }
set { SetField(ref mPorts, value); }
}
/// <summary>
///
/// </summary>
public String TextoLog
{
get { return logText.ToString(); }
set
{
if (logText.Length >= logText.MaxCapacity)
{
logText.Clear();;
logText.Append(value);
}
else
{
logText.Append(value);
//MainWindow.last = value;
}
OnPropertyChanged("TextoLog");
}
}
/// <summary>
///
/// </summary>
public String SelectedPort
{
get { return mSelectedPort; }
set {SetField(ref mSelectedPort, value); }
}
#endregion
#region Construtors
/// <summary>
///
/// </summary>
public SerialManager()
{
InitComponents();
}
/// <summary>
///
/// </summary>
private void InitComponents()
{
RefreshPorts();
/*Initialize the log variable*/
logText = new StringBuilder();
/* Update selected port */
SelectedPort = COMPorts.Count > 0 ? COMPorts[0] : "";
}
#endregion
#region Public Methods
/// <summary>
///
/// </summary>
public void RefreshPorts()
{
// Update ports
string[] pPorts = SerialPort.GetPortNames();
// Sort alphabetically
Array.Sort(pPorts);
// Sort by string length
Array.Sort(pPorts, (x, y) => x.Length.CompareTo(y.Length));
// Create collection
COMPorts = new ObservableCollection<string>(pPorts);
}
/// <summary>
///
/// </summary>
/// <param name="mSelectedPort"></param>
public void ConnectSerial(String mSelectedPort)
{
PortaSerial = new SerialPort();
PortaSerial.PortName = mSelectedPort;
PortaSerial.BaudRate = mBaudRate;
PortaSerial.Parity = Parity.None;
PortaSerial.DataBits = mDataBits;
PortaSerial.StopBits = StopBits.One;
PortaSerial.Handshake = Handshake.None;
PortaSerial.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
Trace.WriteLine("DataReceived definida");
try
{
PortaSerial.Open();
}
catch (SystemException)
{
MessageBox.Show("A porta serial esta sendo usada em outra aplicação.", "Erro", MessageBoxButton.OK);
throw new SystemException();
}
}
/// <summary>
///
/// </summary>
public void DesconnectSerial()
{
if (PortaSerial.IsOpen)
{
PortaSerial.Close();
}
}
/// <summary>
///
/// </summary>
public void writeSerial(String text)
{
if (PortaSerial.IsOpen)
{
if (text.Length > 0)
{
/* char[] array = text.ToCharArray(0,text.Length);
foreach(char ch in array)
{
PortaSerial.Write(ch.ToString());
Thread.Sleep(50);
}*/
PortaSerial.WriteLine(text);
}
else
{
PortaSerial.WriteLine("");
}
}
else
{
MessageBox.Show("Porta serial não esta aberta.", "Erro", MessageBoxButton.OK);
Console.WriteLine("Porta serial não esta aberta");
}
}
/// <summary>
///
/// </summary>
public bool IsOpen()
{
return PortaSerial.IsOpen;
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
MainWindow.StartRawData = true;
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
TextoLog = indata;
/*Omited code only logical operation*/
}
#endregion
}
}
If i don't do any instance or reference to serial port the applications don't crashes. Exist a way to force this part of code compiled by .NET 3.5? Or exist another suggestion of solution for this problem?
The solution i found at http://blogs.msdn.com/b/bclteam/p/asynctargetingpackkb.asp , Issue 8. Installing the .NET 4.0 update the problems don't occured anymore.