The process is elevated and I ensured that the path was correct in VS debugger (I'm using Environment.GetFolderPath(Environment.SpecialFolder.System) not hard coding it in) but File.Exists still returns false.
这个过程被提升了,我确保VS调试器中的路径是正确的(我使用的是Environment.GetFolderPath(Environment.SpecialFolder.System)而不是硬编码)但File.Exists仍然返回false。
The reason I need this is a workaround for ensuring some 3rd party drivers are installed because their registry settings aren't removed on uninstall.
我需要这个的原因是确保安装了一些第三方驱动程序的解决方法,因为他们的注册表设置在卸载时不会被删除。
I know writes are redirected via virtualization but is this also true for checking a file's existence?
我知道写入是通过虚拟化重定向的,但这对于检查文件的存在也是如此吗?
5 个解决方案
#1
Yes, virtualization happens at a very low level. The File.Exists method basically calls the Win32 CreateFile method and checks for errors. CreateFile is redirected by the WOW subsystem.
是的,虚拟化发生在非常低的水平。 File.Exists方法基本上调用Win32 CreateFile方法并检查错误。 CreateFile由WOW子系统重定向。
You can disable virtualization temporarily before calling.
您可以在呼叫前暂时禁用虚拟化。
[DllImport( "kernel32", CharSet=CharSet.Unicode, SetLastError=true )]
public static extern bool Wow64DisableWow64FsRedirection( ref IntPtr oldValue );
[DllImport( "kernel32", CharSet=CharSet.Unicode, SetLastError=true )]
public static extern bool Wow64RevertWow64FsRedirection( IntPtr oldValue );
Of course to be complete you'll have to check for file existence with virtualization on as well as off. The same applies for checking registry entries as well.
当然要完成,你必须检查文件存在与虚拟化以及关闭。这同样适用于检查注册表项。
public static bool FileExists( string path )
{
if( File.Exists( path ) ) return true;
IntPtr oldValue = IntPtr.Zero;
try
{
if( Environment.GetEnvironmentVariable( "PROCESSOR_ARCHITEW6432" ) == null )
return false;
Wow64DisableWow64FsRedirection( ref oldValue );
if( File.Exists( path ) ) return true;
return false;
}
finally
{
if( oldValue != IntPtr.Zero )
Wow64RevertWow64FsRedirection( ref oldValue );
}
}
Update: You may also need to check the OS version before disabling the WOW redirection because earlier versions of XP (Pre SP2 I believe) do not expose those methods.
更新:您可能还需要在禁用WOW重定向之前检查操作系统版本,因为早期版本的XP(我相信的Pre SP2)不会公开这些方法。
Update 2: Added OS check for 64-bit. All 64-bit versions of the OS implement these methods and you only need to disable the sate if running on a 64-bit OS.
更新2:添加了64位操作系统检查。所有64位版本的操作系统都实现了这些方法,如果在64位操作系统上运行,则只需要禁用状态。
#2
Is your process 32 bit or 64 bit? and are the drivers 64 or 32? What I'm getting at is that maybe your host OS redirects you to the Wow64 folder instead.
你的进程是32位还是64位?并且是64或32的驱动程序?我得到的是,您的主机操作系统可能会将您重定向到Wow64文件夹。
#3
Have you tried disabling folder virtualization for your app? You'll need add a manifest file containing:
您是否尝试过为您的应用禁用文件夹虚拟化?您需要添加包含以下内容的清单文件:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
However, if you need to write to those folders you'll have to request admin ability. To do that, change level="asInvoker"
to level="requireAdministrator"
in the xml.
但是,如果您需要写入这些文件夹,则必须请求管理员能力。为此,请在xml中将level =“asInvoker”更改为level =“requireAdministrator”。
#4
This is an virtualization issue - the file just isn't there. You will have to look for it in the folder the contains the virtualized files.
这是一个虚拟化问题 - 文件不存在。您必须在包含虚拟化文件的文件夹中查找它。
#5
If you have the rights, why don't you attempt to create a file in the same location in your code, and see where it ends up? As suggested by another, Windows might be redirecting your call based on a few settings.
如果您拥有这些权限,为什么不尝试在代码中的相同位置创建文件,并查看它的最终位置?正如另一个人所建议的那样,Windows可能会根据一些设置重定向您的呼叫。
Also, you could try doing a DirectoryInfo and enumerating Files it contains to see if anything looks familiar.
此外,您可以尝试执行DirectoryInfo并枚举它包含的文件,以查看是否有任何看起来很熟悉的内容。
#1
Yes, virtualization happens at a very low level. The File.Exists method basically calls the Win32 CreateFile method and checks for errors. CreateFile is redirected by the WOW subsystem.
是的,虚拟化发生在非常低的水平。 File.Exists方法基本上调用Win32 CreateFile方法并检查错误。 CreateFile由WOW子系统重定向。
You can disable virtualization temporarily before calling.
您可以在呼叫前暂时禁用虚拟化。
[DllImport( "kernel32", CharSet=CharSet.Unicode, SetLastError=true )]
public static extern bool Wow64DisableWow64FsRedirection( ref IntPtr oldValue );
[DllImport( "kernel32", CharSet=CharSet.Unicode, SetLastError=true )]
public static extern bool Wow64RevertWow64FsRedirection( IntPtr oldValue );
Of course to be complete you'll have to check for file existence with virtualization on as well as off. The same applies for checking registry entries as well.
当然要完成,你必须检查文件存在与虚拟化以及关闭。这同样适用于检查注册表项。
public static bool FileExists( string path )
{
if( File.Exists( path ) ) return true;
IntPtr oldValue = IntPtr.Zero;
try
{
if( Environment.GetEnvironmentVariable( "PROCESSOR_ARCHITEW6432" ) == null )
return false;
Wow64DisableWow64FsRedirection( ref oldValue );
if( File.Exists( path ) ) return true;
return false;
}
finally
{
if( oldValue != IntPtr.Zero )
Wow64RevertWow64FsRedirection( ref oldValue );
}
}
Update: You may also need to check the OS version before disabling the WOW redirection because earlier versions of XP (Pre SP2 I believe) do not expose those methods.
更新:您可能还需要在禁用WOW重定向之前检查操作系统版本,因为早期版本的XP(我相信的Pre SP2)不会公开这些方法。
Update 2: Added OS check for 64-bit. All 64-bit versions of the OS implement these methods and you only need to disable the sate if running on a 64-bit OS.
更新2:添加了64位操作系统检查。所有64位版本的操作系统都实现了这些方法,如果在64位操作系统上运行,则只需要禁用状态。
#2
Is your process 32 bit or 64 bit? and are the drivers 64 or 32? What I'm getting at is that maybe your host OS redirects you to the Wow64 folder instead.
你的进程是32位还是64位?并且是64或32的驱动程序?我得到的是,您的主机操作系统可能会将您重定向到Wow64文件夹。
#3
Have you tried disabling folder virtualization for your app? You'll need add a manifest file containing:
您是否尝试过为您的应用禁用文件夹虚拟化?您需要添加包含以下内容的清单文件:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
However, if you need to write to those folders you'll have to request admin ability. To do that, change level="asInvoker"
to level="requireAdministrator"
in the xml.
但是,如果您需要写入这些文件夹,则必须请求管理员能力。为此,请在xml中将level =“asInvoker”更改为level =“requireAdministrator”。
#4
This is an virtualization issue - the file just isn't there. You will have to look for it in the folder the contains the virtualized files.
这是一个虚拟化问题 - 文件不存在。您必须在包含虚拟化文件的文件夹中查找它。
#5
If you have the rights, why don't you attempt to create a file in the same location in your code, and see where it ends up? As suggested by another, Windows might be redirecting your call based on a few settings.
如果您拥有这些权限,为什么不尝试在代码中的相同位置创建文件,并查看它的最终位置?正如另一个人所建议的那样,Windows可能会根据一些设置重定向您的呼叫。
Also, you could try doing a DirectoryInfo and enumerating Files it contains to see if anything looks familiar.
此外,您可以尝试执行DirectoryInfo并枚举它包含的文件,以查看是否有任何看起来很熟悉的内容。