I want to use msscript.ocx to call VBScript from C#, and allow the VBScript code to call back to functions in the C# program.
For example, in the following VBScript code, Clicktext is a custom C# function in the same clsss that is using msscript.ocx to run the VBScript.
For i=0 to i=4
Clicktext("Auto")
Next
The Clicktext function shoud be called 5 times.
Is there any way to do it?
This ComVisible console application with a reference to Interop.MSScriptControl:
// !! http://sandsprite.com/blogs/index.php?uid=11&pid=83
using System;
using MSScriptControl;
//class test has to support IDispatch to AddObject(). So make the assembly ComVisible
//via AssemblyInfo.cs or [assembly: System.Runtime.InteropServices.ComVisible(true)]
namespace MsScTest {
public class CsHelper {
public int increment(int y) { return ++y; }
}
class Program {
public static MSScriptControl.ScriptControl sc = new ScriptControl();
static void Main(string[] args) {
sc.Language = "VBScript";
sc.AddObject("CsHelper", new CsHelper(), true);
sc.AddCode(#"
Function inc(n)
inc = CsHelper.increment(n)
End Function
MsgBox inc(4711), 0, 'With a little help from my friend CsHelper'
".Replace("'", "\""));
return;
}
}
}
pudding:
---------------------------
With a little help from my friend CsHelper
---------------------------
4712
---------------------------
OK
---------------------------
demonstrates how to call a method of a C# object from VBScript code added to a MSScriptControl.
Related
I have created a console application .NET 6.0 for learning of Singleton Pattern.
But I have observed a significant change in Program.cs file.
namespace, class and Main method have been removed from program.cs in .NET 6.0.
I believe the code that will be written in program.cs will be considered as within Main method.
But I want to create two static methods which are using globally intialized instances but I am not able to do that.
By declaring the instances like below:
It gives Compile Error:
CS0106 The modifier 'static' is not valid for this item
While using the instances in static methods like below:
It gives Compile Error:
CS8421: A static local function cannot contain a reference to
'tableservers1'.
Here is all the code of program.cs :
using SingletonApp;
static TableServers tableservers1 = TableServers.GetInstance();
static TableServers tableservers2 = TableServers.GetInstance();
Console.WriteLine("Hello, World!");
for (int i = 0; i < 5; i++)
{
Host1();
Host2();
}
Console.WriteLine();
static void Host1()
{
Console.WriteLine("Host1 Next server is: " + tableservers1.GetNextServer());
}
static void Host2()
{
Console.WriteLine("Host2 Next server is: " + tableservers2.GetNextServer());
}
Please someone can explain how can we use this new minified program.cs, specially to use global instance and variables and creating methods.
As in this answer since C# 10 you can achieve this by introducing public partial class Program (at the bottom of you top level statement file or in separate file):
// rest of your top-level statement code
// ...
public partial class Program
{
static TableServers tableservers1 = TableServers.GetInstance();
static TableServers tableservers2 = TableServers.GetInstance();
}
But I would argue that switching to "old style" Program class or moving static fields to another class would be a better option.
I'm trying to build a a simple C# application to test passing data between languages. I have a simple main in C# calling a function that I wish to pass to C++:
using System;
namespace CS_Console
{
class Program
{
static void Main(string[] args)
{
CPP_Sum(5, 2); //pseudo code
}
}
}
and then the function in a C++ project:
CPP_Sum(int x, int y)
{
return x+y;
}
The problem is, I don't even know where to start on how to pass these between each other.
This is being done via two projects, CS_Console and CPP_Console, in the same solution in Visual Studio.
It has already been mentioned by #steveo314. The easiest way to call a C++-based function from C# is using PInvoke. I assume you can create a DLL without any documentation but this looks like it will give you all the information you need to use your DLL from C#.
Basically:
Put your function as a C++ DLL; then
Use a DllImport attribute to create a function prototype in your C# code.
Make sure you export your C++ function definitions.
Daniel's answer above is also correct, but if you really want to dive into the guts of this, you may want to learn C++/CLI, as that's more or less C++ running on top of the .NET framework, with more precise interop, and depending on where/what your DLL is, communication both ways (P/Invoke is just calling C++, not calling back into .NET... usually).
C++/CLI allows this kind of thing:
public class Program
{
public void main(String [] args)
{
NativeWrapper wrapper = new NativeWrapper(); // C++/CLI ref class
wrapper.doStuff("hey there!");
}
}
In a C++/CLI DLL, in the .h file:
// This is C++/CLI
class NativeClass; // Forward declare
ref class NativeWrapper
{
public:
NativeWrapper(); // Constructor - MUST be in .cpp file, as size of NativeClass not known here
~NativeWrapper(); // Destructor - MUST be in .cpp file, same reason as above
void doStuff(System::String^ inputString);
private:
NativeClass* mp_impl;
};
In a C++/CLI .cpp file:
class NativeClass // True C++ class, could be defined elsewhere!
{
public:
void nativeDoStuff(const std::string& inputString)
{
std::cout << "Previous input was: '" << cachedResult << "'";
cachedResult = inputString;
}
private:
std::string cachedResult{};
};
NativeWrapper::NativeWrapper()
{
mp_impl = new NativeClass();
}
NativeWrapper::~NativeWrapper()
{
delete mp_impl;
mp_impl = nullptr;
}
// Utility function!
std::string _convertClrString(System::String^ instr)
{
marshal_context context;
std::string mystring{ context.marshal_as<const char*>(instr) };
return mystring;
}
void NativeWrapper::doStuff(System::String^ inputString)
{
auto native_string = _convertClrString(inputString);
mp_impl->nativeDoStuff(native_string);
}
It's a toy example (necessary includes removed), but hopefully that gets the idea across of what's possible with C++/CLI. The link I put near the top is the main start of the resources at Microsoft for doing this. Keep in mind what files are compiling as .NET, which aren't (you can do it per-file), and what that all means.
I need to call a native method of an unmanaged DLL From C#.
DLL source code is not available of course (provided by a "third party").
Native DLL method is supposed to accept two arguments and returns a (native) integer code:
MyDLLNativeMethod(string filename, int returncode)
The first argument of native DLL method is a string (filename) & second has to be a "reference" to gather return code after execution. I'm confused about how to get return code. DLL calls are working properly, producing expected files based on first argument.
How should I implement the desired callback to perform operation on different return codes values retrieved?
// ~~~~~~~~~~~~~~~~~~~~
// Main entry point
// ~~~~~~~~~~~~~~~~~~~~
namespace MyProject
{
class Program
{
static void Main(string[] args)
{
MyDLLCaller _dllcaller = new MyDLLCaller();
_dllcaller.MyDLLNativeMethod("test_file.txt");
}
}
}
// ~~~~~~~~~~~~~~~~~~~~
// DLL calling class
// ~~~~~~~~~~~~~~~~~~~~
namespace MyProject
{
class MyDLLCaller
{
// DLL Loading
[DllImport(#"C:\test\mydll.dll")]
public static extern int MyDLLNativeMethod(string _filename);
// Native DLL method pseudo code :
// MyDLLNativeMethod(string filename, int returncode).
}
}
Thanks in advance
If the return code is the second parameter I think you should use out keyword for this:
int returncode = 0;
[DllImport(#"C:\test\mydll.dll")]
public static extern int MyDLLNativeMethod(string _filename, out int returncode);
if(returnCode != 0)
{
// something went wrong
}
Try it with some file that you know should return error code.
If the above declaration for the external call works with your library, you get the return code from the call.
var retCode = _dllcaller.MyDLLNativeMethod("test_file.txt");
I found a technet blog article the said it was possible to have PowerShell use C# code.
Article: Using CSharp (C#) code in Powershell scripts
I found the format I need to get the C# code to work in PowerShell, but if it don't pass the Main method an argument ([namespace.class]::Main(foo)) the script throws an error.
Is there a way I can pass a string of "on" or "off" to the main method, then depending on which string is passed run an if statement? If this is possible can you provide examples and/or links?
Below is the way I'm currently trying to structure my code.
$Assem = #( //assemblies go here)
$source = #"
using ...;
namespace AlertsOnOff
{
public class onOff
{
public static void Main(string[] args )
{
if(args == on)
{//post foo }
if(arge == off)
{ //post bar }
}
"#
Add-Type -TypeDefinition $Source -ReferencedAssumblies $Assem
[AlertsOnOff.onOff]::Main(off)
#PowerShell script code goes here.
[AlertsOnOff.onOff]::Main(on)
Well to start, if you are going to compile and run C# code, you need to write valid C# code. On the PowerShell side, if you invoke Main from PowerShell, you need to pass it an argument. PowerShell will automatically put a single argument into an array for you, but it won't insert an argument if you don't have one. That said, its not clear why this is in a Main method. It's not an executable. It could very well just have two static methods, TurnOn and TurnOff. The code below compiles and runs, modify as you see fit:
$source = #"
using System;
namespace AlertsOnOff
{
public class onOff
{
public static void Main(string[] args)
{
if(args[0] == `"on`")
{
Console.WriteLine(`"foo`");
}
if(args[0] == `"off`")
{
Console.WriteLine(`"bar`");
}
}
}
}
"#
Add-Type -TypeDefinition $Source
[AlertsOnOff.onOff]::Main("off")
# Other code here
[AlertsOnOff.onOff]::Main("on")
I'm converting an .NET Windows application for Mono to run on Linux (Ubuntu). One of the features depends on a native library (user32.dll). The Mono guide that talks about conversion of applications (Linux Platform Differences) suggests that one approach would be to modify this code.
I'm trying to use GDK to access the Title of a Gdk.Window that I had access through the property Gdk.Global.ActiveWindow. But I found this error at compile time:
Error CS0154: The property or indexer `Gdk.Window.Title` cannot be used in this context because it lacks the `get` accessor (CS0154) (GetActiveWindow)
If i remove the code that reads de Title property of activeW, everything works fine. There is another way to read this property?
Here my unit of work:
using System;
using Gtk;
using Gdk;
using System.Threading;
namespace GetActiveWindow
{
class GdkApp : Gtk.Window
{
public static void Main ()
{
Application.Init ();
new GdkApp ();
Application.Run ();
}
public GdkApp () : base("Simple App")
{
SetDefaultSize (150, 150);
ShowAll();
while (true) {
var activeW = Gdk.Global.ActiveWindow;
Console.WriteLine("Active Window: {0}",activeW.Title); // Where my compile error happens.
Console.WriteLine("Simple App Window: {0}",this.Title); // This code works perfectily.
Thread.Sleep(1000);
}
}
}
}
I think that with Gdk is imposible. Try it with Wnck library giving to a C compiler this '-DWNCK_I_KNOW_THIS_IS_UNSTABLE' and works but with a warning: Unhandled action type _OB_WM_ACTION_UNDECORATE
Sorry I have used genie instead vala.
//valac *.gs --pkg gtk+-3.0 --pkg libwnck-3.0 -X '-DWNCK_I_KNOW_THIS_IS_UNSTABLE'
init
Gtk.init(ref args)
var ventana= new win()
ventana.inicio()
ventana.printinfo()
Gtk.main()
class win:Gtk.Window
won:weak GLib.List of Wnck.Window
def inicio()
var button= new Gtk.Button()
button.clicked.connect(printinfo)
this.add(button)
this.show_all()
def printinfo()
won= Wnck.Screen.get_default().get_windows()
won.foreach(allwin)
def allwin(w:Wnck.Window)
if w.is_skip_tasklist() or w.is_skip_pager()
pass
else
print w.get_name()