Powershell implement C# System.Diagnostics.Tracing.EventSource - c#

So maybe I am just ignorant, but C# has some lovely functionality with System.Diagnostics.Tracing.EventSource that make writing new event sources super simple. I've got some functionality built up around this convenient api that allows these logs to be processed after ingestion.
All of this however is being moved to powershell and I'm trying to get it working. If I consume a current implementation of a EventSource subclass through dlls everything works as expected. If I try to write a new EventSource subclass purely in powershell, the event stop showing up.
I have researched the googles quite thoroughly and it has become clear to me that this is not a standard approach. (Surprising because it is such a handy chunk of coding) Can anyone help or tell me what I may be doing wrong?
class TestEventSource2 : System.Diagnostics.Tracing.EventSource
{
static [TestEventSource2] $Log = [TestEventSource2]::New()
static [string] $LogName = "its a name"
[void] WriteTestEvent() {
Write-Information "WriteTestEvent"
WriteEvent(1,"Hello world from a powershell test event.")
}
}
$loglog = [TestEventSource2]::Log
$loglog.WriteTestEvent()

Related

How to write a DiagnosticAnalyzer for razor files?

My Goal
My team decided, that they wanted to incorporate automation to enforce coding guidelines in .razor files.
Since we're already using StyleCopAnalyzers, I might implement our own Analyzer to achieve this goal.
Example
To better make you understand what's in my mind, consider the following example.
Let the following be valid code:
<MyGrid>
<MyItem></MyItem>
<MyItem></MyItem>
<MyItem></MyItem>
</MyGrid>
Now, If someone wouldn't encapsulate <MyItem> within <MyGrid> it would cause the Analyzer to report a diagnostic like "MyItem should be direct child of a MyGrid".
What I tried
Firstly, I followed microsoft's tutorial: Write your first analyzer and code fix. This worked perfectly well.
However, my next step was to create a Sample Blazor WASM Application using the default template. When I executed the MakeConstAnalyzer on the Sample Blazor Application, I'd get the following behavior.
Modifying Program.cs like this:
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
// I get squiggly lines here with the expected analyzer message from the MakeConstAnalyzer
int bla = 0;
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
await builder.Build().RunAsync();
}
}
But modifying Counter.razor like this:
private void IncrementCount()
{
int bla = 0; // add this line
currentCount++;
}
now, this won't show the analyzers message. Of course this will
trigger a compiler warning, but mainly this tells me, that for some
reason the Analyzer isn't executed on the Counter.razor file.
The Microsoft.CodeAnalysis.Razor Package
I thought, I'd mention it here. I found it on Nuget and tried to integrate it in the sample.
Caution
I have no clue, If the purpose of the package is even remotely connected, to what I want to achieve, since I really didn't find any documentation.
Since the microsoft tutorial clearly states, that any Analyzer must in some way inherit DiagnosticAnalyzer, I also checked the package for an implementation. But in both, the Microsoft.CodeAnalysis.Razor and Microsoft.AspNetCore.Razor.Language Package there is no class, that inherits from DiagnosticAnalyzer.
I've also tried to decorate my Analyzer, to specify, that it should also parse *.razor files, like that:
[DiagnosticAnalyzer(LanguageNames.CSharp, Microsoft.CodeAnalysis.Razor.RazorLanguage.Name)]
Summary
At this point, I don't know, what else to try. Also I didn't find anything remotely like that in the web.
These are my Questions:
How can I instruct my Analyzer to also parse .razor files?
Also how would I access the razor code in that approach?
I can imagine to either use Analyzers Syntax to traverse the Component Tree, but I think I could realize most of my usecases by only having the plain unparsed code.

Is it possible to use Gephi compiled with IKVM in a website?

