I'm trying to add Application Insights to a WPF app using this documentation: https://learn.microsoft.com/en-us/azure/azure-monitor/app/windows-desktop. The basic integration is working. I am now trying to remove the RoleInstance property from the submitted data, as described in the documentation, as this contains the user's computer name (personally identifiable information). Here's my code, based on the documentation above:
Telemetry.cs
public static class Telemetry
{
public static TelemetryClient Client;
public static void Close()
{
if (Client != null)
{
Client.Flush();
System.Threading.Thread.Sleep(1000);
}
}
public static void Initialize()
{
TelemetryConfiguration.Active.InstrumentationKey = "xxxxxxxx";
TelemetryConfiguration.Active.TelemetryInitializers.Add(new MyTelemetryInitializer());
Client = new TelemetryClient(TelemetryConfiguration.Active);
Client.Context.Session.Id = Guid.NewGuid().ToString();
Client.Context.Device.OperatingSystem = Environment.OSVersion.ToString();
}
private class MyTelemetryInitializer : ITelemetryInitializer
{
public void Initialize(ITelemetry telemetry)
{
if (string.IsNullOrEmpty(telemetry.Context.Cloud.RoleName))
{
telemetry.Context.Cloud.RoleInstance = null;
}
}
}
}
App.xaml.cs
public partial class App : Application
{
protected override void OnExit(ExitEventArgs e)
{
Telemetry.Close();
base.OnExit(e);
}
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
Telemetry.Initialize();
}
}
When I call Telemetry.Client.TrackEvent(), Telemetry.Initialize() runs, and RoleInstance is null from the start. But, the data sent to AI contains my computer name as the RoleInstance. Not sure how to debug further.
Note: the documentation describes integration into WinForms, and I'm in WPF, so I've guessed at using App.OnStartup instead of Main.
I just found something interesting, if you set a dummy value for RoleInstance, it really takes effect. Maybe the null/empty value will be checked and replaced by the real RoleInstance in the backend. As a workaround, you can just specify a dummy value instead of null/empty value.
Here is my test result with a dummy value:
in azure portal:
Related
I have created a custom event log and would like all my applications to write to the same event log. As you can see below in the image attached, DistributedCOM and Svc Ctrl Mgr are 2 sources writing to the same event log System.
Similarly, I have 2 services that I want to write to the same eventLog.
I tried doing that by creating one event log and passing different source names from the 2 Windows Services that I have created. But I find only one Service writing to the log while the other doesn't.
Below is the class library that I created for Event Log.
public class EventLogger
{
private EventLog eventLog1 = new System.Diagnostics.EventLog();
public EventLogger(string logSource)
{
if (!System.Diagnostics.EventLog.SourceExists(logSource))
{
System.Diagnostics.EventLog.CreateEventSource(logSource, "SampleLog");
}
eventLog1.Source = logSource;
eventLog1.Log = "SampleLog";
}
public void WriteLog(string message)
{
eventLog1.WriteEntry(message);
}
Created 1st Windows Service
public partial class Service1 : ServiceBase
{
private EventLogger.EventLogger eventLog;
public Service1()
{
InitializeComponent();
eventLog = new EventLogger.EventLogger("WinService1");
}
protected override void OnStart(string[] args)
{
try
{
eventLog.WriteLog("Service started in 1st");
}
catch (Exception ex)
{
EventLog.WriteEntry(ex.ToString());
}
}
protected override void OnStop()
{
eventLog.WriteLog("Service stopped");
}
}
Created the 2nd windows Service as well, as above.
public partial class Service2 : ServiceBase
{
private EventLogger.EventLogger eventLog;
public Service2()
{
InitializeComponent();
eventLog = new EventLogger.EventLogger("WinService2");
}
protected override void OnStart(string[] args)
{
try
{
eventLog.WriteLog("Service started in 2nd");
}
catch (Exception ex)
{
EventLog.WriteEntry(ex.ToString());
}
}
protected override void OnStop()
{
eventLog.WriteLog("Service stopped");
}
}
Service1 doesn't seem to log anything, whereas, I can see the logs for Service2. I might be doing a lot of things incorrectly here. Please help me in finding a solution to this. Also, if this can be achieved by using log4Net then solutions with respect to that are welcome as well. thanks in advance.
EDIT: Also, when I try to stop the services, Service 1 fails to stop and throws an error. Image given below.
EDIT 2: Just changed the constructor of the EventLogger class as below and then it worked!! I am not entirely sure if this was the actual cause for the improper functioning. And I'm not quite sure if it had anything to do with the setting of the Log property either. Any light thrown on this by any one of you would be appreciated. I would like to understand better as to what exactly happened here. Thanks.
string logName = "NewLog";
public EventLogger(string logSource)
{
if (!System.Diagnostics.EventLog.SourceExists(logSource))
{
System.Diagnostics.EventLog.CreateEventSource(logSource, logName);
}
eventLog1.Source = logSource;
}
I'm trying to build a metronome application that has the capability to run in the background. As a starting point I decided to create something simple, a class that has a timer (the metronome itself), a class responsible for obtaining the MIDI output device and a class to play the sound. I'm having difficulty with how to make this run in the background. Additionally, another problem is the fact that the metronome needs to be executed when clicking an application button (in the main process).
Metronome Class:
public class Metronome
{
private DispatcherTimer timer = new DispatcherTimer();
private MidiDeviceSelector deviceSelector = new MidiDeviceSelector();
private void TimerStart()
{
timer.Start();
timer.Tick += timer_Tick;
}
private void timer_Tick(object sender, object e)
{
AudioPlayback.Beep1();
}
public void Start(int bpm)
{
double interval = (double)60.000f / (bpm);
timer.Interval = TimeSpan.FromSeconds(interval);
TimerStart();
}
public void Stop()
{
timer.Stop();
}
}
MidiDeviceSelector:
class MidiDeviceSelector
{
public MidiDeviceSelector()
{
GetOutputMidiDevice();
}
public async void GetOutputMidiDevice()
{
IMidiOutPort currentMidiOutputDevice;
DeviceInformation devInfo;
DeviceInformationCollection devInfoCollection;
string devInfoId;
devInfoCollection = await DeviceInformation.FindAllAsync(MidiOutPort.GetDeviceSelector());
if (devInfoCollection == null)
{
//notify the user that any device was found.
System.Diagnostics.Debug.WriteLine("Any device was found.");
}
devInfo = devInfoCollection[0];
if (devInfo == null)
{
//Notify the User that the device not found
System.Diagnostics.Debug.WriteLine("Device not found.");
}
devInfoId = devInfo.Id.ToString();
currentMidiOutputDevice = await MidiOutPort.FromIdAsync(devInfoId);
if (currentMidiOutputDevice == null)
{
//Notify the User that wasn't possible to create MidiOutputPort for the device.
System.Diagnostics.Debug.WriteLine("It was not possible to create the OutPort for the device.");
}
MidiDevice.midiDevice = currentMidiOutputDevice;
}
Class to Holds the MidiDevice:
class MidiDevice
{
public static IMidiOutPort midiDevice; //Bad practice i know.
}
Class to play the "toc" sound:
class AudioPlayback
{
static IMidiMessage beep1 = new MidiNoteOnMessage(9, 76, 90);
//static IMidiOutPort midiOutputDevice = (IMidiOutPort)MidiDeviceSelector.GetOutputMidiDevice();
public static void Beep1()
{
try
{
MidiDevice.midiDevice.SendMessage(beep1);
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine(e.Message);
}
}
}
Each class is contained in a different file. As you can see, it is a very simple code, if you see any bad programming practice, I apologise, I do not have much experience.
I was looking at the documentation, however, I did not succeed. How do I register an activity in the background and that there is interaction with the application's user interface (a button to stop and start the metronome).
My apologies for bad English, not my native language.
Thank you.
Two things you need to add to make this scenario work:
add the "backgroundMediaPlayback" capability as documented here: https://learn.microsoft.com/en-us/windows/uwp/audio-video-camera/background-audio
since you are using the MiDI APIs, you need to explicitly integrate with the SystemMediaTransportControls to prevent getting muted on minimize
I have update your repro sample and verified that it works correctly after adding those two things.
Sharing it here for your reference: https://1drv.ms/u/s!AovTwKUMywTNl9QJTeecnDzCf0WWyQ
ASP.NET C#
I have a question, how can I make an access control to a request provided by a botton, to stop the execution of the function, I need something generic in which it can be configured and say that roles or profiles can access to certain functions request Executed by a button.
I don't want something like that
protected void DownloadFile_ServerClick(object sender, EventArgs e)
{
if (RoleAdmin)
{
// do something
}
}
I need something that directly validates in the request of the pag when the method is executed, to see if that profile matches with the method stored in the base, so I do for all pag and do not have to put it in hard in each one of the executed methods.
I need the name of fucntion that is request.
public class PageBase : Page
{
protected override void OnLoad(EventArgs e)
{
***How to capture the function name of request ???***
if (User.Identity.IsAuthenticated == false) { Response.Redirect("~/Account/login.aspx?ReturnUrl=/admin"); };
if (!(User.IsInRole("admin") || User.IsInRole("super user"))) { Response.Redirect("/"); };
}
}
Maybe with this:
public class StaticObjects
{
public static string UserRole
{
get
{
try
{
return (string)HttpContext.Current.Session["UserRole"];
}
catch (Exception)
{
return "";
}
}
set
{
HttpContext.Current.Session["UserRole"]=value;
}
}
public static bool AuthorizeExecution(EventHandler method)
{
bool autorized = YourDataBaseQuery(UserRole, method.Method.Name);
return autorized;
}
}
////////////////////////////// ANOTHER FILE /////////////////
public static void DownloadFile_ServerClick(object sender, EventArgs e)
{
//You send the method itself because it fits the delegate "EventHandler"
if(!StaticObjects.AuthorizeExecution(DownloadFile_ServerClick))
return;
}
I install Windows Service with following code:
ServiceBase.Run(new ServiceProcess(serviceName, serviceArgs));
From documentation I see, that this method also call OnStart method on service. But I want to install service as stopped and later start it manually.
private static InitialStartDone = false; // declared in service class
protected Overrride void OnStart(string[] args);
{
if(!InitialStartDone)
{
InitialStartDone = true;
}
else
{
base.OnStart(args);
}
}
Try overriding the default behavior of on start and use static variable to detect if it is called first time
I researched our project and found custom installer. I overrided method OnCommitted and check parameter Delayed to start service now or do it later by hand.
[RunInstaller(true)]
public class CustomInstaller : System.Configuration.Install.Installer
{
public CustomInstaller()
{
_installProcess = new ServiceProcessInstaller { Account = ServiceAccount.NetworkService };
_installService = new CustomServiceInstaller(typeof(ServiceImplementation));
// Remove built-in EventLogInstaller:
_installService.Installers.Clear();
Installers.Add(_installProcess);
Installers.Add(_installService);
}
public override void Install(IDictionary stateSaver)
{
//install
base.Install(stateSaver);
}
protected override void OnCommitted(IDictionary savedState)
{
var delyed = bool.Parse(GetContextParameter(#"Delayed"));
if (!delyed)
{
new ServiceController(GetContextParameter(ServiceNameKey)).Start();
}
}
private string GetContextParameter(string parameterKey)
{
var parameterValue = Context.Parameters[parameterKey];
if (string.IsNullOrWhiteSpace(parameterValue))
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, MissingRequiredParameterErrorMessage, parameterKey));
return parameterValue;
}
}
I am trying to write a simple c# console application which shows the accessed websites (sort of proxy server) . I understood that the right approach would be using .Net Sockets and TCP Listeners. However, I tried some code samples and I can get working none of them.
Any suggestions would be great!
You can use FiddlerCore
public class HttpProxy : IDisposable
{
public HttpProxy()
{
Fiddler.FiddlerApplication.BeforeRequest += FiddlerApplication_BeforeRequest;
Fiddler.FiddlerApplication.Startup(8888, true, true);
}
void FiddlerApplication_BeforeRequest(Fiddler.Session oSession)
{
Console.WriteLine(String.Format("REQ: {0}", oSession.url));
}
public void Dispose()
{
Fiddler.FiddlerApplication.Shutdown();
}
}
static void Main(string[] Args)
{
var p = new HttpProxy();
Console.ReadLine();
p.Dispose();
}