Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在安装过程中解压和重新压缩XAP文件以修改配置文件时出现问题_C#_Silverlight_Zip_Installshield_Dotnetzip - Fatal编程技术网

C# 在安装过程中解压和重新压缩XAP文件以修改配置文件时出现问题

C# 在安装过程中解压和重新压缩XAP文件以修改配置文件时出现问题,c#,silverlight,zip,installshield,dotnetzip,C#,Silverlight,Zip,Installshield,Dotnetzip,我有一个有趣的两难境地,我希望有人能给出答案。我的公司有一个非常复杂的web应用程序,我们通过一个InstallShield多实例安装程序包交付给我们的客户。该应用程序是用ASP.NET MVC3(使用Web窗体视图引擎)、C#4.0和Silverlight编写的。这是应用程序的Silverlight组件,我们在安装过程中遇到了问题 我们的许多客户希望以我们称之为“混合绑定模式”的方式安装我们的web应用程序。这可能不是正确的术语。我的意思是,客户端将在客户端防火墙内部的web服务器上安装web

我有一个有趣的两难境地,我希望有人能给出答案。我的公司有一个非常复杂的web应用程序,我们通过一个InstallShield多实例安装程序包交付给我们的客户。该应用程序是用ASP.NET MVC3(使用Web窗体视图引擎)、C#4.0Silverlight编写的。这是应用程序的Silverlight组件,我们在安装过程中遇到了问题

我们的许多客户希望以我们称之为“混合绑定模式”的方式安装我们的web应用程序。这可能不是正确的术语。我的意思是,客户端将在客户端防火墙内部的web服务器上安装web应用程序,并通过DMZ中的代理服务器将其公开给web。这样,防火墙内部的所有内容都将解析为HTTP,而每个外部请求都将解析为HTTPS

在安装过程中,这不会对大多数web应用程序造成问题,因为它将在防火墙内运行,并且当应用程序以“混合绑定模式安装时,它将始终是HTTP”。Silverlight组件并非如此。因为它在最终用户的浏览器进程空间中运行,所以它位于代理和防火墙之外,必须通过HTTPS进行解析

Silverlight文件位于XAP文件中。在XAP文件中,我们有一个配置文件(XML格式),必须根据web应用程序的绑定模式(HTTP、HTTPS或混合)修改该文件。众所周知,XAP文件只是Zip文件,因此理论上,编辑XAP中包含的文件所需的全部工作就是将其从“.XAP”重命名为“.Zip”,并使用任何与Zip兼容的实用程序或库组件提取配置文件,通过一些手动或自动方式对其进行编辑,然后使用相同的zip组件将修改后的文件重新归档到XAP文件中

“问题就在这里!”这必须在InstallShield Basic MSI过程中自动发生。首先,我们使用DotNetZip库尝试使用InstallShield托管代码自定义操作;但是,DotNetZip似乎与InstallShield不兼容。每次InstallShield启动自定义操作时,安装程序都会在自定义操作尝试执行第一个DotNetZip命令时抛出InstallShield1603错误。(是的,在尝试解压缩该文件之前,我们确实将XAP文件从“.XAP”重命名为“.zip”。SharpZipLib也遇到了同样的问题

接下来,我们使用Shell32库来降低到较低级别的算法。我们知道使用此方法时需要考虑时间因素,因为Shell32进程在单独的线程中运行,因此我们将等待状态构建到进程中,如下所示:

//从.zip存档中提取配置文件

Shell=new Shell32.Shell()

string extractedFolderPath=tempZipFileName.Substring(0,tempZipFileName.Length-4)+“\”

if(Directory.Exists(extractedFolderPath))

Delete(extractedFolderPath,true)

CreateDirectory(extractedFolderPath)

//文件夹名称将删除文件扩展名

Shell32.Folder output=shell.NameSpace(extractedFolderPath)

Shell32.Folder input=shell.NameSpace(tempZipFileName)

foreach(input.Items()中的FolderItem F)

{

字符串名称=F.名称

//我们只提取配置文件

if(name.Equals(CFG_文件))

{

输出。移动到此处(F,4); 系统线程线程睡眠(长超时)

}

}

//你得在这里睡一会儿

//因为shell32在单独的线程中运行

系统线程线程睡眠(MED_超时)

这似乎对当时的大多数人都有效

注意:以上“多数”一词的使用。该进程在速度快的服务器上工作不一致,而在速度慢的机器上工作一致。别问我为什么,我的数学教授总是教我一秒钟就是一秒钟(至少在这个宇宙中是这样)

我们甚至用一个PowerShell脚本来尝试这一点。在这种情况下,我们可以提取配置文件并将其重命名到提取到的目标文件夹中;但是,我们尝试将重命名的文件复制回ZIP存档的所有操作都失败了。这是非常不寻常的,因为我们添加了第二个调用来将目标文件夹及其所有子文件夹推送到Zip存档中,而且效果很好(请参见下面的代码参考)

#摘录_XAP.ps1

#===============

$shell=新对象-com shell.application

#将当前位置建立为当前位置

$CurrentLocation=获取位置

#确定$CurrentLocation的路径

$CurrentPath=$CurrentLocation.path

#使用$CurrentPath创建命名空间

$Location=$shell.namespace($CurrentPath)

#将XAP文件重命名为ZIP文件,以便提取

获取ChildItem*.xap |重命名项-NewName{

$\名称-替换“xap”、“zip”

}

#使用ZIP文件创建一个ChildItem对象

$ZipFile=get childitem SunGard.OmniWA.WebAdmin.zip

#确保ZIP文件不是只读的

(dir$ZipFile).IsReadOnly=$false