2015-01-19 9 views
5

Próbuję napisać menedżera certyfikatów i chcę zarządzać uprawnieniami nad plikiem certyfikatu. Wolałbym nie wymyślać koła okna dialogowego uprawnień Windows, więc najlepiej byłoby, gdyby istniała jakaś komenda powłoki, którą mógłbym przekazać ścieżce elementu, którego uprawnienia są zarządzane. Następnie mógłbym go wywołać i pozwolić powłoce zająć się aktualizowaniem uprawnień.W jaki sposób można programowo wywołać okno dialogowe Uprawnienia systemu Windows?

Widziałem niektóre wspomnieć tu i tam o funkcji powłoki, SHObjectProperties, ale nic jasne, jak z niego korzystać. Każda pomoc będzie doceniona.

+0

http://www.codeguru.com/csharp/csharp/cs_webservices/security/article.php/c14315/The-Basics-of-Manipulating-File-Access-Control-Lists-with-C. htm – Plutonix

Odpowiedz

9

można wyświetlić okno dialogowe uprawnienia plików systemu Windows przy użyciu ShellExecuteEx (za pomocą czasownika „Właściwości”, a parametr „Zabezpieczenia”).

Spowoduje to wyświetlenie okna dialogowego, jak następuje w ciągu procesu, a oglądanie dostępu do pliku i edycji będzie w pełni funkcjonalny tak jakbyś dostał ten dialog za pośrednictwem Eksploratora Windows powłoki:

enter image description here

Oto przykład z Windows Forms, w którym plik jest zaznaczony, a następnie wyświetlone właściwości zabezpieczeń tego pliku. Użyłem kodu P/Invoke dla ShellExecuteEx z 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()); 
     } 
    } 
} 

Jeśli ufaliśmy dostać dialogowym Uprawnienia plików na własną rękę, a nie jako zakładki w oknie właściwości pliku ogólnego, które jest możliwe przy użyciu aclui.dll, np przy użyciu EditSecurity function, ale to NIE da ci jeszcze innego wymogu dotyczącego obsługi uprawnień do plików, ponieważ musisz zapewnić interfejs, który pobiera i ustawia właściwości zabezpieczeń, jeśli przejdziesz na tę trasę, oraz wygląda na dużo kodowania.

0

Opps mój zły "attrib" jest jak dawniej.

Uważam, że "zmieniaj deskryptory zabezpieczeń folderów i plików". Narzędzie wiersza poleceń to cacls.

proszę zobaczyć: http://en.wikipedia.org/wiki/Cacls

+0

Tak ... Próbuję wywołać okno dialogowe systemu Windows, aby móc nim zarządzać. Próbuję uniknąć konieczności pisania całego kodu zarządzania ACL i kodu interfejsu użytkownika. Najgorszy scenariusz, po prostu powielę interfejs użytkownika Windows i sam będę zarządzał listami ACL, ale będzie to ból ... –

6

Oto klasa, która pozwala na posiadanie tylko arkusza właściwości zabezpieczeń (nie wszystkich arkuszy wyświetlanych przez powłokę).

enter image description here

można nazwać jak to w aplikacji konsoli:

class Program 
{ 
    [STAThread] 
    static void Main(string[] args) 
    { 
     // NOTE: if the dialog looks old fashioned (for example if used in a console app), 
     // then add an app.manifest and uncomment the dependency section about Microsoft.Windows.Common-Controls 
     PermissionDialog.Show(IntPtr.Zero, @"d:\temp\killroy_was_here.png"); 
    } 
} 

lub jak to w app winform

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     PermissionDialog.Show(IntPtr.Zero, @"d:\temp\killroy_was_here.png"); 
    } 
} 

i to jest główną klasą. Zasadniczo używa tego samego, co powłoka, ale we własnym arkuszu właściwości.

