use hangfire as windows service by topshelf (.net core 2.2) - c#

I am trying to use hangfire as windows service by using Topshelf in console app .net core 2.2 . I just want to load hangfire dashboard, not adding any job or anything else.
Program.cs
using System;
using Topshelf;
namespace HangfireAsService
{
class Program
{
static void Main(string[] args)
{
HostFactory.Run(config =>
{
config.Service<Bootstrap>(service =>
{
service.ConstructUsing(s => new Bootstrap());
service.WhenStarted(s => s.Start());
service.WhenStopped(s => s.Stop());
});
config.RunAsLocalSystem();
config.SetDescription("Hangfire as windows Service for DataCrawling Project");
config.SetDisplayName("Hangfire Service Custom");
});
}
}
}
Bootstrap.cs
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Owin.Hosting;
namespace HangfireAsService
{
public class Bootstrap
{
private IDisposable _host;
public void Start()
{
var options = new StartOptions { Port = 8999 };
_host = WebApp.Start<Startup>(options);
Console.WriteLine();
Console.WriteLine("Hangfire has started");
Console.WriteLine("Dashboard is available at http://localhost:8999/hangfire");
Console.WriteLine();
}
public void Stop()
{
_host.Dispose();
}
}
}
Startup.cs
using Hangfire;
using Microsoft.AspNetCore.Builder;
using Owin;
using System;
using System.Collections.Generic;
using System.Text;
namespace HangfireAsService
{
public class Startup
{
public void Configuration(IApplicationBuilder appBuilder)
{
GlobalConfiguration.Configuration
.UseSqlServerStorage("Server=111.111.11.1\\INS2017; Database=Hangfire; user=sa;
password=;");
appBuilder.UseHangfireDashboard();
appBuilder.UseHangfireServer();
}
}
}
As you can see, I created 2 classes for my self-host owin and after reviewing the event viewer I got the error displayed below:
The description for Event ID 0 from source HangfireAsService cannot be
found. Either the component that raises this event is not installed on
your local computer or the installation is corrupted. You can install
or repair the component on the local computer.
If the event originated on another computer, the display information
had to be saved with the event.
The following information was included with the event:
Service cannot be started. System.NullReferenceException: Object
reference not set to an instance of an object. at
Microsoft.Owin.Hosting.Utilities.SettingsLoader.FromConfigImplementation..ctor()
at
Microsoft.Owin.Hosting.Utilities.SettingsLoader.<>c.b__1_0()
at System.Threading.LazyInitializer.EnsureInitializedCore[T](T&
target, Func1 valueFactory) at
Microsoft.Owin.Hosting.Utilities.SettingsLoader.LoadFromConfig(IDictionary2
settings) at
Microsoft.Owin.Hosting.Engine.StartContext..ctor(StartOptions options)
at
Microsoft.Owin.Hosting.Starter.DirectHostingStarter.Start(StartOptions
options) at
Microsoft.Owin.Hosting.Starter.HostingStarter.Start(StartOptions
options) at HangfireAsService.Bootstrap.Start() in
C:\MyWorkSpace\Data
Crawling\dataCrawlingConsole\HangfireAsService\Bootstrap.cs:line 17
at HangfireAsService.Program.<>c.b__0_3(Bootstrap s) in
C:\MyWorkSpace\Data
Crawling\dataCrawlingConsole\HangfireAsService\Program.cs:line 15
at
Topshelf.ServiceConfiguratorExtensions.<>c__DisplayClass2_01.<WhenStarted>b__0(T
service, HostControl control) at
Topshelf.Builders.DelegateServiceBuilder1.DelegateServiceHandle.Start(HostControl
hostControl) at
Topshelf.Runtime.Windows.WindowsServiceHost.OnStart(String[] args)
at System.ServiceProcess.ServiceBase.ServiceQueuedMainCallback(Object
state)
The message resource is present, but the message was not found in the message table.

i used same code inside .net framework instead of .net core and work perfectly.after a test something else i notice this problem because of OWIN happened so after i removed it and use using .net core self-host instead of OWIN everything work perfectly.
below link will help you a lot.
https://medium.com/#tocalai/create-windows-service-using-net-core-console-application-dc2f278bbe42

Related

Azure WebJob BlobTrigger - Output Blob makes trigger not fire

I have a v3 WebJob that successfully fires when my function method signature is as follows:
public static void ProcessQueueMessage(
[BlobTrigger("process/{name}", Connection = "storage-connection")] Stream blob,
ILogger log
)
However when I add an output blob the BlobTrigger never fires.
public static void ProcessQueueMessage(
[BlobTrigger("process/{name}", Connection = "storage-connection")] Stream blob,
[Blob("output/{name}", FileAccess.Write, Connection = "storage-connection")] Stream processedBlob,
ILogger log
)
The documentation I'm following is here: https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-blob#output
If you want to use Azure WebJob BlobTrigger and also use a Output binding, you can follow my steps.
In my side, it works fine.
1.create a console app and install everything needed. You can follow by this doc. This will tell you how to use the WebJob SDK.
This is my code:
Functions.cs:
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;
using System.IO;
namespace ConsoleApp1
{
public class Functions
{
public static void ProcessQueueMessage(
[BlobTrigger("images/{name}")]Stream myBlob,
[Blob("form/{name}", FileAccess.Write)] Stream imageSmall,
string name,
ILogger log
)
{
log.LogInformation("webjobs blob trigger works!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
}
}
}
Program.cs:
using System;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var builder = new HostBuilder();
builder.ConfigureWebJobs(b =>
{
b.AddAzureStorage();
b.AddAzureStorageCoreServices();
});
builder.ConfigureLogging((context, b) =>
{
b.AddConsole();
});
builder.ConfigureWebJobs(b =>
{
b.AddAzureStorageCoreServices();
b.AddAzureStorage();
});
var host = builder.Build();
using (host)
{
host.Run();
}
}
}
}
appsettings.json:
{
"AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=bowmanimagestorage02;AccountKey=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxSAHfYi1d2yc+BU3NG9hkbGEPU/lJP5wtqYZ3pdDq1lGEkdUx7w==;EndpointSuffix=core.windows.net"
}
You can find that I have already add the output binding in the blobtrigger, Just follow the doc you give. I upload a image to the images container and the console show the loginformation, the image also been upload to the form container.
Things works in my side, if you have more questions, please show more details. I hope my answer can give you some help.

