I am trying to write something that would access methods I have written in a WPF c# application, from a vba worksheet, an intermediary would be acceptable, as well as any command line solution, as long as I can run this intermediary from excel where the data I need to send will be kept.
Does anyone know any decent solutions for sending data to a c# without registering the dll, and preferably in a portable way that I can move to other machines easily?
Any help in that matter would be greatly appreciated, I am looking for pointers in the right direction as a COM solution is not viable right now.
Cheers.
You could write a C# Console Application which accepts command-line arguments, then call this using the Shell command.
Here's a sample Console application which handles the input parameters:
using System;
namespace ConsoleAppWithParams
{
class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Number of command line parameters = {0}",
args.Length);
foreach (string s in args)
{
Console.WriteLine(s);
}
Console.ReadLine();
}
}
}
Note that the parameters are coming from the command-line, so they are strings. You'd need to validate and convert the parameters if you need other data types.
You can call this from Excel VBA as follows:
Sub UseCSharpApp()
Shell "D:\Documents\ConsoleAppWithParams.exe Tom Dick Harry"
End Sub
If your C# application is fairly straightforward, then the only requirement would be for it to be copied to the expected directory, and for the correct version (or a more recent version) of the .NET Framework to be installed on the PC. If the C# app is written to target .NET Framework 2.0, then it's likely that most Windows PCs in a business environment would be able to use this, but obviously you should check whether that's the case in your environment.
Note that with this approach, you're limited to passing in values when first calling the application. This wouldn't be a useful solution in all scenarios, but might work if that's all you need to do.
Related
As I had never written a console application, I thought it was a good idea to start now. If only because of the fact that I find Visual Studio rather sluggish and the idea to be able to test code quickly on one of the playgrounds such as dotnetfiddle seems attractive. The default compiler on dotnetfiddle.net is on .NET 4.7.2 but I noticed that that one choked on the more recent code I borrowed. So I got used to the fact that I have to switch the compiler to .NET 5 to be able to take advantage of for instance niceties such as the $ to format text.
TL;DR
However, I found that a simple ReadLine() such as found in the example on https://dotnetfiddle.net/tAJulh doesn't work if you change the compiler to .NET 5. Has something changed in the specification of ReadLine in .NET 5 or is this a limitation of dotnetfiddle? And is there a way around this?
using System;
public class Program
{
public static void Main()
{
// Simply writes the following text to the standard output
Console.WriteLine("Input some text!");
// Reads text until you hit "enter"; and saves it to the "input"-variable
var input = Console.ReadLine();
// Writes the "input"-variable to the console.
Console.WriteLine("Your input was: " + input);
// The program will not exit until you hit "Enter".
Console.ReadLine();
}
}
You are absolutely right. Does look like an error on dotnetfiddle and you should report it here: https://dotnetfiddle.uservoice.com/forums/228764--net-fiddle-ideas
As far as i can tell, there is no way around it before they correct the bug.
As some other guys have stated i highly recommend that you get an IDE, this could be visual studio code or the plain visual studio
Personally i enjoy VS code for it's simplicity and it works great for C# and .net
I can confirm that Console.ReadLine isn't supported at the moment by dotnetfiddle and our's .NET Core implementation. The reason is that we use sandboxes since we need to be safe when we execute user's code. And for .NET 5 we are using docker while for regular .NET 4.7.2\Roslyn we are using AppDomains. In the docker case we are just compiling code and execute it as is. In the AppDomain case we are restricting it by injecting own code on top of user's code.
And since these ways are different, each of them might have some limitations over other. The problem with ReadLine is that when user runs own code, we need to partially execute it, then inject into Console.In stream and if something is requested from the stream, then we stop execution and ask user to provide input, and then after input is provided, we need to restart execution again and use that user's input in Console.In and repeat it over and over until code is fully executed. It's much easier to inject it for AppDomain so it works fine in .NET 4.7.2 but harder to do it in docker since we don't inject own code there so this feature is missing for now.
I want to integrate MATLAB Coder output with a C# project in Visual Studio 2010. My main idea is:
Create a *.m script in Matlab
Make sure the script is compatible with Matlab Coder.
Generate a C++ shared library (DLL) with Matlab Coder
Integrate with C# using something like this:
//Starts the model execution. May take several minutes
public static class DllHelper
{
[DllImport(#"test.dll",CallingConvention=CallingConvention.Cdecl,EntryPoint = "Run()")]
public static extern int Run();
}
Also, I would like to be able to stop the execution and retrieve some partial results. To do this, I was thinking in two methods: StopExecution and RetrievePartialResults
[DllImport(#"test.dll",CallingConvention=CallingConvention.Cdecl,EntryPoint = "StopExecution ()")]
public static extern int StopExecution ();
[DllImport(#"test.dll",CallingConvention=CallingConvention.Cdecl,EntryPoint = "RetrievePartialResults()")]
public static extern MyResults RetrievePartialResults();
Is it possible to do? If no, is there any alternatives? If yes, where can I find more examples?
I have no idea if your plan works, but MATLAB Builder NE might be an alternative. It directly outputs a .Net dll without those hard limitations to the m-code.
The disadvantage is, that MCR is required on the target machine.
I've done both ways. Formerly, our project was using MATLAB Compiler, but we now switched to Coder, because that avoids the overhead of having to install the runtime (which btw often failed to start inside the process for no apparent reason).
We compile the coder output as an unmanaged C project with a C interface and use a C++/CLR project as a wrapper. This has the advantage that we don't need to manually specify the interface for P/Invoke as the compiler will directly read the header files. The C++/CLR assembly is the linked to the C# project where the code is going to be used. Be aware that this is kind of expensive, so try to avoid calling the matlab code in a tight loop and better move the whole loop into the library if that is possible.
Here's a snippet from the wrapper library (still uses old Managed C++ syntax, but that doesn't matter here)
bool CTurconConnect2::Init()
{
// Call the exported function in the library. Imported using a header file.
turcon_initialize();
// Call one of the matlab functions (in this case, the entry function is manually defined
// in the C library, to have a clean interface)
SetParameters(36.0,400.0,20.0,30.0,15.0,40.0,110.0, 0.0, 100.0);
return true;
}
bool CTurconConnect2::Exit()
{
turcon_terminate();
return true;
}
I think your plan of writing a DLL and calling it from c# seems to be one of the two main ways to go.
The alternative would be to:
use the MATLAB as an automation server from C# using the engine
interface via com automation. This allows you to simultaneously debug
your C# application from both the C# side and the MATLAB side, using
debuggers on each side.
Here are examples for both methods, and even a third alternate method (that seems less recommended).
Integrating MATLAB with C# on File Exchange
I've achieved the exact functionality you're asking about using the MATLAB Compiler. I don't have any experience with the MATLAB Coder, but should be the same principle. Once you have a MATLAB Library compiled, you can access it using P/Invoke in C# like you would with any other unmanaged library (and as you specified in your question).
Theres a couple of caveats:
I think you might have an issue design-wise trying to successfully implement your "stop execution" strategy. The MATLAB executables/libraries are meant to execute from start to finish without much control over the runtime. If you can split your script up into multiple pieces to handle that design, that may work better.
Compiled MATLAB libraries require you to "Start" and "Stop" the MATLAB Component Runtime manually, as well as a component runtime for each script. So, execution flow, would be something like:
StartMCL();
StartScript1_Runtime();
Run_Script1();
StopScript1_Runtime();
StopMCL();
If you attempt to run the "Script 1 Runtime" prior to starting the overall MCL, the app will crash. So, you need to be careful with how you design the wrapper class to handle that properly. Also, you want to be sure to Stop everything before exiting your app, otherwise, the MCR will effectively see 2 "Runs" in a row, and will crash.
You didn't cover any input/output arguments in your question, but in most cases, you will need to use MATLAB functions to create the MEX variables to hand data in/out of the MATLAB environment.
There is a great set of sample source here that should cover all of the above:
http://www.mathworks.com/matlabcentral/fileexchange/12987-integrating-matlab-with-c
Also, the Compiler help itself has a bunch of useful resources.
http://www.mathworks.com/help/compiler/shared-libraries.html
So in a list form,
I doubt that you will be able to stop the matlab code unless you break it up into multiple functions, which you may call as needed.
That you should be able to halt execution by calling on a thread and stopping the thread as you need, or better, send a signal for the thread to stop, which it will abort between functions (for the purpose of partial results)
That matlab is a terrible language for fulfilling the requirements on item 1 (not that I have ever had any good experiences with it myself)
I have used reflector until its trial period ended
I have decoded many applications successfully. And by my recent post i was able to identify it can also decode delphi.net vcl apps (d2007).
Can i decode delphi.net vcl and translate it to a c# application which can be compiled success fully using visual studio.
The answer to the question Can i decode delphi.net vcl app and translate it to a c# application which can be compiled success fully using visual studio ? is No
This is the Why.
When you create a vcl net application using delphi (8), 2005, 2006 or 2007, the delphi compiler create an .NET application with a lot of dependencies to internal classes which are wrappers and helpers to call the real .net classes, these classes (wrappers) was created to facilitate the creation of .net applications to the existing delphi win32 developers.
Consider this sample.
This a delphi .net app
program DelphiNetConsole;
{$APPTYPE CONSOLE}
uses
SysUtils;
begin
try
Writeln('Hello From Delphi 2007.Net');
except
on E:Exception do
Writeln(E.Classname, ': ', E.Message);
end;
end.
if you translate manually this code to C#
using System;
using System.Text;
namespace ConsoleApplication8
{
class Program
{
static void Main(string[] args)
{
try
{
Console.WriteLine("Hello From Delphi 2007.Net");
}
catch (System.Exception E)
{
Console.WriteLine(E.Message);
}
}
}
}
But using reflector you get this for the first snippet
public static void DelphiNetConsole()
{
System.IsConsole = true;
try
{
TextOutput.Output.WriteWideString("Hello From Delphi 2007.Net", 0).WriteLn();
System.#_IOTest();
}
catch (Exception exception1)
{
Exception exception2 = System.#ExceptObject = exception1;
Exception E = exception1;
TextOutput.Output.WriteWideString(TObjectHelper.ClassName(System.#GetMetaFromObject(E)), 0).WriteWideString(": ", 0).WriteWideString(E.Message, 0).WriteLn();
System.#_IOTest();
System.#ExceptObject = null;
}
}
As you can see the last code call a lot of helper classes and functions (like TextOutput) which are not part of the standard .net framework, rather they are part of the Borland.Delphi.System namespace.
Reflector can help you to translate some snippets of code but not the full application in an automated way.
The answer is no, and even if you deploy the corresponding Delphi assemblies, such as Borland.Delphi.dll and Borland.Vcl.dll, you have structures that have no equivalent in C#, such as class references, that cannot be used within Visual Studio/C#. I managed to convert about 80,000 lines of a non-visual application framework in Delphi to use in Visual Studio/C#, but it took me over 3 months and I had to convert code that used things like class references to use the System.Type class, amongst other things. After all this work, and with the deployment of some basic Delphi assemblies, an Indy assembly, and a Jcl assembly, I can now develop in either Delphi or Visual Studio and maintain communication compatibility between the two types of applications.
One other thing I did is to run some custom pre-processing of the source code before building to strip of the "T..." type prefix so that the actual framework assemblies look just like C# assemblies when used in Visual Studio. This was no easy task but was made possible by the fact that all types, constants, etc in my framework were ALL prefixed as well by either "Csi", "App", "Fwk", or "Dev". Without this I could not have stripped off the Deplhi-specific identifier naming conventions.
Unless there is an overwhelming benefit for doing this which outweighs the cost (like me), and your code is essentially non-visual (like me), the amount of effort involved is likely to be far too great to justify the work. I wonder if I am the only Delphi developer in the world to succesfully have migrated a significant amount of code from Delphi for use in Visual Studio. Nobody else seems to be able to provide a success story like this, which really makes you wonder how feasible this is.
My application needs to:
Run an external command-line application
Capture the standard output/error during execution
Parse the data from the output/error and use it for status display in the main app
While it's not hard to do it, it seems to me it's a very common task, and I was wondering if there's a library or framework simplifying this task in C#.
Edit: Here's a "Mono.Options inspired" example of the kind of thing I'm looking for:
ProcessWithParser proc= new ProcessWithParser(filename, arguments);
proc.AddWatch("percent=??", v => this.percent = Convert.ToInt32(v));
proc.Start();
In the "concept" above, it would locate "percent=" in the output, read the next two characters as a string, and call the delegate using this string as a parameter.
The base class library provides the tools for this already - there isn't much a framework would really need to add to it.
Redirection of the process standard input and output streams is trivial. RegEx and using streams makes parsing this fairly easy, as well.
The framework pretty much does what any (flexible) custom library would normally do in other languages.
This question already has answers here:
Closed 14 years ago.
DUPLICATE:Login method Customization using GINA
Hi All,
I know it's not easy to find a master in GINA, but my question is most near to Interprocess Communication(IPC), I wrote my custom GINA in unmanaged c++, I included it a method that checks for validity of a fingerprint for the user try to login, this function will call some method in a running system windows service written in c#, the code follows:
in GINA, unmanaged c++
if(Fingerprint.Validate(userName,finerprintTemplate)
{
//perform login
}
in windows service, C#
public class Fingerprint
{
public static bool Validate(string userName, byte[] finerprintTemplate)
{
//Preform Some code to validate fingerprintTemplate with userName
//and retuen result
}
}
Does anyone know how to do such Communication between GINA and the windows service, or simply between c++ written service and C# written service.
Thanks
The canonical method for communicating with a service (or most IPC that potentially needs to cross a session/desktop boundary) is a named pipe. You can use mailslots as well, but you have to deal with duplication issues because mailslot messages get duped across all installed protocols, so you need some kind of tagging system... gets kinda messy.
See the docs for CreateNamedPipe and work your way out from there. I have talked between C++ and C# using pipes: the interop got a little messy (binary messages), but its do-able. There's some sample code for C# pipes (from both sides) here.
The nice thing about using a pipe for your specific service to service comms problem is you can expand the design later on to support a UI if you need it.