为不同的操作系统保持独立的条件 [英] to keep seperate conditions for different os's

查看:87
本文介绍了为不同的操作系统保持独立的条件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嘿,伙计们,我已经编写了一个代码来检索任务调度信息,该信息显示任务及其状态的名称。代码效果很好。但我现在面临的问题是在Windows Server 2003中我发现我的代码没有运行,因为ITaskService无法实例化或无法识别。因此,我已经写了另一个代码。它的作用是重新检索

 C中的所有任务列表:C:\ WINDOWS \ Tasks 



但现在我想将其状态打印为好吧,没有通过我的代码显示。我该怎么回头呢?



这里我的代码:



  #include     stdafx.h 
#include < windows.h >
#include < tchar.h >
#include < span class =code-preprocessor> < windows.h >
#include < windows.h >
#pragma warning(disable:4996)
#include dirent.h
int main()
{

DIR * dirp;
struct dirent * ent;
if ((dirp = opendir( C:\\WINDOWS \\Tasks))!= NULL){
/ * 打印目录中的所有文件和目录* /
while ((ent = readdir(dirp))!= NULL) {
printf( %s \ n,ent-> d_name);
}
closedir(dirp);
}
其他 {
/ * 无法打开目录* /
perror( );
返回 EXIT_FAILURE;
}
}



以及这个我还想把条件设置为win server 2003上面的代码应该运行在其他操作系统的地方必须运行以下代码:





 TASK_STATE taskState; 
