Add-Type PowerShell 2.0 找不到方法
我已经制作了 ac# 类,我尝试使用 add-Type 在 PowerShell 中运行它。 我引用了一些我自己的程序集,还有一些来自 .net4。我使用自己的 PowerShell 主机,因为我引用的程序集是在 .net4 框架上生成的,而 PowerShell 控制台尚不支持。
这是我尝试运行的脚本示例:
$Source = @"
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using MyOwn.Components.Utilities;
using MyOwn.Components;
using MyOwn.Entities;
public class ComponentSubtypeMustMatchTemplate
{
public static Guid ProblemId
{
get { return new Guid("{527DF518-6E91-44e1-B1E4-98E0599CB6B2}"); }
}
public static ProblemCollection Validate()
{
SoftwareStructureEntityContainer softwareEntityStructure = new SoftwareStructureEntityContainer();
if (softwareEntityStructure == null)
{
throw new ArgumentNullException("softwareStructure");
}
ProblemCollection problems = new ProblemCollection();
foreach (var productDependency in softwareEntityStructure.ProductDependencies)
{......
return problems;
}
}
"@
$refs = @("d:\Projects\MyOwn\bin\MyOwn.Components.dll",
"d:\Projects\MyOwn\bin\MyOwn.Entities.dll",
"d:\Projects\MyOwn\bin\MyOwn.OperationalManagement.dll",
"c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Core.dll",
"c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Data.Entity.dll",
"c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Data.dll")
Add-Type -ReferencedAssemblies $refs -TypeDefinition $Source
$MyProblemCollection = new-Object ComponentSubtypeMustMatchTemplate
$MyProblemCollection.Validate()
现在,当我运行此脚本时,我收到此错误:
{“方法调用失败,因为 [ComponentSubtypeMustMatchTemplate] 不包含名为“Validate”的方法。”}
我也尝试过最后一点以不同的方式(找到了许多关于如何执行此操作的不同示例),但它们似乎都给出了相同的错误。我真的不知道如何让它工作,而且我似乎找不到任何类似的例子。
第二个注意事项(当我解决这个问题时)我想知道是否可以只加载 .cs 文件而不是将 c# 代码放入脚本中。会更好阅读并且更易于维护。
我尝试看看是否可以使用 Get-Member -static 看到方法,如下所示:
$MyProblemCollection = New-Object ComponentSubtypeMustMatchTemplate
$MyProblemCollection | Get-Member -Static
它确实看到了那里的方法:
TypeName: ComponentSubtypeMustMatchTemplate
Name MemberType Definition
---- ---------- ----------
Equals Method static bool Equals(System.Object objA, System.Obje...
ReferenceEquals Method static bool ReferenceEquals(System.Object objA, Sy...
Validate Method static MyOwn.ComponentSubtypeMustMatchTemplate... <--
ProblemId Property static System.Guid ProblemId {get;}
那么为什么它不起作用!?
@菲利普 在我的脚本中,它是静态还是非静态并不重要,因为它总是只运行一次,结果将用于我的程序。但奇怪的是,如果我使用静态语法(除了我根本没有得到任何结果),它似乎确实有效,如果我使用非静态语法,我会得到相同的错误。我还在互联网上找到的另一个 PowerShell 控制台中尝试了该脚本,但我得到了一个完全不同的错误:
PS C:\temp.
ps1
The following exception occurred while retrieving member "Validate": "Could not
load file or assembly 'MyOwn.Entit
ies, Version=1.0.0.0, Culture=neutral, PublicKeyToken=fc80acb30cba5fab' or one
of its dependencies. The system cannot find the file specified."
At D:\Projects\temp.ps1:145 char:30
+ $MyProblemCollection.Validate <<<< ()
+ CategoryInfo : NotSpecified: (:) [], ExtendedTypeSystemExceptio
n
+ FullyQualifiedErrorId : CatchFromBaseGetMember
嗯,nvm,它自发地工作了!奇怪但我很高兴! =)
I've made a c# class that I'm trying to run in PowerShell with add-Type.
I have a few of my own assemblies referenced and some from .net4. I'm using my own PowerShell host because the assemblies I'm referencing are made on the .net4 framework and the PowerShell Console doesn't support that yet.
Here is a sample of the script that i'm trying to run:
$Source = @"
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using MyOwn.Components.Utilities;
using MyOwn.Components;
using MyOwn.Entities;
public class ComponentSubtypeMustMatchTemplate
{
public static Guid ProblemId
{
get { return new Guid("{527DF518-6E91-44e1-B1E4-98E0599CB6B2}"); }
}
public static ProblemCollection Validate()
{
SoftwareStructureEntityContainer softwareEntityStructure = new SoftwareStructureEntityContainer();
if (softwareEntityStructure == null)
{
throw new ArgumentNullException("softwareStructure");
}
ProblemCollection problems = new ProblemCollection();
foreach (var productDependency in softwareEntityStructure.ProductDependencies)
{......
return problems;
}
}
"@
$refs = @("d:\Projects\MyOwn\bin\MyOwn.Components.dll",
"d:\Projects\MyOwn\bin\MyOwn.Entities.dll",
"d:\Projects\MyOwn\bin\MyOwn.OperationalManagement.dll",
"c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Core.dll",
"c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Data.Entity.dll",
"c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Data.dll")
Add-Type -ReferencedAssemblies $refs -TypeDefinition $Source
$MyProblemCollection = new-Object ComponentSubtypeMustMatchTemplate
$MyProblemCollection.Validate()
Now when i run this I get this error:
{"Method invocation failed because [ComponentSubtypeMustMatchTemplate] doesn't contain a method named 'Validate'."}
Ive also tried the last bit in different ways (found many different examples on how to do this) but they all seem to give the same error. I really have no idea how to get this working, and i can't seem to find any example's on something similar.
On a second note(for when i get this fixed) I was wondering if it was possible to be able to just load the .cs file instead of putting the c# code in the script. would be a better read and more maintainable.
Ive tried to see if I can see the methods with Get-Member -static like this:
$MyProblemCollection = New-Object ComponentSubtypeMustMatchTemplate
$MyProblemCollection | Get-Member -Static
And it does see the method there:
TypeName: ComponentSubtypeMustMatchTemplate
Name MemberType Definition
---- ---------- ----------
Equals Method static bool Equals(System.Object objA, System.Obje...
ReferenceEquals Method static bool ReferenceEquals(System.Object objA, Sy...
Validate Method static MyOwn.ComponentSubtypeMustMatchTemplate... <--
ProblemId Property static System.Guid ProblemId {get;}
So why doesn't it work!?
@Philip
in my script it doesn't really matter if its static or non static cause it will always just be run once and the results will be used my program. But strange thing is it does seem to work if i use the static syntax (except for that i get no results at all) and if i use the non-static syntax i'll get the same error. I also tried the script in an other PowerShell console i found on the interwebs, and there i get an entirely different error :
PS C:\temp.
ps1
The following exception occurred while retrieving member "Validate": "Could not
load file or assembly 'MyOwn.Entit
ies, Version=1.0.0.0, Culture=neutral, PublicKeyToken=fc80acb30cba5fab' or one
of its dependencies. The system cannot find the file specified."
At D:\Projects\temp.ps1:145 char:30
+ $MyProblemCollection.Validate <<<< ()
+ CategoryInfo : NotSpecified: (:) [], ExtendedTypeSystemExceptio
n
+ FullyQualifiedErrorId : CatchFromBaseGetMember
hmm nvm, it spontaneously worked! strange BUT i'm happy! =)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的方法是静态的,但您试图通过实例调用它。
创建
ComponentSubtypeMustMatchTemplate
的新实例。对
$MyProblemCollection
引用的对象调用名为Validate
的实例方法。但是,由于没有名为 Validate 的实例方法,因此调用失败。您可以使这些方法成为非静态的(如果它们要在对象中保留状态,您就会这样做),或者您可以使用不同的 powershell 语法来调用静态方法:
记住(如果您保持这些静态方法)设置静态属性意味着在同一进程中查询该属性的任何内容都将获得该值。如果您持有状态,那么我建议从每个声明中删除
static
。Your method is static, but you are trying to call it via an instance.
Creates a new instance of
ComponentSubtypeMustMatchTemplate
.Calls the instance method named
Validate
on the object referenced by$MyProblemCollection
. However, since there is no instance method named Validate, the call fails.You can either make the methods non-static (which you would do if they were going to keep state in the object), or you can use a different powershell syntax used to call a static method:
Remember ( if you keep these static ) that setting a static property means anything querying that property in the same process will get that value. If you are holding state, then I would advise removing the
static
from each declaration.