gpt4 book ai didi

c# - 使用 C# 在 Windows Server 2012 上强制关闭打开的网络文件

转载 作者:行者123 更新时间:2023-11-30 23:19:06 25 4
gpt4 key购买 nike

有没有办法强制关闭 Server 2012 上特定文件的任何实例?

为了论证,调用文件 D:\Shares\Shared\Sharedfile.exe 的链接

我有 C# 代码可以将程序的最新版本复制到这个目录中,白天经常有人使用该程序。关闭打开的文件句柄并替换文件效果很好,因为这仅意味着用户下次打开程序时他们拥有所有最新更改。

但是,通过服务器上的计算机管理来执行此操作有点单调,所以我想知道是否有一种方法可以通过 C# 代码来执行此操作?

我试过了,但它没有我需要的正确重载。也许 File 类中有什么我可以使用的?

编辑关闭文件的 C# 代码不会在主机服务器上运行。

[DllImport("Netapi32.dll", SetLastError=true, CharSet = CharSet.Unicode)]
public static extern int NetFileClose(string servername, int id);

最佳答案

您可以包装NetFileClose API,这也需要包装NetFileEnum API。像这样:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct FILE_INFO_3 {
public int fi3_id;
public int fi3_permissions;
public int fi3_num_locks;
public string fi3_pathname;
public string fi3_username;
}

static class NativeMethods {
[DllImport("netapi32.dll", CharSet = CharSet.Unicode)]
public extern static int NetFileEnum(
string servername,
string basepath,
string username,
int level,
out IntPtr bufptr,
int prefmaxlen,
out int entriesread,
out int totalentries,
ref IntPtr resume_handle
);

[DllImport("netapi32.dll", CharSet = CharSet.Unicode)]
public extern static int NetFileClose(string servername, int fileid);

[DllImport("netapi32.dll")]
public extern static int NetApiBufferFree(IntPtr buffer);
}

非常难看的签名,对吧?让我们围绕它包装一点管理的爱。

class RemoteFile {
public RemoteFile(string serverName, int id, string path, string userName) {
ServerName = serverName;
Id = id;
Path = path;
UserName = userName;
}
public string ServerName { get; }
public int Id { get; }
public string Path { get; }
public string UserName { get; }

public void Close() {
int result = NativeMethods.NetFileClose(ServerName, Id);
if (result != 0) {
// handle error decently, omitted for laziness
throw new Exception($"Error: {result}");
}
}
}

IEnumerable<RemoteFile> EnumRemoteFiles(string serverName, string basePath = null) {
int entriesRead;
int totalEntries;
IntPtr resumeHandle = IntPtr.Zero;
IntPtr fileEntriesPtr = IntPtr.Zero;
try {
int result = NativeMethods.NetFileEnum(
servername: serverName,
basepath: basePath,
username: null,
level: 3,
bufptr: out fileEntriesPtr,
prefmaxlen: -1,
entriesread: out entriesRead,
totalentries: out totalEntries,
resume_handle: ref resumeHandle
);
if (result != 0) {
// handle error decently, omitted for laziness
throw new Exception($"Error: {result}");
}
for (int i = 0; i != entriesRead; ++i) {
FILE_INFO_3 fileInfo = (FILE_INFO_3) Marshal.PtrToStructure(
fileEntriesPtr + i * Marshal.SizeOf(typeof(FILE_INFO_3)),
typeof(FILE_INFO_3)
);
yield return new RemoteFile(
serverName,
fileInfo.fi3_id,
fileInfo.fi3_pathname,
fileInfo.fi3_username
);
}
} finally {
if (fileEntriesPtr != IntPtr.Zero) {
NativeMethods.NetApiBufferFree(fileEntriesPtr);
}
}
}

现在关闭特定文件很容易:关闭它所有打开的实例。

foreach (var file in EnumRemoteFiles(server, path)) {
Console.WriteLine($"Closing {file.Path} at {file.ServerName} (opened by {file.UserName})");
file.Close();
}

请注意,这段代码还没有完全准备好生产,尤其是错误处理很糟糕。此外,在我的测试中,文件路径似乎可能会受到一些破坏,具体取决于它们的打开方式(比如一个文件显示为 C:\\Path\File,带有一个额外的反斜杠在驱动器根目录之后),因此您可能希望在验证名称之前进行规范化。不过,这涵盖了地面。

关于c# - 使用 C# 在 Windows Server 2012 上强制关闭打开的网络文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40458957/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com