我正在使用 Visual Studio 2019 的Visual Studio Installer Projects擴展。我已經創建了我的安裝專案并想要添加我想要作為 C# 方法實作的自定義操作(我想要安裝/卸載證書的方法)。我不清楚的是自定義操作面板中的自定義操作配置(出現在 Visual Studio 中)和我要呼叫的 C# 代碼之間的聯系。如何創建類/方法,以便安裝程式可以看到它們并根據需要激活它們?類是否必須具有一定的繼承性,如果是,需要哪些程式集?
uj5u.com熱心網友回復:
您可以像創建普通課程一樣創建它們。您將需要匯入幾個命名空間來執行此操作。
具體來說
- Microsoft.Deployment.WindowsInstaller;
- Microsoft.Tools.WindowsInstallerXml;
這是我不久前為安裝程式所做的自定義操作的簡化版本。
using Microsoft.Deployment.WindowsInstaller;
using Microsoft.Tools.WindowsInstallerXml;
public class CustomActions : WixExtension
{
[CustomAction]
public static ActionResult CreateAndPopulateStorageFolder(Session session)
{
ActionResult result = ActionResult.Success;
try
{
session.Log("In Custom Action: CreateAndPopulateStorageFolder");
if (!Directory.Exists("C:\\Path"))
{
session.Log("In Custom Action: CreateAndPopulateStorageFolder: Directory does not exist");
Directory.CreateDirectory("C:\\Path");
Directory.CreateDirectory("C:\\Path");
Directory.CreateDirectory("C:\\Path");
}
}
catch (Exception ex)
{
session.Log(ex.Message);
result = ActionResult.Failure;
}
return result;
}
}
uj5u.com熱心網友回復:
我在這篇文章中找到了答案。基本上相當于向Installer我的程式集添加一個類(從 繼承System.Configuration.Install.Installer)并覆寫適當的方法。需要將自定義操作屬性的InstallerClass屬性設定為True。
using System.Collections;
using System.ComponentModel;
using System.Configuration.Install;
using System.IO;
namespace InstallerCustomAction
{
[RunInstaller(true)]
public partial class MyInstaller : Installer
{
public MyInstaller()
{
InitializeComponent();
}
public override void Install(IDictionary stateSaver)
{
File.WriteAllText(@"C:\InstallTest.txt", "This is a test of an install action");
base.Install(stateSaver);
}
}
}
(注意模板會創建對應的 Designer.cs 檔案)
這似乎不支持傳入引數,但這不是我需要的。
uj5u.com熱心網友回復:
在 DllExport ( https://github.com/3F/DllExport/wiki )中找到了我正在尋找的答案。這使我能夠創建一個 .NET Framework 程式集并將入口點匯出到程式集方法,就好像它們是傳統的非托管 C DLL 匯出一樣,可以由 msiexec 作為自定義操作呼叫。
基本步驟:
- 創建程式集專案并添加一個具有要匯出的靜態方法的類。
- 將DllExport nuget 參考添加到專案中。nuget 包含一個配置工具;添加 nuget 會啟動該工具。您需要確定您的解決方案、解決方案中的專案以及(令人困惑的)包含 DllExport 屬性的命名空間(應該是
System.Runtime.InteropServices)。當您“應用”時,它會修改 vcproj。 - 將
[DllExport]屬性添加到要匯出的每個靜態方法。在構建時,將創建一個具有 C 方法入口點的程式集。注意默認情況下,除了 x86 和 x64 版本的程式集之外,還有一個“AnyCPU”版本的程式集不包含任何匯出。您需要使用其中之一。 - 將 x86 程式集添加到安裝程式專案并在自定義操作中參考程式集和匯出的名稱。您還可以為CustomActionData指定一個值。
示例代碼:
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows;
namespace CustomActionFrameworkTest
{
public class CustomActions
{
/// <summary>
/// Import the MsiGetProperty method
/// </summary>
/// <param name="hInstall">Handle to the install instance</param>
/// <param name="szName">Property name we want the value of</param>
/// <param name="szValueBuf">Value</param>
/// <param name="pchValueBuf">Length of value (buffer size on input, actual length output)</param>
/// <returns></returns>
[DllImport("msi.dll", CharSet = CharSet.Unicode)]
static extern int MsiGetProperty(int hInstall, string szName,
[Out] StringBuilder szValueBuf, ref int pchValueBuf);
[DllExport]
public static int InstallTest(int handle)
{
// Debugger.Launch(); // If you need to debug
var sb = new StringBuilder(512); // Initialize to an arbitrary size
int size = 512; // Must give the function a buffer size
var status = MsiGetProperty(handle, "CustomActionData", sb, ref size);
if (status == 0)
{
var message = $"Got value '{sb}' from CustomActionData";
MessageBox.Show(message, "Test", 0);
}
else
{
MessageBox.Show($"MsiGetProperty failed with error code: {status}", "Error", 0);
}
return 0;// 0= success, 1602 = user exit, 1603 = failure
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/455812.html
上一篇:如何通過查詢字串傳遞物件陣列并在asp.net控制器中讀取它們
下一篇:附加svg解決了這個問題