Trying to use Application.Current in TestCase, however Application cannot be imported from System.Windows

I try to unit-test a Gui application code that uses
Application.Current.Dispatcher.Invoke() and would like to use the solution provided by #informatorius in the similar thread Using the WPF Dispatcher in unit tests. The code is listed below.
The problem I have is that Application is not resolved, even if I add using System.Windows. Is there some special mechanism to resolve
Application from within a class library that defines the testcases ?
I have the MSTest.TestFramework and MSTest.TestAdapter packages installed.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public class ApplicationInitializer
{
[AssemblyInitialize]
public static void AssemblyInitialize(TestContext context)
{
var waitForApplicationRun = new TaskCompletionSource<bool>();
Task.Run(() =>
{
var application = new Application();
application.Startup += (s, e) => { waitForApplicationRun.SetResult(true); };
application.Run();
});
waitForApplicationRun.Task.Wait();
}
[AssemblyCleanup]
public static void AssemblyCleanup()
{
Application.Current.Dispatcher.Invoke(Application.Current.Shutdown);
}
}
[TestClass]
public class MyTestClass
{
[TestMethod]
public void MyTestMethod()
{
// implementation can access Application.Current.Dispatcher
}
}
Answer pointed me into the right direction:
using System.Windows is not enough, I also needed to add reference to PresentationFramework to the project. Dont really understand the auto magic behind that.

How do you track custom events from Azure WebJobs in Application Insights?

I have an Azure WebJobs (v2.2.0) project that I would like to monitor with Application Insights (AI), and there are events that I would like to be able to track. In a normal web app that is configured to use AI you can just use this:
TelemetryClient tc = new TelemetryClient();
tc.TrackEvent("EventName");
However this seems not to work in the context of a WebJob! I have configured my WebJob project as per the instructions on the WebJob SDK repo which ends up looking like this:
Program
using System.Configuration;
using System.Diagnostics;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;
namespace WebJobs
{
public class Program
{
public static void Main()
{
JobHostConfiguration config = new JobHostConfiguration();
config.UseTimers();
using (LoggerFactory loggerFactory = new LoggerFactory())
{
string key = ConfigurationManager.AppSettings["webjob-instrumentation-key"];
loggerFactory.AddApplicationInsights(key, null);
loggerFactory.AddConsole();
config.LoggerFactory = loggerFactory;
config.Tracing.ConsoleLevel = TraceLevel.Off;
if (config.IsDevelopment)
config.UseDevelopmentSettings();
JobHost host = new JobHost(config);
host.RunAndBlock();
}
}
}
}
Functions
This is just a test function that will run every minute for half an hour.
using Core.Telemetry;
using Microsoft.ApplicationInsights;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Timers;
using System;
using System.Collections.Generic;
namespace WebJobs.Functions
{
public class TestFunctions
{
public void TelemetryTest([TimerTrigger(typeof(Schedule))] TimerInfo timer)
{
TelemetryClient tc = new TelemetryClient();
tc.TrackEvent("TelemetryTestEvent");
}
// schedule that will run every minute
public class Schedule : DailySchedule
{
private static readonly string[] times =
{
"12:01","12:02","12:03","12:04","12:05","12:06","12:07","12:08","12:09","12:10",
"12:11","12:12","12:13","12:14","12:15","12:16","12:17","12:18","12:19","12:20",
"12:21","12:22","12:23","12:24","12:25","12:26","12:27","12:28","12:29","12:30"
};
public Schedule() : base(times) { }
}
}
}
This seems to partially work in that I can see some telemetry in AI but not the custom events. For example I can see a Request show up each time TestFunctions.TelemetryTest() runs and various Traces during the initialisation of the WebJob.
I have probably not configured something properly or am not getting the TelemetryClient in the correct manner, but I cannot find any documentation on tracking custom events in WebJobs.
Any help would be appreciated.
Try setting the instrumentationkey explicit:
tc.Context.InstrumentationKey = "<your_key>";
According to the docs you should be able to get the key using
System.Environment.GetEnvironmentVariable(
"APPINSIGHTS_INSTRUMENTATIONKEY", EnvironmentVariableTarget.Process)
if you have set up application insights integration.

