65.9K
CodeProject 正在变化。 阅读更多。
Home

WSH 剪贴板访问

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.54/5 (8投票s)

2009年2月26日

CPOL
viewsIcon

48095

downloadIcon

426

在 Windows 脚本宿主中编写剪贴板内容。

引言

我最近做了一些 Windows 脚本宿主编程,我对它的强大功能、特性和灵活性感到惊喜。有一件事是我无法完成的,那就是从 WSH 访问剪贴板。在互联网上搜索,我找到了一些解决方案,例如这个,它基于 Internet Explorer 自动化。正如我在关于 Internet Explorer 自动化的文章中所述,这种方法存在一些问题:Internet Explorer 自动化有什么问题?

使用代码

在 WSH 中编写剪贴板内容的解决方案是一个使用 VC++ 和 ATL 创建的常规 COM 对象。要安装 COM 对象,请运行 register.bat

这里有一个从 WSH 使用该组件的简单示例

var clipboardHelper = null;

try
{
    clipboardHelper = WScript.CreateObject("ClipboardHelper.ClipBoard");
}
catch (ex)
{
    WScript.Echo(ex.message + "\n\nClipboardHelper library is not properly registered!");
    WScript.Quit(1);
}

var msg = "Some text";

// Put the text into the clipboard.
clipboardHelper.SetClipboardText(msg);

// Get the text from clipboard.
var text = clipboardHelper.GetClipboardText();

WScript.Echo(text);

关注点

实现只是常规的 ATL/COM 代码。使用 Win32 API 函数来访问剪贴板文本(OpenClipboardIsClipboardFormatAvailableGetClipboardDataSetClipboardDataCloseClipboardGlobalAllocGlobalLockGlobalFree)。

以下是检索剪贴板文本的方法的实现(支持 CF_TEXTCF_UNICODETEXT 格式)

STDMETHODIMP CClipBoard::GetClipboardText(BSTR* pBstrClipboardText)
{
    if (NULL == pBstrClipboardText)
    {
        return E_INVALIDARG;
    }

    CComBSTR bstrResult = L"";

    if (::OpenClipboard(NULL))
    {
        if (::IsClipboardFormatAvailable(CF_TEXT) || 
            ::IsClipboardFormatAvailable(CF_UNICODETEXT))
        {
            // First try to ge UNICODE text.
            BOOL   bUnicode   = TRUE;
            HANDLE hClipboard = ::GetClipboardData(CF_UNICODETEXT);

            if (NULL == hClipboard)
            {
                // If UNICODE text was not available try to get ANSI text.
                bUnicode   = FALSE;
                hClipboard = ::GetClipboardData(CF_TEXT);
            }

            if (hClipboard != NULL)
            {
                LPCSTR szClipboardData = (LPCSTR)::GlobalLock(hClipboard);

                if (szClipboardData != NULL)
                {
                    if (bUnicode)
                    {
                        LPCWSTR szClipboardWText = (LPCWSTR)szClipboardData;

                        bstrResult       = szClipboardWText;
                        szClipboardWText = NULL;
                    }
                    else
                    {
                        LPCSTR szClipboardText = (LPCSTR)szClipboardData;

                        bstrResult      = szClipboardText;
                        szClipboardText = NULL;
                    }

                    ::GlobalUnlock(hClipboard);

                    *pBstrClipboardText = bstrResult.Detach();
                    hClipboard = NULL;
                }
                else
                {
                    ATLTRACE("GlobalLock failed in CClipBoard::GetClipboardText\n");
                }
            }
            else
            {
                ATLTRACE("GetClipboardData failed in CClipBoard::GetClipboardText\n");
            }

            hClipboard = NULL;
        }
        else
        {
            ATLTRACE("CF_TEXT NOT available in CClipBoard::GetClipboardText\n");
        }

        BOOL bRes = ::CloseClipboard();
        ATLASSERT(bRes);
    }
    else
    {
        ATLTRACE("Can NOT OpenClipboard in CClipBoard::GetClipboardText\n");
    }

    return S_OK;
}
© . All rights reserved.