如何防止 C# 将临时路径作为原始路径的前缀?
How do I prevent C# from prefixing the temporary path to my original path?
我正在尝试在自定义操作中编辑已安装的 cmd
文件:
<CustomAction
Id="CA_EditScriptAction"
Return="check"
Execute="deferred"
Impersonate="no"
BinaryKey="CustomActions"
DllEntry="EditScriptAction"
/>
它在 PublishProduct
操作之后调用。
问题是,我找不到该文件,因为出于某种原因,当它使用 Directory.GetFiles(ABSOLUTE_PATH)
等方法时,它会在绝对路径前加上临时安装程序目录的路径。这是日志:
SFXCA: Extracting custom action to temporary directory: C:\Windows\Installer\MSI941A.tmp-\
SFXCA: Binding to CLR version v4.0.30319
Calling custom action MSIActions!MSIActions.CustomActions.EditScriptAction
CUSTOM_DEBUG: C:\Program Files\SomeApp\
ERROR in EditScriptAction: System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\Windows\Installer\MSI941A.tmp-\C:\Program Files\SomeApp\'.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileSystemEnumerableIterator`1.CommonInit()
at System.IO.FileSystemEnumerableIterator`1..ctor(String path, String originalUserPath, String searchPattern, SearchOption searchOption, SearchResultHandler`1 resultHandler, Boolean checkHost)
at System.IO.Directory.GetFiles(String path)
at MSIActions.CustomActions.EditScriptAction(Session session) in D:\Projects\Visual Studio\app\MSIActions\CustomAction.cs:line 57
CustomAction CA_EditScriptAction returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox)
正如我在日志中看到的那样,它将操作提取到 C:\Windows\Installer\MSI941A.tmp-\
文件夹中,而不是 C# 方法将该文件夹添加到我传递给函数的任何路径之前,如下所示:
ERROR in EditScriptAction: System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\Windows\Installer\MSI941A.tmp-\C:\Program Files\SomeApp\'.
而我经过的路径是C:\Program Files\SomeApp\
。
这是它发生的地方的代码:
[CustomAction]
public static ActionResult EditWebsharkScriptAction(Session session)
{
CustomActionData data = session.CustomActionData;
var install_dir = data["INSTALLFOLDER"];
session.Log("CUSTOM_DEBUG: " + install_dir);
var files = Directory.GetFiles(install_dir); //Exception is thrown here
//the rest of the code
}
如何防止 C# 将临时路径作为我的原始路径的前缀?
编辑:
正如我所观察到的,这只发生在非常量变量上。如果我使用硬编码路径创建一个 const 变量,C# 不会在该临时文件夹路径前添加...
延迟的自定义操作只能在执行顺序表中的 InstallInitialize 和 InstallFinalize 操作之间排序。
所以你有两个选择:
在 InstallInitialize 和 InstallFinalize 之间移动操作的执行。
将执行更改为“立即”。 In some cases this way isn't recomended,一切都取决于你的目的。
<CustomAction
Id="CA_EditScriptAction"
Return="check"
Execute="immediate"
Impersonate="no"
BinaryKey="CustomActions"
DllEntry="EditScriptAction"
/>
并将您的 CustomAction 更改为
[CustomAction]
public static ActionResult EditWebsharkScriptAction(Session session)
{
var install_dir = session["INSTALLFOLDER"];
session.Log("CUSTOM_DEBUG: " + install_dir);
var files = Directory.GetFiles(install_dir);
}
问题出在我将属性传递给自定义操作的过程中。
我过去是通过 属性 元素来完成的,但是如果是延迟的自定义操作,我必须通过另一个 CustomAction 元素来传递它们,如此 answer.
中所示
Unfortunately this will work in immediate CA only, this means that if you want to use the value of this property in a deferred CA you will need to have two custom actions:
- CA 1 to set the CustomActionData for the CA executed as immediate. (Remember to name the property with the same name defined for your CustomAction.
- CA 2 the CA with the specific logic that consumes CustomActionData.
我正在尝试在自定义操作中编辑已安装的 cmd
文件:
<CustomAction
Id="CA_EditScriptAction"
Return="check"
Execute="deferred"
Impersonate="no"
BinaryKey="CustomActions"
DllEntry="EditScriptAction"
/>
它在 PublishProduct
操作之后调用。
问题是,我找不到该文件,因为出于某种原因,当它使用 Directory.GetFiles(ABSOLUTE_PATH)
等方法时,它会在绝对路径前加上临时安装程序目录的路径。这是日志:
SFXCA: Extracting custom action to temporary directory: C:\Windows\Installer\MSI941A.tmp-\
SFXCA: Binding to CLR version v4.0.30319
Calling custom action MSIActions!MSIActions.CustomActions.EditScriptAction
CUSTOM_DEBUG: C:\Program Files\SomeApp\
ERROR in EditScriptAction: System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\Windows\Installer\MSI941A.tmp-\C:\Program Files\SomeApp\'.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileSystemEnumerableIterator`1.CommonInit()
at System.IO.FileSystemEnumerableIterator`1..ctor(String path, String originalUserPath, String searchPattern, SearchOption searchOption, SearchResultHandler`1 resultHandler, Boolean checkHost)
at System.IO.Directory.GetFiles(String path)
at MSIActions.CustomActions.EditScriptAction(Session session) in D:\Projects\Visual Studio\app\MSIActions\CustomAction.cs:line 57
CustomAction CA_EditScriptAction returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox)
正如我在日志中看到的那样,它将操作提取到 C:\Windows\Installer\MSI941A.tmp-\
文件夹中,而不是 C# 方法将该文件夹添加到我传递给函数的任何路径之前,如下所示:
ERROR in EditScriptAction: System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\Windows\Installer\MSI941A.tmp-\C:\Program Files\SomeApp\'.
而我经过的路径是C:\Program Files\SomeApp\
。
这是它发生的地方的代码:
[CustomAction]
public static ActionResult EditWebsharkScriptAction(Session session)
{
CustomActionData data = session.CustomActionData;
var install_dir = data["INSTALLFOLDER"];
session.Log("CUSTOM_DEBUG: " + install_dir);
var files = Directory.GetFiles(install_dir); //Exception is thrown here
//the rest of the code
}
如何防止 C# 将临时路径作为我的原始路径的前缀?
编辑: 正如我所观察到的,这只发生在非常量变量上。如果我使用硬编码路径创建一个 const 变量,C# 不会在该临时文件夹路径前添加...
延迟的自定义操作只能在执行顺序表中的 InstallInitialize 和 InstallFinalize 操作之间排序。
所以你有两个选择:
在 InstallInitialize 和 InstallFinalize 之间移动操作的执行。
将执行更改为“立即”。 In some cases this way isn't recomended,一切都取决于你的目的。
<CustomAction Id="CA_EditScriptAction" Return="check" Execute="immediate" Impersonate="no" BinaryKey="CustomActions" DllEntry="EditScriptAction" />
并将您的 CustomAction 更改为
[CustomAction]
public static ActionResult EditWebsharkScriptAction(Session session)
{
var install_dir = session["INSTALLFOLDER"];
session.Log("CUSTOM_DEBUG: " + install_dir);
var files = Directory.GetFiles(install_dir);
}
问题出在我将属性传递给自定义操作的过程中。
我过去是通过 属性 元素来完成的,但是如果是延迟的自定义操作,我必须通过另一个 CustomAction 元素来传递它们,如此 answer.
中所示Unfortunately this will work in immediate CA only, this means that if you want to use the value of this property in a deferred CA you will need to have two custom actions:
- CA 1 to set the CustomActionData for the CA executed as immediate. (Remember to name the property with the same name defined for your CustomAction.
- CA 2 the CA with the specific logic that consumes CustomActionData.