Visual Studio Moving a Content File on Publish - c#

I'm developing a Web application that uses a couple XML files to store data. I have their Build Action set to Content, and on install the files are copied successfully to the Applications Virtual Directory:
C:\inetpub\wwwroot\ApplicationName\
The problem I'm having is that writing to these XML files (in order to save settings and things like that) causes a lot of write permissions issues. Therefore to get around it, I'm trying to copy these files from the virtual directory they're installed to to a new directory under the C drive, using the following PostBuildEvent in the Web Deployment Project:
xcopy "$(TargetDir)*.xml" "C:\CompanyName\ApplicationName\" /y
However, this does nothing. I'm not sure if this is because PostBuildEvents in the installer are not actually fired on install, but only on building the installer, or if TargetDir represents the bin directory:
C:\inetpub\wwwroot\ApplicationName\bin\
instead of the root application virtual directory:
C:\inetpub\wwwroot\ApplicationName\
Does anyone have any ideas? Has anyone dealt with this sort of thing before? I'm really stumped on this one.
Update:
I included a PostBuildEvent that should give full permissions to all users:
icacls "$(TargetDir)" /grant Users:F
But it doesn't seem to have resolved the problem.
I'm also unsure where exactly $(TargetDir) if pointing to, if it would be ..\ApplicationName\ or ..\ApplicationName\bin\

All you have to do is give full permissions to the user under whose context the Web Application Pool runs.
You can find this user by starting IIS manager and look at the Application Pools and Identity column
Something like
cacls C:\inetpub\wwwroot\ApplicationName /G Users:F
will give all permissions to this subdirectory to all users on the computer, If you are running under ApplicationPoolIndentity refer here

Turns out there's a much easier way to do what I was trying to do.
Instead of using PostBuildEvents to create a new directory structure and move files there, I added the new directory structure into
InstallerProject > View > File System
after which I located the Content Files from SomeProject entry in my installer project, and changed the Folder value to the newly specified directory structure, in this case
C:\CompanyName\ApplicationName\
This seems to work fine, I'm now able to access these files freely as I originally intended.

Related

How could I move WebView2 folders to a different location?

Is there any possible way of moving the runtimes and *.exe.WebView2 folders created by the Microsoft WebView2 WPF package to a different folder or perhaps embedding them?
The 2 folders are selected in the screenshot below.
I already use Costura.Fody to embed dlls. The ideal result would be if those 2 folders would be moved to the bin folder.
You have to fix both folder issues separately
The *.exe.WebView2 is a cache folder created when you run the webview2 inside the application. The following is how to redirect the folder to where you want it it to go, I used Path.GetTempPath().
CoreWebView2Environment cwv2Environment = await CoreWebView2Environment.CreateAsync(null, Path.GetTempPath(), new CoreWebView2EnvironmentOptions());
await webBrowser.EnsureCoreWebView2Async(cwv2Environment);
Path.GetTempPath() will redirect to the users local app data temp so it would prevent permission issues on the servers and be easily maintained by infrastructure on growing hard drive space.
A current temp solution is move the runtimes folder to the home directory if that is where you want it and the second line deletes it. In Visual Studio go to the project properties -> Compile -> Build Events and in the Post-build event command line and added the following.
xcopy /y $(TargetDir)runtimes\win-x64\native\WebView2Loader.dll $(TargetDir)$(OutDir)
RD /S /Q "$(TargetDir)runtimes\"
The .\{ExecutableName}.WebView2 folder is the default location of the user data folder. This contains all state generated by the WebView2 (cookies, HTTP cache, indexeddb storage, and so on) and by default is placed in the same folder as the host app's executable. But you can (and should) specify a different path to store the user's WebView2 state. For more information about the user data folder and where to place it see the Manage user data folders doc.
The second folder .\runtimes contains the WebView2Loader.dll file in different CPU architectures. There's currently no way to specify the path to find this but that has been requested (GH issue) and is in our backlog.

Can I use C:\Program Files as the UNC path when publishing my project

I want to publish a c# project. I want to know if I can use C:\Program Files as the UNC path Or I must add my PC name like C:\mypcname\folder
I want to make sure it can be installed from another computer system.
I think, you have a big misunderstanding here. First of all, if you include a computername, you need to write it in the form \computername.
But what do you have in mind? Publishing my project? When you publish or install a project, you will never ever use absolute pathes like "C:\Program Files", but instead you will use variable names for system folders. You may check for Environment specialfolder enumeration to get an idea.
And - you should have in mind, that EVERY installer available today will properly do that job for you. Have a look at Innosetup. Or, make that question more clear.
If you are using the publish dialog, then you are deploying using ClickOnce. If you are distributing it, then typically you would be using FTP to publish it to a web server or something - if you choose a location on your hard drive, then that is just where the files will be placed; you would need to copy those files onto a flash drive and take it from computer to computer to deploy it.
C:\mypcname\folder is not a valid file path, so that one is out. C:\Program Files is probably not a very good option. A folder under "My Documents" would probably be better.
Either way, the option you choose has nothing to do with where the project will wind up on your users' computers once they "install" it... ClickOnce actually puts everything into the hidden AppData folder under the Users folder of the user. If you want the application to wind up in C:\Program Files, then ClickOnce is not the deployment technique you are looking for. Look into something like InstallShield instead.

