我试图在Windows 7上使用GCC从MSDN编译一些示例代码(请忽略使用goto和可怕的格式化;这不是我的代码):
#include <stdio.h>
#include <windows.h>
typedef struct _TOKEN_ELEVATION {
DWORD TokenIsElevated;
} TOKEN_ELEVATION, *PTOKEN_ELEVATION;
BOOL IsProcessElevated()
{
BOOL fIsElevated = FALSE;
DWORD dwError = ERROR_SUCCESS;
HANDLE hToken = NULL;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
{
dwError = GetLastError();
goto Cleanup;
}
TOKEN_ELEVATION elevation;
DWORD dwSize;
if (!GetTokenInformation(hToken, TokenElevation, &elevation,
sizeof(elevation), &dwSize))
{
dwError = GetLastError();
goto Cleanup;
}
fIsElevated = elevation.TokenIsElevated;
Cleanup:
if (hToken)
{
CloseHandle(hToken);
hToken = NULL;
}
if (ERROR_SUCCESS != dwError)
{
throw dwError;
}
return fIsElevated;
}
int main()
{
try
{
if (IsProcessElevated())
wprintf (L"Process is elevated\n");
else
wprintf (L"Process is not elevated\n");
}
catch (DWORD dwError)
{
wprintf(L"IsProcessElevated failed w/err %lu\n", dwError);
}
}
我不断收到错误TokenElevation was not declared in this scope
。在试图找出它时,我看到TOKEN_INFORMATION_CLASS结构的TokenElevation成员位于两个#ifdef标记之间:
typedef enum _TOKEN_INFORMATION_CLASS {
TokenUser=1,
TokenGroups,
TokenPrivileges,
TokenOwner,
TokenPrimaryGroup,
TokenDefaultDacl,
TokenSource,
TokenType,
TokenImpersonationLevel,
TokenStatistics,
TokenRestrictedSids,
TokenSessionId,
TokenGroupsAndPrivileges,
TokenSessionReference,
TokenSandBoxInert,
TokenAuditPolicy,
TokenOrigin,
//#if (_WIN32_WINNT >= 0x0600)
TokenElevationType,
TokenLinkedToken,
TokenElevation,
TokenHasRestrictions,
TokenAccessInformation,
TokenVirtualizationAllowed,
TokenVirtualizationEnabled,
TokenIntegrityLevel,
TokenUIAccess,
TokenMandatoryPolicy,
TokenLogonSid,
//#endif
MaxTokenInfoClass
} TOKEN_INFORMATION_CLASS;
我评论了这些,编译的代码没有错误或警告。我的问题实际上是两个问题。他们是一个更好的方法(在我的代码中定义一些内容吗?),从长远来看,编辑头文件是否会伤害我?
答案 0 :(得分:5)
编辑标题会受到影响,因为您的代码不再针对您依赖的外部库构建。相反,您已经有效地将外部代码作为项目的一部分,现在您必须像项目中的其他源代码一样对其进行管理。例如,您应该将它保存在版本控制系统中。
是的,有一种更好的方法:您可以简单地定义_WIN32_WINNT
,因为Windows代码需要定义它。 Visual Studio项目默认定义此宏,但在Windows上使用gcc构建时必须手动执行此操作。
This page定义每个Windows版本的值。
答案 1 :(得分:0)
是的,您可以编辑和更改GCC头文件。
请注意,当GCC升级时,您的更改可能会丢失。您必须将更改合并到较新的头文件中。
出于这个原因,常见的经验法则是不修改编译器头文件。
编辑1:
此外,如果您共享代码,则需要让客户端对您执行的GCC头文件进行相同的修改。某些客户端可能不希望其编译器头文件发生更改。如果您有其他人在同一个项目上工作,则适用相同的规则。
此外,您的更改是否会影响未来的项目?未来的项目也可以使用GCC头文件。
答案 2 :(得分:0)
你可以修改它们,但这通常是个坏主意,因为它会让你难以重复编译。
在这种特殊情况下,正确的解决方案就是将_WIN32_WINNT
定义为0x0600
或更高。此宏用于指定您要定位的Windows版本,并且您显然至少定位到版本6,否则您将无法使用此值。 Windows SDK头文件使用此宏来条件地包含每个Windows版本中可用的声明,因此您无法在打算在Windows 7中运行的程序中使用Windows 8中的函数/字段/枚举值。
所以只需将-D_WIN32_WINNT=0x0600
添加到编译命令中并保留头文件......