Wix: cách cài đặt thư mục chia sẻ
Tôi đang chạy WiX 3.11 với bổ trợ C # VSTO. Tôi cần tạo một tính năng sẽ cài đặt một thư mục, đăng ký nó để chia sẻ với mọi người và xóa phần chia sẻ khi gỡ cài đặt.
Tôi đã thử 2 cách tiếp cận khác nhau nhưng không thành công (tên và id được thay đổi để đơn giản hóa):
- Với sự trợ giúp của các liên kết bên dưới, tôi đã cố gắng tạo quyền khi thư mục được tạo:
WiX đặt quyền thư mục App_Data để sửa đổi cho NetworkService
Wix: CustomAction để đặt quyền cho thư mục
Đặt quyền cho các thư mục và tệp hiện có trong ProgramData bằng WiX Toolset
<Directory Id="TARGETDIR" Name="SourceDir"> <Directory Id="WINDOWSVOLUME"> <Directory Id="INSTALLFOLDER" Name="."> <Directory Id="FOLDERTOSHARE" Name="Share"> <Component Id="ShareFolderPermissions" Guid="SOMEGUID"> <CreateFolder> <util:PermissionEx User="Everyone" GenericAll="yes" /> </CreateFolder> </Component> </Directory> </Directory> </Directory>
Với ShareFolderPermissions được tham chiếu trong tính năng mới của tôi.
Tôi đã thử điều chỉnh nó một chút nhưng nó không hiệu quả với tôi.
- Giải pháp thứ hai của tôi là thử sử dụng các lệnh Windows thông qua CustomActions để hoàn thành công việc (spoiler: Dù sao thì sau này tôi cũng cần CustomActions).
Nó hoạt động tốt tại một số thời điểm nhưng tôi không thể thực hiện toàn bộ quá trình.
Tôi đã sử dụng một trang web không phải tiếng Anh để thiết lập cách tạo dự án WiX CustomAction để nhập vào tệp Product.wxs của mình và tôi sẽ cung cấp bên dưới những gì đã giúp tôi thiết lập các dòng lệnh trong C #.
Cách sử dụng lệnh Windows với tài liệu chia sẻ C #
Net
Product.wxs (xml):
<?if $(var.Configuration) = MyShareConfiguration?>
<Property Id="SHAREFEATURE" Value="1" />
<?endif?>
<Feature Id="ShareFeature" Title="ShareSetup" Level="0">
<Condition Level="1">SHAREFEATURE</Condition>
<ComponentGroupRef Id="MyShareFiles"/>
</Feature>
<CustomAction Id="CustomActionShareFolder" BinaryKey="CustomActionProject" DllEntry="ShareFolder" Execute="immediate" Return="check" Impersonate="no" />
<CustomAction Id="CustomActionUnShareFolder" BinaryKey="CustomActionProject" DllEntry="UnShareFolder" Execute="immediate" Return="check" Impersonate="no" />
<Binary Id="CustomActionProject" SourceFile="CustomActionProjectPath" />
<InstallExecuteSequence>
<Custom Action="CustomActionShareFolder" After="InstallFiles"> SHAREFEATURE AND (NOT REMOVE) </Custom>
<Custom Action="CustomActinUnShareFolder" Before="RemoveFiles"> SHAREFEATURE AND (REMOVE~="ALL") </Custom>
</InstallExecuteSequence>
CustomAction.cs trong dự án CustomAction của tôi (C #), nhật ký được xóa để rõ ràng:
private static readonly string SHAREFEATURENAME= "MyShareFeatureName";
private static void ExecuteCMD(string command)
{
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo
{
WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden,
FileName = "CMD.exe",
Arguments = command,
CreateNoWindow = true,
UseShellExecute = true,
Verb = "runas"
};
process.StartInfo = startInfo;
process.Start();
}
[CustomAction]
public static ActionResult ShareFolder(Session session)
{
ActionResult result = ActionResult.Success;
string directoryPath = session.GetTargetPath("FOLDERTOSHARE"); // See Directory setup in 1.
string command = string.Format("/c net share {0}=\"{1}\"", SHAREFEATURENAME, directoryPath.Remove(directoryPath.Length - 1)); // Remove '\' at the end of the path
try
{
ExecuteCMD(command);
}
catch (Exception)
{
result = ActionResult.Failure;
}
return result;
}
[CustomAction]
public static ActionResult UnShareFolder(Session session)
{
ActionResult result = ActionResult.Success;
string command = string.Format("/c net share {0} /delete", SHAREFEATURENAME);
try
{
ExecuteCMD(command);
}
catch (Exception)
{
result = ActionResult.Failure;
}
return result;
}
Tôi đã thử nghiệm lệnh của mình trong một dự án ứng dụng riêng biệt với các giá trị được mã hóa cứng mà tôi nhận được từ nhật ký msi của mình.
msiexec /i "C:\MyPackage\Example.msi" /L*V "C:\log\example.log"
Mã từ dự án riêng biệt (tên được thay đổi theo mục đích):
static void Main(string[] args)
{
string command = "/c net share SHAREFEATURENAME=\"MyFolderPath\"";
//string command = "/c net share SHAREFEATURENAME /delete";
Console.WriteLine("Command : " + command);
Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.RedirectStandardInput = true;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.CreateNoWindow = true;
cmd.StartInfo.UseShellExecute = false;
cmd.StartInfo.Arguments = command;
cmd.StartInfo.Verb = "runas";
cmd.Start();
cmd.StandardInput.WriteLine("echo test");
cmd.StandardInput.Flush();
cmd.StandardInput.Close();
cmd.WaitForExit();
Console.WriteLine(cmd.StandardOutput.ReadToEnd());
}
Mã từ dự án riêng biệt hoạt động tốt miễn là VS chạy với tư cách quản trị viên.
Đối với msi của tôi, tôi đã đặt Impersonate = "no" để nó yêu cầu quyền nâng cao khi cài đặt / gỡ cài đặt.
Cả hai lệnh đều được gọi chính xác và kết thúc không có lỗi. Tuy nhiên, thư mục được nhắm mục tiêu không bao giờ được chia sẻ.
Ai có thể giúp tôi không ?
Trả lời
Những gì bạn mô tả - theo như tôi hiểu - có thể đạt được với các cấu trúc WiX tích hợp sẵn. Đây là một số gợi ý, tôi muốn tránh trùng lặp quá nhiều mã và đánh dấu. Vui lòng làm theo liên kết 2 ít nhất. Liên kết 1 chỉ dành cho bản ghi:
Luôn cố gắng tránh các hành động tùy chỉnh (tôi biết bạn nói rằng bạn cần chúng).
Có lẽ hãy thử mẫu WiX này để chia sẻ thư mục ?