Objective:
Need to unzip the InfoPath form of the Xsn file, in the project before the use of expand command line decompression, have not had a problem, the recent project suddenly error decompression failure, through the analysis decompression operation concluded:
1. Normal normal situation, expand command line decompression without any problems, the same site, the same request, randomly occurred decompression failure error. And the most easily reproduced scenario is: High frequency refresh page.
2. Monitor the target directory for decompression, the directory does not change when the decompression fails. When the decompression succeeds, directory monitoring is normal.
Then put the expand command into the bat file, in the bat file, before executing the expand command, execute the "MD" command to create a random directory, C # code code executes the bat command, found that when the decompression failed, the bat command even if the execution is complete, Directory monitoring also found no directories created by the MD command. It is only possible to guess that C # is in some cases out of sync when executing the command line.
There is no time to specifically study this synchronization problem, the project has the use of C # call COM components, and then go to the web search for the COM component extracted CAB file data, found that using SHELL32 to extract the problem. Just pay attention to the way you add Shell32 references:
1. Add the "Microsoft Shell Controls and Automation" reference as shown in:
2. Build the project, generate a "Interop.Shell32.dll" assembly in the bin directory, copy it to a different directory, and then remove the reference to SELL32:
3. Add a reference to the "Interop.Shell32.dll" assembly, and the effect is as follows:
As for why this is done, it is because: add a reference to the "Microsoft Shell ..." directly, after the code is generated in other systems may not be properly called, such as win 2003 generated can not be used on the win2007, but the above-mentioned method is available. This allows you to use the shell to operate normally. For the shell operation information can be consulted: http://www.fluxbytes.com/csharp/unzipping-files-using-shell32-in-c/
The final code is organized as follows: The code also includes the CMD command line in this way, for reference.
Code:
Public partial class Extract:System.Web.UI.Page {//<summary>///The file name to unzip///</summ ary> private String Xsnfilename = @ "Infopath.xsn"; <summary>//extract to .... The target path///</summary> private String targetdirectory = @ "C:\xsn"; <summary>//CAB file name///</summary> private String CABFileName = "Cab.cab"; protected void Page_Load (object sender, EventArgs e) {//Use the cmd command to extract this. Extractbycmd (); Use Shell32 to extract this. Extractbyshell (); #region the cmd command to unzip///<summary>///To decompress with cmd command///</summary> private Voi D extractbycmd () {//Use cmd command: Expand sourcefile targetdir-f:*//above command Note: Target directory cannot be sour The Cefile directory. 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 ("Unzip with cmd command: Files that have been unzipped: <br/>"); foreach (var item in Tempdirectory.getfiles ()) Sbstring.appendformat ("{0} <br/>", item. Name); This. Response.Write (Sbstring.tostring ()); #endregion #region Use Shell to extract//<summary>///Use Shell to extract//</summary> private void Extractbyshell () {//shell can decompress the zip and cab files, the XSN file is a cab format file, but you need to be aware that using the suffix XSN decompression will fail. You need to rename the cab to the same//shell is supported for the same file and destination directory that you want to decompress. 1. Rename the 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. Unzip 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); The meaning of each parameter, refer to: 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/>The final test results are as follows:
Use the cmd command to extract: The extracted files: manifest.xsf sampledata.xml schema.xsd template.xml view1.xsl use SHELL32 for decompression. Files that have been unzipped: manifest.xsf sampledata.xml schema.xsd template.xml view1.xsl
On the problematic Project Server, the XSN file was decompressed using SHELL32, and the test found that there were no problems, even if the high frequency was repeatedly refreshed.
The above is only the project encountered in the actual situation, and is not necessarily the best solution, if everyone better plan, please leave a message.
C # using expand, Shell32 decompression cab, XSN file