public static class PermissionDialog 
{ 
    public static bool Show(IntPtr hwndParent, string path) 
    { 
     if (path == null) 
      throw new ArgumentNullException("path"); 

     SafePidlHandle folderPidl; 
     int hr; 
     hr = SHILCreateFromPath(Path.GetDirectoryName(path), out folderPidl, IntPtr.Zero); 
     if (hr != 0) 
      throw new Win32Exception(hr); 

     SafePidlHandle filePidl; 
     hr = SHILCreateFromPath(path, out filePidl, IntPtr.Zero); 
     if (hr != 0) 
      throw new Win32Exception(hr); 

     IntPtr file = ILFindLastID(filePidl); 

     System.Runtime.InteropServices.ComTypes.IDataObject ido; 
     hr = SHCreateDataObject(folderPidl, 1, new IntPtr[] { file }, null, typeof(System.Runtime.InteropServices.ComTypes.IDataObject).GUID, out ido); 
     if (hr != 0) 
      throw new Win32Exception(hr); 

     // if you get a 'no such interface' error here, make sure the running thread is STA 
     IShellExtInit sei = (IShellExtInit)new SecPropSheetExt(); 
     sei.Initialize(IntPtr.Zero, ido, IntPtr.Zero); 

     IShellPropSheetExt spse = (IShellPropSheetExt)sei; 
     IntPtr securityPage = IntPtr.Zero; 
     spse.AddPages((p, lp) => 
     { 
      securityPage = p; 
      return true; 
     }, IntPtr.Zero); 

     PROPSHEETHEADER psh = new PROPSHEETHEADER(); 
     psh.dwSize = Marshal.SizeOf(psh); 
     psh.hwndParent = hwndParent; 
     psh.nPages = 1; 
     psh.phpage = Marshal.AllocHGlobal(IntPtr.Size); 
     Marshal.WriteIntPtr(psh.phpage, securityPage); 

     // TODO: adjust title & icon here, also check out the available flags 
     psh.pszCaption = "Permissions for '" + path + "'"; 

     IntPtr res; 
     try 
     { 
      res = PropertySheet(ref psh); 
     } 
     finally 
     { 
      Marshal.FreeHGlobal(psh.phpage); 
     } 
     return res == IntPtr.Zero; 
    } 

    private class SafePidlHandle : SafeHandle 
    { 
     public SafePidlHandle() 
      : base(IntPtr.Zero, true) 
     { 
     } 

     public override bool IsInvalid 
     { 
      get { return handle == IntPtr.Zero; } 
     } 

     protected override bool ReleaseHandle() 
     { 
      if (IsInvalid) 
       return false; 

      Marshal.FreeCoTaskMem(handle); 
      return true; 
     } 
    } 

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 
    private struct PROPSHEETHEADER 
    { 
     public int dwSize; 
     public int dwFlags; 
     public IntPtr hwndParent; 
     public IntPtr hInstance; 
     public IntPtr hIcon; 
     public string pszCaption; 
     public int nPages; 
     public IntPtr nStartPage; 
     public IntPtr phpage; 
     public IntPtr pfnCallback; 
    } 

    [DllImport("shell32.dll")] 
    private static extern IntPtr ILFindLastID(SafePidlHandle pidl); 

    [DllImport("shell32.dll", CharSet = CharSet.Unicode)] 
    private static extern int SHILCreateFromPath(string pszPath, out SafePidlHandle ppidl, IntPtr rgflnOut); 

    [DllImport("shell32.dll")] 
    private static extern int SHCreateDataObject(SafePidlHandle pidlFolder, int cidl, IntPtr[] apidl, System.Runtime.InteropServices.ComTypes.IDataObject pdtInner, [MarshalAs(UnmanagedType.LPStruct)] Guid riid, out System.Runtime.InteropServices.ComTypes.IDataObject ppv); 

    [DllImport("comctl32.dll", CharSet = CharSet.Unicode)] 
    private static extern IntPtr PropertySheet(ref PROPSHEETHEADER lppsph); 

    private delegate bool AddPropSheetPage(IntPtr page, IntPtr lParam); 

    [ComImport] 
    [Guid("1f2e5c40-9550-11ce-99d2-00aa006e086c")] // this GUID points to the property sheet handler for permissions 
    private class SecPropSheetExt 
    { 
    } 

    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
    [Guid("000214E8-0000-0000-C000-000000000046")] 
    private interface IShellExtInit 
    { 
     void Initialize(IntPtr pidlFolder, System.Runtime.InteropServices.ComTypes.IDataObject pdtobj, IntPtr hkeyProgID); 
    } 

    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
    [Guid("000214E9-0000-0000-C000-000000000046")] 
    private interface IShellPropSheetExt 
    { 
     void AddPages([MarshalAs(UnmanagedType.FunctionPtr)] AddPropSheetPage pfnAddPage, IntPtr lParam); 
     void ReplacePage(); // not fully defined, we don't use it 
    } 
} 
Powiązane problemy