ClickOnce not replacing App_Data files during re-install

I noticed a behavior I don't understand happening with my application's ClickOnce deployment: a database file (Main.accdb) that is marked as a data file isn't replaced in C:\Users\username\AppData\Roaming\AppName after re-installing or installing a newer version.
In the Project Properties > Publish > Application Files I have:
File Name App_Data\Main.accdb
Publish Status = Data File
Download Group = (Required)
Hash = Include
In the file properties I have:
Build Action = Content
Copy to Output Directory = Copy always
When I install my WPF application using ClickOnce the first time, the file is found in C:\Users\username\AppData\Roaming\AppName. However, if I uninstall, delete the file in that folder, and re-install it is not replaced. In fact, anything removed from that folder isn't replaced by re-installation.
I tried various options for the Publish Status but the same behavior happens regardless of which options I choose. I'm using WPF with C# in Visual Studio 2017.
Why is this happening and how can I make it so that the file is always there when the application installs (or even better, launches)?
It turns out that the App_Data folder behaves differently and the issue can be resolved by using a folder with any name except App_Data.
I can't find this documented anywhere except for a handful of forum posts of users with similar issues, however, I was able to verify that it all works exactly as expected once I changed the folder name.
All that being said, Microsoft does seem to want developers to use App_Data for databases, so perhaps this is an exception to the norm and may not be the right approach for most projects. In my case, it's a desktop application that needs to deploy a local Access database to the user's computer on install and keep it up to date/replaced during re-install and updates.

Defining where files are installed

I am trying to deploy a .NET application as a ClickOnce Application, but I am having trouble defining where the application is installed. I need to know this because I have to include support files. I have already added the support files as "existing items". I had assumed that the program would install in Program Files, but it does not exist there. Instead, there is just a shortcut on the desktop. Can someone explain how/where the install path is defined using VS2012?
One solution I found was to use some of the Application class properties to determine where ClicOnce installed an instance of my program. But be aware that some those are deleted on uninstall of the program.
// To get the path for the executable file that started the application, not including the executable name.
PATH_RESOURCES = Application.StartupPath ;
For persistant data I created references to specific paths like :
PATH_USERDATA = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + #"\myAppName\";
if (!System.IO.Directory.Exists((string)PATH_USERDATA))
{
System.IO.Directory.CreateDirectory((string)PATH_USERDATA);
}
PATH_REPORTS = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + #"\myAppName\";
if (!System.IO.Directory.Exists((string)PATH_REPORTS ))
{
System.IO.Directory.CreateDirectory((string)PATH_REPORTS );
}
Clickonce application gets installed under the user profile, not the Program Files path.
On windows Vista and Windows 7, clickonce application path will be somewhere in c:\users\username\AppData\Local\Apps\2.0\
On Windows XP, clickonce application path will be somewhere in c:\document and Settings\username\LocalSettings\Apps\2.0\
Note that Clickonce application path is different everytime upon installation, I found the best way is to make your app to write its own app path to the reg key, this way you know exactly where the app path is by looking at the reg.
So as user831062 pointed out, ClickOnce apps get installed under the user profile, not the Program Files path. Because of this, the install directory is different on every machine and almost impossible to access directly.
The part that I was hung-up on, was where are the files that I have included in the project located, and more importantly - how do I access them?
Well, as mentioned IN THIS LINK, if you mark the file as a "data file", under:
Project Properties > Publish > Application Files > Publish Status
you'll be able to access them using something like:
textBox = File.ReadAllLines(ApplicationDeployment.CurrentDeployment.DataDirectory + #"\myFile.txt")).ToList();
If you don't mark it as a "data file", but rather as just an "Include (Auto)", it will just be located in the install directory itself, which can be accessed by calling the file directly using something like:
textBox = File.ReadAllLines(#"myFile.txt")).ToList();
Anyway, took me an hour or so to find this, so hopefully it helps someone else out.
If you have added your files to your project, set the property for "build action" to "content" and set "copy to output directory" to "copy always". This way, the files will be included in your deployment. When the application is run, retrieve the location of the assembly and look in the same relative folder as where they were included in the project. For example, if they are in the top folder of the build output directory (/bin/debug/ or /bin/release/), they will be included in the same folder as the executable, which you can discover using this:
System.Reflection.Assembly.GetExecutingAssembly().Location

Working Directory in Visual Studio C# file

What exactly is Working Directory in the properties of Visual Studio C# project.
I have see a project where I right click and go to Properties and then I go to Debug tab, it shows me Working Directory where Author of the code has specified folder in local machine. I want to know what does that working directory means and what kinds of file will it store in that directory.
Thank you in advance.
Every process has a current Working Directory which is where all relative paths will be formed from. If not specified, this directory is the directory in which the active application started.
You can check which directory is set by calling:
System.IO.Directory.GetCurrentDirectory();
As mentioned above in a comment by #0xA3 this setting has no effect to your deployed product, it is is only for debugging.
The working directory of a project (and any Windows program in general) is the default place in which a program is looking up it's files. For example: My program has working directory C:\dir and tries to open test.txt, it would look in C:\dir\test.txt.
So every opened file will be opened relative to the working folder.
I think it will store nothing there, unless you add/write code in your application which explicitly creates files, either explicitly in the application's working directory, or implicitly specifying only a filename without specifying a directory at all.

Categories