I have the following code which works fine when I use it within a Windows Forms application, however the application I'm writing needs to run as a Windows service, and when I moved my code into the Windows Service template in Visual Studio 2015 Community Edition, I get the following error.
Cannot implicitly convert type "MyWindowsService.Main" to "System.ComponentModel.ISynchronizeVoke". An explicit conversion exists (are you missing a cast?)
Could anyone shed some light on why I am getting this error, and what I need to do to resolve it?
The code which throws the error is the line below, and it is located within the OnStart method of my main class (named Main.cs). The code is used to create an instance of the DataSubscriber class (AdvancedHMI library).
dataSubscribers[dataSubscriberIndex].SynchronizingObject = this;
It has to have something to do with the fact that the code is in a Windows service template, because using this works perfectly in my forms application running the same code.
UPDATE
Correction, I've attempted to cast this to the required type, and now get the following error on run.
Additional information: Unable to cast object of type 'MyWindowsService.Main' to type 'System.ComponentModel.ISynchronizeInvoke'.
Code:
dataSubscribers[dataSubscriberIndex].SynchronizingObject = (System.ComponentModel.ISynchronizeInvoke)this;
UPDATE
I've included the entire contents of the Main.cs file from my Windows Service application.
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using MySql.Data.MySqlClient;
using AdvancedHMIDrivers;
using AdvancedHMIControls;
using MfgControl.AdvancedHMI.Drivers;
using MfgControl.AdvancedHMI.Controls;
using System.Collections.ObjectModel;
namespace PLCHistoricDataHarvester {
public partial class Main : ServiceBase {
private EthernetIPforCLXCom commObject = new EthernetIPforCLXCom();
private globals globals = new globals();
private Dictionary<String, String> operationLines = new Dictionary<String, String>();
private Dictionary<String, String> tags = new Dictionary<String, String>();
private Collection<DataSubscriber> dataSubscribers = new Collection<DataSubscriber>();
private int harvesterQueueCount = 0;
private string harvesterInsertValues = String.Empty;
public Main() {
InitializeComponent();
}
protected override void OnStart(string[] args) {
// Initialize our harvester program
initializeHarvester();
Console.WriteLine("The program has started");
}
protected override void OnStop() {
// Call code when the service is stopped
Console.WriteLine("Program has stopped");
Console.ReadLine();
}
public void initializeHarvester() {
// First, we connect to the database using our global connection object
globals.dbConn.DatabaseName = "operations";
if (!globals.dbConn.IsConnect()) {
// TODO: Unable to connect to database. What do we do?
}
// Second, we connect to the database and pull data from the settings table
globals.initializeSettingsMain();
// Set IP address of PLC
commObject.IPAddress = globals.getSettingsMain("Processor_IP");
// Pull distinct count of our parent tags (Machines ex: Line 1, etc)
operationLines = globals.getOperationLines();
// If we have at least 1 operation line defined...we continue
if (operationLines.Keys.Count > 0) {
//Now we loop over the operation lines, and pull back the data points
int dataSubscriberIndex = 0;
foreach (KeyValuePair<String, String> lines in operationLines) {
int line_id = int.Parse(lines.Key);
string name = lines.Value;
tags = globals.getTags(line_id);
// If we have at least 1 tag for this operation line, we continue...
if (tags.Keys.Count > 0 && tags["tags"].ToString().IndexOf(",") != -1) {
// Create our dataSubscriber object
dataSubscribers.Add(new DataSubscriber());
dataSubscribers[dataSubscriberIndex].SynchronizingObject = (ISynchronizeInvoke)this;
dataSubscribers[dataSubscriberIndex].CommComponent = commObject;
dataSubscribers[dataSubscriberIndex].PollRate = 1000;
dataSubscribers[dataSubscriberIndex].PLCAddressValue = tags["tags"];
dataSubscribers[dataSubscriberIndex].DataChanged += new EventHandler<MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs>(subscribeCallback);
// Increment our dataSubscriberIndex
dataSubscriberIndex++;
}
}
}
}
private void subscribeCallback(object sender, MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs e) {
// code removed as it is irrelevant
}
}
}
The error message says this:
An explicit conversion exists (are you missing a cast?)
So add a cast like this:
dataSubscribers[dataSubscriberIndex].SynchronizingObject = (ISynchronizeInvoke)this;
^^^^^^^^^^^^^^^^^^^^
//Add this
If you've got a console app, the easiest way to convert it to a windows service is by using Topshelf, a nuget package which lets you run in either console mode or nt service mode.
Here's the quickstart guide.
We use it to write services all the time and it helps you avoid this kind of fragile shenanigans.
Related
I'm trying to make a web browser application, but when I relaunch Visual Studio Community 2019, it shows me about 500 errors such as The type or namespace name 'System' could not be found (are you missing a using directive or an assembly reference?).
I tried reloading Visual Studio Community 2019 a few times, but still doesn't work either.
Some project infos:
Target framework: .NET Framework 4.8
NuGet Packages used: EasyTabs, CefSharp.WinForm
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;
using CefSharp;
using CefSharp.WinForms;
using EasyTabs;
Just before I post the question, I found out that you need to use .NET Framework 4.7.2 in order to fix the problem.
So you're using easy tabs, I have the code for you. create new windows form project, in the project create another form and rename it AppContainer with the caps and everything, then open the app container with framework 4.7.2 then type in C# code
namespace YOUR_PROGRAM_NAME_HERE
{
public partial class AppContainer : TitleBarTabs
{
public AppContainer()
{
InitializeComponent();
AeroPeekEnabled = true;
TabRenderer = new ChromeTabRenderer(this);
}
// Handle the method CreateTab that allows the user to create a new Tab
// on your app when clicking
public override TitleBarTab CreateTab()
{
return new TitleBarTab(this)
{
// The content will be an instance of another Form
// In our example, we will create a new instance of the Form1
Content = new Form1
{
Text = "New Tab"
}
};
}
// The rest of the events in your app here if you need to .....
}
}
also at the top of where it says using please type using EasyTabs and then type using CefSharp. basically every package code you use you need to refer to that package then add a subtitle for Browser. Next Open Form1.cs and type this Code.
// 2. Important: Declare ParentTabs
protected TitleBarTabs ParentTabs
{
get
{
return (ParentForm as TitleBarTabs);
}
}
type this where the namespace of your code is For example.
namespace YOUR_PROGRAM_NAME_HERE
{
public partial class Form1 : Form
{
// 2. Important: Declare ParentTabs
protected TitleBarTabs ParentTabs
{
get
{
return (ParentForm as TitleBarTabs);
}
}
public object HTMLcodeec { get; }
public Form1()
{
InitializeComponent();
}
now co into the program.cs file in your solution explorer and click on it one you do you need to type the following code
namespace YOUR_PROGRAM_NAME_HERE
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
AppContainer container = new AppContainer();
// Add the initial Tab
container.Tabs.Add(
// Our First Tab created by default in the Application will have as
content the Form1
new TitleBarTab(container)
{
Content = new Form1
{
Text = "New Tab"
}
}
);
// Set initial tab the first one
container.SelectedTabIndex = 0;
// Create tabs and start application
TitleBarTabsApplicationContext applicationContext = new
TitleBarTabsApplicationContext();
applicationContext.Start(container);
Application.Run(applicationContext);
}
}
}
Now open Form1.cs and go to Form1. Load Event and at the top of it type
ChromiumWebBrowser Browser;
private void Form1_Load(object sender, EventArgs e)
{
CefSettings settings = new CefSettings();
//Initialize
CefSharpSettings.LegacyJavascriptBindingEnabled = true; // Enable Register JS Object, -- RegisterAsyncJsObject, RegisterJsObject allow
settings.CachePath = "cache";
settings.CefCommandLineArgs.Add("enable-media-stream", "1"); //Enable WebRTC4
settings.CefCommandLineArgs.Add("disable-gpu", "1");
settings.CefCommandLineArgs.Add("disable-gpu-compositing", "1");
BrowserSettings browserSettings = new BrowserSettings
{
FileAccessFromFileUrls = CefState.Enabled,
UniversalAccessFromFileUrls = CefState.Enabled,
WebSecurity = CefState.Enabled,
WebGl = CefState.Enabled,
BackgroundColor = (uint)CefState.Enabled,
};
Browser = new ChromiumWebBrowser(AddressText.Text);
this.pContainer.Controls.Add(Browser);
Browser.DownloadHandler = new DownloadHandler();
Browser.Dock = DockStyle.Fill;
Browser.Load("https://ask.com/");
this.AcceptButton = this.NavigateToURL;
Browser.AddressChanged += Browser_AddressChanged;
Browser.TitleChanged += Browser_TitleChanged;
}
before you don any of this please download cefsharp and easy tabs to your project
if you want to see my Browser project I build Go to https://cleverdamontoutube.wixsite.com/downloaddamonic and you can see what iv done
it is a .exe file you can download "if you need any more help subscrie to my youtube channel because ill be making a video on this topic shorrtly"
I have already create some customization in screen Payment and Application of Acumatica ERP. I have created new Extension of ARPaymentEntryExtension.cs
The following is the source code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
using PX.Data;
using PX.Objects.AR;
using PX.Objects.GL;
namespace SGLCustomizeProject
{
public class ARPaymentEntryExtension: PXGraphExtension<ARPaymentEntry>
{
#region Override Button Menu
public override void Initialize()
{
Base.report.AddMenuAction(ReceiptVoucher);
}
#endregion
#region Button Receipt Vocher
public PXAction<ARPayment> ReceiptVoucher;
[PXButton]
[PXUIField(DisplayName = "Receipt Voucher")]
public IEnumerable receiptVoucher(PXAdapter adapter)
{
var result = adapter.Get<ARPayment>();
foreach (ARPayment doc in result)
{
object FinPeriodID;
if (Base.Caches[typeof(ARPayment)].GetStatus(doc) == PXEntryStatus.Notchanged)
{
Base.Caches[typeof(ARPayment)].SetStatus(doc, PXEntryStatus.Updated);
}
Base.Save.Press();
var docPeriod = (FinPeriodID = Base.Caches[typeof(ARPayment)].GetValueExt<ARRegister.finPeriodID>(doc)) is PXFieldState ? (string)((PXFieldState)FinPeriodID).Value : (string)FinPeriodID;
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters["ReferenceNbr"] = doc.RefNbr;
throw new PXReportRequiredException(parameters, "AR909095", "Report");
}
return result;
}
#endregion
}
}
I used extensoin above to preview report from current screen and it works.
When user need to create new document and then add some detail document and then click on save button, it will work.
But, when user need to add another detail document and then click on save button, system will show the error message.
Please refer to the following screenshot.
Actually the error message appear after Acumatica was upgraded into version 2017 R2 - Build 17.207.0029.
In previous version (Version 5.3 - Build 5.30.4209) it work fine.
Does anyone know how to solve this issue ?
I have solve this problem by remove the following If Condition of the code:
if (Base.Caches[typeof(ARPayment)].GetStatus(doc) == PXEntryStatus.Notchanged)
{
Base.Caches[typeof(ARPayment)].SetStatus(doc, PXEntryStatus.Updated);
}
After remove code above, the customization is work and no error.
I am trying to implement routing funcationality in MS SQL Server 2012 using the prospatial tutorial, I created a C# class and successfully build DLL file.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SqlServer.Server;
using Microsoft.SqlServer.Types;
namespace ProSQLSpatial.Ch14
{
public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlGeometry GeometryTSP(SqlGeometry PlacesToVisit)
{
// Convert the supplied MultiPoint instance into a List<> of SqlGeometry points
List<SqlGeometry> RemainingCities = new List<SqlGeometry>();
// Loop and add each point to the list
for (int i = 1; i <= PlacesToVisit.STNumGeometries(); i++)
{
RemainingCities.Add(PlacesToVisit.STGeometryN(i));
}
// Start the tour from the first city
SqlGeometry CurrentCity = RemainingCities[0];
// Begin the geometry
SqlGeometryBuilder Builder = new SqlGeometryBuilder();
Builder.SetSrid((int)PlacesToVisit.STSrid);
Builder.BeginGeometry(OpenGisGeometryType.LineString);
// Begin the LineString with the first point
Builder.BeginFigure((double)CurrentCity.STX, (double)CurrentCity.STY);
// We don't need to visit this city again
RemainingCities.Remove(CurrentCity);
// While there are still unvisited cities
while (RemainingCities.Count > 0)
{
RemainingCities.Sort(delegate(SqlGeometry p1, SqlGeometry p2)
{ return p1.STDistance(CurrentCity).CompareTo(p2.STDistance(CurrentCity)); });
// Move to the closest destination
CurrentCity = RemainingCities[0];
// Add this city to the tour route
Builder.AddLine((double)CurrentCity.STX, (double)CurrentCity.STY);
// Update the list of remaining cities
RemainingCities.Remove(CurrentCity);
}
// End the geometry
Builder.EndFigure();
Builder.EndGeometry();
// Return the constructed geometry
return Builder.ConstructedGeometry;
}
};
}
I also enabled CLR and when I try to create a assembly using the above created DLL:
CREATE ASSEMBLY GeometryTSP
FROM 'D:\Routing\my example\GeometryTSP\GeometryTSP\bin\Debug\GeometryTSP.dll'
WITH PERMISSION_SET = EXTERNAL_ACCESS;
GO
I'm getting "Failed to create AppDomain" error like this:
Msg 6517, Level 16, State 1, Line 2
Failed to create AppDomain "master.dbo[ddl].12".
Exception has been thrown by the target of an invocation.
What should be the reason?
try remove the neamespace section
namespace ProSQLSpatial.Ch14
{
}
sql server use default namespace
After Some research i found the solution,
its the problem with a system restart after .NET framework installation
I tring to test a new dll that I've build for c#
private void button1_Click(object sender, EventArgs e)
{
String [] first = UserQuery.Get_All_Users();
//MessageBox.Show(first);
}
but I get the following error at String [] first = UserQuery.Get_All_Users();
An unhandled exception of type 'System.NullReferenceException' occurred in User_Query.dll
Additional information: Object reference not set to an instance of an object.
I been tring to figure this one out for hours but can't find any null varibles
I post my dll in case the dll is wrong
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.DirectoryServices;
namespace User_Query
{
public class UserQuery
{
public static string[] Get_All_Users()
{
string[] names = new string[10];
var path = string.Format("WinNT://{0},computer", Environment.MachineName);
using (var computerEntry = new DirectoryEntry(path))
{
var userNames = from DirectoryEntry childEntry in computerEntry.Children
where childEntry.SchemaClassName == "User"
select childEntry.Name;
byte i = 0;
foreach (var name in userNames)
{
Console.WriteLine(name);
names[i] = name;
i++;
}
return names;
}
}
}
}
There is a problem with your. path variable... since there should be \\ instead of //
The problem here turned out not to be the code but be VS2010 not loading the dll. This happen because I decided to change the program from using the dll from the debug to the release version but I did not clean the project after doing it and therefore the program was not correctly loading the dll. All that need to be done was clean the project
I have a db4o database that was generate by a Java app and I'm trying to read it using a C# app.
However, when running the following line of code:
IObjectContainer db = Db4oEmbedded.OpenFile(#"..\..\..\Databases\people.db4o");
I get the following error:
Unable to cast object of type
'Db4objects.Db4o.Reflect.Generic.GenericObject' to type
'Db4objects.Db4o.Ext.Db4oDatabase'.
Any ideas? I know there are person objects that contain personId fields (along with others) in the DB. I'm using db4o version 8. I'm not sure what version was used to generate the database.
The entire program is:
using System;
using System.Collections.Generic;
using System.Linq;
using Db4objects.Db4o;
using Db4objects.Db4o.Config;
using MyCompany.Domain;
namespace MyCompany.Anonymizer
{
internal class Program
{
// Private methods.
private static IEmbeddedConfiguration ConfigureAlias()
{
IEmbeddedConfiguration configuration = Db4oEmbedded.NewConfiguration();
configuration.Common.AddAlias(new TypeAlias("com.theircompany.Person", "MyCompany.Domain.Person, MyCompany.Domain"));
configuration.Common.Add(new JavaSupport());
return configuration;
}
private static void Main(string[] args)
{
IObjectContainer db = Db4oEmbedded.OpenFile(#"..\..\..\Databases\people.db4o");
try
{
IList<Person> result = db.Query<Person>();
for (int i = 0; i < result.Count; i++)
{
Person person = result[i];
Console.WriteLine(string.Format("Person ID: {0}", person.personId));
}
}
finally
{
db.Close();
}
}
}
}
The most common scenario in which this exception is thrown is when db4o fails to resolve the type of a stored object.
In your case, db4o is failing to read one of its internal objects which makes me believe you have not passed the configuration to the OpenFile() method (surely, the code you have posted is not calling ConfigureAlias() method);
Keep in mind that as of version 8.0 no further improvement will be done regarding cross platform support (you can read more details here).