【问题标题】:How to use .NET Uri within VBScript如何在 VBScript 中使用 .NET Uri
【发布时间】:2017-08-13 11:34:30
【问题描述】:

我有一个用于公开 COM 互操作的 .NET 程序集。一个简单的代码示例是:

namespace ClassLibraryWithUri
{
    [ComVisible(true)]
    public class UriGenerator
    {
        public UriGenerator()
        { }

        public Uri GetUri()
        {
            return new Uri("http://www.google.com");
        }
    }
}

然后我尝试在 Visual Basic 脚本中使用:

dim myObj
Set myObj = WScript.CreateObject("UriGenerator.UriGenerator")
Dim myUri
Set myUri = myObj.GetUri()
Dim url 
Set url = myUri.ToString()
WScript.Echo(url)

但我收到错误:Microsoft VBScript 运行时错误:需要对象,位于Set url = myUri.ToString()

我的问题是:为什么?是否支持 Uri?我在谷歌和 Stack Overflow 上都没有找到任何东西 我是不是做错了什么?

感谢您的帮助。

【问题讨论】:

  • 这是因为Uri类没有通过com暴露,请尝试将Uri转换为string后再返回。
  • 感谢您的回答。太可惜了。我正在用 Uri 替换字符串,以便为 .NET 开发人员提供更好的体验。我想如果我从 C++ 尝试同样适用?是否有关于 COM 互操作类型的文档?
  • 我发现检查的最佳方法是在HKEY_CLASS_ROOT 下的注册表中查找CreateObject 使用的关联progid 使用regedit.exe
  • 抱歉,progid 与什么相关联?
  • 所有内置引用类型都不是 COM 可见的(字符串的特殊情况)。例如,想象一下 linux 上的 .net 核心 - 根本没有 COM。以下是支持类型的映射:msdn.microsoft.com/en-us/library/sak564ww(v=vs.100).aspx

标签: c# .net vbscript com uri


【解决方案1】:

我相信您必须为 .NET 的 Uri 类创建一个 COM 包装器类才能使其正常工作。我很好奇它需要付出的努力,我写了以下内容。这或多或少是你必须做的。在您想在公共界面中使用 URI 的任何地方,请使用IUri,定义如下。

// COM doesn't have constructors, so in order to create Url objects from COM clients, you need a factory
[ComVisible(true)]
public interface IUriFactory
{
    IUri Create1(string uriString);
    IUri Create2(string uriString, UriKind uriKind);
    IUri Create3(IUri baseUri, string relativeUri);
    IUri Create4(IUri baseUri, IUri relativeUri);
}

[ComVisible(true)]
public interface IUri
{
    string GetComponents(UriComponents components, UriFormat format);
    string GetLeftPart(UriPartial part);
    bool IsBaseOf(IUri uri);
    bool IsWellFormedOriginalString();
    IUri MakeRelativeUri(IUri uri);
    string ToString();
    string AbsolutePath { get; }
    string AbsoluteUri { get; }
    string Authority { get; }
    string DnsSafeHost { get; }
    string Fragment { get; }
    string Host { get; }
    UriHostNameType HostNameType { get; }
    bool IsAbsoluteUri { get; }
    bool IsDefaultPort { get; }
    bool IsFile { get; }
    bool IsLoopback { get; }
    bool IsUnc { get; }
    string LocalPath { get; }
    string OriginalString { get; }
    string PathAndQuery { get; }
    int Port { get; }
    string Query { get; }
    string Scheme { get; }
    string[] Segments { get; }
    bool UserEscaped { get; }
    string UserInfo { get; }
}

[ComVisible(true)]
public enum UriKind
{
    RelativeOrAbsolute = System.UriKind.RelativeOrAbsolute,
    Absolute = System.UriKind.Absolute,
    Relative = System.UriKind.Relative,
}

