我一直在尝试将磁盘设为只读,几天后我做到了。 我从here获得了参考,并将尝试添加更多功能以用于练习目的! 我还看到有些人从 Windows 注册表中执行此操作,这有效还是以后不会出现问题?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
const uint GENERIC_READ = 0x80000000;
const uint GENERIC_WRITE = 0x40000000;
const int FILE_SHARE_READ = 0x1;
const int FILE_SHARE_WRITE = 0x2;
const uint IOCTL_DISK_SET_DISK_ATTRIBUTES = 0x0007c0f4;
const ulong DISK_ATTRIBUTE_READ_ONLY = 0x0000000000000002;
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr CreateFile(
string lpFileName,
uint dwDesiredAccess,
uint dwShareMode,
IntPtr SecurityAttributes,
uint dwCreationDisposition,
uint dwFlagsAndAttributes,
IntPtr hTemplateFile
);
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
private static extern bool DeviceIoControl(
IntPtr hDevice,
uint dwIoControlCode,
IntPtr lpInBuffer,
uint nInBufferSize,
IntPtr lpOutBuffer,
uint nOutBufferSize,
out uint lpBytesReturned,
IntPtr lpOverlapped
);
[StructLayout(LayoutKind.Sequential)]
struct SET_DISK_ATTRIBUTES
{
public uint Version;
[MarshalAs(UnmanagedType.I1)]
public bool Persist;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] Reserved1;
public ulong Attributes;
public ulong AttributesMask;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public uint[] Reserved2;
};
public Form1()
{
InitializeComponent();
}
public IntPtr CreateHandle(int diskNumber)
{
string filename = @"\\.\\PhysicalDrive" + diskNumber;
IntPtr handle = CreateFile(
filename,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
IntPtr.Zero,
3, // OPEN_EXISTING
0, // No special flags
IntPtr.Zero
);
if (handle == IntPtr.Zero)
{
int errorCode = Marshal.GetLastWin32Error();
MessageBox.Show("Failed to create handle. Error: " + new Win32Exception(errorCode).Message);
}
return handle;
}
private void SetReadonly(IntPtr handle)
{
if (handle == IntPtr.Zero)
{
MessageBox.Show("Handle is invalid.");
return;
}
var sda = new SET_DISK_ATTRIBUTES
{
Version = (uint)Marshal.SizeOf<SET_DISK_ATTRIBUTES>(),
Persist = true,
AttributesMask = DISK_ATTRIBUTE_READ_ONLY,
Attributes = DISK_ATTRIBUTE_READ_ONLY,
Reserved1 = new byte[3],
Reserved2 = new uint[4]
};
IntPtr ptrQuery = Marshal.AllocHGlobal(Marshal.SizeOf(sda));
try
{
Marshal.StructureToPtr(sda, ptrQuery, false);
uint byteReturned;
// Set the disk to read-only
bool res = DeviceIoControl(handle, IOCTL_DISK_SET_DISK_ATTRIBUTES, ptrQuery, (uint)Marshal.SizeOf(sda), IntPtr.Zero, 0, out byteReturned, IntPtr.Zero);
if (!res)
{
MessageBox.Show("Failed to set readonly. Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message);
}
}
finally
{
Marshal.FreeHGlobal(ptrQuery);
}
}
private void DisplayDiskAttributes(int diskNumber,string Msg)
{
MessageBox.Show(Msg);
}
private void button1_Click(object sender, EventArgs e)
{
if (int.TryParse(textBox1.Text.Trim(), out int diskNumber) && diskNumber >= 0)
{
IntPtr handle = CreateHandle(diskNumber);
SetReadonly(handle); // Set to read-only
DisplayDiskAttributes(diskNumber, "Set to Read only succesfuul");
}
else
{
MessageBox.Show("Please enter a valid disk number (e.g., 0, 1, 2).");
}
}
}
}
当我使用 DiskPart 显示属性时,它显示如下:
但我想让它像:
但是我找不到一种方法来使其成为可能,因为Set_Disk_Attribute结构无法做到这一点! 还有其他办法吗? 抱歉写得不好,我是新来的! 谢谢!
与 坚持=假 你应该会得到预期的结果。