Can I use objects created in C# within metro ui javascript code? - c#

I really like C# and I am familiar with it, but I also want to use HTML5/JavaScript to manage the UI for my Windows 8 Metro app. So, how can I import and use objects from a library made in C# in the Javascript files?
Example here is the starting JS code for an empty HTML5/JS project...
// For an introduction to the Blank template, see the following documentation:
// http://go.microsoft.com/fwlink/?LinkId=232509
(function () {
"use strict";
var app = WinJS.Application;
app.onactivated = function (eventObject) {
if (eventObject.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {
if (eventObject.detail.previousExecutionState !== Windows.ApplicationModel.Activation.ApplicationExecutionState.terminated) {
// TODO: This application has been newly launched. Initialize
// your application here.
} else {
// TODO: This application has been reactivated from suspension.
// Restore application state here.
}
WinJS.UI.processAll();
}
};
app.oncheckpoint = function (eventObject) {
// TODO: This application is about to be suspended. Save any state
// that needs to persist across suspensions here. You might use the
// WinJS.Application.sessionState object, which is automatically
// saved and restored across suspension. If you need to complete an
// asynchronous operation before your application is suspended, call
// eventObject.setPromise().
};
app.start();
})();
Can I pull in and use libraries and objects in JS that are written in C#?
I was kind of bummed they appear to segregate C# from HTML5 based projects...

You absolutely can do this. This is the beauty of the Windows 8 and the new application model. There are a lot of places to start and look at.
Start here: http://msdn.microsoft.com/en-us/library/windows/apps/br230301(v=vs.110).aspx You can drill down further in the above link where it also links to a real basic sample. http://msdn.microsoft.com/en-us/library/windows/apps/hh779077(v=vs.110).aspx
In a nutshell, you'll create a metro class library in C# and then set the output type of your C# from a "Class Library" to a WinMD. You can then reference and use that library in your javascript project.
There is a lot of documentation on building metro apps available at http://msdn.microsoft.com/en-us/library/windows/apps

Related

c#, Xamarin.Forms, and SentrySDK context info not making it to sentry errors

I am trying to add User & Device context to the SentrySdk using c# and but that information never shows in the sentry portal.
here is the code
SentrySdk.ConfigureScope(scope =>
{
scope.SetTag("SStGAppAId", sstgAppId);
scope.User = new User
{
Id = sstgAppId
};
scope.Contexts.Device.Model= DeviceInfo.Model;
scope.Contexts.Device.Manufacturer = DeviceInfo.Manufacturer;
scope.Contexts.Device.Name = DeviceInfo.Name;
scope.Contexts.Device.Simulator = DeviceInfo.DeviceType != DeviceType.Physical;
});
this what sentry shows
What is not being done for the context information to be sent to sentry?
We solved "Global Mode" on version 3.8.1.
It makes it so that any call to SentrySdk.SetTag or AddBreadcrumb or anything else that you do through SentrySdk.ConfigureScope mutates a single, static Scope object that affects all threads of the app. This is useful for Desktop and Mobile apps when you have a single user session and you add context to Sentry anywhere in the app and want that to be included if it crashes in any other thread.
You can opt-in to this mode through:
options.IsGlobalModeEnabled = true
This option will be set by default on Sentry.Xamarin and Sentry.Xamarin.Forms which you could be using to get extra device information and breadcrumbs for system events.
It's a bug in the SDK, a AsyncLocal issue. For now to bypass it you can call SentrySdk.ConfigureScope every time before logging.

Unity Android: NoClassDefFoundError: Can't create Notifications

Edit
I found out, that the requirements for showing a notification consist of setting a content-title, a context-text and a small icon. The last of which I do not do. Unfortunately, I don't know, how to provide a small icon especially in unity.
Original Question
I'm currently trying to show a notification from a unity-instance via android. I want to show the notification, when the user enters a specific gps-area. Thus, the script should run, when the app is paused. That's why I want to use the android-functionality.
With this code, I currently try to show the notification manually:
public void createNotification(){
NotificationManagerCompat nManager = NotificationManagerCompat.from(curContext);
NotificationCompat.Builder builder = new NotificationCompat.Builder(curContext, CHANNEL_ID)
.setContentTitle("Stuff")
.setContentText("MoreStuff")
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
nManager.notify(1551, builder.build());
}
The context is stored in a static variable and is set, when calling the method.
The function is called in C# with:
PluginInstance.Call("createNotification");
The PluginInstance works, the function can be called, but I get the error:
AndroidJavaException: java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/core/app/NotificationManagerCompat
I found the solution for my problem: I used the Unity Android Jar-Resolver in which I provided the *Dependencies.xml (Where the * presents the Name of my project). In the *Dependenices.xml I specified: <androidPackage spec="androidx.appcompat:appcompat:1.1.0"> and run through the steps, provided in the Tutorial of the Resolver.
Afterwards, multiple dependencies appeared in my /Assets/Plugin/Android-Folder, which were successfully transferred to the app, when building it.

Calling a Windows Forms Application via C# API

I have a windows form application written in C# that allows me to point to a folder of images and parse those images into a easily view able format for a user. This is a stand alone application and it works fine. I want to extend this application so that instead of it parsing a folder of images, I can hand it a prebuilt data set, with all of the images and meta data preset by an external application via an API.
I have been able to compile the application into a class library and access the classes and structs to actually build the data set without issue, the problem I am having now is launching the application externally with the data set I have built.
For context, I am writing a tool that will allow the user to call this windows form application from Spotfire. Inside of spotfire I am parsing a DataTable object and building the data set from the information I have. Once this data set is built I need to be able to launch the application as a stand-alone process instead of calling the forms explicitly inside of Spotfire. (This is due to a limitation of GUI threads in Spotfire and we can't call a multi threaded process in a single threaded application as well as we want to keep the Spotfire GUI responsive which can't be done if we call the forms directly)
I know I can launch the exe standalone using Process.Start(), however this doesn't let me pass my information to teh application. How can I build this application to allow me to pass information to it? I've been trying to google examples of how to do this and keep coming up empty handed as people will reference ASP.net or things that are over my head.
Thank you in advance!
EDIT: An example of an application that handles this really well is below. We use DPlot Jr to create graphs externally. The dplot.dll exposes the following function:
[System.Runtime.InteropServices.DllImport("dplotlib64.dll")]
public static extern int DPlot_Plot8(
ref DPLOT d, double[] x, double[] y, string cmds);
which I can then use in my code
docNum = dplot.DPlot_Plot8(ref dPlot, X, Y, cmds);
docNums.Add(docNum);
calling this function in this way actually launches the dplot application and passes the object I've built "dPlot" along with the X and Y data in order to plot the information. I would like to build something like this in my windows form application in order to be able to launch it easily from an external application. Unfortunately I don't know how this function works inside the .dll
EDIT2: I have been able to modify the runtime via the commandline as suggested by Aybe. In my desktop application I have created a conditonal in the main program like so.
if (args.Length == 0 && false)
{
Application.Run(new frmWaveFormViewer());
}
else
{
DataSet dataSet = new DataSet();
//dataSet.LoadMetaData(args[0]);
dataSet.LoadMetaData(#"C:\Users\a0273881\AppData\Local\Temp\tmp1141.tmp");
Application.Run(new frmWaveFormViewer(dataSet));
}
the user can then call the forms externally by using the following...
DataSet dataSet = new DataSet(dpList);
dataSet.PrintDatasetMetadataToFile(String.Format(#"C:\Spotfire\DataSetTesting_{0}.csv", DateTime.Now.ToString("yyyyMMdd_HHmmss")));
string args = dataSet.GetMetaData();
ProcessStartInfo starter = new ProcessStartInfo();
starter.FileName = #"C:\Users\a0273881\Desktop\WaveFormViewer.exe";
starter.Arguments = args;
Process.Start(starter);
However, this is not easy to use for other developers.
I am starting to look into WCF, can anyone provide good resources on WCF for dummies? I'm currently reading through: http://www.codemag.com/article/0705041
I have been able to spawn a NamedPipeServer on the application when it is launched. The named pipeserver names itself tagged with the name of the application + the process id that it spawns with. The process number is logged to a ini file in the users appdata folder. The process can be started with an optional command line argument to effect the value of the "callingApplication" which is the INI Header. This way, we can create multiple instances of the application from different callers without interfering and ensuring connection to the correct named pipe.
static void Main(string[] args)
{
string callingApplication = "None";
if (args.Length != 0)
{
callingApplication = args[0];
}
int pId = Process.GetCurrentProcess().Id;
PipeServer.StartPipeServer(pId, callingApplication);
// do things
PipeServer.StopPipeServer();
}
The PipeClient side is accessed through public functions available in a API static class. Functions that connect through the pipe are all housed in a seperate PipeClient class. These functions require a spawned process id in order to connect to the correct pipe. These are api functions to either launch or return the needed pipe from an api
public static class API
{
public static int SendCommand(int aKey, ...)
{
try
{
PipeClient.StartCommandSendClient(input, aKey);
}
catch (TimeoutException)
{
// returns error codes based on exceptions
}
return 0;
}
}
So with this I've managed to create a link between two applications. All that is really required past this is custom implementation of methods exposed through the API class which have custom client methods to call as well. All of this together is pretty simple to call from my calling app...
int aKey = API.GetKey("callingAppName");
API.SendCommand(aKey, "[Reset()][AddPoint(arg1, arg2, arg3)]");

JINT - Unable to "console.log"

I am new to JINT, and trying to just do some basic tests to kind of learn the ropes. My first attempt was to just store some javascript in my database, load it, and execute it in a unit test. So that looks essentially like this....
[Fact]
public void can_use_jint_engine() {
using (var database = DocumentStore()) {
using (var session = database.OpenSession()) {
var source = session.Load<Statistic>("statistics/1");
// join the list of strings into a single script
var script = String.Join("\n", source.Scripting);
// this will create the script
// console.log("this is a test from jint.");
//
var engine = new Jint.Engine();
// attempt to execute the script
engine.Execute(script);
}
}
}
And it doesn't work, I get this error, which makes absolutely no sense to me, and I cannot find any documentation on.
Jint.Runtime.JavaScriptExceptionconsole is not defined at
Jint.Engine.Execute(Program program) at
Jint.Engine.Execute(String source) at
SampleProject.Installers.Instanced.__testing_installer.can_use_jint_engine()
in _testing_installer.cs: line 318
Can anyone assist in shedding some light on this? I'm pretty confused at this point.
With JavaScript there are three entities - we care about. The host (browser, your application etc), the engine (JINT in this case) and the script ("console.log(...)") in this case.
JavaScript defines a bunch of functions and object as part of the language, but console is not one of them. By convention, browsers define a console object that can be used in the manner you describe. However, since your app is not a browser (and JINT does not do this by itself), there's no console object defined in your namespace (globals).
What you need to do is add a console object that will be accessible in JINT. You can find how to do this in the docs, but here's a simple example of how to add a log function to the engine so it can be used from the JS code (example taken from github).
var engine = new Engine()
.SetValue("log", new Action<object>(Console.WriteLine))
;
engine.Execute(#"
function hello() {
log('Hello World');
};
hello();
");

How to make my C# checkbox remember value

Here is my timer enabled/disabled code:
{
if (checkboxConsoleStats.Checked == true)
{
frmMain.frmObj.consoleStatTimer.Enabled = true;
}
else if (!checkboxConsoleStats.Checked == false)
{
frmMain.frmObj.consoleStatTimer.Enabled = false;
}
I want to make the form remember the 'Checked' value after termination of the form and the application, sorry this is vague, I am in a rush. Thanks.
If you need to store the value after full termination of the app - you'll have to use a persistent storage that the app can access on init.
The easiest would be to use a flat file (just store a flag), but if you believe you will have more values that you'll need to remember - consider using XML/JSON file that you parse upon init and write to upon termination.
If you have more dynamic data (that needs to be written and read while the app is running) - you should consider using a DB. For a small app you can use an embedded DB such as SQLITE. Easy to use and needs no installation for the end-user.

Categories