Visual c++ C++/CLI服务,在调试期间作为控制台应用程序运行

Visual c++ C++/CLI服务,在调试期间作为控制台应用程序运行,visual-c++,windows-services,c++-cli,Visual C++,Windows Services,C++ Cli,我正在尝试构建一个新的windows服务,可以在调试期间作为控制台应用程序运行。我的想法是,我需要实例化服务类,并将所有输出发送到控制台 因此,不使用下面的调用,而是使用新实例 ServiceBase::Run(gcnew myWinService()); 目前它只是一个骨架,只是想了解一下这一点。谢谢 int _tmain(int argc, _TCHAR* argv[]) { if (argc >= 2) { if (argv[1][0] == _T('/')

我正在尝试构建一个新的windows服务,可以在调试期间作为控制台应用程序运行。我的想法是,我需要实例化服务类,并将所有输出发送到控制台

因此,不使用下面的调用,而是使用新实例

ServiceBase::Run(gcnew myWinService());
目前它只是一个骨架,只是想了解一下这一点。谢谢

int _tmain(int argc, _TCHAR* argv[]) {
    if (argc >= 2) {
        if (argv[1][0] == _T('/'))
            argv[1][0] = _T('-');

        if (_tcsicmp(argv[1], _T("-Install")) == 0) {
            array<String^>^ myargs = System::Environment::GetCommandLineArgs();
            array<String^>^ args = gcnew array<String^>(myargs->Length - 1);

            // Set args[0] with the full path to the assembly,
            Assembly^ assem = Assembly::GetExecutingAssembly();
            args[0] = assem->Location;

            Array::Copy(myargs, 2, args, 1, args->Length - 1);
            AppDomain^ dom = AppDomain::CreateDomain(L"execDom");
            Type^ type = System::Object::typeid;
            String^ path = type->Assembly->Location;
            StringBuilder^ sb = gcnew StringBuilder(
                        path->Substring(0, path->LastIndexOf(L"\\")));
            sb->Append(L"\\InstallUtil.exe");
            Evidence^ evidence = gcnew Evidence();
            dom->ExecuteAssembly(sb->ToString(), evidence, args);
        }
    } else
        ServiceBase::Run(gcnew myWinService());
}
int-tmain(int-argc,_-TCHAR*argv[]{
如果(argc>=2){
如果(argv[1][0]==_T('/'))
argv[1][0]=_T('-');
如果(_tcsicmp(argv[1],_T(“-Install”)==0){
数组^myargs=System::Environment::GetCommandLineArgs();
数组^args=gcnew数组(myargs->Length-1);
//使用程序集的完整路径设置args[0],
Assembly^assem=Assembly::GetExecutionGassembly();
args[0]=assem->Location;
数组::复制(myargs,2,args,1,args->Length-1);
AppDomain ^dom=AppDomain::CreateDomain(L“execDom”);
Type^Type=System::Object::typeid;
字符串^path=类型->装配->位置;
StringBuilder ^sb=gcnew StringBuilder(
路径->子字符串(0,路径->LastIndexOf(L“\\”));
sb->Append(L“\\InstallUtil.exe”);
证据^证据=新证据();
dom->ExecuteAssembly(sb->ToString(),证据,args);
}
}否则
ServiceBase::Run(gcnewmywinservice());
}
如果您真的愿意,只需将对
ServiceBase::Run()
的调用替换为调用服务方法的自定义代码即可。由于*()上的
服务通知处理程序受到保护,这基本上需要一种变通方法,例如
myWinService
的公共方法,该方法自动正确调用通知处理程序

然而,这是一个非常糟糕的想法,感觉有点像黑客。您应该编写第二个程序,以同步模式执行通常在服务后台线程中执行的任何操作(您可能在
OnStart()
方法中启动该线程)


基本上,制作两个程序,为流程类型放置相关的锅炉板代码,并让它们调用相同的代码,这实际上包含了您的应用程序。

有一些能力从服务与控制台交互。在Windows服务属性对话框中,查找名为“允许与控制台交互”的复选框


您还可以考虑将应用程序的大部分放入程序集/DLL中,并从控制台应用程序或Windows服务调用函数。

@ 0A0D:不是重复的。所引用的问题是关于从Windows服务启动另一个程序。这个问题是关于运行与服务或AS相同的程序。取决于发布/调试模式的常规过程。您可以使用
#ifdef
来编译/不编译相关的代码。@Merlyn:是的,但如果OP的所有代码都处于
myWinService
中,这是相当微妙的,因为您必须手动调用不同的事件处理程序。@Andre:是的,他可能必须手动执行一个大的重构。直接在框架的回调中抛出实现会使你的应用程序不那么容易移植…@Merlyn:在这种情况下,这意味着你正在实现框架的一部分以重用你的代码。谢谢,我会尝试这种方法