ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

WPF-mvvm学习4 cmd运行与多线程通信

2022-07-12 23:37:00  阅读:219  来源: 互联网

标签:count CMD mvvm -- cmd private print byte 多线程


mvvm多线程通信 绑定 执行cmd 相关问题

情景

我想使用cmd调用yara 并实时获取执行结果 由于想要扫描的目录比较大 如果使用阻塞函数可能会被卡死

解决方案1 官方文档

https://docs.microsoft.com/en-us/windows/communitytoolkit/mvvm/observableobject

image-20220527131742873

很好 但是不适合我 似乎cmd在运行时等待输入会自动阻塞)

但是执行别的异步函数没问题

关于该解决方案的一个demo

private TaskNotifier<int> _count;
/// <summary>
/// 任务属性绑定
/// </summary>
public Task<int> Count
{
    get => _count;
    set => SetPropertyAndNotifyOnCompletion(ref _count, value);
}
public ICommand RequestValueCmd { get; set; }

private async void RequestValue()
{
    await Task.Delay(5000);
    Count = Task.Run(() =>
                     {
                         return 50;
                     });
}
<TextBlock Text="{Binding Count.Result, UpdateSourceTrigger=PropertyChanged}" />
<Button
        Command="{Binding RequestValueCmd}"
        Content="延时绑定" />

解决方案2

https://blog.csdn.net/fangyu723/article/details/118783975

使用他封装好的类


namespace CmdNameSpace
{
    
    public class Command
    {
        private const int _ReadSize = 1024;
        private Process _CMD;//cmd进程
        private Encoding _OutEncoding;//输出字符编码
        private Stream _OutStream;//基础输出流
        private Stream _ErrorStream;//错误输出流
        public event Action<string> Output;//输出事件
        public event Action<string> Error;//错误事件
        public event Action Exited;//退出事件
        private bool _Run;//循环控制
        private byte[] _TempBuffer;//临时缓冲
        private byte[] _ReadBuffer;//读取缓存区
        private byte[] _ETempBuffer;//临时缓冲
        private byte[] _ErrorBuffer;//错误读取缓存区
        public Command()
        {
            _CMD = new Process();
            _CMD.StartInfo.FileName = "cmd.exe";
            _CMD.StartInfo.UseShellExecute = false;//是否使用操作系统shell启动
            _CMD.StartInfo.RedirectStandardInput = true;//接受来自调用程序的输入信息
            _CMD.StartInfo.RedirectStandardOutput = true;//由调用程序获取输出信息
            _CMD.StartInfo.RedirectStandardError = true;//重定向标准错误输出
            _CMD.StartInfo.CreateNoWindow = true;//不显示程序窗口
            _CMD.Exited += _CMD_Exited;
            _ReadBuffer = new byte[_ReadSize];
            _ErrorBuffer = new byte[_ReadSize];
            ReStart();
        }

        /// <summary>
        /// 停止使用,关闭进程和循环线程
        /// </summary>
        public void Stop()
        {
            _Run = false;
            _CMD.Close();
        }
        /// <summary>
        /// 重新启用
        /// </summary>
        public void ReStart()
        {
            Stop();
            _CMD.Start();
            _OutEncoding = _CMD.StandardOutput.CurrentEncoding;
            _OutStream = _CMD.StandardOutput.BaseStream;
            _ErrorStream = _CMD.StandardError.BaseStream;
            _Run = true;
            _CMD.StandardInput.AutoFlush = true;
            ReadResult();
            ErrorResult();
        }
        //退出事件
        private void _CMD_Exited(object sender , EventArgs e)
        {
            Exited?.Invoke();
        }

        /// <summary>
        /// 执行cmd命令
        /// </summary>
        /// <param name="cmd">需要执行的命令</param>
        public void RunCMD(string cmd)
        {

            if (!_Run)
            {
                if (cmd.Trim().Equals("/restart" , StringComparison.CurrentCultureIgnoreCase))
                {
                    ReStart();
                }
                return;
            }
            if (_CMD.HasExited)
            {
                Stop();
                return;
            }
            _CMD.StandardInput.WriteLine(cmd);
        }



        //异步读取输出结果
        private void ReadResult()
        {
            if (!_Run)
            {
                return;
            }
            _OutStream.BeginRead(_ReadBuffer , 0 , _ReadSize , ReadEnd , null);
        }

        //一次异步读取结束
        private void ReadEnd(IAsyncResult ar)
        {
            int count = _OutStream.EndRead(ar);

            if (count < 1)
            {
                if (_CMD.HasExited)
                {
                    Stop();
                }
                return;
            }

            if (_TempBuffer == null)
            {
                _TempBuffer = new byte[count];
                Buffer.BlockCopy(_ReadBuffer , 0 , _TempBuffer , 0 , count);
            }
            else
            {
                byte[] buff = _TempBuffer;
                _TempBuffer = new byte[buff.Length + count];
                Buffer.BlockCopy(buff , 0 , _TempBuffer , 0 , buff.Length);
                Buffer.BlockCopy(_ReadBuffer , 0 , _TempBuffer , buff.Length , count);
            }

            if (count < _ReadSize)
            {
                string str = _OutEncoding.GetString(_TempBuffer);
                Output?.Invoke(str);
                _TempBuffer = null;
            }

            ReadResult();
        }


