How does one invoke the Windows Permissions dialog programmatically?

前端 未结 3 1835
小蘑菇
小蘑菇 2020-12-19 11:39

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

3条回答
  •  死守一世寂寞
    2020-12-19 11:57

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

    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:

    enter image description here

    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
            /// 
            /// Required designer variable.
            /// 
            private System.ComponentModel.IContainer components = null;
    
            /// 
            /// Clean up any resources being used.
            /// 
            /// true if managed resources should be disposed; otherwise, false.
            protected override void Dispose(bool disposing)
            {
                if (disposing && (components != null))
                {
                    components.Dispose();
                }
                base.Dispose(disposing);
            }
    
            #region Windows Form Designer generated code
    
            /// 
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// 
            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
        {
            /// 
            /// The main entry point for the application.
            /// 
            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new FileSelectorForm());
            }
        }
    }
    

    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.

提交回复
热议问题