在.NET中是否可以在子进程中执行方法(委托,静态方法,等等)? System.Diagnostics.Process似乎需要一个实际的文件名,这意味着需要一个单独的可执行文件.
我要做的是在单元测试中验证在进程退出时是否清理了OS资源.我知道可以使用CodeDOM或IL生成来创建这样的程序集并执行它,但单元测试的重点是隔离组件,而不是创建复杂性.出于同样的原因,我想完全避免单独的组装.
理想情况下,我会做类似的事情:
public static void CreateCounter()
{
var counter = new PerformanceCounter("category", "counter", "instance");
counter.InstanceLifetime = PerformanceCounterInstanceLifetime.Process;
}
[Test]
public void TestResourceDisposal()
{
// Start child process to execute CreateCounter()
...
// verify the resource is disposed
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试在F#应用程序中使用P/Invoke设置一个低级键盘钩子.Win32函数SetWindowsHookEx接受HOOKPROC第二个参数,我将其表示为委托(int * IntPtr * IntPtr) -> IntPtr,类似于在C#中处理它的方式.在调用方法时,我得到一个MarshalDirectiveException声明,委托参数无法封送,因为
通用类型无法编组
我不确定如何涉及泛型,因为具体指定了所有类型.任何人都可以对此有所了解吗?代码如下.
编辑
这可能与F#编译器处理类型签名的方式有关 - Reflector指示委托LowLevelKeyboardProc实现为接受一个类型的参数的方法Tuple<int, IntPtr, IntPtr>- 并且将存在不可编组的泛型类型.有没有办法解决这个问题,或者F#函数是不是能够被编组到本机函数指针?
let WH_KEYBOARD_LL = 13
type LowLevelKeyboardProc = delegate of (int * IntPtr * IntPtr) -> IntPtr
[<DllImport("user32.dll")>]
extern IntPtr SetWindowsHookEx(int idhook, LowLevelKeyboardProc proc, IntPtr hMod, UInt32 threadId)
[<DllImport("kernel32.dll")>]
extern IntPtr GetModuleHandle(string lpModuleName)
let SetHook (proc: LowLevelKeyboardProc) =
use curProc = Process.GetCurrentProcess ()
use curMod = curProc.MainModule
SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curMod.ModuleName), 0u)
Run Code Online (Sandbox Code Playgroud) 我正在尝试发出一个实例化System.Lazy并在PEVerify失败时出现"无效令牌"错误的方法 newobj instance void class [mscorlib]System.Lazy`1<class Example.ExpensiveType>::.ctor(class [mscorlib]System.Func`1<class Example.ExpensiveType>)
使用ILDasm查看其他地方,我看到正确的调用将如下所示:
newobj instance void class [mscorlib]System.Lazy`1<class Example.IHeater>::.ctor(class [mscorlib]System.Func`1<!0>)
Run Code Online (Sandbox Code Playgroud)
不幸的是,我对如何使用Mono.Cecil API重现这一点感到茫然.有人可以帮助使用仿制药吗?
这是我到目前为止所拥有的:
var get = new MethodDefinition(
"Get",
MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual,
ModuleDefinition.TypeSystem.Object);
var funcType = new GenericInstanceType(ImportedTypes.FuncOfT);
funcType.GenericArguments.Add(lazyElementType);
var funcTypeCtor = new MethodReference(".ctor", ModuleDefinition.TypeSystem.Void, funcType);
funcTypeCtor.Parameters.Add(new ParameterDefinition(ModuleDefinition.TypeSystem.Object));
funcTypeCtor.Parameters.Add(new ParameterDefinition(ModuleDefinition.TypeSystem.IntPtr));
funcTypeCtor.HasThis = true;
funcTypeCtor = ModuleDefinition.Import(funcTypeCtor);
var lazyTypeCtor = new MethodReference(".ctor", ModuleDefinition.TypeSystem.Void, lazyType);
var parameterDefinition = new ParameterDefinition(funcType);
lazyTypeCtor.Parameters.Add(parameterDefinition);
lazyTypeCtor.HasThis = true;
lazyTypeCtor = ModuleDefinition.Import(lazyTypeCtor);
il = get.Body.GetILProcessor();
il.Emit(OpCodes.Ldarg_0); …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用本机API方法(GetNativeSystemInfo),该方法在Windows 8.1上标记为支持手机和桌面应用商店应用.在文档中,它被列为生活在kernel32.dll中.大!所以我对P/Invoke的第一次尝试看起来像这样:
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = false, PreserveSig = true)]
private static extern void GetNativeSystemInfo(ref SYSTEM_INFO lpSysInfo);
Run Code Online (Sandbox Code Playgroud)
不幸的是,这无法在实际设备上运行 - 找不到kernel32!碰巧,有是 kernelBase.dll,这样我的第二次尝试:
[DllImport("kernelBase.dll", CharSet = CharSet.Unicode, ExactSpelling = false, PreserveSig = true)]
private static extern void GetNativeSystemInfo(ref SYSTEM_INFO lpSysInfo);
Run Code Online (Sandbox Code Playgroud)
虽然这在我的手机上运行良好,但它会导致应用程序无法通过认证; 方法名称和"kernelBase.dll"似乎没有列入白名单.
这是对WACK的监督,还是导致此API在商店应用中无法使用的错误?我的目标是获取有关正在运行的处理器(架构,类型等)的信息,我不想为了这么简单的事情而使用C++.如果此API在实践中不可用,是否有其他方法可以获取此信息?
c# pinvoke windows-runtime windows-store-apps windows-phone-8.1