        //异步读取错误输出
        private void ErrorResult()
        {
            if (!_Run)
            {
                return;
            }
            _ErrorStream.BeginRead(_ErrorBuffer , 0 , _ReadSize , ErrorCallback , null);
        }

        private void ErrorCallback(IAsyncResult ar)
        {
            int count = _ErrorStream.EndRead(ar);

            if (count < 1)
            {
                if (_CMD.HasExited)
                {
                    Stop();
                }
                return;
            }

            if (_ETempBuffer == null)
            {
                _ETempBuffer = new byte[count];
                Buffer.BlockCopy(_ErrorBuffer , 0 , _ETempBuffer , 0 , count);
            }
            else
            {
                byte[] buff = _ETempBuffer;
                _ETempBuffer = new byte[buff.Length + count];
                Buffer.BlockCopy(buff , 0 , _ETempBuffer , 0 , buff.Length);
                Buffer.BlockCopy(_ErrorBuffer , 0 , _ETempBuffer , buff.Length , count);
            }

            if (count < _ReadSize)
            {
                string str = _OutEncoding.GetString(_ETempBuffer);
                Error?.Invoke(str);
                _ETempBuffer = null;
            }

            ErrorResult();
        }

        ~Command()
        {
            _Run = false;
            _CMD?.Close();
            _CMD?.Dispose();
        }

    }
}

调用

private async void ScanSingleFileExecute()
{
    fppath.Info = "";
    Command command = new Command();
    command.Output += Command_Output;
    //用Task避免发送命令太多堵塞
    
    _ = Task.Run(() =>
                 {
                     for (int i = 0 ; i < fppath.RuleList.Count ; i++)
                     {
                         string cmdString = currentpath + "\\yara\\yara64.exe " + fppath.RuleList[i] + " " + fppath.FilePath + " -r";
                         // string cmdString = "ipconfig";
                         command.RunCMD(cmdString);
                     }
                 });
}

private void Command_Output(string msg)
{	//或者对msg做些处理啥的再加
    fppath.test += msg;
}
<TextBox
         Grid.Row="2"
         Grid.Column="0"
         Margin="0,0,0,0"
         Text="{Binding fppath.test, Mode=OneWay, 				   UpdateSourceTrigger=PropertyChanged}" />

这样就实现了绑定到xaml 并实时更新返回值

image-20220527184118310

MVVM 跨线程更改数据源

 ThreadPool.QueueUserWorkItem(delegate
                {
                    System.Threading.SynchronizationContext.SetSynchronizationContext(new
                        System.Windows.Threading.DispatcherSynchronizationContext(System.Windows.Application.Current.Dispatcher));
                    System.Threading.SynchronizationContext.Current.Post(p1 =>
                    {
                       //代码
                    } , null);
                });

yara

yara是病毒匹配工具

先上help

YARA 4.2.0, the pattern matching swiss army knife.
Usage: yara [OPTION]... [NAMESPACE:]RULES_FILE... FILE | DIR | PID
Mandatory arguments to long options are mandatory for short options too.

       --atom-quality-table=FILE           path to a file with the atom quality table
  -C,  --compiled-rules                    load compiled rules
  -c,  --count                             print only number of matches
  -d,  --define=VAR=VALUE                  define external variable
       --fail-on-warnings                  fail on warnings
  -f,  --fast-scan                         fast matching mode
  -h,  --help                              show this help and exit
  -i,  --identifier=IDENTIFIER             print only rules named IDENTIFIER
       --max-process-memory-chunk=NUMBER   set maximum chunk size while reading process memory (default=1073741824)
  -l,  --max-rules=NUMBER                  abort scanning after matching a NUMBER of rules
       --max-strings-per-rule=NUMBER       set maximum number of strings per rule (default=10000)
  -x,  --module-data=MODULE=FILE           pass FILE's content as extra data to MODULE
  -n,  --negate                            print only not satisfied rules (negate)
  -N,  --no-follow-symlinks                do not follow symlinks when scanning
  -w,  --no-warnings                       disable warnings
  -m,  --print-meta                        print metadata
  -D,  --print-module-data                 print module data
  -e,  --print-namespace                   print rules' namespace
  -S,  --print-stats                       print rules' statistics
  -s,  --print-strings                     print matching strings
  -L,  --print-string-length               print length of matched strings
  -g,  --print-tags                        print tags
  -r,  --recursive                         recursively search directories
       --scan-list                         scan files listed in FILE, one per line
  -z,  --skip-larger=NUMBER                skip files larger than the given size when scanning a directory
  -k,  --stack-size=SLOTS                  set maximum stack size (default=16384)
  -t,  --tag=TAG                           print only rules tagged as TAG
  -p,  --threads=NUMBER                    use the specified NUMBER of threads to scan a directory
  -a,  --timeout=SECONDS                   abort scanning after the given number of SECONDS
  -v,  --version                           show version information

Send bug reports and suggestions to: vmalvarez@virustotal.com.

img

img

简单使用yara yourrules.yar testfile来检测

使用yarac yourrule compilerule来编译规则以加快检测速度

标签:count,CMD,mvvm,--,cmd,private,print,byte,多线程
来源: https://www.cnblogs.com/FW-ltlly/p/16466567.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有