程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#使用Expand、Shell32解壓Cab、XSN文件,

C#使用Expand、Shell32解壓Cab、XSN文件,

編輯:C#入門知識

C#使用Expand、Shell32解壓Cab、XSN文件,


 

前言:

  需要解壓InfoPath表單的xsn文件,在項目中以前使用的是Expand命令行解壓,都沒有出過問題,近段時間項目中突然報錯解壓失敗,通過分析解壓操作得出結論:

    1.正常正常情況下,expand命令行解壓沒有任何問題,同一個站點,相同的請求,隨機出現解壓失敗的錯誤。而且最容易復現的情況為:高頻率刷新頁面。

    2.監視解壓的目標目錄,解壓失敗的時候,目錄沒有任何變化。而解壓成功時,目錄監視則正常。

  然後將expand命令放到bat文件中,在bat文件中,執行expand命令之前,先執行 “md” 命令創建隨機目錄,C#代碼代碼執行bat命令,發現在解壓失敗的時候,bat命令即使執行完成,目錄監視也沒有發現md命令創建的目錄。只能猜測C#在執行命令行的時候,某些情況下會存在不同步的情況。

  也沒有時間專門去研究這個同步的問題,項目中有使用C#調用COM組件的地方,然後去網上搜了一下COM組件解壓的cab文件的資料,發現使用shell32進行解壓則沒有問題。只是需要注意添加Shell32引用的方式:

  1.添加“Microsoft Shell Controls And Automation” 引用,如下圖所示:

    

  2.生成項目,在bin目錄下會生成“Interop.Shell32.dll”程序集,拷貝到其他目錄,然後移除對Sell32的引用:

    

  3.添加對“Interop.Shell32.dll”程序集的引用,然後效果如下圖所示:

    

  至於為什麼要進行上述操作,是因為:直接添加對“Microsoft Shell...”的引用,代碼生成之後在其他系統可能無法正常調用,如Win 2003 生成的無法在win2007上使用,但是通過上述方式引用之後,則可以了了。這樣就可以正常使用Shell進行操作了。進行Shell操作的資料可以參考:http://www.fluxbytes.com/csharp/unzipping-files-using-shell32-in-c/

  最終代碼整理如下:代碼中也包括cmd命令行的方式,在此供參考。

代碼:

public partial class Extract : System.Web.UI.Page

    {

        /// <summary>

        /// 要解壓的文件名稱

        /// </summary>

        private String XSNFileName = @"infopath.xsn";

 

        /// <summary>

        /// 解壓到....  的目標路徑

        /// </summary>

        private String TargetDirectory = @"C:\xsn";

 

        /// <summary>

        /// cab文件名稱

        /// </summary>

        private String CabFileName = "cab.cab";

 

        protected void Page_Load(object sender, EventArgs e)

        {

            //使用cmd命令解壓

            this.ExtractByCmd();

            

            //使用shell32進行解壓

            this.ExtractByShell();

        }

 

        #region cmd命令解壓

        /// <summary>

        /// 使用cmd命令進行解壓

        /// </summary>

        private void ExtractByCmd()

        {

            //使用cmd命令:expand  sourcefile  targetDir  -F:*    

            //  上面的命令得注意:目標目錄不能是sourceFile的目錄。

 

            System.Text.StringBuilder sbString = new System.Text.StringBuilder();

            

            String tempDir = Guid.NewGuid().ToString();

            System.IO.Directory.CreateDirectory(System.IO.Path.Combine(this.TargetDirectory, tempDir));

            String cmdString = String.Format("\"{0}\" \"{1}\" -F:*", this.XSNFileName,tempDir);

            using (Process process = new Process())

            {

                process.StartInfo.FileName = "expand";

                process.StartInfo.WorkingDirectory = this.TargetDirectory;

                process.StartInfo.Arguments = cmdString;

 

                process.StartInfo.RedirectStandardInput = true;

                process.StartInfo.RedirectStandardOutput = true;

                process.StartInfo.RedirectStandardError = true;

                process.StartInfo.UseShellExecute = false;

 

                process.Start();

                process.WaitForExit();

 

                //this.Response.Write(process.StandardOutput.ReadToEnd());

            }

            System.IO.DirectoryInfo tempDirectory = new System.IO.DirectoryInfo(System.IO.Path.Combine(this.TargetDirectory, tempDir));

            sbString.Append("使用CMD命令進行解壓:已經解壓的文件:<br />");

            foreach (var item in tempDirectory.GetFiles())

                sbString.AppendFormat("{0} <br />", item.Name);

 

            this.Response.Write(sbString.ToString());

        }

        #endregion

 

        #region 使用shell解壓

        /// <summary>

        /// 使用Shell解壓

        /// </summary>

        private void ExtractByShell()

        {

            //shell能解壓zip和cab文件,xsn文件是cab格式文件,但是需要注意直接使用後綴xsn解壓會失敗。此時需要重命名為cab即可

            //shell是支持要解壓的文件和目標目錄相同。

 

            //1.重命名

            String tempString=Path.Combine(this.TargetDirectory,this.CabFileName);

            if (File.Exists(tempString)) File.Delete(tempString);

            new FileInfo(Path.Combine(this.TargetDirectory, this.XSNFileName)).CopyTo(tempString);

 

            //2.解壓

            Shell32.ShellClass shellClass = new Shell32.ShellClass();

            Shell32.Folder sourceFoloder = shellClass.NameSpace(Path.Combine(this.TargetDirectory, this.CabFileName));

            tempString = Path.Combine(this.TargetDirectory, Guid.NewGuid().ToString());

            Directory.CreateDirectory(tempString);

            Shell32.Folder targetDir = shellClass.NameSpace(tempString);

            foreach (var item in sourceFoloder.Items())

                targetDir.CopyHere(item, 4);

            //各個參數的含義,參照:http://www.fluxbytes.com/csharp/unzipping-files-using-shell32-in-c/

 

            DirectoryInfo tempDire = new DirectoryInfo(tempString);

            System.Text.StringBuilder sbString = new System.Text.StringBuilder();

            sbString.Append("<br /><br /><hr />使用Shell32進行解壓。已經解壓的文件:<br />");

            foreach (var item in tempDire.GetFiles())

                sbString.AppendFormat("{0} <br />", item.Name);

            this.Response.Write(sbString.ToString());

               

        }

        #endregion 

    }

 

  最終測試結果如下:

使用CMD命令進行解壓:已經解壓的文件:
manifest.xsf 
sampledata.xml 
schema.xsd 
template.xml 
view1.xsl 



使用Shell32進行解壓。已經解壓的文件:
manifest.xsf 
sampledata.xml 
schema.xsd 
template.xml 
view1.xsl 

  

  在出問題的項目服務器上,使用shell32的方式進行xsn文件解壓,測試後發現沒有任何問題,即使高頻率重復刷新。

  以上只是項目中遇到的實際情況闡述,並不一定是最好的解決方案,如果大家更好的方案,請留言。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved