我的C#应用程序有两个版本的安装程序。说V1和V2。
我已经安装了V1。在安装项目的注册表设置中,我创建了一个注册表项InstallDir= [TARGETDIR]
,它提供了我的应用程序的安装文件夹。
因此,当我想获取安装文件夹时,我可以使用我生成的注册表项来获取Path。
问题出在安装版本2 V2期间,应该将我之前版本安装文件夹中的example.txt文件复制到某处。
我已在安装状态的安装程序类中创建自定义操作,如下所示。
public override void Install(IDictionary stateSaver)
{
base.Install(stateSaver);
string path = null;
string registry_key = @"SOFTWARE\";
using (Microsoft.Win32.RegistryKey key = Registry.LocalMachine.OpenSubKey(registry_key))
{
foreach (string subkey_name in key.GetSubKeyNames())
{
if (subkey_name == "default Company Name")
{
using (RegistryKey subkey = key.OpenSubKey(subkey_name))
{
path = (string)subkey.GetValue("InstallDir");
}
}
}
}
string fileName = "example.txt";
string sourcePath = path;
string targetPath = @"C:\Users\UserName\Desktop";
// Use Path class to manipulate file and directory paths.
string sourceFile = System.IO.Path.Combine(sourcePath, fileName);
string destFile = System.IO.Path.Combine(targetPath, fileName);
// To copy a folder's contents to a new location:
// Create a new target folder, if necessary.
if (!System.IO.Directory.Exists(targetPath))
{
System.IO.Directory.CreateDirectory(targetPath);
}
// To copy a file to another location and
// overwrite the destination file if it already exists.
System.IO.File.Copy(sourceFile, destFile, true);
}
我的想法是,如果我在自定义Action的Install方法中指定注册表中的路径,它将采用Previous版本路径并在先前版本的安装路径中复制该文件。
但即使我在自定义操作的Install方法中复制,注册表也已使用较新版本的路径进行更新,并获取当前值并使用较新的版本文件进行更新。
但是我需要在该安装文件夹中使用以前的版本文件。
我怎么能实现这个目标?
答案 0 :(得分:1)
我建议你按照这种方法,
所以你的问题是你的Sqllite文件应该在安装文件夹中,当你安装新的MSI版本时,它会卸载现有的应用程序,在trun中删除所有文件,包括Sqllite,
您可以通过创建console application
来解决此问题。将sqllit文件添加到控制台应用程序,当执行console exe时,它应该将sqllite文件复制到当前正在执行的文件夹中
AppDomain.CurrentDomain.BaseDirectory;
将此控制台exe添加到您的MSI项目,并在安装程序类中使用Process.Start()
执行此exe。由于此sqllite文件由不同的exe应用程序复制,并且由于此sqllite文件在卸载MSI时不是MSI项目的一部分,因此将sqllite文件保留在文件夹中而不删除。
希望这能解决您的问题。
答案 1 :(得分:0)
经过一番研究后,我想出了一种在安装新版本时从上一个安装中提取单个文件的方法。
添加一个单独的控制台应用程序来复制文件@AccessDenied说。
在安装程序的注册表选项中的HKEY_LOCAL_MACHINE \ Software中添加一个注册表项[ProductCode],其子项installdir
的值为[TARGETDIR].
拥有旧版本的产品代码并将其存储在某处,比如配置文件。
在安装程序类中,应处理两种情况。 检查注册表以检查应用程序是否已安装。
案例1:
如果尚未安装,请运行控制台应用程序将其复制到当前安装文件夹。
或 案例2:
在密钥安装结构下的注册表中搜索先前版本的ProductCode
。
(如果你想经常更新文件,如果它是一个SQLite文件,那么有一个单独的类来更新项目中的文件)
在找到它时,提取子键值installdir
和可以分配给路径的值。
然后使用该路径复制所需文件并存储它。
进阶:
可以卸载以前的版本。
单一安装。
从以前的安装中复制所需的文件
编辑:一个简单的解决方案
在自定义操作中,安装方法会复制当前安装文件夹中将来使用所需的文件,并将其放在同一安装文件夹的某个文件夹中。
public override void Install(IDictionary stateSaver)
{
base.Install(stateSaver);
string path = null;
string registry_key = @"SOFTWARE\";
// In my case I am getting the user selected current installation folder from the registry
using (Microsoft.Win32.RegistryKey key = Registry.LocalMachine.OpenSubKey(registry_key))
{
foreach (string subkey_name in key.GetSubKeyNames())
{
if (subkey_name == "Default Company Name")
{
using (RegistryKey subkey = key.OpenSubKey(subkey_name))
{
path = (string)subkey.GetValue("InstallDir");
}
}
}
}
string fileName = "example.txt";
string sourcePath = path;
//Have created a folder named "tmp" in current innstallation folder.
string targetPath =System.IO.Path.Combine(path,"tmp");
// Use Path class to manipulate file and directory paths.
string sourceFile = System.IO.Path.Combine(sourcePath, fileName);
string destFile = System.IO.Path.Combine(targetPath, fileName);
// To copy a folder's contents to a new location:
// Create a new target folder, if necessary.
if (!System.IO.Directory.Exists(targetPath))
{
System.IO.Directory.CreateDirectory(targetPath);
}
//Copy the required file.
System.IO.File.Copy(sourceFile, destFile, true);
}
现在即使我们卸载tmp文件夹也不会被删除。安装另一个版本时,我们可以从tmp文件夹访问以前的版本文件。
感谢。