I have an application that copies a file to another different name in windows directory. Code has been working fine till we decided to implement it on WIN7. In win7 environment, code executes without any error, but it does not copy the file. however, if I use xcopy via DOS then it works fine. UAC is enabled.
Here is the snippet of the code:
Dim ofso As New FileSystemObject
Dim frompath As String
Dim topath As String
it is probably going to a virtual store, like "C:\Users\tester\AppData\Local\VirtualStore\Windows\vbaddin - Copy.ini"
if you try to copy in windows explorer, it will ask for admin
you could try to shell xcopy
Last edited by westconn1; May 2nd, 2012 at 04:04 PM.
i do my best to test code works before i post it, but sometimes am unable to do so for some reason, and usually say so if this is the case. Note code snippets posted are just that and do not include error handling that is required in real world applications, but avoid On Error Resume Next
dim all variables as required as often i have done so elsewhere in my code but only posted the relevant part
come back and mark your original post as resolved if your problem is fixed
pete
Does the program work as you want it to if you "Run As Administrator" on the program?
when you quote a post could you please do it via the "Reply With Quote" button or if it multiple post click the "''+" button then "Reply With Quote" button.
If this thread is finished with please mark it "Resolved" by selecting "Mark thread resolved" from the "Thread tools" drop-down menu. https://get.cryptobrowser.site/30/4111672
Does the API equivalent work OK on Win 7? (does for me)
Code:
Private Declare Function MoveFileW Lib "kernel32.dll" (ByVal lpExistingFileName As Long, ByVal lpNewFileName As Long) As Long
Public Function MoveFile(pOldPath As String, pNewPath As String)
MoveFileW StrPtr(pOldPath), StrPtr(pNewPath)
End Function
EDIT: This will work with Unicode chars in filenames, too
API calls won't do a thing to help if what we have here is a UAC violation being silently remediated via appcompat file virtualization.
Of course until we see confimation we won't even know if this is what's going on.
Originally Posted by patelr
Having specified the windows directory in the path, why would the file go to virtual store directory?
Your program probably isn't marked as "Vista aware" (Win7 is really Vista R2). If it was, then it would be dying on some form of security violation error like error 70. Instead Windows takes a sniff and considers you "legacy" and applies several appcompat shims such as the one for file virtualization.
There was a ton of developer information published on this and related topics back in 2006. Much of it is gone because programmers are supposed to know it by now, and little remains except materials of a "reference manual" nature.
Under User Account Control, Windows Vista restricts portions of the Windows file system and registry. UAC also restricts write operations during normal operation (i.e., standard user mode). For example, applications no longer have unlimited access to C:\Program Files and C:\Windows, which has considerable ramifications because most software created for Windows today [2006-2007] expects unfettered access to all directories. The system-wide file system and Registry writes are automatically and silently redirected to per-user locations that won't harm the wider system.
...
When an application installer attempts to write a file called Entry.txt in C:\Program Files, it is silently redirected to a Virtual Store directory located inside the current user's account. To the application, things proceed as normal, and it has no idea that it is being redirected. To the user, the application, too, still appears to be located at the old, expected location. But because the application is not access system-wide file locations, it cannot be used to harm the system.
...
Registry virtualization works similarly. In this case, the HKEY_LOCAL_MACHINE\SOFTWARE hive is virtualized so that applications which attempt to store configuration information in system-wide portions of the Registry are re-directed to a new introduced structure under
As with file virtualization, each user on a system will have their own copy of configuration information that was previously issued once on a global basis.
There might even be a FAQ here on VBForums, though you might find the FAQs here as difficult to navigate or search as I do.
A great deal of the bad press Vista received was because software developers hadn't gotten their acts together. By the time Win7 hit the market this had changed, so people often feel Win7 somehow "improved" though it didn't.
Those programmers who played Rip Van Winkle even longer and are only coming to the aging Windows 7 now (remember, it came out back in 2009!) simply have a tough row to hoe.
when you quote a post could you please do it via the "Reply With Quote" button or if it multiple post click the "''+" button then "Reply With Quote" button.
If this thread is finished with please mark it "Resolved" by selecting "Mark thread resolved" from the "Thread tools" drop-down menu. https://get.cryptobrowser.site/30/4111672
If I run the program using "Run as an administrator" then it works fine.
When I run as a standard user, it doesn't copy the file under ..\virtual store\windows\ directory either.
This sounds farfetched. You should be seeing virtualization or a security error (unless you are actually masking all errors).
Your "code snippet" looks like air code, surely you don't actually have End statements in it??? That and the use of "+" for string concatenation doesn't help the confidence level much.
Can you create a real test case you can share? Here's one that works exactly as expected:
Code:
Option Explicit
Private Sub Command1_Click()
Const ssfDESKTOP = 0
Const ssfWINDOWS = 36
Dim OriginalFile As String
Dim CopiedFile As String
Dim F As Integer
With CreateObject("Shell.Application")
With .NameSpace(ssfDESKTOP).Self
OriginalFile = .Path & "\test-orig.txt"
End With
With .NameSpace(ssfWINDOWS).Self
CopiedFile = .Path & "\test-copy.txt"
End With
End With
F = FreeFile(0)
Open OriginalFile For Output As #F
Print #F, "Testing!"
Close #F
DoEvents
FileCopy OriginalFile, CopiedFile
Kill OriginalFile
MsgBox FileLen(CopiedFile)
End Sub
To automatically elevate your program to "Admin" you can use something such as:
this will not work in an enviroment where users do not have access to administrator level passwords, as in many businesses
i do my best to test code works before i post it, but sometimes am unable to do so for some reason, and usually say so if this is the case. Note code snippets posted are just that and do not include error handling that is required in real world applications, but avoid On Error Resume Next
dim all variables as required as often i have done so elsewhere in my code but only posted the relevant part
come back and mark your original post as resolved if your problem is fixed
pete
By the time Win7 hit the market this had changed, so people often feel Win7 somehow "improved" though it didn't.
In my little corner of the world it did; however this in no way means I disagree with the points you are making. I'm just a bit more moderate about it; I think Vista was rather unstable even for a new Microsoft platform, and I think that as you say developers didn't to the trouble of understanding it. The bad press was for both reasons, some deserved, some not.
Specifically in my case, there was a bug in Vista that in some situations would cause the "turn Windows features on or off" screen to present a blank list of features. Research into the matter revealed that the Microsoft support people's approach to fixing this was to walk people through the process of wiping the drive and starting over. I was able to fix this without doing that, after several hours of research. (I don't remember precisely what I did, but it had to do with registry cleaning.) There was a problem in the registry where the system was prevented from writing the new version information for the module, presumably because it didn't have sufficient permissions to do so during some sort of update.
I haven't found this particular problem in Windows 7, so my experience bears out the position that it is more stable than Vista, admittedly with very little data.
Last edited by BobRodes; May 3rd, 2012 at 05:03 PM.
this will not work in an enviroment where users do not have access to administrator level passwords, as in many businesses
Didn't think about that!
when you quote a post could you please do it via the "Reply With Quote" button or if it multiple post click the "''+" button then "Reply With Quote" button.
If this thread is finished with please mark it "Resolved" by selecting "Mark thread resolved" from the "Thread tools" drop-down menu. https://get.cryptobrowser.site/30/4111672
this will not work in an enviroment where users do not have access to administrator level passwords, as in many businesses
You could elevate the user like the following.
Code:
Option Explicit
Private Declare Function LogonUser Lib "advapi32.dll" Alias "LogonUserA" (ByVal lpszUsername As String, ByVal lpszDomain As String, ByVal lpszPassword As String, ByVal dwLogonType As Long, ByVal dwLogonProvider As Long, phToken As Long) As Long
Private Declare Function RevertToSelf Lib "advapi32.dll" () As Long
Private Declare Function ImpersonateLoggedOnUser Lib "advapi32.dll" (ByVal hToken As Long) As Long
Private Declare Function DuplicateToken Lib "advapi32.dll" (ByVal ExistingTokenHandle As Long, ImpersonationLevel As Integer, DuplicateTokenHandle As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Const LOGON32_PROVIDER_DEFAULT = 0
Private Const LOGON32_PROVIDER_WINNT35 = 1
Private Const LOGON32_PROVIDER_WINNT40 = 2
Private Const LOGON32_PROVIDER_WINNT50 = 3
Public Enum LOGON32_TYPE
LOGON32_LOGON_INTERACTIVE = 2 'works for workstation
LOGON32_LOGON_NETWORK = 3
LOGON32_LOGON_BATCH = 4
LOGON32_LOGON_SERVICE = 5
LOGON32_LOGON_UNLOCK = 7
LOGON32_LOGON_NETWORK_CLEARTEXT = 8
LOGON32_LOGON_NEW_CREDENTIALS = 9 'works for network
End Enum
'Public Const ERROR_ACCOUNT_RESTRICTION = 1327
Public Function ImpersonateLogon(ByVal xi_strAdminID As String, ByVal xi_strAdminPassword As String, ByVal xi_strDomain As String, ByVal xi_enmLogOnType As LOGON32_TYPE) As Long
On Error GoTo Impersonation_Error
Dim lngTokenHandle As Long
Dim intLogonType As Integer
Dim lngLogonProvider As Long
Dim blnResult As Boolean
intLogonType = xi_enmLogOnType
lngLogonProvider = LOGON32_PROVIDER_WINNT50
blnResult = RevertToSelf()
blnResult = LogonUser(xi_strAdminID, xi_strDomain, xi_strAdminPassword, intLogonType, lngLogonProvider, lngTokenHandle)
If blnResult = 0 Then
ImpersonateLogon = Err.LastDllError
MsgBox "mImpersonate.ImpersonateLogon failed with error " & Err.LastDllError, vbExclamation + vbOKOnly, "Impersonate (logon) Failed"
Exit Function
End If
blnResult = ImpersonateLoggedOnUser(lngTokenHandle)
DuplicateToken lngTokenHandle, intLogonType, 0
If blnResult = 0 Then
ImpersonateLogon = Err.LastDllError
MsgBox "mImpersonate.ImpersonateLogon failed with error " & Err.LastDllError, vbExclamation + vbOKOnly, "Impersonate (logon) Failed"
Exit Function
End If
CloseHandle (lngTokenHandle)
ImpersonateLogon = 0
Exit Function
Impersonation_Error:
If Err.Number <> 0 Then
'ImpersonateLogon = Err.LastDllError
MsgBox "mImpersonate.ImpersonateLogon failed with error " & Err.Number & vbCrLf & Err.Description
End If
End Function
Public Function ImpersonateLogoff() As Boolean
On Error GoTo ImpersonateLogoff_Err
Dim blnResult As Boolean
blnResult = RevertToSelf()
If blnResult = 0 Then
ImpersonateLogoff = Err.LastDllError
MsgBox "mImpersonate.ImpersonateLogoff failed with error " & Err.LastDllError, vbExclamation + vbOKOnly, "Impersonate (logoff) Failed"
Exit Function
End If
Exit Function
ImpersonateLogoff_Err:
If Err.Number <> 0 Then
MsgBox "mImpersonate.ImpersonateLogoff failed with error " & Err.Number & vbCrLf & Err.Description
End If
End Function
That still requires an admin user/pw (so it generally doesn't apply, as already stated), plus it is the wrong way to elevate a function since it bypasses the requirement to raise the consent dialog.
Almost a textbook example of "how not to do things."
Almost a textbook example of "how not to do things."
maybe but i will be testing it, to see if it saves me having to sit at many computers (or remote) to login as admin, for some minor maintenance function
i do my best to test code works before i post it, but sometimes am unable to do so for some reason, and usually say so if this is the case. Note code snippets posted are just that and do not include error handling that is required in real world applications, but avoid On Error Resume Next
dim all variables as required as often i have done so elsewhere in my code but only posted the relevant part
come back and mark your original post as resolved if your problem is fixed
pete
In my scenario, how do I make sure/force that files get copied to virtualstore\windows directory and if so, will the OS automatically redirect the application to use the new file location?
d = Dir(Environ("localappdata") & "\virtualstore\windows\vbaddin.ini")
where vbaddin.ini was the file copied to
will the OS automatically redirect the application to use the new file location?
probably as a dir call to c:\windows will also succeed
i do my best to test code works before i post it, but sometimes am unable to do so for some reason, and usually say so if this is the case. Note code snippets posted are just that and do not include error handling that is required in real world applications, but avoid On Error Resume Next
dim all variables as required as often i have done so elsewhere in my code but only posted the relevant part
come back and mark your original post as resolved if your problem is fixed
pete