Test for File Blocked, Un-block it - vb.net

I have a VB.NET executable that I distribute via a ZIP file (along with other supporting files). When the ZIP is downloaded my instructions call for the file properties to be checked and un-blocked if needed. This really only applies to the executable in it, it is just easier to have the user un-block the ZIP file.
A large part of the time this instruction is not followed and I have to work with them to get it taken care of. There is another executable in the ZIP that copies files to where they belong and does some other work.
Can this application check if the main executable is blocked? If so, can it unblock it programmatically?

Related

How to overwrite Files for Update Procedure

I'm trying to create an updater for my app in VB.NET, No, I do not want to use clickonce, it sucks because I have to deal with managing self signed certs etc.
I know the code to check for new update files:
http://pastebin.com/ZjYBWABu
I also know the code for specifying where those files download to, the issue is I dont want to just download 1 .exe...I want to download all the latest build files which I would have uploaded to my server, which i would have taken from my Bin\release folder of my project.
Then when the updater downloads the files to a directory, it would go to the directory of the application, and somehow overwrite/replace all the files that have changed...maybe by using a hash or something?
I do not know how to proceed with this. What I do know is this.
The updater and the main app would have to be separate so that the updater could do the replacing while the app is closed so it doesn't get file in use errors. After the updater app has finished it would then start up the main app from the new exe.
Would appreciate help here thank you guys.
I am currently working on a project for which I have to implement a similar approach for updates. The project is lengthy, it would take some time to finish. But this is how I have planned to apply the updates:
There will be two main parts of the application Launcher (main application program) and Updater (To download files from server and replace them with the new ones and then launch the new file)
The application will have the option to manually check for update and also to check for update on startup.
If an update is available, it asks the user to apply the update now or later.
If the user selects to apply the update now then Updater application is executed in a separate process and then Launcher application is closed from within the code in Launcher. I have following approaches in my mind to launch another program from within first one and then exit:
Execute the Updater directly from within the Launcher using Process.Start
If that causes problem then as second approach launch command prompt from Process.Start, execute another program (Updater) from command prompt, close the command prompt and then exit the Launcher.
The Updater application then downloads all the relevant files from the server and upon completion old application files are replaced with the new ones.
Update availability information from server will include the new Version_No of application. For the purpose of providing all files for update, I will compress (zip) all of them in a single file named as Application.Version_No (as given by the server).
Upon download completion decompress (unzip) them to a folder named as the same Application.Version_No.
After decompressing all the files in this (Application.Version_No) folder will be copied to the Bin folder of application.
The new application Launcher file is executed in a separate process and Updater application is closed from within the code in Updater.
I have NOT yet tried this scenario as currently my focus is on completing the main application, but surely this must work.
UPDATE:
Another approach to check for updates is to use a bootstrap like application startup. It will be the main entry point of the program. Upon execution it will check for the updates and if there is none the Launcher is executed otherwise it will download the files, replace the old ones and then execute the new / updated Launcher.
For copying / overriding the files
One approach is to include only those files in the compressed (zip) file which are required to be replaced with the old ones and then after the download completes, either directly decompress them to the Bin folder or decompress them to a designated folder and then copy all of them to the Bin folder.
As another approach which seems somewhat lengthy, an additional helper file (XML, text or any other format) could be prepared for the download.
This helper file contains information of updated files like version number of each file, location where these are to be copied etc.
The files may be downloaded to a specific folder named as the new application version.
After downloading all the required files to a specific folder process each file mentioned in the helper file. Compare version of every old file with the new downloaded file. If it is latest then replace it in the folder mentioned in the helper file.
As another step in between all the downloads may be verified prior to copying and replacing.
Built an updater that ships with a daemon. Main project here:
https://github.com/UVLabs/dotNetUpdatify
There should be a way to eliminate the use of the daemon, if i figure it out i will update.

Is there a possible way to open a file in visual basic by just putting the name of the drive?

