How to write a blank service binary for Windows? - windows-services

I'm trying to create a service that does absolutely nothing for testing purposes. For that I need a binary that does absolutely nothing but services don't seem to start for just any executable, only ones specifically designed to be service binaries. I've tried to find information as to how to make service binaries but can't seem to find anything. Thanks in advance.

Check out the demo service in this little nuget library:
https://github.com/wolfen351/windows-service-gui
It should give you a good starting point for making a test service to use, it is a trivial implementation of a windows service that does nothing. Also the nuget package will help you run it! :)
Here is the heart of the code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading;
namespace DemoService
{
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
Timer t1 = new Timer(AutoStopCallback, null, 15000, -1); // auto stop in 15 seconds for testing
}
private void AutoStopCallback(object state)
{
Stop();
}
protected override void OnStart(string[] args)
{
Thread.Sleep(2000);
base.OnStart(args);
}
protected override void OnStop()
{
Thread.Sleep(2000);
base.OnStop();
}
protected override void OnContinue()
{
Thread.Sleep(2000);
}
protected override void OnPause()
{
Thread.Sleep(2000);
}
}
}

Related

How to test database actions in asp.net core integration test?

I am trying to integration test my app.
for example, in my AbController I have PostAb(AbDTO abDTO) method, and I want to test that calling this method will add abDTO to db.
now my test setup:
[SetUp]
public void SetUp()
{
_server = new TestServer(new WebHostBuilder()
.UseEnvironment("testing")
.UseStartup<Startup>());
_client = _server.CreateClient();
}
and my test should look like:
[Test]
public async Task PostAbSanity()
{
await _client.PostAsync("/rest/v1/Ab", new Ab{Id=1});
_context.Abs.find(1).should().NotBeNull();
}
but, how can I inject _context into test? in my app I inject it through constructors, but in tests I cant.
thanks!
I'm assuming you are using SqlLite, so you can edit your SetUp method like this:
[SetUp]
public void SetUp()
{
_server = new TestServer(new WebHostBuilder()
.UseEnvironment("testing")
.UseStartup<Startup>());
_client = _server.CreateClient();
var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>();
optionsBuilder.UseSqlite("Filename=./blog.db");
_context = new BloggingContext(optionsBuilder.Options);
}
Please let me know if this is useful
While I will concede that integration testing with an in-memory database is the most thorough and safe way to work, my specific situation would make this aspect extremely difficult and time consuming. I am using a hosted SQL development server that I overwrite after a period of tests. I worked for several days and found the below to be the process that gave me the results I was looking for.
DotNet Core 2.1
Hexagonal (Onion) architecture needing to test the business logic written in my Data
Access Layer
Program.CS file I added:
//for integration testing
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureServices(services => services.AddAutofac())
.UseStartup<Startup>();
My Integration Test File:
using Core.Data.Entities.Model;
using Core.Data.Entities.UTIA;
using FluentAssertions;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.EntityFrameworkCore;
using Profile.Data.Repos;
using Profile.Domain.DomainObjects;
using Super2.Web;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Xunit;
namespace Profile.Test
{
public class EmployeeProfileIntegrationTest : IClassFixture<WebApplicationFactory<Startup>>
{
private readonly HttpClient _client;
public EmployeeProfileIntegrationTest(WebApplicationFactory<Startup> factory)
{
_client = factory.CreateClient();
}
private DBContext GetContext()
{
var options = new DbContextOptionsBuilder<DBContext>()
.UseSqlServer("Server = 'Connection String from appsettings'")
.Options;
var context = new DBContext(options);
return context;
}
[Fact]
public async Task TestChildProtectionEmployeeGetData()
{
//Arrange
var ApplicationUserId = XXXX;
var repo = new EmployeeProfileRepo(GetContext());
//ACT
var sut = await repo.GetChildProtectionHistory(ApplicationUserId);
//Assert
var okResult = sut.Should().BeOfType<List<DomainObject>>().Subject;
okResult.First().ApplicationUserId.Should().Be(XXXX);
}
}
}
While I am injecting my context into a different layer, I would suspect that it would work the same for a controller. I included the startup snippet as this caused me some issues as the testserver was looking for IWebHostBuilder instead of the default Core2.1 IWebHost.
Either way, this worked for me. Hope you can get some help from this.

How to detect IIS events in windows event logs and detemine its application pool according to this code?

