Probably the inline tasks for msbuild will remain the best method for .net hybridization. But this will require .net framework 4.6 (can it be installed on something different than windows 10?) so it is not so portable.
Using c# without msbuild will produce redundant output because of the '// 2>nul||@goto :batch' line (vb.net also will produce something similar). JScript.net does not support syntax sugaring for platform invokes but it is still possible (
http://cx20.main.jp/blog/hello/2013/03/ ... net-world/):
Code: Select all
@if (@X)==(@Y) @end /* JScript comment
@echo off
setlocal
set "jsc="
for /r "%SystemRoot%\Microsoft.NET\Framework\" %%# in ("*jsc.exe") do set "jsc=%%#"
if not exist "%jsc%" (
echo no .net framework installed
exit /b 10
)
::if not exist "%~n0.exe" (
call "%jsc%" /r:"System.Windows.Forms.dll" /nologo /out:"%~n0.exe" "%~dpsfnx0"||(
exit /b %errorlevel%
)
::)
"%~n0.exe"
endlocal & exit /b %errorlevel%
*/
import System;
import System.Reflection;
import System.Reflection.Emit;
import System.Runtime;
import System.Text;
// Invoke a Win32 P/Invoke call.
// http://www.leeholmes.com/blog/2006/07/21/get-the-owner-of-a-process-in-powershell-%e2%80%93-pinvoke-and-refout-parameters
function InvokeWin32(dllName:String, returnType:Type,
methodName:String, parameterTypes:Type[], parameters:Object[])
{
// Begin to build the dynamic assembly
var domain = AppDomain.CurrentDomain;
var name = new System.Reflection.AssemblyName('PInvokeAssembly');
var assembly = domain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);
var module = assembly.DefineDynamicModule('PInvokeModule');
var type = module.DefineType('PInvokeType',TypeAttributes.Public + TypeAttributes.BeforeFieldInit);
// Define the actual P/Invoke method
var method = type.DefineMethod(methodName, MethodAttributes.Public + MethodAttributes.HideBySig + MethodAttributes.Static + MethodAttributes.PinvokeImpl, returnType, parameterTypes);
// Apply the P/Invoke constructor
var ctor = System.Runtime.InteropServices.DllImportAttribute.GetConstructor([Type.GetType("System.String")]);
var attr = new System.Reflection.Emit.CustomAttributeBuilder(ctor, [dllName]);
method.SetCustomAttribute(attr);
// Create the temporary type, and invoke the method.
var realType = type.CreateType();
return realType.InvokeMember(methodName, BindingFlags.Public + BindingFlags.Static + BindingFlags.InvokeMethod, null, null, parameters);
}
function MessageBox(hWnd:Int32, lpText:String, lpCaption:String, uType:Int32)
{
var parameterTypes:Type[] = [Type.GetType("System.Int32"),Type.GetType("System.String"),Type.GetType("System.String"),Type.GetType("System.Int32")];
var parameters:Object[] = [hWnd, lpText, lpCaption, uType];
return InvokeWin32("user32.dll", Type.GetType("System.Int32"), "MessageBoxA", parameterTypes, parameters );
}
MessageBox( 0, "Hello, Win32 API World!", "Hello, World!", 0 );
the interesting part is in the InvokeWin32 function (nothing so complicated and can't be used directly without knowing too much about reflection ).
Despite it is no more supported by MS jscript.net is the most backward compatible .net tool installed by default on Windows machines (it is not installed on win XP by default though it is highly probable ,but it is time to let XP die anyway).
With pure batch scripts and with WSH/jscript/vbscript there are limits that can't be overcome without accessing windows system libraries - so jscript.net is a worthy thing to dig in.
Probably I'll try to 'translate' the tools I've wrote with C# to jscript.net and if possible to update the examples in
http://pinvoke.net/