如何以编程方式调用 Windows 权限对话框? [英] How does one invoke the Windows Permissions dialog programmatically?

查看:19
本文介绍了如何以编程方式调用 Windows 权限对话框?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个证书管理器,我想管理对证书文件的权限.我不想重新发明 Windows 权限对话框的轮子,所以理想情况下会有某种 shell 命令,我可以传递正在管理其权限的项目的路径.然后,我可以调用它并让 shell 负责更新权限.

I'm trying to write a certificate manager, and I want to manage the permissions over the certificate file. I'd prefer not reinventing the wheel of the Windows permissions dialog, so ideally there would be some kind of shell command that I could pass the path of the item whose permissions are being managed. Then, I could just invoke it and let the shell take care of updating the permissions.

我在这里和那里看到有人提到了一个 shell 函数 SHObjectProperties,但没有明确说明如何使用它.任何帮助将不胜感激.

I've seen some mention here and there of a shell function, SHObjectProperties, but nothing clear on how to use it. Any help would be appreciated.

推荐答案

您可以使用 ShellExecuteEx(使用属性"动词和安全"参数)显示 Windows 文件权限对话框.

You can display the Windows file permissions dialog using ShellExecuteEx (using the "properties" verb and the "Security" parameter).

这将在您的进程中显示如下所示的对话框,并且文件权限查看和编辑功能将完全正常,就像您通过 Windows 资源管理器外壳获得此对话框一样:

This will display a dialog like the following within your process, and the file permission viewing and editing will be fully functional just as if you had got this dialog through the Windows explorer shell:

以下是 Windows 窗体示例,其中选择了一个文件,然后显示该文件的安全属性.我已经使用了 this Stackoverflow answerShellExecuteEx 的 P/Invoke 代码.

Here is an example with Windows Forms where a file is selected and the Security properties of that file then displayed. I have used the P/Invoke code for ShellExecuteEx from this Stackoverflow answer.

using System;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace FileSecurityProperties
{
    public partial class FileSelectorForm : Form
    {
        private static bool ShowFileSecurityProperties(string Filename, IntPtr parentHandle)
        {
            SHELLEXECUTEINFO info = new SHELLEXECUTEINFO();
            info.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(info);
            info.lpVerb = "properties";
            info.lpFile = Filename;
            info.nShow = SW_SHOW;
            info.fMask = SEE_MASK_INVOKEIDLIST;
            info.hwnd = parentHandle;
            info.lpParameters = "Security"; // Opens the file properties on the Security tab
            return ShellExecuteEx(ref info);
        }

        private void fileSelectButton_Click(object sender, EventArgs e)
        {
            if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                ShowFileSecurityProperties(
                    openFileDialog.FileName,
                    this.Handle); // Pass parent window handle for properties dialog
            }
        }

        #region P/Invoke code for ShellExecuteEx from https://stackoverflow.com/a/1936957/4486839
        [DllImport("shell32.dll", CharSet = CharSet.Auto)]
        static extern bool ShellExecuteEx(ref SHELLEXECUTEINFO lpExecInfo);

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct SHELLEXECUTEINFO
        {
            public int cbSize;
            public uint fMask;
            public IntPtr hwnd;
            [MarshalAs(UnmanagedType.LPTStr)]
            public string lpVerb;
            [MarshalAs(UnmanagedType.LPTStr)]
            public string lpFile;
            [MarshalAs(UnmanagedType.LPTStr)]
            public string lpParameters;
            [MarshalAs(UnmanagedType.LPTStr)]
            public string lpDirectory;
            public int nShow;
            public IntPtr hInstApp;
            public IntPtr lpIDList;
            [MarshalAs(UnmanagedType.LPTStr)]
            public string lpClass;
            public IntPtr hkeyClass;
            public uint dwHotKey;
            public IntPtr hIcon;
            public IntPtr hProcess;
        }

        private const int SW_SHOW = 5;
        private const uint SEE_MASK_INVOKEIDLIST = 12;
        #endregion

        #region Irrelevant Windows forms code
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.openFileDialog = new System.Windows.Forms.OpenFileDialog();
            this.fileSelectButton = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // 
            // openFileDialog1
            // 
            this.openFileDialog.FileName = "";
            // 
            // fileSelectButton
            // 
            this.fileSelectButton.Location = new System.Drawing.Point(52, 49);
            this.fileSelectButton.Name = "fileSelectButton";
            this.fileSelectButton.Size = new System.Drawing.Size(131, 37);
            this.fileSelectButton.TabIndex = 0;
            this.fileSelectButton.Text = "Select file ...";
            this.fileSelectButton.UseVisualStyleBackColor = true;
            this.fileSelectButton.Click += new System.EventHandler(this.fileSelectButton_Click);
            // 
            // FileSelectorForm
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(248, 162);
            this.Controls.Add(this.fileSelectButton);
            this.Name = "FileSelectorForm";
            this.Text = "File Selector";
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.OpenFileDialog openFileDialog;
        private System.Windows.Forms.Button fileSelectButton;

        public FileSelectorForm()
        {
            InitializeComponent();
        }

        #endregion
    }

    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new FileSelectorForm());
        }
    }
}

如果您希望自己获得文件权限对话框,而不是作为一般文件属性对话框中的选项卡,则可以使用 aclui.dll,例如使用 EditSecurity 功能,但是这不会给您其他要求为您处理文件权限的要求,因为您必须提供一个接口来获取和设置安全属性,如果您沿着这条路走下去,它看起来像很多编码.

If you were hoping to get the file permissions dialog on its own, rather than as a tab in the general file properties dialog, that is possible using aclui.dll, e.g. using the EditSecurity function, but this will NOT then give you your other requirement of having the file permissions handling taken care of for you, because you have to provide an interface which does the getting and setting of security properties if you go down that route, and it looks like a lot of coding.

这篇关于如何以编程方式调用 Windows 权限对话框?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