Wix:如何安装共享文件夹 [英] Wix : how to install a shared folder

查看:45
本文介绍了Wix:如何安装共享文件夹的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在运行带有 C# VSTO 插件的 WiX 3.11.我需要创建一个功能来安装文件夹、注册它以便与所有人共享并在卸载时删除共享.

我尝试了 2 种不同的方法,但都没有成功(为了简化而更改了名称和 ID):

  1. 借助以下链接,我尝试在创建文件夹时创建权限:
    WiX 设置 App_Data 文件夹权限以修改 NetworkService
    Wix:用于设置文件夹权限的自定义操作
    设置现有文件夹和文件的权限带有 WiX 工具集的 ProgramData

<块引用>

 <目录ID=WINDOWSVOLUME"><目录 ID=安装程序"名称=."<目录ID=FOLDERTOSHARE"名称=共享"><Component Id="ShareFolderPermissions";Guid=SOMEGUID"><创建文件夹><util:PermissionEx User="Everyone";GenericAll=是"/></创建文件夹></组件></目录></目录></目录>

在我的新功能中引用了 ShareFolderPermissions.
我试过稍微调整一下,但对我不起作用.

  1. 我的第二个解决方案是尝试通过 CustomActions 使用 Windows 命令来完成工作(剧透:无论如何我以后都需要 CustomActions).
    它在某些时候运行良好,但我一直无法实施整个过程.

我使用了一个非英语网站来设置如何创建一个 WiX CustomAction 项目以导入到我的 Product.wxs 文件中,我在下面给出了帮助我在 C# 中设置命令行的内容.
如何在 C# 中使用 Windows 命令
网络共享文档

Product.wxs (xml):

<Property Id="SHAREFEATURE";值=1"/><?endif?><Feature Id="ShareFeature";标题=共享设置"级别=0"><条件级别=1">SHAREFEATURE</条件><ComponentGroupRef Id="MyShareFiles"/></功能><CustomAction Id="CustomActionShareFolder";BinaryKey=CustomActionProject"DllEntry=共享文件夹"执行=立即"返回=检查"冒充=不"/><CustomAction Id="CustomActionUnShareFolder";BinaryKey=CustomActionProject"DllEntry="UnShareFolder"执行=立即"返回=检查"冒充=不"/><Binary Id="CustomActionProject";SourceFile=CustomActionProjectPath"/><安装执行序列><Custom Action="CustomActionShareFolder";After="InstallFiles">共享和(不删除)</自定义><自定义操作=CustomActinUnShareFolder"Before=RemoveFiles">SHAREFEATURE AND (REMOVE~=ALL") </Custom></InstallExecuteSequence>

我的 CustomAction 项目 (C#) 中的 CustomAction.cs,为清楚起见,删除了日志:

private static readonly string SHAREFEATURENAME=MyShareFeatureName";私有静态无效 ExecuteCMD(字符串命令){System.Diagnostics.Process process = new System.Diagnostics.Process();System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo{WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden,FileName = "CMD.exe",参数 = 命令,CreateNoWindow = true,UseShellExecute = true,动词 = runas"};process.StartInfo = startInfo;process.Start();}[自定义动作]公共静态 ActionResult 共享文件夹(会话会话){ActionResult 结果 = ActionResult.Success;string directoryPath = session.GetTargetPath(FOLDERTOSHARE");//参见 1 中的目录设置.string command = string.Format("/c net share {0}=\"{1}\"", SHAREFEATURENAME, directoryPath.Remove(directoryPath.Length - 1));//删除路径末尾的'\'尝试{执行CMD(命令);}捕获(异常){结果 = ActionResult.Failure;}返回结果;}[自定义动作]公共静态 ActionResult UnShareFolder(会话会话){ActionResult 结果 = ActionResult.Success;string command = string.Format("/c net share {0}/delete", SHAREFEATURENAME);尝试{执行CMD(命令);}捕获(异常){结果 = ActionResult.Failure;}返回结果;}

我已经在一个单独的应用程序项目中测试了我的命令,并使用从我的 msi 日志中获得的硬编码值.

msiexec/i "C:\MyPackage\Example.msi";/L*V "C:\log\example.log";

来自单独项目的代码(故意更改名称):

static void Main(string[] args){string command = "/c net share SHAREFEATURENAME=\"MyFolderPath\"";//string command = "/c net share SHAREFEATURENAME/delete";Console.WriteLine("命令:" + 命令);进程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 = 命令;cmd.StartInfo.Verb = "runas";cmd.Start();cmd.StandardInput.WriteLine(回声测试");cmd.StandardInput.Flush();cmd.StandardInput.Close();cmd.WaitForExit();Console.WriteLine(cmd.StandardOutput.ReadToEnd());}

只要 VS 以管理员身份运行,来自单独项目的代码就可以正常工作.
从我的 msi 开始,我已经设置了 Impersonate="no"所以它要求提升安装/卸载权限.

两个命令都被正确调用并且没有错误结束.但是,目标文件夹永远不会共享.

有人可以帮我吗?

解决方案

你所描述的——据我所知——应该可以通过内置的 WiX 结构来实现.这里有一些提示,我想避免过多的代码和标记重复.请至少遵循链接 2.链接 1 仅供记录:

  1. 总是尽量避免自定义操作(我知道你说你需要它们).

  2. 也许可以试试这个用于文件夹共享的 WiX 示例?

I'm running WiX 3.11 with a C# VSTO add-in. I need to create a feature that will install a folder, register it for sharing with everyone and remove the share upon uninstall.

I've tried 2 different approaches with no success (names and Ids are changed for simplification) :

  1. With the help of the links below, I've tried to create permissions when the folder is created :
    WiX set App_Data folder permission to modify for NetworkService
    Wix: CustomAction to set Folder permissions
    Set permissions for existing folders and files in ProgramData with 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>

With ShareFolderPermissions referenced in my new feature.
I've tried tweaking it a bit but it didn't work for me.

  1. My second solution was to try using Windows commands through CustomActions to get the job done (spoiler: I'll need CustomActions later anyway).
    It worked fine at some point but I've been unable to implement the whole process.

I used a non-english website to get set up on how to create a WiX CustomAction project to import into my Product.wxs file, and I'm giving below what helped me set up command lines in C#.
How to use Windows command with C#
Net share documentation

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 in my CustomAction project (C#), logs are removed for clarity:

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; 
}

I've tested my command in a separate application project with hard coded values I got from my msi logs.

msiexec /i "C:\MyPackage\Example.msi" /L*V "C:\log\example.log"

Code from the separate project (names changed on purpose) :

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());
}

The code from the separate project works fine as long as VS runs as administrator.
As of my msi, I've set Impersonate="no" so it asks for elevated rights on install / uninstall.

Both command are correctly called and end with no error. However, the targeted folder is never shared.

Can anybody help me out ?

解决方案

What you describe - as far as I understand it - should be possible to achieve with built-in WiX constructs. Here are some pointers, I want to avoid too much code and markup duplication. Please DO follow link 2 at least. Link 1 is just for the record:

  1. Always try to avoid custom actions (I know you state you need them).

  2. Perhaps try this WiX sample for folder sharing?

这篇关于Wix:如何安装共享文件夹的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