이유 :
Okay, sane results so far. Now let's query an unrelated non-existent variable.
myvar is not set
.NET이 kernel32!GetEnvironmentVariableW ("myvar", <pointer>, 128)
를 호출하고 0 GetLastError()
가 203로 설정되어 반환 = 입력 된 환경 옵션을 찾을 수 없습니다.
이 API는 여기 http://msdn.microsoft.com/en-us/library/windows/desktop/ms683188(v=vs.85).aspx
iteration gives value of myvar as ""
단계 환경 문자열의 블록에 대한 포인터를 반환이 전화 GetEnvironmentStringsW()
를 설명되어 있습니다. 여기에 MyVar가 있습니다.
이 API는 여기 http://msdn.microsoft.com/en-us/library/windows/desktop/ms683187(v=vs.85).aspx
설명되어이 정보는 다음 API 모니터를 연결, 응용 프로그램의 시작 부분에 일시 중지를 넣어해야 할 수도 있습니다 닷넷 EXE에 대한 API 모니터를 사용하는 경우 Rohitab API는 http://www.rohitab.com/apimonitor을 모니터링하여 얻은 후에. 이 경우 활성화 된 모니터링 시스템 서비스에서
-> 프로세스와 스레드 -> 프로세스 ->의 Kernel32.dll 및 선택 해제 GetCurrentProcess()는
라는 .NET 소스 코드는 여기 http://referencesource.microsoft.com/#mscorlib/system/environment.cs
Win32Native.ERROR_ENVVAR_NOT_FOUND =입니다 203,이 반환 null을 트리거합니다.
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
public static String GetEnvironmentVariable(String variable)
{
if (variable == null)
throw new ArgumentNullException("variable");
Contract.EndContractBlock();
#if !FEATURE_CORECLR
(new EnvironmentPermission(EnvironmentPermissionAccess.Read, variable)).Demand();
#endif //!FEATURE_CORECLR
StringBuilder blob = new StringBuilder(128); // A somewhat reasonable default size
int requiredSize = Win32Native.GetEnvironmentVariable(variable, blob, blob.Capacity);
if(requiredSize == 0) { // GetEnvironmentVariable failed
if(Marshal.GetLastWin32Error() == Win32Native.ERROR_ENVVAR_NOT_FOUND)
return null;
}
while (requiredSize > blob.Capacity) { // need to retry since the environment variable might be changed
blob.Capacity = requiredSize;
blob.Length = 0;
requiredSize = Win32Native.GetEnvironmentVariable(variable, blob, blob.Capacity);
}
return blob.ToString();
}
Win32 C++에서 다음 코드는 예상대로 작동합니다.NET :
DWORD dwResult;
wchar_t buffer[128];
if (!SetEnvironmentVariableW(L"myvar", L""))
{
dwResult = GetLastError();
std::cout << "ERROR #" << dwResult << std::endl;
}
if (!GetEnvironmentVariableW(L"myvar", buffer,128))
{
dwResult = GetLastError();
std::cout << "ERROR #" << dwResult << std::endl;
}
std::wcout << "Buffer : '" << buffer << "'";
다음 API 호출
가 발생
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool SetEnvironmentVariable(string lpName, string lpValue);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern uint GetEnvironmentVariable(string lpName, [Out] StringBuilder lpBuffer, uint nSize);
StringBuilder buffer = new StringBuilder(128);
SetEnvironmentVariable("myvar", String.Empty);
uint result=GetEnvironmentVariable("myvar", buffer, 128);
if (result==0)
{
Console.WriteLine(string.Format("Error: {0}", Marshal.GetLastWin32Error()));
}
이 : 서로 직접 후이 경우 IP/호출 SetEnvironmentVariable 및 GetEnvironmentVariable에서 .NET 4에서 호출
ConsoleTest.exe!SetEnvironmentVariableW ("myvar", "") TRUE
KERNELBASE.dll!RtlSetEnvironmentVar (NULL, "myvar", 5, "", 0) STATUS_SUCCESS
ConsoleTest.exe!GetEnvironmentVariableW ("myvar", <pointer 1>, 128) 0 0 = The operation completed successfully.
KERNELBASE.dll!RtlQueryEnvironmentVariable (NULL, "myvar", 5, <pointer 1>, 128, <pointer 2>) STATUS_SUCCESS
이 API 호출/결과의 결과는
clr.dll->SetEnvironmentVariableW ("myvar", "") TRUE
KERNELBASE.dll!RtlSetEnvironmentVar (NULL, "myvar", 5, "", 0) STATUS_SUCCESS
clr.dll->SetLastError (ERROR_ENVVAR_NOT_FOUND)
clr.dll->SetLastError (ERROR_ENVVAR_NOT_FOUND)
clr.dll->SetLastError (ERROR_ENVVAR_NOT_FOUND)
clr.dll->SetLastError (ERROR_ENVVAR_NOT_FOUND)
clr.dll!GetEnvironmentVariableW ("myvar", <pointer 1>, 128) 0 203 = The system could not find the environment option that was entered.
KERNELBASE.dll!RtlQueryEnvironmentVariable (NULL, "myvar", 5, <pointer 1>, 128, <pointer 2>) STATUS_SUCCESS
내가 clr.dll이 GetEnvironmentVariableW의 반환 값에 영향을 미치는 것을 볼 수 있습니다로 .NET 버전에서
통화 KERNELBASE.dll! RtlQueryEnvironmentVariable는 지금까지
을 성공합니다.
당신은 WinDbg를에서의 .NET EXE를 시작하고 당신의 주소를 찾기 위해 "someValue와"
로드 .NET 디버깅 확장
0:003> .loadby sos clr
표시 프로세스 환경 블록 (PEB)를 설정 한 후 휴식 경우 메모리에 우리의 값의 위치에 대한 환경
0:003> !peb
PEB at 7f40d000
InheritedAddressSpace: No
ReadImageFileExecOptions: No
BeingDebugged: Yes
ImageBaseAddress: 00250000
Ldr 77d891e0
etc...
Environment: **006b0c68**
etc..
검색 ...
는
Breakpoint 1 hit
eax=0000003d ebx=006b1212 ecx=006b1214 edx=01fe2b0a esi=006b1208 edi=00000001
eip=77cda2f7 esp=003def5c ebp=003def74 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
ntdll!RtlpScanEnvironment+0xa7:
77cda2f7 75f7 jne ntdll!RtlpScanEnvironment+0xa0 (77cda2f0) [br=0]
0:000> kv
ChildEBP RetAddr Args to Child
003def74 77cda138 01fe2b0a 003df000 00000080 ntdll!RtlpScanEnvironment+0xa7 (FPO: [Non-Fpo])
003defc8 77732b88 00000000 01fe2b00 00000005 ntdll!RtlQueryEnvironmentVariable+0xa7 (FPO: [SEH])
003defec 005d0682 01fe2b00 003df000 00000080 KERNELBASE!GetEnvironmentVariableW+0x39 (FPO: [Non-Fpo])
, 여기에서 onwords 실행을 추적 ... 우리가 값을 다시 읽을 때 우리는 지금 중단 점
0:003> ba r 1 **006b1214**
0:000> du 6b1214
006b1214 "somevalue"
0:000> g
Breakpoint 1 hit
eax=00000000 ebx=006b1228 ecx=006b1214 edx=00000000 esi=00000000 edi=006b293a
eip=77ce37ad esp=003df094 ebp=003df108 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
ntdll!RtlSetEnvironmentVar+0x516:
77ce37ad 83c102 add ecx,2
0:000> du 6b1214
006b1214 ""
0:000> kv
ChildEBP RetAddr Args to Child
003df108 7774029e 00000000 01fe2b00 00000005 ntdll!RtlSetEnvironmentVar+0x516 (FPO: [SEH])
003df12c 005d04a3 01fe2b00 01fe1230 ed4737ca KERNELBASE!SetEnvironmentVariableW+0x47 (FPO: [Non-Fpo])
WARNING: Frame IP not in any known module. Following frames may be wrong.
003df1f8 73cc2552 0068e698 003df258 73ccf237 0x5d04a3
003df204 73ccf237 003df29c 003df248 73e18ad2 clr!CallDescrWorkerInternal+0x34
003df258 73ccff60 00000000 00000001 003df2b8 clr!CallDescrWorkerWithHandler+0x6b (FPO: [Non-Fpo])
003df2d0 73de671c 003df3cc efea5369 004e37fc clr!MethodDescCallSite::CallTargetWorker+0x152 (FPO: [Non-Fpo])
003df3f4 73de6840 01fe2a68 00000000 efea5495 clr!RunMain+0x1aa (FPO: [Non-Fpo])
003df668 73e23dc5 00000000 efea56e5 00250000 clr!Assembly::ExecuteMainMethod+0x124 (FPO: [1,149,0])
003dfb68 73e23e68 efea5b5d 00000000 00000000 clr!SystemDomain::ExecuteMainMethod+0x63c (FPO: [0,313,0])
003dfbc0 73e23f7a efea5c9d 00000000 00000000 clr!ExecuteEXE+0x4c (FPO: [Non-Fpo])
003dfc00 73e26b86 efea5ca1 00000000 00000000 clr!_CorExeMainInternal+0xdc (FPO: [Non-Fpo])
003dfc3c 7436ffcc eff9e4d3 7573980c 74360000 clr!_CorExeMain+0x4d (FPO: [Non-Fpo])
003dfc74 743ebbb7 003dfc8c 743ebbcc 00000000 mscoreei!_CorExeMain+0x10a (FPO: [0,10,4])
003dfc7c 743ebbcc 00000000 00000000 003dfc98 MSCOREE!_CorExeMain_Exported+0x77 (FPO: [Non-Fpo])
003dfc8c 7573919f 7f40d000 003dfcdc 77cda8cb MSCOREE!_CorExeMain_Exported+0x8c (FPO: [Non-Fpo])
003dfc98 77cda8cb 7f40d000 eea2cea9 00000000 KERNEL32!BaseThreadInitThunk+0xe (FPO: [Non-Fpo])
003dfcdc 77cda8a1 ffffffff 77ccf663 00000000 ntdll!__RtlUserThreadStart+0x20 (FPO: [SEH])
003dfcec 00000000 743ebb40 7f40d000 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])
0:000> !clrstack
OS Thread Id: 0x3464 (0)
Child SP IP Call Site
003df140 77ce37ad [InlinedCallFrame: 003df140]
003df13c 005d04a3 *** WARNING: Unable to verify checksum for ConsoleApplicationTest.exe
DomainBoundILStubClass.IL_STUB_PInvoke(System.String, System.String)
003df140 005d0106 [InlinedCallFrame: 003df140] ConsoleApplication1.Program.SetEnvironmentVariable(System.String, System.String)
003df1a4 005d0106 ConsoleApplication1.Program.Main(System.String[]) [c:\Users\mccafferym\Documents\Visual Studio 2013\Projects\ConsoleApplicationTest\ConsoleApplicationTest\Program.cs @ 32]
003df378 73cc2552 [GCFrame: 003df378]
0:000> g
그 메모리 위치에 읽기 중단 점을 ... 설정 우리 참조 오류가 여기에 설정됩니다
KERNELBASE!GetEnvironmentVariableW+0x52:
77732ba9 c20c00 ret 0Ch
006f0682 8b4d98 mov ecx,dword ptr [ebp-68h] ss:002b:0033f040=004ee698
006f0685 c6410801 mov byte ptr [ecx+8],1 ds:002b:004ee6a0=00
006f0689 833d64a32f7400 cmp dword ptr [clr!g_TrapReturningThreads (742fa364)],0 ds:002b:742fa364=00000000
006f0690 7407 je 006f0699 [br=1]
006f0699 c7458000000000 mov dword ptr [ebp-80h],0 ss:002b:0033f028=006f0682
006f06a0 8945ac mov dword ptr [ebp-54h],eax ss:002b:0033f054=0033f288
006f06a3 e801545e73 call clr!StubHelpers::SetLastError (73cd5aa9)
이 문제는 내가 RAIS을 권 해드립니다 변경 필요한 경우 Microsoft 지원 사례.
관찰 : 네이티브'SetEnvironmentVariable' 결과를 확인하지 마십시오. 모든 통화에서 올바르게 작동하는지 어떻게 알 수 있습니까? – leppie
'Environment.GetEnvironmentVariable ("nonexistent")'다음에 별다른 결과가 없다. myVar은 공백을 계속한다. "" " – Luizgrs
그리고 나는 많은 명령 행/박쥐 연산에서'String.Empty'와 정의 된 하나는 똑같은 것입니다 (이것은 제가 규칙으로 캠핑하는 것입니다 :)). 변수가 비어 있는지 확인하기 위해 사용자에게 확인을 지시 할 때 MS가 말하는 것은 다음과 같습니다. http://support.microsoft.com/kb/121170. – Luizgrs