V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
phpfpm
V2EX  ›  问与答

问两个.net 的问题,获取其他进程的内存/访问其他进程修改的文件

  •  
  •   phpfpm · 2020-04-13 10:11:17 +08:00 · 842 次点击
    这是一个创建于 1693 天前的主题,其中的信息可能已经有所发展或是发生改变。

    1 openProcess 的特殊权限 PROCESS_VM_READ

    这个权限获取其他进程一定要当前进程具有管理员权限( UAC 授权)? 我看了一下微软官方的文档,可能我阅读理解有点问题, https://docs.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights

    The following specific access rights are not allowed from a process to a protected process:
    
    PROCESS_ALL_ACCESS
    PROCESS_CREATE_PROCESS
    PROCESS_CREATE_THREAD
    PROCESS_DUP_HANDLE
    PROCESS_QUERY_INFORMATION
    PROCESS_SET_INFORMATION
    PROCESS_SET_QUOTA
    PROCESS_VM_OPERATION
    PROCESS_VM_READ
    PROCESS_VM_WRITE
    The PROCESS_QUERY_LIMITED_INF
    

    不太熟悉这些 term,是不是可以理解为除非是管理员权限启动否则拿不到?

    2 与其他外部进程共同读一个文件尽量减少冲突?

    外部进程会访问并写入这个文件,我的程序利用.net 内置的 FileWatch 组件监控文件修改,一旦获取到修改信息进行读取刷新。

    打开文件句柄我用的是

    IO.FileStream(target_file_full_path, IO.FileMode.Open) as IO.FileStream
    

    这个是最低的读权限了 但是如果在监控到文件修改之后马上调用获取流的方法,会阻塞外部进程的写导致外部进程写入失败。 而且如果这个流使用时间过长也会导致外部进程写失败。

    我暂时的解决方案是:

    a 当发现文件修改的时候缓一下再进行读取操作(sleep 个 100ms ) b 读取文件的时候先读取到内存流,马上关闭这个句柄

    Dim stream As IO.FileStream = New IO.FileStream(target_file_full_path, IO.FileMode.Open)
    Dim shadow As IO.MemoryStream = New IO.MemoryStream()
    stream.CopyTo(shadow)
    stream.Close()
    # ...use shadow blow
    

    但是还是会出现极少数时候无法正确获取流 or 阻塞外部进程的写

    想问下还有没有更好的方式去更透明的读取外部写入的文件呢?

    3 第一个问题带来的额外的问题

    我的程序是用 clickonce 发布的,但是 clickonce 不允许申请 uac 授权,即便取消安全,但是发布的时候仍然不允许。 查了一些解决方案, https://www.cnblogs.com/mic86/p/5438109.html

    大概是启动三次,第一次检查更新,第二次给启动参数加个 flag,第三次发现有 flag 的时候启动 admin 版本。

    略……麻烦诶

    因此我给客户的一个折中方案是启动之后会在桌面生成一个原始 exe 的快捷方式,想用管理员版本自己用,不想用屏蔽掉一些功能就好。

    2 条回复    2020-04-13 22:35:18 +08:00
    canbingzt
        1
    canbingzt  
       2020-04-13 16:07:30 +08:00   ❤️ 1
    第二个问题,https://referencesource.microsoft.com/#mscorlib/system/io/filestream.cs,61a48e2f76fa12ba
    2 参数的构造函数默认 FileShare 是 FileShare.Read,你用 4 参数构造函数指定 FileShare 为 FileShare.ReadWrite 就可以了


    用文件共享数据不是一个好的设计,建议换 MQ
    phpfpm
        2
    phpfpm  
    OP
       2020-04-13 22:35:18 +08:00
    @canbingzt 谢谢!!!
    不是我想文件共享,而是一个 hook 的第三方功能不得不这样……

    所以四参数的这个构造函数好像后面三个参数分别描述了这么几件事情:

    Filemode 是创建模式,没有怎么办
    FileAccess 是自己要干啥
    FileShare 是别人能干啥

    我真的是写的时候没仔细看,以为默认是 open 就是只读的。。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2544 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 04:37 · PVG 12:37 · LAX 20:37 · JFK 23:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.