- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在 .NET 4.5.1 或 .NET 4.5.2 上执行的以下代码示例(相同结果)中,当代码查询“不存在”变量时会发生一些奇怪的事情。另一个完全存在的值为空字符串的变量“myvar”将不再通过调用 GetEnvironmentVariable
看到,但通过整个环境的迭代仍然可以看到。
此行为可能无法仅使用 .NET API 重新创建,因为它们不允许将环境变量设置为空字符串;但 native API 允许这样做。
调用 Environment.GetEnvironmentVariable
会使另一个变量从环境中消失,或半消失,感觉很奇怪。
目标框架设置为 .NET 2.0 时的行为略有不同。直接获取 myvar
与迭代之间的不匹配发生在对 SetEnvironmentVariable
的 native 调用之后 - 无需查询另一个变量即可查看它。
编辑:添加 Charset=CharSet.Auto
,正如 Hans Passant 的善意建议(谢谢!)将 .NET 4.5.x 的疯狂级别降低到 .NET 4.5.x 的疯狂级别。 NET 2.0,除了修复 Unicode 处理之外,完全按照上一段中的描述。 DllImport
也缺少一个 SetLastError
参数,但这只是一个人为的例子,我们知道这个 native 调用在 Win32 级别上是成功的。所以,到目前为止没有任何解释。我知道解决该问题的几种方法,但我想更好地理解我所看到的。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
[DllImport("Kernel32.dll")]
public static extern int SetEnvironmentVariable(string name, string value);
static void Main(string[] args)
{
ShowMyVar();
Environment.SetEnvironmentVariable("myvar", "somevalue");
ShowMyVar();
Environment.SetEnvironmentVariable("myvar", String.Empty);
ShowMyVar();
SetEnvironmentVariable("myvar", String.Empty);
ShowMyVar();
// once again, for good measure.
ShowMyVar();
Console.WriteLine("\nOkay, sane results so far. Now let's query an unrelated non-existent variable.");
Environment.GetEnvironmentVariable("nonexistent");
ShowMyVar(); // Here we get weird results.
Console.WriteLine("\nNow again, but purely through .NET APIs.");
Environment.SetEnvironmentVariable("myvar", "somevalue");
ShowMyVar();
Environment.SetEnvironmentVariable("myvar", String.Empty);
ShowMyVar();
Environment.GetEnvironmentVariable("nonexistent");
ShowMyVar();
}
private static void ShowMyVar()
{
if (Environment.GetEnvironmentVariable("myvar") != null)
{
Console.WriteLine("myvar is set to \"{0}\"", Environment.GetEnvironmentVariable("myvar"));
}
else
{
Console.WriteLine("myvar is not set");
}
foreach (var x in Environment.GetEnvironmentVariables().Keys)
{
if (x.ToString() == "myvar")
{
Console.WriteLine("iteration gives value of myvar as \"{0}\"", Environment.GetEnvironmentVariable("myvar"));
return;
}
}
Console.WriteLine("iteration over environment does not yield myvar");
}
}
}
最佳答案
这样做的原因:
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 ""
第 2 步调用 GetEnvironmentStringsW()
它返回指向环境字符串 block 的指针。MyVar 出现在这里。
此 API 记录在此处 http://msdn.microsoft.com/en-us/library/windows/desktop/ms683187(v=vs.85).aspx
此信息是使用 Rohitab API 监视器获得的 http://www.rohitab.com/apimonitor将 API 监视器用于 .NET EXE 时,您可能需要在应用程序开始时暂停,然后再附加 API 监视器。
在这种情况下启用监控系统服务 -> 进程和线程 -> 进程 -> 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();
}
与 .NET 不同,在 Win32 C++ 中,使用以下代码可以正常工作:
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 调用:
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
当从 .NET 4 调用时,在这种情况下,我直接依次调用 SetEnvironmentVariable 和 GetEnvironmentVariable:
[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()));
}
这会导致这些 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
在 .NET 版本中调用 KERNELBASE.dll!RtlQueryEnvironmentVariable 成功
据我所知,clr.dll 正在影响 GetEnvironmentVariableW 的返回值。
如果在 WinDbg 中启动 .NET exe,并在设置“somevalue”后中断
加载 .NET 调试扩展
0:003> .loadby sos clr
显示进程环境 block (PEB) 以查找环境的地址
0:003> !peb
PEB at 7f40d000
InheritedAddressSpace: No
ReadImageFileExecOptions: No
BeingDebugged: Yes
ImageBaseAddress: 00250000
Ldr 77d891e0
etc...
Environment: **006b0c68**
etc..
在内存中搜索我们的值的位置...
0:003> s -u **006b0c68** **006b0c68**+1000 "somevalue"
**006b1214** 0073 006f 006d 0065 0076 0061 006c 0075 s.o.m.e.v.a.l.u.
在该内存位置设置读取断点...
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
我们现在在读回值时遇到断点...
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,我们看到这里设置了错误:
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)
如果此行为需要更改,我建议向 Microsoft 提出支持案例。
关于c# - 调用 `Environment.GetEnvironmentVariable`影响后续调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26993642/
这是一个非常笼统的问题,我希望我能答对。 我正在研究 SSL/TLS 重新协商并已阅读了一些内容。这是我从阅读中了解到的内容: 从 SSL/TLS 重新协商的角度来看,客户端分为两个主要组,打补丁的和
第一个屏幕是艺术的细节。当我向上滚动时,标题将是 alpha。我点击另一个“艺术”到另一个细节 UI,然后按回到 Previous UI。之前的UI标题是黑色的,怎么变透明了。 布局:
想知道 mv 对基表的影响。它会减慢基表的速度吗?它什么时候开始写入 mv,就像同时写入基表和 mv 一样? 如果我有 local_quorum 的 CL 且 RF=3,客户端是否必须等到写入 mv
似乎在任何地方都找不到太多关于此问题的帮助,所以我想我会在这里尝试。 我正在尝试制作一个简单的 for 循环,当我将鼠标悬停在 html 卡上时,它会隐藏卡中的一些文本。该卡有一个简单的名字和姓氏,我
我有一个程序每帧运行 tick() 方法。我希望一个对象根据设定的重力常数下落,因此我创建了一个 Ball 对象,该对象会将其位置更新为前一帧的位置减去 y 速度。每个刻度 y 速度都会减少重力常数。
我的 KeyHandler 在这里: private void KeyHandler(java.awt.event.KeyEvent evt) {
我有一个方法,其中使用了很多其他类,包括链接列表、队列和堆栈。在我的方法中,我有一个 for 循环,我想在其中弹出堆栈(方便地命名为 s)并将队列(方便地命名为 q)出队到 s1 和 q1。由于某种原
我有一个 JTree 节点数组和另一个自定义对象的相应数组。 我想要什么:当选择 JTree 的节点时,相应对象(其数组中索引与节点数组中所选节点索引相同的对象)的字段填充 JLabels。 我被困在
我知道浏览器完成了处理客户端脚本(Javascript、JQuery 等)的所有工作,但想知道在性能方面是否还有其他重要因素(网络速度、客户端计算机速度、服务器环境) 如果它完全依赖于浏览器(类型和版
我有一个 Android 服务在后台运行,它将使用以下代码: while(true) { ServerSocket server = new ServerSocket(1234); Socke
对JQM有以下疑惑: 1.如果我们在单独的 html 文件中使用重复的 id,对 jquery mobile 有什么影响。 假设我们在单独的 html 文件中有重复的 id,但如果我们不使用该 id
我正在尝试更新两个(inventory、sold)MySQL 表的表库存。 假设我们正在处理的 sku 是 BT888-16 UPDATE inventory JOIN sold ON invento
我使用这种方法来更改我的表格单元格值, 它在 jtable 上改变但在文本文件上没有改变! public class user_AllBooks extends AbstractTableModel
我想在向表中插入数据时创建一个 MYSQL 存储过程,数据也会被插入到其他服务器表中。 我知道这在 ORACLE 数据库中是可能的,但我不知道它是否适用于 MYSQL。 有什么办法吗? 最佳答案 是的
我在 css 方面非常糟糕,只能靠 SO 答案来解决 - 但是我找不到针对这个特定问题的任何解释。 我有一个表单,其中包含一个 textarea 和一个 button(input/submit),仅此
我在一个元素上有动画,但它的移动也会影响 sibling 。如何在不影响兄弟元素的情况下仅在元素上使用动画? 问题示例: function animateSearch() { $('.glyph
我试图在我的 ViewController 中的 UIView 的所有四个边上建立一个阴影 — 在我通过 Xcode 向 UIView 添加约束之前,它工作得很好。我怎样才能使 UIView 的阴影显
自从我使用 JavaScript 以来已经有一段时间了 - 在获得证书之后我开始学习 Perl 并从那时起就一直使用它。我只是想重新开始使用 JS,我已经写了这个,我想说的是,这是一个简单的小脚本,可
我正在处理一个 HTML 元素,我添加了一个复选框,选中后会高亮显示所有文本输入字段。唯一的问题是一些输入字段在表格内,出于某种原因我无法用我的代码影响它们。任何帮助将不胜感激。 相关代码: HTML
我为 String 类创建了一个小扩展,以便方便地从中删除字符。这是它的样子: mutating func drop(characters chars: [String]) { for c i
我是一名优秀的程序员,十分优秀!