以编程方式关闭共享文件

7
我正在与一家公司合作,他们的程序是用古老的vb6编写的,经常更新,大多数客户从映射的网络驱动器运行可执行文件。这实际上有很少问题,其中最大的问题是自动更新。目前,更新程序(用c++编写)会将现有的exe重命名,然后下载并放置新版本到旧版本的位置。这通常可以正常工作,但在某些环境中会失败。
解决方案是运行来自Microsoft的此命令:
for /f "skip=4 tokens=1" %a in ('net files') do net files %a /close

这个命令关闭所有网络文件的共享(好吧...大部分),然后更新程序可以替换exe文件。

在C++中,我可以使用System("");函数来运行该命令,或者我可以重定向net files的输出,并遍历结果查找特定的文件,然后运行net file /close命令来关闭它们。但是,如果有类似于winapi函数的功能,则更可靠且更加安全。

是否有办法以编程方式查找所有网络共享文件并关闭相关文件?


听起来这是一个关于Windows特定的C ++问题... - shargors
是的,我知道了,抱歉,我会添加一个标签。 - wizebin
1
我建议您搜索MSDN以查找一些Windows API,这些API可以帮助您关闭网络文件。 - Thomas Matthews
不错的提醒,@ThomasMatthews 我经常忘记做显而易见的事情。找到了一个不错的资源,一旦我得到一个可行的解决方案,我会发布一些额外的信息。 - wizebin
请注意,虽然这将关闭文件,但也意味着客户端在下次需要请求页面可执行文件时将会崩溃。 - Raymond Chen
更加简洁的解决方案是在PE头中设置“RunFromNetwork”位。这会告诉操作系统首先不要保持文件处于打开状态。 - MSalters
1个回答

8
你可以通过编程实现与net file /close相同的功能。只需包含lmshare.h并链接到Netapi32.dll即可。你有两个可以使用的函数:NetFileEnum用于枚举所有打开的网络文件(在给定计算机上),以及NetFileClose用于关闭它们。

快速(假设程序正在同一台服务器上运行,并且没有太多的打开连接,请参见最后一段)和简单(无错误检查)的示例:

FILE_INFO_2* pFiles = NULL;
DWORD nRead = 0, nTotal = 0;

NetFileEnum(
  NULL, // servername, NULL means localhost
  "c:\\directory\\path", // basepath, directory where VB6 program is
  NULL, // username, searches for all users
  2, // level, we just need resource ID
  (LPBYTE*)&pFiles, // bufptr, need to use a double pointer to get the buffer
  MAX_PREFERRED_LENGTH, // prefmaxlen, collect as much as possible
  &nRead, // entriesread, number of entries stored in pFiles
  &nTotal, // totalentries, ignore this
  NULL //resume_handle, ignore this 
);

for (int i=0; i < nRead; ++i)
    NetFileClose(NULL, pFiles[i].fi2_id);

NetApiBufferFree(pFiles);

请参考MSDN获取有关NetFileEnumNetFileClose的详细信息。请注意,如果有更多数据可用,NetFileEnum可能会返回ERROR_MORE_DATA


3
几乎没有修改,这个函数运行得非常顺利。我的编译器在枚举函数中最后一个 NULL 后面多了一个逗号时发出了警告,并且我不得不将 pFiles 强制转换为 (BYTE**)&pFiles,并将访问方式从 pFile[i]->fi2_id 更改为成员访问而不是指针访问 pFile[i].fi2_id - wizebin
@wizebin 你是对的,我在这里写代码时没有测试。我的错,谢谢! - Adriano Repetti
lpvoid这一行需要更改为(LPBYTE*)&pFiles,//bufptr - Dan
我可能在某个地方添加了一个“s”,因为你到处都有“pFile”,但是我的代码行中没有。 - Dan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接