【问题标题】:How do I open a URL from C++?如何从 C++ 打开 URL?
【发布时间】:2013-06-25 05:42:33
【问题描述】:

如何从我的 C++ 程序打开 URL?

在红宝石中你可以做到

%x(open https://google.com)

C++ 中的等价物是什么?我想知道是否有独立于平台的解决方案。但如果没有,我更喜欢 Unix/Mac :)

这是我的代码:

#include <stdio.h>
#include <string.h>
#include <fstream>

int main (int argc, char *argv[])
{
    char url[1000] = "https://www.google.com";

    std::fstream fs;
    fs.open(url);
    fs.close();

    return 0;
}

【问题讨论】:

  • 像 Qt 这样的库提供了一种独立于平台的方式来执行此操作。 c++ 语言本身没有任何东西可以提供。
  • Curl 正如其他人所指出的那样好。但是在您使用的环境中可能存在类似的情况。使用它会是一种更好的方法,因为您不必添加额外的库,并且它会更符合您应用程序其余部分的风格。
  • 您是想从您的 C++ 代码中启动默认浏览器并打开 url,还是要将网页下载到您的 C++ 应用程序中以便您自己处理 html?

标签: html c++ unix url browser


【解决方案1】:

您的问题可能意味着两件事:

1.) 使用浏览器打开网页。

#include <windows.h>
#include <shellapi.h>
...
ShellExecute(0, 0, L"http://www.google.com", 0, 0 , SW_SHOW );

这应该可以,它会打开带有相关程序的文件。应该打开浏览器,通常是默认的网络浏览器。


2.) 获取网页的代码,然后您将自己渲染或执行其他操作。为此,我建议阅读this 或/和this


我希望它至少有点帮助。

编辑:没有注意到,您对 UNIX 的要求是什么,这只适用于 Windows。

【讨论】:

  • 它仅适用于 Windows,对吗?我的意思是 ShellExecute。还是谢谢
  • 这是一个仅限 Windows 的解决方案,用于启动默认浏览器以打开 URL。 OP确实提到了平台无关。 Qt 会提供这一点,尽管对于这项任务来说它会很繁重..
  • 只是为了让这个问题更有趣一点:如果我想从我的 C/C++ 代码运行一个普通的终端程序怎么办。有办法吗?例如,运行 cd
  • 参数 3 不应是宽字符字符串:删除 L 或使用 ShellExecuteW
  • @Salvador ShellExecute 是一个扩展为ShellExecuteAShellExecuteW 的宏。我现在没有看到有人使用编译设置将其扩展为A 版本。
【解决方案2】:

使用libcurl,这里是一个简单的example

编辑:如果这是关于从 C++ 启动 Web 浏览器,您可以在 POSIX 系统上使用 system 调用 shell 命令:

system("<mybrowser> http://google.com");

通过将&lt;mybrowser&gt; 替换为您要启动的浏览器。

【讨论】:

【解决方案3】:

这是一个使用winsock的windows代码示例。

#include <winsock2.h>
#include <windows.h>
#include <iostream>
#include <string>
#include <locale>
#pragma comment(lib,"ws2_32.lib")
using namespace std;

string website_HTML;
locale local;


void get_Website(char *url );

int main ()
{
    //open website
    get_Website("www.google.com" );

    //format website HTML
    for (size_t i=0; i<website_HTML.length(); ++i) 
        website_HTML[i]= tolower(website_HTML[i],local);

    //display HTML
    cout <<website_HTML;

    cout<<"\n\n";



    return 0;
}



//***************************
void get_Website(char *url )
{
    WSADATA wsaData;
    SOCKET Socket;
    SOCKADDR_IN SockAddr;


    int lineCount=0;
    int rowCount=0;

    struct hostent *host;
    char *get_http= new char[256];

        memset(get_http,' ', sizeof(get_http) );
        strcpy(get_http,"GET / HTTP/1.1\r\nHost: ");
        strcat(get_http,url);
        strcat(get_http,"\r\nConnection: close\r\n\r\n");

        if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) 
        {
            cout << "WSAStartup failed.\n";
            system("pause");
            //return 1;
        }

        Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
        host = gethostbyname(url);

        SockAddr.sin_port=htons(80);
        SockAddr.sin_family=AF_INET;
        SockAddr.sin_addr.s_addr = *((unsigned long*)host->h_addr);

        cout << "Connecting to "<< url<<" ...\n";

        if(connect(Socket,(SOCKADDR*)(&SockAddr),sizeof(SockAddr)) != 0)
        {
            cout << "Could not connect";
            system("pause");
            //return 1;
        }

        cout << "Connected.\n";     
        send(Socket,get_http, strlen(get_http),0 );

        char buffer[10000];

        int nDataLength;
            while ((nDataLength = recv(Socket,buffer,10000,0)) > 0)
            {       
                int i = 0;

                while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r') 
                {                    
                    website_HTML+=buffer[i];                     
                    i += 1;
                }               
            }
        closesocket(Socket);
        WSACleanup();

            delete[] get_http;
}