I'm currently trying to load and use the Gephi Toolkit from within a .Net 4 C# website.
I have a version of the toolkit jar file compiled against the IKVM virtual machine, which works as expected from a command line application using the following code:
var controller = (ProjectController)Lookup.getDefault().lookup(typeof(ProjectController));
controller.closeCurrentProject();
controller.newProject();
var project = controller.getCurrentProject();
var workspace = controller.getCurrentWorkspace();
The three instances are correctly instantiated in a form similar to org.gephi.project.impl.ProjectControllerImpl#8ddb93.
If however I run the exact same code, with the exact same using statements & references, the very first line loading the ProjectController instance returns null.
I have tried a couple of solutions
Firstly, I have tried ignoring the Lookup.getDefault().lookup(type) call, instead trying to create my own instances:
var controller = new ProjectControllerImpl();
controller.closeCurrentProject();
controller.newProject();
var project = controller.getCurrentProject();
var workspace = controller.getCurrentWorkspace();
This fails at the line controller.newProject();, I think because internally (using reflector) the same Lookup.getDefault().lookup(type) is used in a constructor, returns null and then throws an exception.
Secondly, from here: Lookup in Jython (and Gephi) I have tried to set the %CLASSPATH% to the location of both the toolkit JAR and DLL files.
Is there a reason why the Lookup.getDefault().lookup(type) would not work in a web environment? I'm not a Java developer, so I am a bit out of my depth with the Java side of this.
I would have thought it possible to create all of the instances myself, but haven't been able to find a way to do so.
I also cannot find a way of seeing why the ProjectController load returned null. No exception is thrown, and unless I'm being very dumb, there doesn't appear to be a method to see the result of the attempted load.
Update - Answer
Based on the answer from Jeroen Frijters, I resolved the issue like this:
public class Global : System.Web.HttpApplication
{
public Global()
{
var assembly = Assembly.LoadFrom(Path.Combine(root, "gephi-toolkit.dll"));
var acl = new AssemblyClassLoader(assembly);
java.lang.Thread.currentThread().setContextClassLoader(new MySystemClassLoader(acl));
}
}
internal class MySystemClassLoader : ClassLoader
{
public MySystemClassLoader(ClassLoader parent)
: base(new AppDomainAssemblyClassLoader(typeof(MySystemClassLoader).Assembly))
{ }
}
The code ikvm.runtime.Startup.addBootClassPathAssemby() didn't seem to work for me, but from the provided link, I was able to find a solution that seems to work in all instances.
This is a Java class loader issue. In a command line app your main executable functions as the system class loader and knows how to load assembly dependencies, but in a web process there is no main executable so that system class loader doesn't know how to load anything useful.
One of the solutions is to call ikvm.runtime.Startup.addBootClassPathAssemby() to add the relevant assemblies to the boot class loader.
For more on IKVM class loading issues see http://sourceforge.net/apps/mediawiki/ikvm/index.php?title=ClassLoader

Run javascript in C# WPF Form

*Please note that this is not for a web based application, it's windows based.
I'm building an application where I will need the user to submit simple javascripts that will be run by the application.
The scripts will call functions that are part of the c# build.
An example:
C# code:
public void helloWorld()
{
Debug.WriteLine("hello world");
}
Javascript submitted by user:
helloWorld();
The JavaScript would be parsed by the application at runtime and then call the required functions in my C# code.
Why?..
My app will be used by people with very little programming experience, they enter very simple JavaScripts and the app will attempt to automate a few tasks on the users computer. So my reason for using JavaScript is because it's simple and very easy to learn for someone with little experience.
It sounds like you want a JavaScript parser for your application. To be honest, I dont think what you're doing is possible, considering the context of the script and your code is different. However, this project seems to be doing something that may get you to the right place:
http://javascriptdotnet.codeplex.com/
Personally, I would think making some kind of XML format would be useful (like how UrlRewriter.net makes rewriting URLs easy):
<xml>
<commands>
<!-- Expose a Set of Condition Objects to Select From -->
<if condition="YourApplication.Conditions.RightClickOnDesktop">
<print text="HelloWorld" />
</if>
</commands>
Here is an example running a javascript code which, in turn, invokes a c# method
[System.Runtime.InteropServices.ComVisible(true)]
public class CSharpClass
{
public void MsgBox(string s)
{
MessageBox.Show(s);
}
}
-
Type scriptType = Type.GetTypeFromCLSID(Guid.Parse("0E59F1D5-1FBE-11D0-8FF2-00A0D10038BC"));
dynamic obj = Activator.CreateInstance(scriptType, false);
obj.Language = "Javascript";
obj.AddObject("mywindow", new CSharpClass(), true);
var result = obj.Eval(
#"
function test(){
mywindow.MsgBox('hello');
}
test();
"
);
Why do you "need the user to submit simple javascripts"? What is your application and what do users need it to do? Why have you decided a scripting language is the way to do this? I'm not saying that is the wrong answer, but that you have not justified this conclusion.
If your app will be used by "people with very little programming experience" I do not recommend implementing a scripting language. Basic concepts like source code and variables are very difficult for non-programmers to understand.
I suggest first investigating macro recording for user scripting. For .NET there is UI Automation and the White automation framework.

