【问题标题】:Creating a Service in vs2019在 vs2019 中创建服务
【发布时间】:2021-12-09 08:34:50
【问题描述】:

我想在 VS2019 中创建一个服务,但它没有模板。所以我创建了一个空项目,然后我尝试从头开始编写服务。我写了下面的main函数。

#define SERVICE_NAME  _T("My Sample Service")

int _tmain(int argc, TCHAR* argv[])
{
    OutputDebugString(_T("My Sample Service: Main: Entry"));

    SERVICE_TABLE_ENTRY ServiceTable[] =
    {
        {SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain},
        {NULL, NULL}
    };

    if (StartServiceCtrlDispatcher(ServiceTable) == FALSE)
    {
        OutputDebugString(_T("My Sample Service: Main: StartServiceCtrlDispatcher returned error"));
        return GetLastError();
    }

    OutputDebugString(_T("My Sample Service: Main: Exit"));
    return 0;
}

但它说,你不能用 const wchar_t 初始化 LPWSTR。此错误属于以下行:

SERVICE_TABLE_ENTRY ServiceTable[] =
        {
            {SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain},
            {NULL, NULL}
        };

但是当我在看视频教程时,作者确实写了上面的代码,但在 vs 2019 中我不能写这样的东西。我现在该怎么办?

【问题讨论】:

  • 使用const_cast<PWSTR>(SERVICE_NAME)这与服务或vs2019无关
  • @RbMm 我可以定义一个非 const 字符串变量吗?如果是怎么办?
  • 旁注:我总是担心像(LPSERVICE_MAIN_FUNCTION)ServiceMain 这样的东西,因为演员可以隐藏ServiceMain 原型中的错误。它的本质是“把ServiceMain 当作LPSERVICE_MAIN_FUNCTION 对待,即使它不是,如果我要开枪打自己的脚,不要提出错误或警告。”最好删除演员表并调整ServiceMain,直到您没有收到错误或警告。
  • 什么时候不需要 const string ,什么时候 const 可以?简单来说,这是一个非常古老的设计 API,它不关心不同的 PWSTRPCWSTR。必须是PCWSTR in SERVICE_TABLE_ENTRY 感觉
  • @rbm 这与旧与新无关。这是关于 C 与 C++ 的。将字符串文字分配给指向非 const 的指针在 C 中是有效的(并且在 C++ 中有效,直到 C++11)。

标签: c++ winapi


【解决方案1】:

问题是结构定义如下:

typedef struct _SERVICE_TABLE_ENTRYW {
  LPWSTR                   lpServiceName;
  LPSERVICE_MAIN_FUNCTIONW lpServiceProc;
} SERVICE_TABLE_ENTRYW, *LPSERVICE_TABLE_ENTRYW;

LPWSTRwchar_t*。字符串文字L"..." 可以分配给const wchar_t* 指针,但不能分配给wchar_t* 指针。

以前 Visual C++ 编译器接受此类代码。现在它会用 /permissive 接受它,但会用/permissive- 拒绝。

/permissive 是编译器的默认选项,但/permissive- 在控制台应用程序项目模板中默认设置。一般来说,你不应该为新代码设置/permissive,它更像是移植旧代码的辅助。

因此,要修复编译,您可以:

  • 使用/permissive
  • 通过 const_cast 或 C 风格的转换来抛弃 constness
  • 使用非常量字符串,如wchar_t ServiceName[] = L"My Sample Service";

最后一个选项通常是最安全的,因为它不做未由类型系统定义的假设。然而,其他的可能已经足够好,因为这似乎是一个广泛的服务代码示例,而且它不太可能停止工作。

【讨论】:

    猜你喜欢
    • 2019-11-11
    • 2021-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-27
    • 1970-01-01
    相关资源
    最近更新 更多