【讨论】:

  • 这实际上是线程的标题当前所说的,但是我相信来自 cmets 的问题实际上是“如何使用平台无关的方法从 c++ 代码在默认浏览器中打开一个 url? "
【解决方案4】:

我在 Windows 中遇到了完全相同的问题。

我注意到在OP's gist 中,他在第 21 行使用了string("open "),但是,使用它却遇到了这个错误:

'open' 未被识别为内部或外部命令

经过研究,我发现open是MacOS默认打开东西的命令。在 Windows 或 Linux 上是不同的。

Linuxxdg-open &lt;URL&gt;

Windowsstart &lt;URL&gt;


对于像我一样使用 Windows 的人,您可以使用以下内容:

std::string op = std::string("start ").append(url);
system(op.c_str());

【讨论】:

    【解决方案5】:

    我使用 ShellExecuteA() 的运气要好得多。我听说使用“system()”时存在很多安全风险。这是我为自己的代码想出的。

    void SearchWeb( string word )
    {    
        string base_URL = "http://www.bing.com/search?q=";
        string search_URL = "dummy";
        search_URL = base_URL + word;
    
        cout << "Searching for: \"" << word << "\"\n";
    
        ShellExecuteA(NULL, "open", search_URL.c_str(), NULL, NULL, SW_SHOWNORMAL);
    }
    

    附言如果我是正确的,它使用 WinAPI。所以它不是多平台解决方案。

    【讨论】:

    • 感谢您发现引号错误。显然,当我复制我的代码时,某些东西被删除了。
    【解决方案6】:

    Windows 已经有了答案。在linux中,我注意到open https://www.google.com总是从shell启动浏览器,所以你可以试试:

    system("open https://your.domain/uri");

    就是这样

    system(("open "s + url).c_str()); // c++

    https://linux.die.net/man/1/open

    【讨论】:

    • @SebastianMach 我附加了错误的链接。应该是man 1 open。刚刚修好了。
    • 如果url是用户定义的,这将创建一个远程执行漏洞
    • @rubenwardy 没错。并且可以通过execv或者在伪造cmd前检查url来修复漏洞。
    • 如果您不知道程序名称,您将如何使用 execv?还是只使用 open 作为程序名称?
    • @rubenwardy 你可以使用/usr/bin/xdg-open/usr/bin/cygstart
    【解决方案7】:

    C 不像您提到的脚本语言那样高级。但是,如果您想远离基于套接字的编程,请尝试使用 Curl。 Curl 是一个很棒的 C 库,有很多特性。我已经使用了很多年并且总是推荐它。它还包括一些用于测试或 shell 的独立程序。

    【讨论】:

    • @rodrigoalves Curl 几乎可以在任何操作系统上使用,包括 Windows 和 Linux 的许多版本。值得花时间学习它。它有很多很多很棒的功能。
    • 是的。我经常从终端使用,主要用于测试 API 输出等。永远不要在 C++ 程序中。
    【解决方案8】:

    对于 linux 环境,您可以使用xdg-open。它默认安装在大多数发行版上。与接受的答案相比的好处是它会打开用户的首选浏览器。

    $ xdg-open https://google.com
    $ xdg-open steam://run/10
    

    当然,您可以将其封装在 system() 调用中。

    【讨论】:

      【解决方案9】:

      使用 Software_Developer 已经提到的 winsock 创建一个函数并复制代码。

      例如:

      #ifdef _WIN32
      
      // this is required only for windows
      
      if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
      {
      
        //...
      
      }
      
      #endif
      

      这里有winsock代码

      #ifdef _WIN32
      
      WSACleanup();
      
      #endif
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-16
        • 2018-06-24
        • 2013-05-05
        • 1970-01-01
        • 1970-01-01
        • 2014-04-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多