我开发了一个PowerShell模块,该模块依赖于.NET程序集进行某些操作。
我将这个模块重构为不需要该Assembly,并注意到了一些奇怪的行为,这最终使我无法删除该类:
function getOrgUsers() {
var orgUserEmails = [];
smartsheet.users.listAllUsers(options)
.then(function(userList) {
userList.data.forEach(function(userEmail) {
orgUserEmails.push(userEmail.email);
})
// console.log(orgUserEmails); // This works and returns the array of emails that are pushed to orgUserEmails
return orgUserEmails; // Trying to return the variable to the function to then call the results of the function elsewhere.
})
.catch(function(error) {
console.log(error);
});
}
getOrgUsers(); // calling the function
如果以交互方式运行此命令,它将成功。
但是,一旦我在ISE中或从psm1文件中“全面”运行它,它将抛出一个错误,指出它无法找到Add-Type -TypeDefinition "public interface ICanTalk { string talk(); }" -Language CSharp
class Talker : ICanTalk {
[string] talk() { return "Well hello there"; }
}
调用中定义的接口。
我可以在Windows-PowerShell和PowerShell Core(6.0.2)中重现该问题
行为不同的原因是什么,我该如何解决?
答案 0 :(得分:1)
显然,PowerShell将在执行代码之前读取文件并处理类定义。
要解决此问题,需要将Add-Type
放入一个自己的脚本文件,该脚本文件在模块加载之前运行(或者在ISE中,仅在运行类定义之前运行代码)。
这可以通过使用PSD1文件中的ScriptsToProcess完成。
对@ TheIncorrigible1表示敬意,让我踏上了轨道。
答案 1 :(得分:1)
PowerShell class
和enum
的定义在执行开始之前进行了解析,并且其中的所有类型被引用这样的定义必须是:
已预先加载到当前会话中。
[从Windows PowerShell v5.1 / PowerShell Core 6.1.0开始仅部分实现]
通过using module
/ using assembly
语句加载
文件顶部。
与此同时,解决方法是通过使用模块清单的NestedModules
条目,预先通过单独的脚本加载引用的类型 strong>。
ScriptsToProcess
条目也可以使用,但是它引用的脚本是基于点的源代码(加载到调用者的当前作用域中),而不是封闭模块。 br />
使用来自编译的代码的类型(包括带有Add-Type
的临时编译的代码)也可以工作,因为此类类型始终在全局会话中可用,但是从概念上讲,使用{{ 1}},因为它在 module 范围内