C# GetLastInputInfo未返回dwTime

C# GetLastInputInfo未返回dwTime,c#,winforms,winapi,interop,user32,C#,Winforms,Winapi,Interop,User32,我有以下代码: using System; using System.Runtime.InteropServices; public class WindowsFunctions { [System.Runtime.InteropServices.DllImport("user32.dll")] static extern bool GetLastInputInfo(ref LASTINPUTINFO plii); public static in

我有以下代码:

using System;
using System.Runtime.InteropServices;

public class WindowsFunctions
{
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);

    public static int TicksSinceLastInput()
    {
        var info = new LASTINPUTINFO();
        GetLastInputInfo(ref info);
        var lastInputTickCount = info.dwTime;
        return (int)lastInputTickCount;
    }
}

[StructLayout(LayoutKind.Sequential)]
struct LASTINPUTINFO
{
    public static readonly int SizeOf = Marshal.SizeOf(typeof(LASTINPUTINFO));

    [MarshalAs(UnmanagedType.U4)]
    public UInt32 cbSize;
    [MarshalAs(UnmanagedType.U4)]
    public UInt32 dwTime;
}
但是,在运行时,
info.dwTime
为零

在VSIDE中运行

更新
我尝试使
ticksincelastInput
不是静态的,无论哪种方式都失败。
我失败的单元测试现在是:

[TestMethod]
public void TestTicksSinceLastInput()
{
    var funcs = new WindowsFunctions();
    var ticks = funcs.TicksSinceLastInput();
    Assert.IsTrue( ticks > 0);
}
更新
我的代码是:

public class WindowsFunctions
{
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);

    public  int TicksSinceLastInput()
    {
        var info = new LASTINPUTINFO();
        var result = GetLastInputInfo(ref info);
        var lastInputTickCount = info.dwTime;
        return (int)lastInputTickCount;
    }
}

结果被设置为false。

显示的
LASTINPUTINFO
的声明来自。
结构包含一个静态int:

public static readonly int SizeOf = Marshal.SizeOf(typeof(LASTINPUTINFO));
它可能看起来像是在定义结构的大小,但实际上没有实际用途

在原始代码中,结构的
cbSize
成员未初始化,必须初始化:它指定结构本身的大小;分配它是强制性的

函数声明是正确的:

[DllImport("user32.dll")]
static extern bool GetLastInputInfo(ref LASTINPUTINFO info);
它的返回类型是
BOOL
(定义为
typedef int BOOL
),而不是
BOOLEAN
(定义为
typedef BYTE BOOLEAN
)。
BOOL
是管理的,它不需要:

[return: MarshalAs(UnmanagedType.Bool)]
可以简化结构的声明和初始化,以包括初始化其成员的非空构造函数:

[StructLayout(LayoutKind.Sequential)]
struct LASTINPUTINFO
{
    public uint cbSize;
    public uint dwTime;

    public LASTINPUTINFO(uint init) {
        cbSize = (uint)Marshal.SizeOf<LASTINPUTINFO>();
        dwTime = init;
    }
}

我看不到您正在初始化
cbSize
。你算了算,但我没有看到任何初始化。Pinvoke.net永远是你的朋友:谢谢大家。我有它现在工作,我没有正确初始化。PInvoke中的代码是正确的
// Better resolution than System.Windows.Forms.Timer
System.Timers.Timer sysIdleTimer = null;
// [...]

protected override void OnLoad(EventArgs e) {
    base.OnLoad(e);

    sysIdleTimer = new System.Timers.Timer() {
        Interval = 100,
        SynchronizingObject = this // Marshal events to the UI Thread
    };
    sysIdleTimer.Elapsed += this.OnTimerElapsed;
    sysIdleTimer.Start();
}

// [...]

static uint GetLastInputTimeMilliseconds()
{
    var info = new LASTINPUTINFO(0);
       
    if (GetLastInputInfo(ref info)) {
        // Valid wihin 24.9 days of machine activity
        uint idleTime = (uint)Environment.TickCount - info.dwTime;
        return idleTime;
    }
    return 0;
}

// [...]
protected void OnTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    // Shows the Input Idle time in a Label
    this.lblInputIdle.Text = $"Idle Time: {GetLastInputTimeMilliseconds()} milliseconds";
}