void Taskschedular()
{

尝试
{


// USES_CONVERSION;
// --------------------- - - - - -任务 - - - - - - - - - - - - - - - - - - - - ---------------------------------
HRESULT hr = CoInitializeEx(NULL,COINIT_MULTITHREADED) ;
if (FAILED(hr))
{
printf( \ nCoInitializeEx failed:%x,hr);
outputFile<< \ nCoInitializeEx failed:%x<<小时;

}

// 设置一般COM安全级别。
hr = CoInitializeSecurity(
NULL,
- 1
NULL,
NULL,
RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
0
NULL);

if (FAILED(hr))
{
printf( \ nCoInitializeSecurity失败:%x,hr);
outputFile<< \ nCoInitializeSecurity failed<<小时;
CoUninitialize();

}

// ------- -----------------------------------------------
// 创建任务服务的实例。
ITaskService * pService = NULL;
hr = CoCreateInstance(CLSID_TaskScheduler,
NULL,
CLSCTX_INPROC_SERVER,
IID_ITaskService,
void ** )及pService);
if (FAILED(hr))
{
printf( 无法CoCreate TaskService类的实例:%x,hr);
CoUninitialize();
outputFile<< 无法CoCreate TaskService类的实例:%x<<小时;

}

// 连接到任务服务。
hr = pService-> Connect(_variant_t(),_ variant_t(),
_variant_t(),_ variant_t());
if (FAILED(hr))
{
printf( ITaskService :: Connect失败:%x,hr);
outputFile<< ITaskService :: Connect failed:%x<<小时;
pService-> Release();
CoUninitialize();

}

// ------- -----------------------------------------------
// 获取指向根任务文件夹的指针。
ITaskFolder * pRootFolder = NULL;
hr = pService-> GetFolder(_bstr_t(L \\) ,& pRootFolder);

pService-> Release();
if (FAILED(hr))
{
printf( 无法获取根文件夹指针:%x,hr);
CoUninitialize();
outputFile<< 无法获取根文件夹指针:%x<<小时;

}

// ------- ------------------------------------------------
// 获取文件夹中的已注册任务。
IRegisteredTaskCollection * pTaskCollection = NULL;
hr = pRootFolder-> GetTasks(NULL,& pTaskCollection);

pRootFolder-> Release();
if (FAILED(hr))
{
printf( 无法获取已注册的任务:%x,hr);
CoUninitialize();
outputFile<< 无法获取已注册的任务:%x<<小时;

}

LONG numTasks = 0 ;
hr = pTaskCollection-> get_Count(& numTasks);

if (numTasks == 0
{
// printf(\ nNoo任务当前正在运行);
pTaskCollection - >推出();
CoUninitialize();

}

// printf(\ nNumber of任务:%d,numTasks);
// cout<< 任务名称:;
outputFile<< 任务名称和状态:\ n \ n;

// outputFile.close();
// TASK_STATE taskState;
// USES_CONVERSIONS;

int t = 0 ;
for (LONG i = 0 ; i< numTasks; i ++)
{
IRegisteredTask * pRegisteredTask = NULL;
hr = pTaskCollection-> get_Item(_variant_t(i + 1 ),& pRegisteredTask);

if (SUCCEEDED(hr))
{
BSTR taskName = NULL;
hr = pRegisteredTask-> get_Name(& taskName);
if (SUCCEEDED(hr))
{
// printf(\t \ n%S,taskName);
// objLog.WriteToLog(MSG,Tasks,taskName);
char TaskLog [ 512 ] = { 0 };
// char taskstatesLog [512] = {0};
sprintf( TaskLog, \t%S,taskName);
x_task.push_back(string(CW2A(taskName)));


// strcpy(x_task,TaskLog);
/ * x_task + = TaskLog;
x_task + =; * /

SysFreeString(taskName);
objLog.WriteToLog( INFO 任务,TaskLog);

/ * std :: wstring tmpString(taskName);

std :: string str(tmpString.begin(),tmpString.end());
outputFile<< str.c_str();
outputFile<< std :: endl; * /


hr = pRegisteredTask-> get_State(& taskState);
if (SUCCEEDED(hr))

printf( ,taskState);


std :: wstring tmpString(taskName);

std :: string str(tmpString.begin(),tmpString.end());
outputFile<< str.c_str();

// outputFile<< std :: endl;
STATE job_state =已排队;

// outputFile<< %s<< job_state<< 1? 已禁用:job_state == 2? 排队:job_state == 3? 就绪:正在运行;
如果(taskState == 1
{

// printf(:disable \\\
) ;

outputFile<< \t:disable \\\
;
objLog.WriteToLog( \t:disable );

}

else if (taskState = = 2
{

// printf(:queued \ n);
outputFile<< \t:queued \ n;
objLog.WriteToLog( \t:排队);
}

else if (taskState == 3
{

// printf(:ready\);

outputFile<< \t:ready \\\
;
objLog.WriteToLog( \t:ready );
}

else if (taskState == 4
{

// printf(:running \ n);
outputFile<< \t:running \\\
;
objLog.WriteToLog( \t:正在运行);
}

else
printf( < span class =code-string> \ n \ t无法获取已注册的任务状态:%x
,hr);

}
else
{
printf( \ n无法获取已注册的任务名称:%x,hr);

}
pRegisteredTask-> Release();
}
else
{
printf( \ n无法在index =%d获取已注册的任务项:%x,i + 1 ,小时);

}

}
outputFile<< \ n ---------------------- ----------------------------- \\\
;
pTaskCollection-> Release();
CoUninitialize();

}



catch (例外e)
{
objLog.WriteToLog( error 任务计划 任务中的异常);
}
}

解决方案



有一种方法可以检测使用#define和Windows版助手功能的操作系统也在那里。



检查这里 [ ^ ]



对于Windows操作系统,请检查此处 [ ^ ]



操作系统版本 [ ^ ]



http://nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system [ ^ ]



希望这有帮助!!


首先(在其他人告诉你之前)你知道对Win Server 2003的支持将在2015年7月结束吗?您是否考虑过迁移到新系统?为什么这么多系统已经死了? ......等等......

现在让我们看一下你的问题:如何为不同的操作系统定制代码。在C中,最常见的方法是使用#if /#else /#endif运算符在条件编译中包含代码的特定部分:

  #ifdef CODETHIS 
... // 一些代码
#else
... // 其他一些代码
#endif



这可以是几乎自动使用来自编译器的特殊预定义符号。即以下代码根据我们使用linux或windows进行条件编译:

  #ifdef _WIN32 
... // 特定于WINDOWS的代码
#elif defined(linux)
... // 特定于linux
#else
#pragma error(未知操作系统!)
#endif





区分Windows版本必须使用 NTDDI_VERSION WIN32_WINNT 。对于他们的价值观 [ ^ ]这个链接。

在你的情况下,你可以从编译器命令行设置2的值(使用选项/ D)并顺从地调整你的代码:

  #if(_WIN32_WINNT == _WIN32_WINNT_WS03)/ * Windows Server 2003 SP1,Windows XP SP2 * / || (_WIN32_WINNT == _WIN32_WINNT_XP)/ * Windows Server 2003,Windows XP * / 
... // 特定于WINDOWS SERVER 2003的代码
#else
... // 其他系统的代码
#endif





一个重要注释仅使用预处理器和预处理器符号,不要使用任何函数来检查操作系统类型。在第一种情况下,不需要的代码被简单地省略(根本不编译),在第二种情况下,函数要求代码执行以获得答案。这意味着编译器会将整个代码编译为标准if / else。那么很可能不会在一个或另一个代码中提供不同操作系统的函数,你永远无法编译代码(即使死代码优化也不能用于函数结果)。


hey guys i have written a code to retrive a task schedular information which displays the names of tasks and its states. the code works well. but the problem i am facing now is in windows server 2003 i found that my code is not running as ITaskService cannot be instantiated or it is not recognisable. hence forth i have written another code. what it does is it retrives the list of all task inside

C:\WINDOWS\Tasks


but now i want to print its states as well which is not getting displayed through my code. how must i retrive it?

here my code :

#include "stdafx.h"
#include <windows.h>
#include <tchar.h>
#include <windows.h>
#include <windows.h>
#pragma warning (disable : 4996)
#include "dirent.h"
int main()
{

	DIR *dirp;
	struct dirent *ent;
	if ((dirp = opendir("C:\\WINDOWS\\Tasks")) != NULL) {
		/* print all the files and directories within directory */
		while ((ent = readdir(dirp)) != NULL) {
			printf("%s\n", ent->d_name);
		}
		closedir(dirp);
	}
	else {
		/* could not open directory */
		perror("");
		return EXIT_FAILURE;
	}
}


along with this i also want to put the condition that for win server 2003 the above code should run where as for other OS's the following code must run:


TASK_STATE taskState;
void Taskschedular()
{
	
	try
	{
		

		//USES_CONVERSION;
		//------------------------------task-------------------------------------------------------------------------
		HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
		if (FAILED(hr))
		{
			printf("\nCoInitializeEx failed: %x", hr);
			outputFile << "\nCoInitializeEx failed: %x" << hr;

		}

		//  Set general COM security levels.
		hr = CoInitializeSecurity(
			NULL,
			-1,
			NULL,
			NULL,
			RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
			RPC_C_IMP_LEVEL_IMPERSONATE,
			NULL,
			0,
			NULL);

		if (FAILED(hr))
		{
			printf("\nCoInitializeSecurity failed: %x", hr);
			outputFile << "\nCoInitializeSecurity failed" << hr;
			CoUninitialize();

		}

		//  ------------------------------------------------------
		//  Create an instance of the Task Service. 
		ITaskService *pService = NULL;
		hr = CoCreateInstance(CLSID_TaskScheduler,
			NULL,
			CLSCTX_INPROC_SERVER,
			IID_ITaskService,
			(void**)&pService);
		if (FAILED(hr))
		{
			printf("Failed to CoCreate an instance of the TaskService class: %x", hr);
			CoUninitialize();
			outputFile << "Failed to CoCreate an instance of the TaskService class: %x" << hr;

		}

		//  Connect to the task service.
		hr = pService->Connect(_variant_t(), _variant_t(),
			_variant_t(), _variant_t());
		if (FAILED(hr))
		{
			printf("ITaskService::Connect failed: %x", hr);
			outputFile << "ITaskService::Connect failed: %x" << hr;
			pService->Release();
			CoUninitialize();

		}

		//  ------------------------------------------------------
		//  Get the pointer to the root task folder.
		ITaskFolder *pRootFolder = NULL;
		hr = pService->GetFolder(_bstr_t(L"\\"), &pRootFolder);

		pService->Release();
		if (FAILED(hr))
		{
			printf("Cannot get Root Folder pointer: %x", hr);
			CoUninitialize();
			outputFile << "Cannot get Root Folder pointer: %x" << hr;

		}

		//  -------------------------------------------------------
		//  Get the registered tasks in the folder.
		IRegisteredTaskCollection* pTaskCollection = NULL;
		hr = pRootFolder->GetTasks(NULL, &pTaskCollection);

		pRootFolder->Release();
		if (FAILED(hr))
		{
			printf("Cannot get the registered tasks.: %x", hr);
			CoUninitialize();
			outputFile << "Cannot get the registered tasks.: %x" << hr;

		}

		LONG numTasks = 0;
		hr = pTaskCollection->get_Count(&numTasks);

		if (numTasks == 0)
		{
			//printf("\nNo Tasks are currently running");
			pTaskCollection->Release();
			CoUninitialize();

		}

		//printf("\nNumber of Tasks : %d", numTasks);
		//cout << "Task Names:";
		outputFile << "Task Names and Status:\n\n";

		//outputFile.close();
		//TASK_STATE taskState;
		//USES_CONVERSIONS;

		int t = 0;
		for (LONG i = 0; i < numTasks; i++)
		{
			IRegisteredTask* pRegisteredTask = NULL;
			hr = pTaskCollection->get_Item(_variant_t(i + 1), &pRegisteredTask);

			if (SUCCEEDED(hr))
			{
				BSTR taskName = NULL;
				hr = pRegisteredTask->get_Name(&taskName);
				if (SUCCEEDED(hr))
				{
					//		printf("\t \n %S", taskName);
					//objLog.WriteToLog("MSG","Tasks",taskName);
					char	TaskLog[512] = { 0 };
					//char	taskstatesLog[512] = { 0 };
					sprintf(TaskLog, "\t  %S", taskName);
					x_task.push_back(string(CW2A(taskName)));


					//strcpy(x_task, TaskLog);
					/*x_task += TaskLog;
					x_task += " ";*/
					SysFreeString(taskName);
					objLog.WriteToLog("INFO", "Task", TaskLog);

					/*std::wstring tmpString(taskName);

					std::string str(tmpString.begin(), tmpString.end());
					outputFile << str.c_str();
					outputFile << std::endl;*/

					hr = pRegisteredTask->get_State(&taskState);
					if (SUCCEEDED(hr))

						printf("", taskState);


					std::wstring tmpString(taskName);

					std::string str(tmpString.begin(), tmpString.end());
					outputFile << str.c_str();

					//	outputFile << std::endl;
					STATE job_state = Queued;

				//	outputFile << "%s" << job_state << 1 ? "Disabled" : job_state == 2 ? "Queued" : job_state == 3 ? "Ready" : "Running";
					if (taskState == 1)
					{

						//	printf(": disable \n");
						outputFile << "\t :disable \n";
						objLog.WriteToLog("", "", "\t : disable");

					}

					else	if (taskState == 2)
					{

						//printf(": queued \n ");
						outputFile << "\t :queued \n";
						objLog.WriteToLog("", "", "\t : queued");
					}

					else	if (taskState == 3)
					{

						//printf(": ready\n");

							outputFile << "\t :ready \n";
						objLog.WriteToLog("", "", "\t : ready");
					}

					else if (taskState == 4)
					{

						//printf(": running \n ");
						outputFile << "\t :running \n";
						objLog.WriteToLog("", "", "\t : running");
					}

					else
						printf("\n\tCannot get the registered task state: %x", hr);

				}
				else
				{
					printf("\nCannot get the registered task name: %x", hr);

				}
				pRegisteredTask->Release();
			}
			else
			{
				printf("\nCannot get the registered task item at index=%d: %x", i + 1, hr);

			}

		}
		outputFile << "\n---------------------------------------------------\n";
		pTaskCollection->Release();
		CoUninitialize();

	}

	
	
	catch (exception e)
	{
		objLog.WriteToLog("error", "task schedular", "exception in tasks");
	}
}

解决方案

hi,
there is a way to detect the OS using #define and for windows version helper functions are also there.

check here[^]

For windows OS check here[^]

Operating System Version[^]

http://nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system[^]

hope this helps !!


First of all (before others will tell you) do you know that support for Win Server 2003 will end on july 2015? Have you considered to migrate to a new system? Why so much effort for a system that is dead? ... etc...
Ok now let's look in more general view your question: "How to tailor code for different OS's". In C the most common way is to include the specifica parts of the code in conditional compilation using the #if/#else/#endif operators:

#ifdef CODETHIS
   ...    //Some code
 #else
   ...    //some other code
 #endif


This can be almost automatic using special predefined symbols that come from compiler. I.e. the following code makes a conditional compilation depending if we are using linux or windows:

#ifdef _WIN32
   ...    //code specific for WINDOWS
 #elif defined(linux)
   ...    //Code specific for linux
 #else
 #pragma error("Unknown OS!")
 #endif



To make distinction between windows versions you have to use NTDDI_VERSION and WIN32_WINNT. For their values see[^] this link.
In your case you can set the value of the 2 from compiler command line (using option /D) and adjust your code conseguently:

#if (_WIN32_WINNT == _WIN32_WINNT_WS03) /*Windows Server 2003 with SP1, Windows XP with SP2*/ || (_WIN32_WINNT == _WIN32_WINNT_XP) /*Windows Server 2003, Windows XP*/
   ...    //code specific for WINDOWS SERVER 2003
 #else
   ...    //Code for other systems
 #endif



One more important note use only the preprocessor and preprocessor symbols, don't use any function to check the OS type. In the first case the code not required is simply omitted (not compiled at all), in the second case a function requires that the code executes to get an answer. This means that the compiler will compile the whole code as a standard if/else. It will be very probable then that the functions for the different OS will not be available in one or another code you'll never be able to compile your code (even the dead code optimization couldn't work with function results).


这篇关于为不同的操作系统保持独立的条件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