[ComVisible(true)]
public enum UriComponents
{
    Scheme = System.UriComponents.Scheme,
    UserInfo = System.UriComponents.UserInfo,
    Host = System.UriComponents.Host,
    Port = System.UriComponents.Port,
    Path = System.UriComponents.Path,
    Query = System.UriComponents.Query,
    Fragment = System.UriComponents.Fragment,
    StrongPort = System.UriComponents.StrongPort,
    NormalizedHost = System.UriComponents.NormalizedHost,
    KeepDelimiter = System.UriComponents.KeepDelimiter,
    SerializationInfoString = System.UriComponents.SerializationInfoString,
    AbsoluteUri = Fragment | Query | Path | Port | Host | UserInfo | Scheme,
    HostAndPort = StrongPort | Host,
    StrongAuthority = HostAndPort | UserInfo,
    SchemeAndServer = Port | Host | Scheme,
    HttpRequestUrl = SchemeAndServer | Query | Path,
    PathAndQuery = Query | Path,
}

[ComVisible(true)]
public enum UriFormat
{
    UriEscaped = System.UriFormat.UriEscaped,
    Unescaped = System.UriFormat.Unescaped,
    SafeUnescaped = System.UriFormat.SafeUnescaped,
}

[ComVisible(true)]
public enum UriPartial
{
    Scheme = System.UriPartial.Scheme,
    Authority = System.UriPartial.Authority,
    Path = System.UriPartial.Path,
    Query = System.UriPartial.Query,
}

[ComVisible(true)]
public enum UriHostNameType
{
    Unknown = System.UriHostNameType.Unknown,
    Basic = System.UriHostNameType.Basic,
    Dns = System.UriHostNameType.Dns,
    IPv4 = System.UriHostNameType.IPv4,
    IPv6 = System.UriHostNameType.IPv6,
}

[ComVisible(true)]
public class UriFactory : IUriFactory
{
    public IUri Create1(string uriString){ return new Uri(new System.Uri(uriString)); }
    public IUri Create2(string uriString, UriKind uriKind) { return new Uri(new System.Uri(uriString, (System.UriKind) (int) uriKind)); }
    public IUri Create3(IUri baseUri, string relativeUri) { return new Uri(new System.Uri(((Uri) baseUri).Inner, relativeUri)); }
    public IUri Create4(IUri baseUri, IUri relativeUri) { return new Uri(new System.Uri(((Uri) baseUri).Inner, ((Uri) relativeUri).Inner)); }
}

[ComVisible(true)]
internal class Uri : IUri
{
    internal readonly System.Uri Inner;
    internal Uri(System.Uri inner) { Inner = inner; }
    public string GetComponents(UriComponents components, UriFormat format) => Inner.GetComponents((System.UriComponents) components, (System.UriFormat) format);
    public string GetLeftPart(UriPartial part) => Inner.GetLeftPart((System.UriPartial) part);
    public bool IsBaseOf(IUri uri) => Inner.IsBaseOf(((Uri) uri).Inner);
    public bool IsWellFormedOriginalString() => Inner.IsWellFormedOriginalString();
    public IUri MakeRelativeUri(IUri uri) => new Uri(Inner.MakeRelativeUri(((Uri) uri).Inner));
    public string AbsolutePath => Inner.AbsolutePath;
    public string AbsoluteUri => Inner.AbsoluteUri;
    public string Authority => Inner.Authority;
    public string DnsSafeHost => Inner.DnsSafeHost;
    public string Fragment => Inner.Fragment;
    public string Host => Inner.Host;
    public UriHostNameType HostNameType => (UriHostNameType) (int) Inner.HostNameType;
    public bool IsAbsoluteUri => Inner.IsAbsoluteUri;
    public bool IsDefaultPort => Inner.IsDefaultPort;
    public bool IsFile => Inner.IsFile;
    public bool IsLoopback => Inner.IsLoopback;
    public bool IsUnc => Inner.IsUnc;
    public string LocalPath => Inner.LocalPath;
    public string OriginalString => Inner.OriginalString;
    public string PathAndQuery => Inner.PathAndQuery;
    public int Port => Inner.Port;
    public string Query => Inner.Query;
    public string Scheme => Inner.Scheme;
    public string[] Segments => Inner.Segments;
    public bool UserEscaped => Inner.UserEscaped;
    public string UserInfo => Inner.UserInfo;
}

【讨论】:

  • 绝对有可能,感谢您的帮助
  • 感谢您的提问。我选择提供一种返回字符串的替代方法(使用 Uri.ToString())。返回 Uri 的方法不是 COM 可见的。这似乎比添加大量代码更容易。
猜你喜欢
  • 1970-01-01
  • 2010-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-22
  • 2016-12-24
  • 2011-01-10
  • 1970-01-01
相关资源
最近更新 更多