如何为在COM对象中声明的枚举创建引用以传递给需要它的方法?具体来说,第三方COM对象上有一个方法SetHomeDir
,它接受枚举作为唯一参数。参数期望的定义基本上是:
typedef enum
{
abFalse = 0,
abTrue = 1,
abInherited = -2
} SFTPAdvBool;
它似乎在COM对象的某处定义,但不能作为我可以使用New-Object创建的对象。我尝试了以下内容,他们都给出了相同的MX Error: 7
响应:
$obj.SetHomeDir($true)
$obj.SetHomeDir(1)
$obj.SetHomeDir([Object]1)
$obj.SetHomeDir([Int16]1)
Exception calling "SetHomeDir" with "1" argument(s): "MX Error: 7 (00000007)"
以下是尝试其他方法的结果:
PS C:\> New-Object -ComObject SFTPCOMINTERFACELib.SFTPAdvBool
New-Object : Cannot load COM type SFTPCOMINTERFACELib.SFTPAdvBool.
PS C:\> [SFTPAdvBool]::abTrue
Unable to find type [SFTPAdvBool]:
make sure that the assembly containing this type is loaded.
PS C:\> [SFTPCOMINTERFACELib.SFTPAdvBool]::abTrue
Unable to find type [SFTPCOMINTERFACELib.SFTPAdvBool]:
make sure that the assembly containing this type is loaded.
COM向PowerShell公开的方法签名如下所示:
PS C:\> $user.SetHomeDir
MemberType : Method
OverloadDefinitions : {void SetHomeDir (SFTPAdvBool)}
TypeNameOfValue : System.Management.Automation.PSMethod
Value : void SetHomeDir (SFTPAdvBool)
Name : SetHomeDir
IsInstance : True
注意:这是在Windows Server 2008 R2上的PowerShell 2.0下运行,但我会考虑在必要时将Windows Management Framework升级到更新版本。
更新:以下是Visual Studio对象资源管理器的屏幕截图,以防提供任何线索。
答案 0 :(得分:3)
我们最终在COM对象周围使用了编译的C#interop包装器。我能够指定-- \i tmp.sql
-- NOTE: date and domain are keywords in SQL
CREATE TABLE ztable
( zdomain TEXT NOT NULL
, zdate DATE NOT NULL
, visitors INTEGER NOT NULL DEFAULT 0
, hits INTEGER NOT NULL DEFAULT 0
, PRIMARY KEY (zdomain,zdate)
);
INSERT INTO ztable (zdomain,zdate,visitors,hits) VALUES
('www.domain1.com', '2016-04-12' ,1231 ,23423 )
,('www.domain1.com', '2016-04-13' ,1374 ,26482 )
,('www.domain1.com', '2016-04-17' ,1262 ,21493 )
,('www.domain3.com', '2016-04-14' ,3245 ,53471 ) -- << cheating!
,('www.domain3.com', '2016-04-15' ,2435 ,34571 )
,('www.domain3.com', '2016-04-16' ,2354 ,35741 )
,('www.domain2.com', '2016-05-09' ,2345 ,35471 ) ;
-- Create "Calendar" table with all possible dates
-- from the existing data in ztable.
-- [if there are sufficient different domains
-- in ztable there will be no gaps]
-- [Normally the table would be filled by generate_series()
-- or even a recursive CTE]
-- An exta advantage is that a table can be indexed.
CREATE TABLE date_domain AS
SELECT DISTINCT zdate AS zdate
FROM ztable;
ALTER TABLE date_domain ADD PRIMARY KEY (zdate);
-- SELECT * FROM date_domain;
-- Finding the closest previous record
-- without using window functions or aggregate queries.
SELECT d.zdate, t.zdate, t.zdomain
,t.visitors, t.hits
, (d.zdate <> t.zdate) AS is_fake -- for fun
FROM date_domain d
LEFT JOIN ztable t
ON t.zdate <= d.zdate
AND NOT EXISTS ( SELECT * FROM ztable nx
WHERE nx.zdomain = t.zdomain
AND nx.zdate > d.zdate
AND nx.zdate < t.zdate
)
ORDER BY t.zdomain, d.zdate
;
作为参数,并使用case语句从枚举中传递正确的值。据我所知,没有办法直接从Powershell执行此操作,并且需要将COM对象包装在托管代码中。
我们已经打开了一个与Globalscape的对话框,希望这将是他们将来发布的内容。
答案 1 :(得分:1)
我们可以尝试通过自己创建枚举来欺骗com对象并将其传递给函数:
如果你可以升级到Powershell 5试试(在Powershell中 - 枚举是第5版中的新关键字):
Enum SFTPAdvBool
{
abFalse = 0
abTrue = 1
abInherited = -2
}
并致电:
$obj.SetHomeDir([SFTPAdvBool]::abTrue)
对于PS 5之前的任何东西,您都可以尝试:
$code = @"
namespace SFTPCOMINTERFACELib {
public enum SFTPAdvBool {
abFalse = 0,
abTrue = 1,
abInherited = -2
}
}
"@
Add-Type -TypeDefinition $code -Language CSharpVersion3
并致电:
$obj.SetHomeDir([SFTPCOMINTERFACELib.SFTPAdvBool]::abTrue)
这基本上会创建一个C#枚举,并将其作为类型添加到Powershell中。
答案 2 :(得分:0)
此时PowerShell v2.0已经过时,但它不应该阻止你到这里来。 SFTPAdvBool
似乎来自GlobalScape EFT Server COM API,这就是我所假设的。
问题是,根据C#scripting examples,您需要类型SFTPAdvBool
的值(请参阅ConfigureUser.cs一次使用)。对于.Net对象,您可以将其定义为[SFTPAdvBool]::abTrue
或[SFTPCOMINTERFACELib.SFTPAdvBool]::abTrue
,但我不确定这是否有效。我之前没有在PowerShell中使用COM枚举。您可能需要New-Object -ComObject SFTPCOMINTERFACELib.SFTPAdvBool
或某些变体。
如果没有任何效果,你可以使用VBScript或C#,或者联系GlobalScape,希望他们加入21世纪并放弃COM,或者使用WinSCP的.Net库......但是我在下注你不能在某个支付EFT服务器的地方工作。
答案 3 :(得分:0)
在他们的知识库中有一些提示,库并不总是在进程外正常工作,因此可以远程应用,或者在64位进程中使用32位库时。
例如:
解决方案是使用C:\Windows\SysWOW64\WindowsPowerShell\
中的32位PowerShell如果你需要远程调用它,你可能必须明确地使用&amp;操作