I try to make a listener on windows event logs, but I need to recognize IIS events in it and determine its application pool.
could I do that according to this code ??? by process id for example or any thing else.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Threading;
using System.DirectoryServices;
using Microsoft.Web;
using Microsoft.Web.Administration;
namespace EventLogEnt
{
class Program
{
static AutoResetEvent signal;
static void Main(string[] args)
{
// create new log
signal = new AutoResetEvent(false);
EventLog myNewLog = new EventLog("Application", "TIS3", "Outlook");
myNewLog.EntryWritten += new EntryWrittenEventHandler(MyOnEntryWritten);
myNewLog.EnableRaisingEvents = true;
myNewLog.WriteEntry("Test message", EventLogEntryType.Information);
signal.WaitOne();
Console.ReadKey();
}
public static void MyOnEntryWritten(object source, EntryWrittenEventArgs e)
{
Console.WriteLine(e.Entry.Message);
Console.WriteLine("the entry type: " + e.Entry.EntryType);
Console.WriteLine("---------------------------------------------");
signal.Set();
}
}
}

How to add logs in asp.net vNext

I need to set up logs in my asp.net application. It's easy to add output to the console, but I need to configure it in Azure. I don't know how to do it. I need to log all information that occurs with my app into some file and read it.
The ILoggerFactory allows an app to use any implementation of ILogger and ILoggerProvider.
For details on how to implement the interfaces properly, look at the framework's ConsoleLogger and ConsoleLoggerProvider. See also the ASP.NET Core documentation on logging.
Here is a minimal example of a custom ILogger to get started. This is not production code, rather, it demos enough technical depth either to write your own ILogger or to use one from the community.
project.json
"dependencies": {
"Microsoft.AspNet.Mvc": "6.0.0-rc1-final",
"Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
"Microsoft.Extensions.Logging": "1.0.0-rc1-final",
"Microsoft.Extensions.Logging.Console": "1.0.0-rc1-final"
}
MyLoggingProvider.cs
namespace LoggingExample
{
using Microsoft.Extensions.Logging;
public class MyLoggingProvider : ILoggerProvider
{
public ILogger CreateLogger(string categoryName)
{
return new MyLogger();
}
public void Dispose()
{
// TODO Cleanup
}
}
}
MyLogger.cs
In Azure you will want to write to somewhere other than C:/temp/some-guid.txt. This is enough to get you started, though, with writing your own simple logger.
namespace LoggingExample
{
using System;
using Microsoft.Extensions.Logging;
public class MyLogger : ILogger
{
public void Log(LogLevel logLevel, int eventId, object state,
Exception exception, Func<object, Exception, string> formatter)
{
var builder = new StringBuilder();
if (formatter != null) {
builder.AppendLine(formatter(state, exception));
}
var values = state as ILogValues;
if (values != null) {
foreach (var v in values.GetValues()) {
builder.AppendLine(v.Key + ":" + v.Value);
}
}
var logPath = string.Format("C:/temp/{0}.txt", Guid.NewGuid());
File.WriteAllText(logPath, builder.ToString());
}
public bool IsEnabled(LogLevel logLevel) {
return true;
}
public IDisposable BeginScopeImpl(object state) {
return null;
}
}
}
Startup.cs
Now in startup you can use add your logger via loggerFactory.AddProvider(new MyLoggingProvider()). Every call to the ILogger will now log with your provider.
namespace LoggingExample
{
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http;
using Microsoft.Extensions.Logging;
public class Startup
{
public void Configure(
IApplicationBuilder app,
ILoggerFactory loggerFactory)
{
loggerFactory
.AddConsole(minLevel: LogLevel.Verbose)
.AddProvider(new MyLoggingProvider());
app.Run(async (context) =>
{
var logger = loggerFactory.CreateLogger("CatchAll");
logger.LogInformation("Hello logger!");
await context.Response.WriteAsync("Hello world!");
});
}
}
}
MyController.cs
Anywhere that supports dependency injection can now receive an ILogger that will log to all of the providers that we registered in the Startup.Configure method.
namespace LoggingExample
{
using Microsoft.AspNet.Mvc;
using Microsoft.Extensions.Logging;
public class MyController : Controller
{
public MyController(ILogger logger)
{
logger.LogInformation("Logging from my controller");
}
}
}
Log4Net
Use Log4Net. Its a common framework for logging that everyone who follows up on your code will understand, and it lets you do things like attach a new log "destination" on the fly just by editing your config file. It already covers most of the things you'll want to do (like create a separate file for each "day"), and most of the log mining tools out there will be able to read the files l4n creates.
Setting it Up
There are tutorials online for how to get started, but they basically require a few simple steps:
Download the Log4Net nuget package.
Adjust the log settings in your web.config file
Create a static instance of the logger object
Log Stuff wherever you need to. If you decide you want your logger to write to a file, it will. If you add a database writer, it will write to the db too. Want your log entries to show up in console, just add that logger in your default (debug) config.
Once you get it setup, logging is as simple as this code:
...
} catch(SystemException ex) {
logger.Error("This error was thrown by the XXX routine", ex);
}
Hope that's helpful.
Edit: Config File + Core
As #auga points out in his oh-so-helpful comment, config for ASP.Net 5 may require you to read carefully the link I added under step #2 above (configuring your logger). Instead of re-writing someone else's blog post, I'll just link to the article I used to set this up in our ASP.NET 5 environment. Works really well.
If you're reading this post to learn (instead of skimming it to critique), I'd suggest following the links...

