这可能不完全是你想要的,但我在我的WPF应用程序和它们的编码UI测试中遇到了类似的问题。在我的情况下,我正在使用TFS构建(通过实验室模板)和它的部署将我们的构建输出(一个MSI文件)安装到目标上,然后测试针对已安装的软件运行。
现在,因为我们希望针对已安装的软件进行测试,所以我们添加了测试初始化方法,通过调用MSI API来获取我们安装程序中产品/组件GUID的安装文件夹。
以下是代码片段,请记得从你的安装程序中替换你的产品和组件GUIDS)
public void StartGui()
{
Console.WriteLine("Starting GUI process...");
try
{
var path = this.DetectInstalledCopy();
var workingDir = path;
var exePath = Path.Combine(path, "gui.exe");
Console.Write("Starting new GUI process... ");
this.guiProcess = Process.Start(new ProcessStartInfo
{
WorkingDirectory = workingDir,
FileName = exePath,
LoadUserProfile = true,
UseShellExecute = false
});
Console.WriteLine("started GUI process (id:{0})", this.guiProcess.Id);
}
catch (Win32Exception e)
{
this.guiProcess = null;
Assert.Fail("Unable to start GUI process; exception {0}", e);
}
}
private string DetectInstalledCopy()
{
Console.WriteLine("Looking for install directory of CORTEX 7 GUI app");
int buffLen = 1024;
var buff = new StringBuilder(buffLen);
var ret = NativeMethods.MsiGetComponentPath(
"{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}",
"{YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY}",
buff,
ref buffLen);
if (ret == NativeMethods.InstallstateLocal)
{
var productInstallRoot = buff.ToString();
Console.WriteLine("Found installation directory for GUI.exe feature at {0}", productInstallRoot);
return productInstallRoot;
}
Assert.Fail("GUI product has not been installed on this PC, or not for this user if it was installed as a per-user product");
return string.Empty;
}
public void StopGui()
{
if (this.guiProcess != null)
{
Console.Write("Closing GUI process (id:[{0}])... ", this.guiProcess.Id);
if (!this.guiProcess.HasExited)
{
this.guiProcess.CloseMainWindow();
if (!this.guiProcess.WaitForExit(30.SecondsAsMilliseconds()))
{
Assert.Fail("Killing GUI process, it failed to close within 30 seconds of being asked to close");
this.guiProcess.Kill();
}
else
{
Console.WriteLine("GUI process closed gracefully");
}
}
this.guiProcess.Close();
this.guiProcess = null;
}
}
这里是API包装器代码:
[DllImport("MSI.DLL", CharSet = CharSet.Unicode)]
internal static extern uint MsiGetComponentPath(
string product,
string component,
StringBuilder pathBuf,
ref int buff);