Recently I made an application that has lots of PDF files in it and I made a setup for it using Inno Setup Compiler. In the setup, I allowed people to change where they want to install the app. For opening my PDF files, I used: system.diagnostics.process.start("My pdf.pdf")
My problem is that in the code above, I put drive "C:" and when my user changed the install directory to drive "D:" the pdf's did not work and the error showed that "Cannot find the specific file". My question is that is there a way to just put the name of "computer" or "a drive" in the code above, not the specific name of the pdf, and let the computer find the file itself?
You seem to be asking for an opposite of what you actually want to achieve.
I assume you are installing files with known names. What you do not know is the directory of the files.
From your description I assume that your actual code is like:
System.Diagnostics.Process.Start("C:\My pdf.pdf")
But when the user chooses a different location (directory) for your application, the above code with a hard-coded absolute path fails.
If your application installs to the same directory as the PDFs, just use a relative path (in this case just a file name without any path). It makes an operating system look to the current working directory, which will typically be an application directory.
System.Diagnostics.Process.Start("My pdf.pdf")
Or to make it more reliable, make it explicitly look to the application directory. For that use Application.StartupPath:
System.Diagnostics.Process.Start(
System.IO.Path.Combine(System.Windows.Forms.Application.StartupPath, "My pdf.pdf"))
See also Get program path in VB.NET?

Why does unzipping an exe file programmatically sometimes fail?

We supply upgrades as zip files.
One of the files included in the Zip file is TeamViewerQS_en.exe, which we supply as a purchased, branded component, that lives in our application's Programs Folder.
The unzipping is done by calling PKZIPC.exe programmatically from a VB.NET class which starts up PKZIPC.exe as a new process with suitable arguments.
At a small minority of our 25 or so customers, the upgrade works perfectly apart from the copy of the TeamViewer component - the application's EXE and all its DLLs are replaced correctly, but the TeamViewer executable is missing. The only difference I can see is that the application EXE and DLLs were part of the original .MSI install.
It works fine in most environments, so it's not as if we've inadvertently omitted the component from the ZIP (which I've checked several times!)
Is there a Windows setting somewhere that would somehow prevent the TeamViewer executable being copied in?
The failure also occurs, if the logged in user is a local admin.

jars, external properties, and external file io

I checked quite a few similar questions, but so far I am unsatisfied with the solutions.
Ever use the Minecraft Server? At initial launch, it creates all the files and folders it needs, and allows you to make changes to files like Server.properties and ops.txt by making them external of the executable jar file.
I'm working on a similar project, and I want to duplicate that behavior. Everything works great when I run it in eclipse. When I export to a jar file though, things get funky. The external files and folders are created without a hitch, but afterword, it would appear as though they cannot be read from or written to. Any ideas how Notch made his server?
--edit--
Scratch that, it doesn't even appear to reliably create the files and folders. Maybe it only creates them the very first run after creation?
--edit again--
It creates them in the root directory. When I tested it in eclipse, the root directory was limited to the folder containing the project, and therefore looked fine. The solution was to make the class aware of it's location, and include it in all file operations.
Have the main class in your executable jar file look up where it is, then have it store that information in a global String or something. Prefix your filenames with that string in your file operations, and voila! It's writing to the correct directory.

Working Directory in Objective-C and Xcode: debug mode vs. executable

I am writing a program in Objective-C using Xcode. My program creates a file as follows:
[#"" writeToFile:fileName atomically:YES encoding:NSUTF8StringEncoding error:NULL];
I would like the file to be created in the same directory as the executable. When I run the program from Xcode, the file is created in the debug directory as expected.
However, when I run the .app file, the file is created in the root directory. How can I get the program to create a file in the directory where the .app file is located.
Thanks a lot.
EDIT: This is a MacOS application
EDIT2: Well, it seems that I shouldn't be writing to the .app directory. Thanks bbum and Paul R. What is the proper way to do it? To be more concrete, here's what I am doing: each time the user clicks a button in the application, a piece of hardware connected to a serial port will send a bunch data which will be written to a new file. This can happen any number of times while the application is running, so numerous files may be created. I would like them all created in the same folder.
You must never make any assumptions about the initial working directory for your application, as this will depend on what method was used to launch it (e.g. Finder, Terminal (via open), Xcode, gdb, third party utility, etc). You should use an appropriate API to find a suitable directory to store temporary files or user-specific files or whatever it is you need to do. This should never be within the app's bundle and never at a path that is relative to the initial working directory.
You do not want the file to be created inside the .app wrapper. That is never the right answer; your application may easily be installed somewhere where the current user does not have write access to the YourApp.app wrapper.
(For example, my main user account is non-admin and all applications are installed admin-write-only. If an app ever fails to work because it can't write to its app wrapper, the app goes in the trash.)
See this question for an outline of where files should be stored. Depends on the role of the file.