EdgeJS calls in C# Web API causing AccessViolation Exception

using System.Threading.Tasks;
using System.Web.Http;
using EdgeJs;
namespace edge2.Controllers
{
public class ValuesController : ApiController
{
public async Task<object> Get(int id)
{
var func = Edge.Func(#"
return function (data, callback) {
callback(null, 'Node.js welcomes ' + data);
}
");
return await func(".NET");
}
}
}
I'm looking at trying to call node.js from C#. I have the above example code that is documented on their GitHub page, but when the code is moved over to a C# Web API project I get a consistent error.
AccessViolation Exception. The error only happens on the first run, and only after a rebuild of the project. All subsequent runs work perfectly.
Tooling:
VS2015
.NET 4.5.2
EdgeJS 4.0.0

How to use .cs Class DataFunctions Inside MVC Controller Classes

I have an asp.net web application, now i am trying to convert it to ASP.NET MVC. The problem is my old project has some .cs classes i, Example one class that handle all user data operations , one handle database operations , one will handle some priority properties like... I had included those classes in mvc Project , i had created a new Folder named Project_Class and copy all of my classes to it, my problem is how to access these classes in mvc controller class, how can i call a function of this class in mvc controller class.
I had include a sample .cs class structure below
**class1.cs**
using System;
using System.Collections;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.Text;
using System.Data.SqlClient;
using System.Xml;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
namespace xyz.abc
{
public class AssignValues:SSS
{
Process Objdb;
SqlCommand sqlcom;
SqlConnection sqlcon;
private int _EId;
private int _CId;
XmlDocument PXML, OutputXML;
XmlElement Root, ParameterElement, InputParamIdNode, OperatorIdNode, OutputParamIdNode, OutputParamValueNode, ConditionStatusNode, ModeNode, InputTypeNode, OutputTypeNode, InputRegisterIdNode, InputRegisterHeaderIdNode, OutputRegisterIdNode, OutputRegisterHeaderIdNode, UIdNode, orderNode;
public int iCount = 0;
public int EId
{
set
{
_EId = value;
}
get
{
return _EId;
}
}
public int CId
{
set
{
_CId = value;
}
get
{
return _CId;
}
}
public AssignValues()
{
}
public AssignValues(SqlCommand SqlComm,SqlConnection SqlConn)
{
Objdb = new Process();
sqlcom=SqlComm;
sqlcon = SqlConn;
}
public string check()
{
string x="hai";
return x
}
}
}
my Controller class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using XYZ.ABC.Controllers;
using XYZ.ABC;
namespace XYZ.ABC.Controllers
{
public class XYZ_Controller :Controller
{
public ActionResult XYZ_Checklist()
{
return View();
}
}
}
i want to call "public string check()" method in my controller class,is it possible? ,i am newbie in mvc, please help me to solve this.
You can simply call that in your MVC controller class
Follow the steps
1) Include the namespace of the class in MVC controller class
2) Inherit old class in Your MVC Controller
Public Class MVCCOntrollerclassname: Class1
3) Create object of the .cs class
like
class1 c=new class1();
4) Create a constructor of MVC controller class
like
MVCCOntrollerclassname()
{
c.methodname();
}
Note : You say you are migrating asp.net to MVC , so if you have any asp.net dll then must change it as MVC Compitable dll
The MVC Framework just instantiates your Controller class and invokes an action method using some defined configuration or convention. So with that in mind ask yourself the question how would I invoke this method if you instantiated the controller yourself and called XYZ_Checklist().
The answer may look something like this:
public ActionResult XYZ_Checklist()
{
var assignValues = new AssignValues();
var result = assignValues.check();
// Do something here with the result ...
return View();
}
That's the short and simple answer. Once you start to understand that the framework isn't magic and is simply calling your code, you can start to delve into better ways to arrange your code (IoC/DI, etc.).
Hope this helps!

Resources