Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
863 views
in Technique[技术] by (71.8m points)

c# - How does one invoke the Windows Permissions dialog programmatically?

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.

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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
        /// <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());
        }
    }
}

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...