Why do 'requires' statements fail when loading (iron)ruby script via a C# program?

IronRuby and VS2010 noob question:
I'm trying to do a spike to test the feasibility of interop between a C# project and an existing RubyGem rather than re-invent that particular wheel in .net. I've downloaded and installed IronRuby and the RubyGems package, as well as the gem I'd ultimately like to use.
Running .rb files or working in the iirb Ruby console is without problems. I can load the both the RubyGems package, and the gem itself and use it, so, at least for that use case, my environment is set up correctly.
However, when I try to do the same sort of thing from within a C# (4.0) console app, it complains about the very first line:
require 'RubyGems'
With the error:
no such file to load -- rubygems
My Console app looks like this:
using System;
using IronRuby;
namespace RubyInteropSpike
{
class Program
{
static void Main(string[] args)
{
var runtime = Ruby.CreateRuntime();
var scope = runtime.ExecuteFile("test.rb");
Console.ReadKey();
}
}
}
Removing the dependencies and just doing some basic self-contained Ruby stuff works fine, but including any kind of 'requires' statement seems to cause it to fail.
I'm hoping that I just need to pass some additional information (paths, etc) to the ruby runtime when I create it, and really hoping that this isn't some kind of limitation, because that would make me sad.
Short answer: Yes, this will work how you want it to.You need to use the engine's SetSearchPaths method to do what you wish.
A more complete example
(Assumes you loaded your IronRuby to C:\IronRubyRC2 as the root install dir)
var engine = IronRuby.Ruby.CreateEngine();
engine.SetSearchPaths(new[] {
#"C:\IronRubyRC2\Lib\ironruby",
#"C:\IronRubyRC2\Lib\ruby\1.8",
#"C:\IronRubyRC2\Lib\ruby\site_ruby\1.8"
});
engine.Execute("require 'rubygems'"); // without SetSearchPaths, you get a LoadError
/*
engine.Execute("require 'restclient'"); // install through igem, then check with igem list
engine.Execute("puts RestClient.get('http://localhost/').body");
*/
Console.ReadKey();

convert code snippet to C#

VS 2008
I have this code snippet I found on a VB website.
But for some reason I am having trouble converting it to C#.
My.Computer.Network.IsAvailable
Many thanks,
using System.Net.NetworkInformation;
internal class Program
{
private static void Main()
{
NetworkInterface.GetIsNetworkAvailable();
}
}
Yes, garethm is right, this class (Network) is from a VB.NET library - you need to reference the Microsoft.VisualBasic assembly if using in a C# project.
Microsoft.VisualBasic.Devices.Network n = new Microsoft.VisualBasic.Devices.Network();
if (n.IsAvailable)
{
// do stuff
}
Works for me - my network is available :).
As far as how Network relates to NetworkInterface class, it depends on what you want to do next. For instance, Network has such nice stuff as NetworkAvailabilityChanged event, and UploadFile method. On the other hand, NetworkInterface can give you a bunch of specific technical info such as speed or whether it supports multicast.
BTW, there is nothing undocumented about using a class from Microsoft.VisualBasic namespace - it's the core idea behind .NET that you can use classes from assemblies regardless of the language they were written in.
What I generally do is write a small app, then load then project in Reflector and disassemble it.
but you can use this class:
System.Net.NetworkInformation.NetworkChange.NetworkAddressChanged
Isn't the whole "My" thing from a VB library?
This appears to work. It's probably very undocumented usage though:
Microsoft.VisualBasic.Devices.Network net = new Microsoft.VisualBasic.Devices.Network();
if (net.IsAvailable)
{
Text = "Network is available";
}
else
{
Text = "Network unavailable";
}
Note that I needed to add a reference to Microsoft.VisualBasic to my project.

Categories