Problem to open REPL using Xamarin Test Cloud

I'm beginner in Xamarin Test Cloud and I want to write tests for Xamarin Test Cloud.
I have Xamarin UITests in my solution and I tried to launch REPL, but UITest REPL window didn't open.
using System;
using System.IO;
using System.Linq;
using NUnit.Framework;
using Xamarin.UITest;
using Xamarin.UITest.Android;
using Xamarin.UITest.Queries;
namespace MurakamiKiev.UITests
{
[TestFixture]
public class Tests
{
AndroidApp app;
[SetUp]
public void BeforeEachTest ()
{
app = ConfigureApp.Android.StartApp ();
}
[Test]
public void TestLaunch ()
{
app.Repl();
}
}
}
Where is the error?
Also, what I need to write to launch specified activity?
If you don't have the application source code in the same solution then you'll need to specify the prebuilt app by pointing to it via a full path.
[SetUp]
public void BeforeEachTest ()
{
app = ConfigureApp.Android.ApkFile("<path-as-string>").StartApp ();
}

Exchange Server 2007 Transport Agent Issue

This is the first time i am working on Exchange Server Development. Below is a simple Transport Agent that i am using, this agent should simply update the email Subjects as shown below in the code.
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Exchange.Data.Transport;
using Microsoft.Exchange.Data.Transport.Smtp;
namespace MyAgents
{
public sealed class MyAgentFactory : SmtpReceiveAgentFactory
{
public override SmtpReceiveAgent CreateAgent(SmtpServer server)
{
return new MyAgent();
}
}
public class MyAgent : SmtpReceiveAgent
{
public MyAgent()
{
this.OnEndOfData += new EndOfDataEventHandler(MyEndOfDataHandler);
}
private void MyEndOfDataHandler(ReceiveMessageEventSource source, EndOfDataEventArgs e)
{
e.MailItem.Message.Subject = "This message passed through my agent: " + e.MailItem.Message.Subject;
}
}
}
Below is the Powershell script i am using to install the Agent.
Net Stop MSExchangeTransport
Install-TransportAgent -Name MyAgent -AssemblyPath EmailLogger.dll -TransportAgentFactory MyAgents.MyAgentFactory
Enable-TransportAgent -Identity MyAgent
Net Start MSExchangeTransport
Agent installed successfully using Exchange Management Shell.
Now when i send/receive emails in exchange, Email subjects are not modified. Emails have their original subjects. I don't know why?
I also performed the steps mentioned in below links to debug the Agent but breakpoints are not being hit by Visual Studio Debugger.
http://www.sf-tools.net/Messaging/tabid/55/EntryId/163/Exchange-2010-Transport-Agent.aspx
Debugging MS Exchange 2007 Transport Agent
http://omarjames.com/blog/index.php/debugging-exchange-transport-agent/
My System Configuration
I am using the Exchange Server 2007 Virtual Machine provided by Microsoft from link below
http://www.microsoft.com/en-pk/download/details.aspx?id=14901
I also installed the Visual Studio 2008 on the VM for debugging.
Please help me in resolving the issue?
Problem Solved. :)
I must use Routing Agent instead of SmtpReceive Agent because only Routing Agents are guaranteed to see all the Emails passing through Exchange Server.
Below is the modified working code, Everything else remains same
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Exchange.Data.Transport;
using Microsoft.Exchange.Data.Transport.Routing;
namespace MyAgents
{
public sealed class MyAgentFactory : RoutingAgentFactory
{
public override RoutingAgent CreateAgent(SmtpServer server)
{
return new MyAgent();
}
}
public class MyAgent : RoutingAgent
{
public MyAgent()
{
this.OnSubmittedMessage += new SubmittedMessageEventHandler(this.MySubmittedMessageHandler);
}
public void MySubmittedMessageHandler(SubmittedMessageEventSource source, QueuedMessageEventArgs e)
{
e.MailItem.Message.Subject = "This message passed through my agent: " + e.MailItem.Message.Subject;
}
}
}

Categories