【问题标题】:Why does my application just stop and does not keep running?为什么我的应用程序只是停止而不继续运行?
【发布时间】:2020-05-07 15:51:32
【问题描述】:

我正在尝试制作一个执行此操作的程序(C#):

  1. 如果我单击鼠标左键,鼠标应该向左移动一个 DeltaX。

问题是,当我运行程序时,它只是打开了控制台应用程序,但没有任何反应。我不确定我在这里做错了什么。 它应该继续运行并检查我是否单击鼠标左键,当我单击它时,光标应该向左移动一个 DeltaX。

代码

using System.Data;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;

namespace Teste
{
    class Program
    {
        static void Main(string[] args)
        {
            var someClass = new Up();
            someClass.Update();
        }
    }
        public class Up
        {
            [DllImport("user32.dll")] static extern short GetAsyncKeyState(int vKey);
            [DllImport("USER32.dll")] static extern short GetKeyState(int nVirtKey);

            int msShootTime = 225;
            System.DateTime lastClick = System.DateTime.Now;

            bool isRunning = true;
            public async void Update()
            {

                while (true)
                {
                    if (isRunning)
                    {
                        await Task.Delay(10);
                        continue;
                    }
                    int res = GetKeyState((int)1);
                    if (res >= 0)
                    {
                        await Task.Delay(1);
                        continue;
                    }
                    Move(-10, 0, true);
                }
            }



            private const int MOUSEEVENTF_LEFTDOWN = 0x02;
            private const int MOUSEEVENTF_LEFTUP = 0x04;
            private const int MOUSEEVENTF_RIGHTDOWN = 0x08;
            private const int MOUSEEVENTF_RIGHTUP = 0x10;


            [DllImport("user32.dll")]
            static extern void mouse_event(int dwFlags, int dx, int dy, uint dwData, UIntPtr dwExtraInfo);

            public void Move(int xDelta, int yDelta, bool pressDown = false)
            {
                if (pressDown)
                {
                    if (System.DateTime.Now.Subtract(lastClick).TotalMilliseconds < msShootTime)
                    {
                        pressDown = false;
                    }
                    else
                    {
                        lastClick = System.DateTime.Now;
                    }
                }

                mouse_event(pressDown ? (MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP) : 0x0001, xDelta, yDelta, 0, UIntPtr.Zero);

            }
        }
}

【问题讨论】:

  • 您似乎对应用程序类型有一个根本性的误解。控制台应用程序不允许您响应鼠标点击(至少不容易)。您需要一个 GUI 应用程序。然后您将能够响应鼠标点击。你没有说你在什么环境下运行,所以很难给你任何进一步的方向。
  • @Optimax GetAsyncKeyState() 允许在此处检测鼠标点击(并通过mouse_event移动鼠标指针(而不是插入符号))。但是isRunning 有点毁了一切。然后,由于当鼠标按钮按下时,该函数返回一个SHORT(不是C#short :),res 永远不会是&gt; 0,但它几乎总是=0,所以鼠标指针会不断移动(当isRunning 不在图片中时)。
  • @Jimi 我说“容易”。我希望“伪 GUI”控制台应用程序成为过去。 OP没有说必须使用控制台。这看起来也是一个非常人为的问题。就像作业一样,也许......
  • @Optimax 这看起来像是一个测试,也许是为了了解这一切如何运作,我不能说。无论如何,只需进行一些更改(如所述),它就可以工作。
  • 我忘了说someClass.Update();调用应该改成Task.Run(() =&gt; someClass.Update());

标签: c#


【解决方案1】:

一些错误在代码中,我已经在代码中直接添加了一些 cmets

class Program
{
    static async Task Main(string[] args) // made Main async
    {
        var someClass = new Up();
        await someClass.Update(); // awaiting async method, you didn't wait it and app have to exit immediately
    }
    public class Up
    {
        [DllImport("user32.dll")]
        private static extern short GetAsyncKeyState(int vKey);
        [DllImport("user32.dll")]
        private static extern short GetKeyState(int nVirtKey);

        // just copied mouse_event and Flags from one of my projects but yours worked too
        [DllImport("user32.dll")]
        private static extern void mouse_event(MouseFlags dwFlags, int dx, int dy, uint dwData, UIntPtr dwExtraInfo);

        [Flags]
        private enum MouseFlags : uint 
        {
            MOUSEEVENTF_ABSOLUTE = 0x8000,   // If set, dx and dy contain normalized absolute coordinates between 0 and 65535. The event procedure maps these coordinates onto the display surface. Coordinate (0,0) maps onto the upper-left corner of the display surface, (65535,65535) maps onto the lower-right corner.
            MOUSEEVENTF_LEFTDOWN = 0x0002,   // The left button is down.
            MOUSEEVENTF_LEFTUP = 0x0004,     // The left button is up.
            MOUSEEVENTF_MIDDLEDOWN = 0x0020, // The middle button is down.
            MOUSEEVENTF_MIDDLEUP = 0x0040,   // The middle button is up.
            MOUSEEVENTF_MOVE = 0x0001,       // Movement occurred.
            MOUSEEVENTF_RIGHTDOWN = 0x0008,  // The right button is down.
            MOUSEEVENTF_RIGHTUP = 0x0010,    // The right button is up.
            MOUSEEVENTF_WHEEL = 0x0800,      // The wheel has been moved, if the mouse has a wheel.The amount of movement is specified in dwData
            MOUSEEVENTF_XDOWN = 0x0080,      // An X button was pressed.
            MOUSEEVENTF_XUP = 0x0100,        // An X button was released.
            MOUSEEVENTF_HWHEEL = 0x01000     // The wheel button is tilted.
        }

        int msShootTime = 225;
        DateTime lastClick = DateTime.Now;

        bool isRunning = false; // it was initially true
        public async Task Update() // async Task
        {

            while (true)
            {
                if (isRunning) // it was always true
                {
                    await Task.Delay(10);
                    continue; // this was always executed
                }
                isRunning = true; // added this
                int res = GetKeyState((int)1);
                if (res >= 0)
                {
                    await Task.Delay(1);
                    isRunning = false; // added this
                    continue;
                }
                Move(-10, 0, true);
                isRunning = false; // added this
            }
        }

        public void Move(int xDelta, int yDelta, bool pressDown = false)
        {
            if (pressDown)
            {
                if (System.DateTime.Now.Subtract(lastClick).TotalMilliseconds < msShootTime)
                {
                    pressDown = false;
                }
                else
                {
                    lastClick = System.DateTime.Now;
                }
            }

            // updated for new Flags enum
            // I'm not sure if sending both MOUSEEVENTF_LEFTDOWN and MOUSEEVENTF_LEFTUP will give any effect
            // try to send it sequentially with some delay: DOWN, then UP
            mouse_event(pressDown ? (MouseFlags.MOUSEEVENTF_LEFTDOWN | MouseFlags.MOUSEEVENTF_LEFTUP) : MouseFlags.MOUSEEVENTF_MOVE, xDelta, yDelta, 0, UIntPtr.Zero);
        }
    }
}

注意:Microsoft 建议使用SendInput 而不是mouse_event

此功能已被取代。请改用SendInput

【讨论】:

    猜你喜欢
    • 2020-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-18
    • 1970-01-01
    • 1970-01-01
    • 2014-10-07
    相关资源
    最近更新 更多