【发布时间】:2016-02-26 02:01:52
【问题描述】:
我围绕我在 VB6 应用程序中使用的 DotNetZip 库为 COM 创建了一个包装器(类库)。我在 XP 机器上使用包装器创建了一个示例应用程序,它工作正常。当我在 Windows Server 2008 R2 上创建安装程序并安装应用程序时,它无法从 UNC 路径读取 zip 文件。
以下是我的 C# 代码:
if (File.Exists(zipFileName))
{
// check if the directory exists
if (Directory.Exists(extractionPath))
{
// remove the directory
Directory.Delete(extractionPath, true);
}
// recreate the directory
Directory.CreateDirectory(extractionPath);
// unzip the files
using (ZipFile loZip = ZipFile.Read(zipFileName))
{
// Add this line to fix an issue with the DLL
// http://dotnetzip.codeplex.com/workitem/14087
loZip.ParallelDeflateThreshold = -1;
loZip.ExtractAll(extractionPath, ExtractExistingFileAction.OverwriteSilently);
}
}
else
{
lsResult = "@@@Error - Zip file does not exist. ";
}
Zip 文件位于以下位置(这是一个共享的本地文件夹,因此我使用的是 UNC 路径,但这很可能位于网络位置)
Zip File Name = '\\\\DEV-2012X\\1454444717051\\MB4.zip'
这是异常消息:
Could not find file '\\DEV-2012X\1454444717051\MB4.zip'.
这是堆栈跟踪
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
at Ionic.Zip.ZipFile.get_ReadStream()
at Ionic.Zip.ZipFile.ReadIntoInstance(ZipFile zf)
at Ionic.Zip.ZipFile.Read(String fileName, TextWriter statusMessageWriter, Encoding encoding, EventHandler`1 readProgress)
at Ionic.Zip.ZipFile.Read(String fileName)
at ZipUtility.Zip.UnZipAllContents(String zipFileName, String extractionPath)
我可以从那台机器访问该文件夹,没有任何问题。我还尝试在 this 链接上使用 .net Impersonation,但这也无济于事。
感谢您对此进行调查
[编辑 - 1]
这是我尝试将流传递给 Read 方法的时候:
MemoryStream ms = new MemoryStream();
try
{
using (FileStream file = new FileStream(zipFileName, FileMode.Open, FileAccess.Read))
{
byte[] bytes = new byte[file.Length];
file.Read(bytes, 0, (int)file.Length);
ms.Write(bytes, 0, (int)file.Length);
}
}
catch (Exception ex)
{
lsResult = "Stream reading crashed. " + ex.Message + Environment.NewLine + Environment.NewLine + ex.InnerException + Environment.NewLine + Environment.NewLine + ex.StackTrace + Environment.NewLine + Environment.NewLine;
}
// unzip the files
using (ZipFile loZip = ZipFile.Read(ms))
{
// Add this line to fix an issue with the DLL
// http://dotnetzip.codeplex.com/workitem/14087
loZip.ParallelDeflateThreshold = -1;
loZip.ExtractAll(extractionPath, ExtractExistingFileAction.OverwriteSilently);
}
以下是我得到的错误:
Stream reading crashed. Could not find file '\\DEV-2012X\SLWatch\Test Everything1454444717051\MB4.zip'.
堆栈跟踪是:
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access)
at ZipUtility.Zip.UnZipAllContents(String zipFileName, String extractionPath)
[/EDIT - 1]
[编辑 - 2]
以下是 ZipFile.Read 方法的签名:
public static ZipFile Read(string fileName)
public static ZipFile Read(System.IO.Stream zipStream)
public static ZipFile Read(string fileName, ReadOptions options)
public static ZipFile Read(System.IO.Stream zipStream, ReadOptions options)
[/EDIT - 2]
[编辑 - 3]
现在运行的代码:
public string UnZipAllContents(string zipFileName, string extractionPath)
{
string lsResult = string.Empty;
string lsRemoteComputerName = string.Empty;
string lsStep = "1-";
try
{
lsRemoteComputerName = Path.GetPathRoot(zipFileName);
lsStep += "2," + lsRemoteComputerName + "-";
lsStep += "3-";
using (UNCAccessWithCredentials unc = new UNCAccessWithCredentials())
{
lsStep += "3.1-";
bool lb = unc.NetUseWithCredentials(Path.GetPathRoot(zipFileName),
"Bhatti",
string.Empty,
"MyPassword");
lsStep += "4, " + lb.ToString() + "-";
string[] dirs = Directory.GetFiles(Path.GetPathRoot(zipFileName), "*",SearchOption.AllDirectories);
lsStep += "4.1,";
foreach (string d in dirs)
{
lsStep += d + ",";
}
lsStep += "-";
if (File.Exists(zipFileName))
{
lsStep += "5-";
// check if the directory exists
if (Directory.Exists(extractionPath))
{
// remove the directory
Directory.Delete(extractionPath, true);
}
// recreate the directory
Directory.CreateDirectory(extractionPath);
lsStep += "6-";
// unzip the files
using (ZipFile loZip = ZipFile.Read(zipFileName))
{
lsStep += "7-";
loZip.ExtractAll(extractionPath, ExtractExistingFileAction.OverwriteSilently);
}
lsStep += "8-";
}
else
{
lsResult += "@@@Error - Zip file does not exist. " + lsStep;
}
}
}
catch (Exception loException)
{
lsResult += lsStep + Environment.NewLine + "@@@Error - " + loException.Message + Environment.NewLine + Environment.NewLine + loException.InnerException + Environment.NewLine + Environment.NewLine + loException.StackTrace;
}
return lsResult;
}
这是创建的日志:
1-2,\\DEV-2012X\SLWatch-3-3.1-4, True-4.1,\\DEV-2012X\SLWatch\BW123.zip,\\DEV-2012X\SLWatch\1454444717051.xml,\\DEV-2012X\SLWatch\1454444717051\MB4.zip,-5-6-
@@@Error - Could not find file '\\DEV-2012X\SLWatch\1454444717051\MB4.zip'.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
at Ionic.Zip.ZipFile.get_ReadStream()
at Ionic.Zip.ZipFile.ReadIntoInstance(ZipFile zf)
at Ionic.Zip.ZipFile.Read(String fileName, TextWriter statusMessageWriter, Encoding encoding, EventHandler`1 readProgress)
at Ionic.Zip.ZipFile.Read(String fileName)
at ZipUtility.Zip.UnZipAllContents(String zipFileName, String extractionPath)
[/EDIT - 3]
【问题讨论】:
-
你能传递文件流而不是 zipfile.read 的路径吗?
-
很可能是权限错误。
-
@SteveWellens:我已授予“所有人”对该文件夹的完全权限。
-
@MigueldeSousa:让我尝试这样做,我会尽快回复您。
-
@SteveWellens:这就是我的想法,不知何故,当 Bhatti 调用包装器时,它会失去当前用户。将文件读入流可能是一种更简单的解决方法。