IDE: VS 2010, Windows service .net 4.0
I created a simple windows service, and tested this service with this code:
protected override void OnStart(string[] args)
{
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"F:\22Yardz_Pro\" + "error.txt", true))
{
file.WriteLine("Service is working \n");
}
//ReceiveMsmqMessage();
}
here in installer I have set
serviceProcessInstaller1. Account = Local System
Then I have changed my code to
** protected override void OnStart(string[] args)
{
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"F:\MyProj\" + "error.txt", true))
{
file.WriteLine("Service is working \n");
}
ReceiveMsmqMessage();
}
private static void ReceiveMsmqMessage()
{
//string MsmqPath = System.Configuration.ConfigurationManager.AppSettings["MsmqPath"];
MessageQueue queue = new MessageQueue(#".\Private$\MyProjQ");
System.Messaging.Message myMessage = queue.Receive();
myMessage.Formatter = new XmlMessageFormatter(new String[] { "System.String,mscorlib" });
string message = (myMessage.Body.ToString());
string labelName = myMessage.Label;
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"F:\MyProj\" + "error.txt", true))
{
file.WriteLine("Service started " + message + " \n");
}
}**
Can you tell me why my msmq code is not working, I have tested sapratly this code in working fine in winForms project also this is working in debugging mode but When I install service using cmd and after going in services.msc, when I start this service I am getting error
The _MsmqTesting service on local computer has started and then stopped. Some services stop automatically if there are not in use by other services or programs
Can you suggest me what mistake I am doing??
Finally It worked, I put my code in Try catch block, and In catch block I have written the exception message in txt File, So got to know that my queue was not accessible for Local or system user, so I changed my queue accessibility and it worked.
Related
We have orders that come in from a third party encoded UTF-16 LE. Our ERP can only read UTF-8 encoding. So I've created the .NET Core console app that watches the directories the orders arrive in and writes them to where the ERP grabs the files. How do I let this run on our Windows Server 2016? Should I scrap it and write it as a Windows Service?
using System;
using System.IO;
public class RewriteUsingUTF8
{
public static void Main()
{
string ordrstkPath = #"\\Rep-app\sftp_root\supplypro\ordrstk";
string conrstkPath = #"\\Rep-app\sftp_root\supplypro\Conrstk";
Watch(ordrstkPath);
Watch(conrstkPath);
Console.ReadLine();
}
private static void Watch(string path)
{
//initialize
FileSystemWatcher watcher = new FileSystemWatcher();
//assign parameter path
watcher.Path = path;
//create event
watcher.Created += FileSystemWatcher_Created;
watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.Size | NotifyFilters.Attributes;
//only look for csv
watcher.Filter = "*.csv";
// Begin watching.
watcher.EnableRaisingEvents = true;
}
// method when event is triggered (file is created)
private static void FileSystemWatcher_Created(object sender, FileSystemEventArgs e)
{
ReadWriteStream(e.FullPath, e.Name);
}
private static void ReadWriteStream(string path, string fileName)
{
FileStream originalFileStream = new FileStream(path, FileMode.Open, FileAccess.Read);
//destination path by replacing SFTP user directory
string destinationPath = path.Replace(#"\supplypro\", #"\ftpuser\");
FileStream destinationFileStream = new FileStream(destinationPath, FileMode.Create, FileAccess.Write);
StreamReader streamReader = new StreamReader(originalFileStream);
StreamWriter streamWriter = new StreamWriter(destinationFileStream);
string currentLine;
try
{
currentLine = streamReader.ReadLine();
while (currentLine != null)
{
streamWriter.WriteLine(currentLine);
currentLine = streamReader.ReadLine();
}
//archive path
string archivePath = path.Replace(fileName, #"\archive\" + fileName);
//move to archive path
File.Move(path, archivePath);
}
catch (Exception e)
{
//error path
string errorPath = path.Replace(fileName, #"\error\" + fileName);
//move to error path
File.Move(path, errorPath);
//need to write code for error to write to event viewer
Console.WriteLine("Exception: " + e.Message);
}
finally
{
//dispose resources
streamReader.Close();
streamWriter.Close();
originalFileStream.Close();
destinationFileStream.Close();
}
}
}
I have looked at a few similar posts, but am unsure what direction I should take. Any direction would be greatly appreciated!
Sounds like we're working in very similar environments. We started off using console apps for our ERP integrations. Their main drawbacks are that they run on a user's desktop, so you have to RDP in as that user to manage them, and they don't restart automatically if the server reboots. I've been converting them all to Windows services. .NET Core makes it fairly easy.
Tim Corey has an excellent video about how to write Windows services in .NET Core 3. He talks about deleting and recreating the service when deploying a new version, but I haven't found that to be necessary. Just RDP in, stop the service so none of the files are in use, deploy, and start it again. It's not as simple as redeploying a .NET Core web app, which manages all the stopping and restarting for you, but it's not too bad.
A crucial thing to know is that exceptions absolutely must not propagate out of Worker.ExecuteAsync. They will not be handled anywhere, and Windows will show your service as running when it's not. Whatever you do in ExecuteAsync, do it in a loop that catches all exceptions and keeps running.
File watchers are deceptively complicated. Make sure you're listening for error events. For example, if you're watching a network share and it becomes unavailable, the FileSystemWatcher will emit an error and will not resume working when the share comes back online. I haven't figured out the best way to handle errors, though. I think making it reliable requires replacing the FileSystemWatcher after any error.
My work environment is:
Windows 7 Professional
Visual Studio 2019, ASP.NET MVC, Entity Framework
SQL Server Express
IIS Version 7.5 (installed locally)
When I debug in Visual Studio, the directory/file is created without problem inside this path ~/Content/Documentacion/log/ (using IIS Express that comes with VS).
But when I publish the solution and run it using IIS 7.5, the directory/file is not created, I cannot understand the problem.
This is the code:
public void CreaLogATiempos(DateTime fin, bool sobrescribir = false)
{
try
{
text = "xxxxx= ";
string docPath = "~/Content/Documentacion/log/" ;
var folder = System.Web.HttpContext.Current.Server.MapPath(docPath );
if (!Directory.Exists(folder))
{
Directory.CreateDirectory(folder);
}
FileInfo MyFile = new FileInfo(System.Web.HttpContext.Current.Server.MapPath(docPath + this.archivo));
if (!MyFile.Exists)
{
StreamWriter crear = new StreamWriter(System.Web.HttpContext.Current.Server.MapPath(docPath + this.archivo));
crear.WriteLine(text);
crear.Close();
}
else
{
StreamWriter crear = new StreamWriter(System.Web.HttpContext.Current.Server.MapPath(docPath + this.archivo), true);
crear.WriteLine(text);
crear.Close();
}
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.Message);
}
}
Maybe someone can see the error or has an idea about the problem?
Can I introduce you to TextWriterTraceListener? Add this to your Global.vb file:
'adding tracing to a log.
Trace.Listeners.Clear()
Dim stream As New IO.FileStream(Server.MapPath("~/App_Data/trace.log"), IO.FileMode.Append)
Dim writer As New IO.StreamWriter(stream, System.Text.Encoding.UTF8)
Dim logListener As New TextWriterTraceListener(writer, "trace.log")
Trace.Listeners.Add(logListener)
Trace.AutoFlush = True
Trace.WriteLine($"{DateTime.Now.ToString} - class: Global.asax - method: Application_Start - message: Trace listener loaded.")
Create a trace.log file inside "~/App_Data"
Select the project in visual studio and press ALT + Enter to open the settings property of that project as following picture
Picture
You can use this folder in your controller as following way
var physicalPath = Server.MapPath(Settings.Default.CompanyImagePath);
I've been trying to create an updater app for my .NET application that gets called when an update is detected using a text file that includes the version info. I've created the said updater but it has some problems. When the file is downloaded, it seems like the anti virus software corrupts the file and it can't be opened. Sometimes the updater doesn't run at all and throws an exception ("The underlying connection was closed: The connection was closed unexpectedly.") which seems to also be caused by the local anti virus software. I figured maybe I could download the file in binary format and create the executable locally, but I am not completely sure on how I would do that (or if it would even work). I am still very much a beginner in a lot of areas. So my question is.. how can I efficiently download an update for my application without triggering the anti- virus?
My code:
public Updater()
{
InitializeComponent();
DownloadInfo.RemoteURI = "http://mywebserver.com/Application.exe";
DownloadInfo.NewExecutableName = "update.exe";
DownloadInfo.ExecutableName = "Application.exe";
DownloadInfo.LocDest = AppDomain.CurrentDomain.BaseDirectory;
InvokeUpdate();
}
private void InvokeUpdate()
{
Thread thr = new Thread(() => GetUpdate());
thr.Start();
}
private void GetUpdate()
{
Process[] proc = Process.GetProcessesByName("Application");
if (proc.Length != 0)
proc[0].Kill();
Util.DownloadFile(new Uri(DownloadInfo.RemoteURI), DownloadInfo.LocDest + DownloadInfo.NewExecutableName);
if (File.Exists(DownloadInfo.LocDest + DownloadInfo.ExecutableName))
File.Replace(DownloadInfo.LocDest + DownloadInfo.NewExecutableName, DownloadInfo.LocDest + DownloadInfo.ExecutableName, DownloadInfo.LocDest + "backup.exe");
else
File.Move(DownloadInfo.LocDest + DownloadInfo.NewExecutableName, DownloadInfo.LocDest + DownloadInfo.ExecutableName);
try
{
File.Delete(DownloadInfo.LocDest + "backup.exe");
}
catch { }
try
{
Process.Start(DownloadInfo.LocDest + DownloadInfo.ExecutableName);
}
catch { };
Invoke((MethodInvoker)(() => this.Close()));
}
And my DownloadFile method from my util class..
public static void DownloadFile(Uri remoteURI, string localDest)
{
try
{
using (WebClient webclient = new WebClient())
{
webclient.DownloadFile(remoteURI, localDest);
}
}
catch { }
}
Here the code is
protected override void OnStart(string[] args)
{
Thread thr = new Thread(new ThreadStart(run));
thr.Start();
}
static void run()
{
while (true)
{
StreamWriter str = new StreamWriter("D:\\Sarojini.txt", true);
str.WriteLine();
str.WriteLine("**** List of Apllication*********");
str.WriteLine();
str.WriteLine("Service started on:" + DateTime.Now.ToString());
string userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name.ToString();
str.WriteLine();
str.WriteLine("the current user is " + userName);
Process[] processlist = Process.GetProcesses();
foreach (Process process in processlist)
{
if (!String.IsNullOrEmpty(process.MainWindowTitle))
{
str.WriteLine("Process::{0} ID::{1} Title::{2}", process.ProcessName, process.Id, process.MainWindowTitle);
}
}
str.Close();
Thread.Sleep(3600000 / 10);
}
}
protected override void OnStop()
{
StreamWriter str = new StreamWriter("D:\\Sarojini.txt", true);
str.WriteLine();
str.WriteLine("the service has been stopped.");
}
here in this code , a text file is created and first line is written on it but the list of running application is not there , where as when i used this code in in windowsFormApllication it is running perfectly. i dont know what is the problem .
This is most likely due to the account you are running the service under not having the correct permissions to use the Process class. When trying to retrieve process names, IDs etc your application needs to have sufficient rights and the default Local System Account is unlikely to meet this.
When you run this code as a Windows Form Application WindowsIdentity.GetCurrent() will return the user who is currently signed in.
When you run this code as a Windows Service WindowsIdentity.GetCurrent() will return the user who setup under the User Account in the Service Setting.
This will show that they are running with different credentials. So, your service may be running under an account that does not have permission to perform the required actions.
To check this:
Go into Services and double-click your service.
Click on The Log On tab
By default Local System Account is checked but you want to select This Account and set a valid account.
For implementing my websocket server in C# I'm using Alchemy framework. I'm stuck with this issue. In the method OnReceive when I try to deserialize json object, I get a FormatException:
"Incorrect format of the input string." (maybe it's different in english, but I'm getting a localized exception message and that's my translation :P). What is odd about this is that when I print out the context.DataFrame I get: 111872281.1341000479.1335108793.1335108793.1335108793.1; __ad which is a substring of the cookies sent by the browser: __gutp=entrystamp%3D1288455757%7Csid%3D65a51a83cbf86945d0fd994e15eb94f9%7Cstamp%3D1288456520%7Contime%3D155; __utma=111872281.1341000479.1335108793.1335108793.1335108793.1; __adtaily_ui=cupIiq90q9.
JS code:
// I'm really not doing anything more than this
var ws = new WebSocket("ws://localhost:8080");
C# code:
static void Main(string[] args) {
int port = 8080;
WebSocketServer wsServer = new WebSocketServer(port, IPAddress.Any) {
OnReceive = OnReceive,
OnSend = OnSend,
OnConnect = OnConnect,
OnConnected = OnConnected,
OnDisconnect = OnDisconnect,
TimeOut = new TimeSpan(0, 5, 0)
};
wsServer.Start();
Console.WriteLine("Server started listening on port: " + port + "...");
string command = string.Empty;
while (command != "exit") {
command = Console.ReadLine();
}
Console.WriteLine("Server stopped listening on port: " + port + "...");
wsServer.Stop();
Console.WriteLine("Server exits...");
}
public static void OnReceive(UserContext context) {
string json = "";
dynamic obj;
try {
json = context.DataFrame.ToString();
Console.WriteLine(json);
obj = JsonConvert.DeserializeObject(json);
} catch (Exception e) {
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
return;
}
}
On the C# side I'm using Newtonsoft.Json, though it's not a problem with this library...
EDIT:
One more thing - I browsed through the code in here: https://github.com/Olivine-Labs/Alchemy-Websockets-Example and found nothing - I mean, I'm doing everything the same way authors did in this tutorial...
EDIT:
I was testing the above code in Firefox v 17.0.1, and it didn't work, so I tested it under google chrome, and it works. So let me rephrase the question - what changes can be made in js, so that firefox would not send aforementioned string?
I ran into the same issue - simply replacing
var ws = new WebSocket("ws://localhost:8080");
with
var ws = new WebSocket("ws://127.0.0.1:8080");
fixed the issue for me.
In C# console app I connect the client to the server using :
var aClient = new WebSocketClient(#"ws://127.0.0.1:81/beef");
Your code above is connecting using
var ws = new WebSocket("ws://localhost:8080");
There could be one of two issues -
First is to see if WebSocketClient works instead.
To make sure your url is of the format ws://ur:port/context. This threw me off for a while.