The following function copies a file from Source & Path to Dest & Path, normally setting file attributes to normal before copying.
Yet, a user of my app has reported it to fail when copying readonly files, returning a permissions-related error. The user is however running the code as administrator, and the error happens - quite strangely - on the SetLastWriteTimeUtc line.
Although the code reports that the file attributes are set to normal, windows explorer shows that they are set to read only.
Sub CopyFile(ByVal Path As String, ByVal Source As String, ByVal Dest As String)
If IO.File.Exists(Dest & Path) Then IO.File.SetAttributes(Dest & Path, IO.FileAttributes.Normal)
IO.File.Copy(Source & Path, Dest & Path, True)
If Handler.GetSetting(ConfigOptions.TimeOffset, "0") <> "0" Then
IO.File.SetAttributes(Dest & Path, IO.FileAttributes.Normal)
IO.File.SetLastWriteTimeUtc(Dest & Path, IO.File.GetLastWriteTimeUtc(Dest & Path).AddHours(Handler.GetSetting(ConfigOptions.TimeOffset, "0")))
End If
IO.File.SetAttributes(Dest & Path, IO.File.GetAttributes(Source & Path))
End Sub
I just fail to see the problem in this code, so after long hours of searching for the solution, I thought one of SO VB.Net Gurus might help :)
Thanks a lot.
Edit:
The actual error is
Access to the path '(..)' is denied.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize)
at System.IO.File.OpenFile(String path, FileAccess access, SafeFileHandle& handle)
at System.IO.File.SetLastWriteTimeUtc(String path, DateTime lastWriteTimeUtc)
If the files being moved are in a place that requires administration permissions per the Vista User Account Controls (UAC), you will need to run the application as administrator, as in the right click menu from below:
alt text http://www.trendystock.com/images/Run%20as%20administrator%20for%20Vista%20PC.jpg
If this is a hassle, the user can right click the shortcut or .exe, and go to properties where you can select to always run the app as administrator. Alternatively, if it's an option, they could just disable UAC.
Related
I have been working on this issue for over a month and have tried everything I have found in forums. Desperately need help.
Background:
1 - I recently started using a brand new PC (windows 10)
2 - I am running the exact same VS2019 version as previous PC
3 - This program is form that contains many checkboxes and text boxes. The user makes selections and enters information on the form then they save it. When it saves, I write the state of every control to a text file (aka .enc extension) using streamwriter. When a user then opens the form again it uses streamreader to open that same text file and set the state of every control on the form so the user can see what was previously entered.
4 - The text file is on a shared network, but when examining the file from the network management it does not show as 'in use' by any user including myself.
This program has been running for several years and there have been no changes to the IT infrastructure. Problem only exists for my PC.
Issue:
• When I open an existing project and make NO changes to it and run the program via debug or release and run the exe everything works fine
• As soon as I make ANY change to the source code (including something as simple as adding a comment character), it will throw an exception which I have at the very end of this post.
• The exception being thrown is tricky because it is most definitely not related to disposal of the stream (from a source code perspective). See Item A below
• When I try to modify or delete the text file through windows explorer it gives me a "file in use" message. When I use another PC to try to delete this file, it works without saying "file in use".
• As far as I suspect, there is something going on with a very deep level aspect of the compiler.
• To be clear, this is the issue: Run the program (creates a text file), no issue there. Then I wait, run the program again and then it crashes when trying to load that same text file. When I look at the text file through windows explorer it is 'in use'.
What I have tried:
A) I have tried both methods of disposing streamwriter and streamreader... stream.Close() method as well as using stream Using ... End Using method. See code snippets below.
B) I have used a colleagues PC to run the exact same source project via debug as well as a released exe, and it causes NO issues.
C) I have tried using processMonitor and processExplorer to search for the text file to find a related process or .dll that is causing the hold up. It never shows up in process dumps.
D) Disabling antivirus
**E) Running on another PC. This works.
F) Compiling exe on another PC then running from my PC **Get same Error
G) Repair and re-install of VS
H) safe mode
I have read through hundreds of forum posts and tried almost every suggestion. If you have any ideas and can help me I would much appreciate it, you would be an absolute legend if you were able to figure this out.
Code:
Method 1
Dim filewriter As System.IO.StreamWriter
filewriter = My.Computer.FileSystem.OpenTextFileWriter(dirNewENC & newfile, True)
filewriter.WriteLine("shortcutCreated=" & shortcutCreated)
filewriter.WriteLine("shortcutPath=" & shortcutPath)
...
filewriter.Close()
Method 2
Using filewriter = My.Computer.FileSystem.OpenTextFileWriter(dirNewENC & newfile, True)
filewriter.WriteLine("shortcutCreated=" & shortcutCreated)
filewriter.WriteLine("shortcutPath=" & shortcutPath)
...
End Using
Exception Detail:
System.IO.IOException
HResult=0x80070020
Message=The process cannot access the file '\affs01\Shared\Sales\Quotes\ENC\TEST8%01%TEST%Q99999998%44456%.enc' because it is being used by another process.
Source=mscorlib
StackTrace:
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
at System.IO.StreamReader..ctor(String path, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize, Boolean checkHost)
at System.IO.StreamReader..ctor(String path, Encoding encoding, Boolean detectEncodingFromByteOrderMarks)
at Microsoft.VisualBasic.FileIO.FileSystem.OpenTextFileReader(String file, Encoding encoding)
at Microsoft.VisualBasic.MyServices.FileSystemProxy.OpenTextFileReader(String file)
at Order_Entry.GlobalSubs.checkOrderType() in C:\Users\RB\OneDrive\Code\repos\Order Entry\Order Entry\GlobalSubs.vb:line 6348
at Order_Entry.frm_NewEntry.btn_searchQuote_Click(Object sender, EventArgs e) in C:\Users\RB\OneDrive\Code\repos\Order Entry\Order Entry\frm_NewEntry.vb:line 152
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.PerformClick()
at System.Windows.Forms.Form.ProcessDialogKey(Keys keyData)
at System.Windows.Forms.Control.ProcessDialogKey(Keys keyData)
at System.Windows.Forms.TextBoxBase.ProcessDialogKey(Keys keyData)
at System.Windows.Forms.Control.PreProcessMessage(Message& msg)
at System.Windows.Forms.Control.PreProcessControlMessageInternal(Control target, Message& msg)
at System.Windows.Forms.Application.ThreadContext.PreTranslateMessage(MSG& msg)
at System.Windows.Forms.Application.ThreadContext.System.Windows.Forms.UnsafeNativeMethods.IMsoComponent.FPreTranslateMessage(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
at Order_Entry.My.MyApplication.Main(String[] Args) in :line 83
Along with #Andrew Morton and #Hursey mentioned, I bit the bullet and wiped the PC with a clean reinstall.
Can happily (in one sense) report that the issue is resolved.
Thank you.
...now to get all my apps back.
Here's my full concept:
I want to be able to search the entire C:\ & D:\ to see if a certain file exists on the drive - not edit/delete/create, I just want to know if it exists or not.
Example:
I want to be able to scan the entire D:\ to see if "Testing321.exe" exists on the drive. The problem I have is I'm able to scan something like "C:\Users\Dan\Desktop" but I'm unable to scan "C:" because I'm given an error related to insufficient permissions even though I have given the program full administrator permissions in the Manifest.
Error:
Unhandled exception. System.UnauthorizedAccessException: Access to the
path 'C:\Documents and Settings' is denied. at
System.IO.Enumeration.FileSystemEnumerator1.CreateRelativeDirectoryHandle(ReadOnlySpan1
relativePath, String fullPath) at
System.IO.Enumeration.FileSystemEnumerator1.MoveNext() at System.Collections.Generic.LargeArrayBuilder1.AddRange(IEnumerable1 items) at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable1
source) at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1
source) at System.IO.Directory.GetFiles(String path, String
searchPattern, SearchOption searchOption) at
Alpha.Program.Main(String[] args) in
C:\AlphaSS\Alpha\Alpha\Program.vb:line 80
Code:
Dim Path As String
Console.WriteLine("Enter Directory to search [Phantom DLL]: ")
Path = Console.ReadLine()
Dim FolderPath = Path
For Each filePath In Directory.GetFiles(FolderPath,
"RXEXV2.dll",
SearchOption.AllDirectories)
If filePath IsNot Nothing Then
Console.WriteLine("DETECTED: Phantom Menu DLL Found: " & filePath)
Else
Console.WriteLine("Nothing Detected")
End If
This code above is essentially an idea I have in mind which will scan a player's computer for certain (cheat) files and if those files are found it will output it back to the console.
If anyone has a solution to this, please let me know!
Right now I'm trying to code a tool that shall be capable of downloading a file from a specific website, beside some other stuff.
My current solution is, that I open the website from where the file shall be downloaded in Internet Explorer, wait some seconds so the website can be loaded and then send a keystroke to Internet Explorer, which is ALT+S, to save the file to the standard download location.
However, my code fails in the line where the keystroke should be sent.
You'll find it below of course plus the error it throws.
Some facts I believe you'll find useful to know:
My application shall be a console app, no forms app
I'm using the Internet Explorer for this so that I can be sure the application works for every Windows PC
I expect the Internet Explorer to have the default configuration for downloading files to be set to "User prompt", i.e. it's asking wether the file shall be openend or saved
The website, as you'll see in the code below, is a third-party website, so I don't have direct access to the files being hosted on the server
What I specifically like to know is:
Can I solve this problem somehow smarter? Are there other, perhaps easier ways, to download a file than what I did?
How can I make my application wait for the website to be loaded or even wait for the "Open - Save - Cancel" prompt to show up?
How do I get the "SendKeys" part to work correctly?
And most important: Please note that I'm a hobby programmer and just started with VB a few weeks ago. If I missed out some important information or my code looks weird, well, then that's why :)
Sub Download()
Dim IE As Object
IE = CreateObject("InternetExplorer.Application")
Console.WriteLine("Start Download")
IE.Navigate("https://toolslib.net/downloads/finish/1-adwcleaner/") 'Opens the website in Internet Explorer
Do 'Waits for Internet Explorer to be launched before going on
If CBool(Process.GetProcesses.Where(Function(P As Process) _
P.ProcessName = "iexplore").Count) Then
Exit Do
End If
Threading.Thread.Sleep(100)
Loop
IE.Visible = True
Threading.Thread.Sleep(5000) 'Some time for the website to load
IE.SendKeys("%{S}", True)
End Sub
When running this code it throws the following error.
Note: Line 67 is the line where IE.SendKeys("%{S}", True) stands.
Unhandled Exception: System.ArgumentException: The process {0} wasn't found.
at Microsoft.VisualBasic.CompilerServices.Symbols.Container.InvokeMethod(Method TargetProcedure, Object[] Arguments, Boolean[] CopyBack, BindingFlags Flags)
at Microsoft.VisualBasic.CompilerServices.NewLateBinding.CallMethod(Container BaseReference, String MethodName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack, BindingFlags InvocationFlags, Boolean ReportErrors, ResolutionFailure& Failure)
at Microsoft.VisualBasic.CompilerServices.NewLateBinding.ObjectLateCall(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack, Boolean IgnoreReturn)
bei Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateCall(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack, Boolean IgnoreReturn)
at MyApp.Module1.Download() in C:\Users\User\Documents\Visual Studio 2017\Projects\MyApp\MyApp\Module1.vb:Line 67.
I used WebBrowser control in form application and its worked fine me!
SendKeys.Send("+{TAB}")
System.Threading.Thread.Sleep(1000)
SendKeys.Send("{ENTER}")
I'm writing a small program in Visual Basic 2008 that flips the values of specific DWORDs in a registry key
The registry key in question is:
'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render\{91801674-82d9-459a-9358-6e5cf3d81d21}\FxProperties'
The dword I'm manipulating is "{e0a941a0-88a2-4df5-8d6b-dd20bb06e8fb},4"
This is the line of code I wrote to set the DWORD's value is this:
Dim keyString = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render\{91801674-82d9-459a-9358-6e5cf3d81d21}\FxProperties"
My.Computer.Registry.SetValue(keyString, "{ad75efc0-8f48-4285-bfa8-40fb036cdab2},2", "00000000")
But I get a UnauthorizedAccessException at runtime stating that "Access to the registry key [KEY_NAME] is denied."
I ran the program with Administrator privileges, changed the app's manifest to include:
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
But that didn't work either. So I searched a few forums and tried this:
Dim rkLM As RegistryKey = Registry.LocalMachine
Dim pRegKey As RegistryKey = rkLM.OpenSubKey("\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render\{91801674-82d9-459a-9358-6e5cf3d81d21}\FxProperties", True)
pRegKey.SetValue("{ad75efc0-8f48-4285-bfa8-40fb036cdab2},2", "00000000")
But that threw a NullReferenceException at me stating "Object reference not set to an instance of an object."
Is there any way I can modify that that key without having to run my program with SYSTEM privileges?
You should probably try with requireAdministrator in your manifest because highestAvailable may not actually be an administrator.
I would also try specifying the data type (in your case I think it is binary):
My.Computer.Registry.SetValue(keyString, _
"{ad75efc0-8f48-4285-bfa8-40fb036cdab2},2", _
"00000000", _
RegistryValueKind.Binary)
However the value you are setting may need to be a byte array (something else you could try)
Thanks Matt, I tried running it with requireAdministrator as well but that didn't help either. Anyway, I found the solution to this and it seems the problem lied with the permissions on the registry key that I was trying to modify.
Full Control access was only given to the TrustedInstaller group, so I granted Full Control to the users in the Administrators group as well.
I started 'regedit' with SYSTEM privileges using Sysinternals' PsExec tool
[psexec -si regedit] and navigated to the key I wished to manipulate using my program and used [Edit -> Permissions] to grant write access to myself.
After doing that, my code worked and this:
Dim keyString = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\" _
+ "MMDevices\Audio\Render\{91801674-82d9-459a-9358-6e5cf3d81d21}\FxProperties"
Dim regKey = "{ad75efc0-8f48-4285-bfa8-40fb036cdab2},2"
My.Computer.Registry.SetValue( _
keyString, regKey, "00000000", RegistryValueKind.DWord)
could successfully flip the value of the DWORD. Although this worked, I would like to know if there's a way to do this without having to manually change permissions on the registry subkey.
I found a similar problem and solution for this in C# given here but I couldn't successfully convert the C# code mentioned there to VB.NET code. Could you help with that?
Here is the vb.net code for the c# link referenced below. You will need to set a reference to System.Security.
Imports System.Security
Imports System.Security.Principal
Imports System.Security.AccessControl
Imports Microsoft.Win32
Private Sub TestMethod(ByVal subkey As String)
' Create access rule giving full control to the Administrator user.
Dim rs As New RegistrySecurity()
rs.AddAccessRule( New RegistryAccessRule( _
"Administrator", _
RegistryRights.FullControl, _
InheritanceFlags.ContainerInherit Or InheritanceFlags.ObjectInherit, _
PropagationFlags.InheritOnly, _
AccessControlType.Allow))
' Get the registry key desired with ChangePermissions Rights.
Dim rk As RegistryKey = Registry.LocalMachine.OpenSubKey( _
subkey, _
RegistryKeyPermissionCheck.ReadWriteSubTree, _
RegistryRights.ChangePermissions Or RegistryRights.ReadKey)
' Apply the new access rule to this Registry Key.
rk.SetAccessControl(rs)
' Get the registry key desired with ChangePermissions Rights.
rk = Registry.LocalMachine.OpenSubKey( _
subkey, _
RegistryKeyPermissionCheck.ReadWriteSubTree, _
RegistryRights.ChangePermissions Or RegistryRights.ReadKey)
' Apply the new access rule to this Registry Key.
rk.SetAccessControl(rs)
' Open the key again with full control.
rk = Registry.LocalMachine.OpenSubKey( _
subkey, _
RegistryKeyPermissionCheck.ReadWriteSubTree, _
RegistryRights.FullControl)
' Set the security's owner to be Administrator.
rs.SetOwner(New NTAccount("Administrator"))
' Set the key with the changed permission so Administrator is now owner.
rk.SetAccessControl(rs)
End Sub
I had this same problem, and setting requireAdministrator didn't help. Then I realized VS2010 never asked me to restart with Administrative rights. I closed and reopened VS2010, ran the program, and then it asked me to start with Administrative privileges. I'm used to changing to requireAdministrator and it asking me to restart at the next time I debug.
So, to clarify, requireAdministrator does help, but may require a manual restart of VS2010 (or just run VS2010 as Administrator).
I'm trying to protect a folder and the files inside it.
I'm able to protect the folder itself, so that if somebody clicks on it he will get a message:
"You don't currently have permission to access this folder!"
But I can still access files in that folder. For example, if somebody knows the name of a file inside the folder he can type D:\ProtectedFolder\pdffile.pdf and he can open the file!
So, my question is:
Can I protect single files inside the folder?
This is the function that I use for folder lock:
Public Function Lock(ByVal folder As
String, ByVal user As String)
Dim FilePath As String = folder
Dim fs As FileSystemSecurity = File.GetAccessControl(FilePath)
fs.AddAccessRule(New FileSystemAccessRule(user,
FileSystemRights.ListDirectory,
AccessControlType.Deny))
fs.AddAccessRule(New FileSystemAccessRule(user,
FileSystemRights.FullControl,
AccessControlType.Deny))
File.SetAccessControl(FilePath, fs)
Return 0
End Function
Thanks!
You will also have to deny FileSystemRights.Read if you want to prevent that. And technically you have to make sure that the files inherited their rights from the folder.
Specify FileShare.None for File.Open. You can see my C# implementation of it here with full source code. Convert it to VB.NET if you'd like.
This is the message you receive when trying to open a file locked by the application:
I think that's what you're after.