简体   繁体   English

C#Windows服务在安装后不返回剪贴板数据

[英]C# windows service does not return clipboard data after install

I have this code for a windows service program that should clear the clipboard every now and then. 我有一个用于Windows服务程序的代码,该程序应不时清除剪贴板。 Testing it in a console app proved it is a working code (then turned the console app into service via Topshelf nuget package). 在控制台应用程序中对其进行测试证明它是可以正常工作的代码(然后通过Topshelf nuget软件包将控制台应用程序投入使用)。 But running it as a service it just won't do the job. 但是将其作为服务运行将无法完成任务。 After some basic logging, I found that the Clipboard.Hastext() (and all the others) return false after installing the service (directly installed from the debug folder). 经过一些基本的日志记录后,我发现在安装服务(直接从debug文件夹安装)后,Clipboard.Hastext()(以及所有其他)返回false。 What did I miss or what is the difference between debug and deployed mode that should be considered? 我错过了什么?应该考虑的调试模式与部署模式之间有什么区别?

    public class Service
    {
        readonly Timer timer;
        object clipboardData;

        public Service()
        {
            timer = new Timer(TimeSpan.FromMinutes(1).TotalMilliseconds)
            {
                AutoReset = true
            };
            timer.Elapsed += Timer_Elapsed;
        }

        /// <summary>
        /// Checks every minute if there is any data on the clipboard.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            CurrentThreadParse(DoWork);
        }

        public void Start()
        {
            timer.Start();
        }

        public void Stop()
        {
            timer.Stop();
        }

        private void ChangeClipboardData()
        {
            if (Clipboard.ContainsText())
            {
                clipboardData = Clipboard.GetText();
                WriteChanged();
            }
            else if (Clipboard.ContainsImage())
            {
                clipboardData = Clipboard.GetImage();
                WriteChanged();
            }
            else if (Clipboard.ContainsAudio())
            {
                clipboardData = Clipboard.GetAudioStream();
                WriteChanged();
            }
            else if (Clipboard.ContainsFileDropList())
            {
                clipboardData = Clipboard.GetFileDropList();
                WriteChanged();
            }
#if DEBUG
            else
                Console.WriteLine("No change!");
#endif
        }

        private void WriteChanged()
        {
#if DEBUG
            Console.WriteLine("Clipboard data has changed!");
#endif
        }

        private object GetClipboardObject()
        {
            if (Clipboard.ContainsText())
                return Clipboard.GetText();
            else if (Clipboard.ContainsImage())
                return Clipboard.GetImage();
            else if (Clipboard.ContainsAudio())
                return Clipboard.GetAudioStream();
            else if (Clipboard.ContainsFileDropList())
                return Clipboard.GetFileDropList();
            return null;
        }

        private void ClearClipboard()
        {
            Clipboard.Clear();
            clipboardData = null;
#if DEBUG
            Console.WriteLine("Clipboard data removed!");
#endif
        }

        /// <summary>
        /// Sets the current thread as STA.
        /// </summary>
        /// <param name="threadStart">The code to run.</param>
        private void CurrentThreadParse(ThreadStart threadStart)
        {
            Thread thread = new Thread(threadStart);
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
            thread.Join();
        }

        private void DoWork()
        {
            object clipboardObject = GetClipboardObject();
            if (clipboardData == null)
            {
                ChangeClipboardData();
            }
            else if (clipboardData.Equals(clipboardObject))
            {
                ClearClipboard();
            }
            else
            {
                //The last check returned data from the clipboard, but was changed,
                //so the clipboard should not be cleared.
                ChangeClipboardData();
            }
        }
    }

Full project can be found here: https://github.com/profgyuri/ClipboardService 完整的项目可以在这里找到: https : //github.com/profgyuri/ClipboardService

It's not possible with a service. 服务是不可能的。

Services are running in a separate session on Windows (session 0). 服务在Windows上的单独会话(会话0)中运行。 Users are in different sessions always (session 1, 2, etc). 用户始终处于不同的会话中(会话1、2等)。 User's clipboards cannot be accessed by services from another session. 来自其他会话的服务无法访问用户的剪贴板。

Instead you may create a Windows Schedule task to be executed in user session, a Run only when user is logged on task ( link ). 相反,您可以创建一个Windows Schedule任务以在用户会话中执行,即Run only when user is logged on任务Run only when user is logged onlink )。 Schedule may have any repeat interval. 日程安排可以有任何重复间隔。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM