ClickOnce是一种新的Windows Form程序的安装方式。与MSI安装程序不同,它更象web程序的运行方式,程序是Window Form类型的,但是通过一个web地址启动的,并且运行在一个“砂箱”环境下,对本机的一些资源(如注册表)没有访问权限。不过我试用ClickOnce最大的好处是可以自动升级。
ClickOnce详细的技术在msdn上有很多文章。这里只是把我遇到的问题记录下来。
先介绍一下我要完成的功能:一个单机版的Window Form程序,带有一个本地的ACCESS数据库和一个数据文件menu.xml。 要求程序更新后可以自动升级,也就是为了这一点,我才使用的ClickOnce安装,其实ClickOnce安装适合哪些C/S结构的发布。
问题1
我的数据库和xml文件原来放在一个叫APP_Data的子目录下。但安装时总是报错找不到文件。
后来研究了一下,发现ClickOnce的Client安装后的目录结构是固定,我没有找到方法能改变它。而且与你的开发环境的设置不一样。
图1:开发环境下的目录结构
图2:部署在Client端的目录结构
当程序跑在Client端时,它的数据和程序分开在两个目录下,而且目录名如此的怪异。这也造成了程序在运行时和开发式数据文件的位置是不一样的。
在程序访问本地数据库文件和xml文件时,需要考虑当前环境。
在开发环境下,数据文件在根目录下。
在Client环境下,数据文件被自动安装到数据目录。
下面是我访问menu,xml的代码:
string menuFile;
try
{
//如果当前是在Client端运行,则通过Deployment namespace的方法得到数据目录的具体位置
menuFile = System.Deployment.Application.ApplicationDeployment.CurrentDeployment.DataDirectory + @"/Menu.xml";
}
catch
{
//发生异常说明当前运行在开发环境下,直接取当前目录下的文件即可
menuFile = System.IO.Directory.GetCurrentDirectory() + @"/Menu.xml";
}
下面是数据库连接字符串,保存在config文件中。
<connectionStrings>
<add name="CVIS.Properties.Settings.CVIS_DBConnect" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|/CVIS_main.mdb"
providerName="System.Data.OleDb" />
</connectionStrings>
注意Data Source=|DataDirectory|/CVIS_main.mdb 中间的|DataDirectory|就是数据文件的目录,你在开发时,数据目录默认是当前目录,如果你为数据文件单独建一个子目录,会在Client安装时出错。在Client端运行时,net会自动计算出数据目录的位置。所以你只要把|DataDirectory|加上,就不需要自己处理了。
问题2
需要将程序 publish到另外一台Wind2003机器CVIS-SVR上。我先在CVIS-SVR上建了一个虚目录CVIs-Setup,然后把publish的地址设置为:http://CVIS-SVR/CVIs-Setup/ 结果失败了。报了一个错误大致意思是这不是一个文件目录。我到CVIS-SVR上把虚目录CVIs-Setup删除。然后再用http://CVIS-SVR/CVIs-Setup/ 发布,成功了。原来虚目录不用自己建,发布程序自动建,我真是自做聪明。