2013-12-06 1 views
2

Мы являемся магазином Windows, использующим Powershell широко. У нас также есть Spacewalk, который я бы хотел опросить некоторые данные из части существующего сценария Powershell. API-интерфейс Spacewalk открывается через XMLRPC.Powershell и XMLRPC

Я потратил некоторое время на поиск примеров того, как это можно сделать, но информация действительно скудна. Самое близкое, что я мог получить, это ссылка (больше недоступна) https://web.archive.org/web/20080202045713/http://thepowershellguy.com/blogs/posh/archive/2008/01/31/powershell-and-xmlrpc-posh-challenge-part-12.aspx

Отсутствие примеров заставляет меня думать, что я смотрю в неправильном направлении. Я знаю о new-webserviceproxy, и я использовал его для запроса Sharepoint, но я не вижу, чтобы кто-нибудь использовал его для вызовов XMLRPC.

Это тривиально, чтобы написать вызов в Perl или Python, но это не то, что мне нужно в данном конкретном случае ...

Собираюсь ли я неправильно здесь?

ответ

1

Вы посмотрели XML-RPC.NET? Вам нужно будет создать класс XmlRpcProxyGen на C#, который реализует IXmlRpcProxy, но как только вы это сделаете, вы сможете загрузить эту сборку .NET и использовать прокси-класс из PowerShell.

+0

Спасибо Кит. Насколько переносимым является это решение? Можно ли его легко использовать несколькими пользователями, скопировав библиотеку на свой рабочий стол? Извините за задание очевидных вопросов, я не разработчик. – Sergei

+0

Загрузка - src zip. Вам понадобится VS для компиляции его в сборку .NET (dll), но вы сможете легко развернуть эту DLL вместе со своим скриптом. –

+0

Отлично, я отдам его, спасибо! – Sergei

3

Только что реализовал это сам, поэтому я думал, что пройду его.

Фактически вы можете загрузить DLL вместо компиляции источника - я нашел DLL с помощью NuGet, но некоторые говорят, что вы можете получить его из zip.

Я решил реализовать интерфейсы в коде C# в powershell, чтобы максимизировать переносимость/простоту разработки. Если вы хотите, вы можете скомпилировать код C# как DLL и загрузить его с помощью powershell, но вам придется возвращаться и перекомпилировать каждый раз, когда вы хотите внести изменения в код C#. Здесь, powershell перекомпилирует для вас на лету. (Единственным недостатком является то, что если вы используете родную Windows PowerShell IDE, вам нужно закрыть и снова открыть сеанс, каждый раз, когда вы вносите изменения в код C#)

Вот пример OpenSubtitles API с использованием XML-RPC .NET и PowerShell (не самый чистый код, но, надеюсь, иллюстрирует использование XML-RPC.net):

$source = @' 
namespace OpenSubtitlesAPI 
{ 
    using CookComputing.XmlRpc; 

    [XmlRpcUrl("http://api.opensubtitles.org/xml-rpc")] 
    public interface IOpenSubtitles : IXmlRpcProxy 
    { 
     [XmlRpcMethod("LogIn")] 
     XmlRpcStruct LogIn(string username, string password, string language, string useragent); 

     [XmlRpcMethod("LogOut")] 
     XmlRpcStruct LogOut(string token); 

     [XmlRpcMethod("SearchSubtitles")] 
     XmlRpcStruct SearchSubtitles(string token, XmlRpcStruct[] queries); 

     [XmlRpcMethod("SearchSubtitles")] 
     XmlRpcStruct SearchSubtitles(string token, XmlRpcStruct[] queries, int limit); 
    } 

    public class ProxyFactory 
    { 
     public static IOpenSubtitles CreateProxy() 
     { 
      return XmlRpcProxyGen.Create<IOpenSubtitles>(); 
     } 
    } 
} 
'@ 

# Load XML-RPC.NET and custom interfaces 
if ([Type]::GetType("OpenSubtitlesAPI.ProxyFactory") -eq $null) 
{ 
    [Reflection.Assembly]::LoadFile("C:\path\to\CookComputing.XmlRpcV2.dll") | Out-Null 
    $dynamicAssembly = Add-Type -TypeDefinition $source -ReferencedAssemblies ("C:\path\to\CookComputing.XmlRpcV2.dll") 
} 

# Set up proxy 
$proxy = [OpenSubtitlesAPI.ProxyFactory]::CreateProxy() 
$proxy.UserAgent = "user agent" 
$proxy.EnableCompression = $true 

# Log in 
$LogInResponse = $proxy.LogIn("user name", "password", "language", "user agent") 

# Build query 
$query = New-Object CookComputing.XmlRpc.XmlRpcStruct 
$query.Add("moviehash", "movie hash") 
$query.Add("moviebytesize", "movie size") 
$query.Add("sublanguageid", "language") 
$queries = @($query) 

# Search 
$SearchResponse = $proxy.SearchSubtitles($LogInResponse.token, $queries) 

# Log out 
$LogOutResponse = $proxy.LogOut($LogInResponse.token) 

Мой ответ немного задерживается на первоначальный вопрос, но, надеюсь, это поможет кому-то там.