Okay first off this is NOT 'how do I find my local location of the click once app.' I know you can go Task Manager>Active Processes>(Find your click once app)>Open File Location. This is more on how do I know if I have four versions of a click once app for deployemnt of (Dev, QA, UAT, and PROD) how do I know which one has which remote install setup?
EG: So when you deploy a click once you choose a path in VS. Once you set up the path the user can go to the UNC path and then get their own local click once app, yay. What happens when this gets junked up? I just want to know simply:
How does the click once app reveal to me the local of the remote target in a place I can reference once the app is deployed?
Like a key pair list or something where I can see:
(Program DEV) | \\Devmachine\installs
(Program QA) | \\QAmachine\installs
From what I can tell from searching this is not as easy as it sounds to get. I am up for coding some C# .NET, some command line inputs, or some Windows commands to get to this information. I just cannot believe something like a target install folder is this hard to get when it is a REQUIREMENT to publish. The user basically uninstalled the program and naturally it did not remove the Click Once stuff at:
C:\Users\(username)\AppData\Local\Apps\2.0\LKE4469P.GDW\X7EMR5P8.B1Z\
I can find the similar named app folders but their naming does not match up to the manifests. And even when I look in manifests it appears the info is not there either unless it is in a masked form to decode.
The ApplicationDeployment.UpdateLocation property gives you the value for the remote location. It can be used like this:
// In any class
public static string GetDeploymentPath()
{
return ApplicationDeployment.IsNetworkDeployed
? ApplicationDeployment.CurrentDeployment.UpdateLocation
: String.Empty; // Debug mode
}
Related
I am having a strange problem that I am unable to access files written by my c# application. My app basically does :
var file = "C:\\Users\\Public\\Documents\\something.txt";
List<string> content = new List<string> { "one thing", "two things" };
Console.WriteLine(System.IO.File.Exists(file));
System.IO.File.WriteAllLines(file, content);
Console.WriteLine(System.IO.File.Exists(file));
The first time I run the app, the output is
False
True
Yet I cannot see the written file in Windows Explorer (Windows 10). I get no exceptions attempting to write the file. The second time I run the app, the output is :
True
True
According to my application the file is being written however Windows thinks differently. As a sanity check I spun up a second app that opens a dialog using OpenFileDialog. When I run that, I am able to see my written files! Windows explorer still cannot. Attached is a screenshot of windows explorer and my openfiledialog side by side.
If I go to notepad and browse for the file I cannot see it or manually type in the name.
Its been a long week of work, there must be some dumb explanation...? Help! :-)
Screenshot - windows explorer on left, c# app open dialog on right :
https://imgur.com/a/8ZTDIe6
per #BACON 's suggestion in the comments above I discovered that after disabling the Comodo anti-virus I am able to write and see my files.
I believe the software is running my app or either only allowing IO from my app in some kind of container. I need to figure out how to grant my apps proper permissions through the anti-virus software, but that was the culprit.
I am developing a Windows Phone 8 application but am having a lot of issues with file access permission exceptions hindering the approval of my application when ever I try accessing files in the "local" folder (this only happens after the application has been signed by the WP store, not when deployed from Visual Studio). To solve this I have moved all file operations to IsolatedStorage and this seems to have fixed the problems.
I only have one problem left though. My application needs to make use of the file extension system to open external files and this seems to involve the file first being copied to the local folder where after I can then manually copy it into IsolatedStorage. I have no problem in implementing this but it seems that a file access permission exception also occurs once the system tries to copy the external file into the local folder.
The only way I think this can be solved is if I can direct the system to directly copy into IsolatedStorage but I cannot figure how to do this or if it is even possible. It seems as if though the SharedStorageAccessManager can only copy into a StorageFolder instance but I have no idea how to create one that is directed into IsolatedStorage, any ideas?
PS. Do you think that the Microsoft system might be signing my application with some incompetent certificate or something because there is not a hint of trouble when I deploy the application from Visual Studio, it only happens when Microsoft tests it or when I install it from the store using the Beta submission method.
Below is a screenshot of the catched exception being displayed in a messagebox upon trying to open a file from an email:
EDIT:
Just to make it even clearer, I do NOT need assistance in figuring out the normal practice of using a deep link uri to copy an external file into my application directory. I need help in either copying it directly into isolatedstorage or resolving the file access exception.
Listening for a file launch
When your app is launched to handle a particular file type, a deep link URI is used to take the user to your app. Within the URI, the FileTypeAssociation string designates that the source of the URI is a file association and the fileToken parameter contains the file token.
For example, the following code shows a deep link URI from a file association.
/FileTypeAssociation?fileToken=89819279-4fe0-4531-9f57-d633f0949a19
Upon launch, map the incoming deep link URI to an app page that can handle the file
// Get the file token from the URI
// (This is easiest done from a UriMapper that you implement based on UriMapperBase)
// ...
// Get the file name.
string incomingFileName = SharedStorageAccessManager.GetSharedFileName(fileID);
// You will then use the file name you got to copy it into your local folder with
// See: http://msdn.microsoft.com/en-us/library/windowsphone/develop/windows.phone.storage.sharedaccess.sharedstorageaccessmanager.copysharedfileasync(v=vs.105).aspx
SharedStorageAccessManager.CopySharedFileAsync(...)
I've inline the information on how to do this from MSDN http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj206987(v=vs.105).aspx
Read that documentation and it should be clear how to use the APIs as well as how to setup your URI mapper.
Good luck :)
Ok I figured it out. The "install" directory is actually restricted access but for some reason the Visual Studio signing process leaves the app with enough permissions to access this folder. The correct procedure of determining a relative directory is not to use "Directory.GetCurrentDirectory()" but rather to use "ApplicationData.Current.LocalFolder". Hope this helps!
I'm working on a online only winform application which I deploy using ClickOnce feature it uploads through FTP to the server and the user executes it online through http.
As you may already know, the Online only feature doesn't place any icons on the desktop, so everytime it runs the user got to run the setup.exe file to do it.
My question is, if there is anyway I could actually create an icon that may point to the setup file or any workaround to make sure the user got an accesible and easy way to run the app without having to look for the setup file everytime?
Users may not know a lot about computers so it can be a hard task to navigate all the way to the downloaded file everytime, and I want to make it easier for them.
I know that if I do an offline/online app it will solve the problem, but I would like it to be online only.
Any ideas?
you can create desktop shortcut manually on the first app run, and point it to either to your app's url, or path to downloaded file (I guess, url will be safer in case user deletes the file). Code can look something like this (need adjusting to your URL):
void CheckForShortcut()
{
ApplicationDeployment ad = ApplicationDeployment.CurrentDeployment;
if (ad.IsFirstRun)
{
Assembly code = Assembly.GetExecutingAssembly();
string company = string.Empty;
string description = string.Empty;
if (Attribute.IsDefined(code, typeof(AssemblyCompanyAttribute)))
{
AssemblyCompanyAttribute ascompany = (AssemblyCompanyAttribute)Attribute.GetCustomAttribute(code,
typeof(AssemblyCompanyAttribute));
company = ascompany.Company;
}
if (Attribute.IsDefined(code, typeof(AssemblyDescriptionAttribute)))
{
AssemblyDescriptionAttribute asdescription = (AssemblyDescriptionAttribute)Attribute.GetCustomAttribute(code,
typeof(AssemblyDescriptionAttribute));
description = asdescription.Description;
}
if (company != string.Empty && description != string.Empty)
{
string desktopPath = string.Empty;
desktopPath = string.Concat(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
"\\", description, ".appref-ms");
string shortcutName = string.Empty;
shortcutName = string.Concat(Environment.GetFolderPath(Environment.SpecialFolder.Programs),
"\\", company, "\\", description, ".appref-ms");
System.IO.File.Copy(shortcutName, desktopPath, true);
}
}
}
credits to http://geekswithblogs.net/murraybgordon/archive/2006/10/04/93203.aspx
What is your reason for wanting an online only ClickOnce app? I always recommend offline unless your app is really an edge case.
There's very little difference between online and offline. All the same files are downloaded to the same location on the client. Offline apps add an entry to the 'Add/Remove Programs', a start menu shortcut, and an optional desktop shortcut (if you are targeting .NET 3.5+). The ability to uninstall through Add/Remove Programs is key. It makes supporting your application much easier when users have install problems.
Also, you mention users running the setup.exe every time. This is unnecessary. The setup.exe will contain your bootstrapped pre-requisites and then launch the app when it finishes. If the user has run the setup.exe once, they only need to click the link to the .application file. That will definitely speed up the app's start time. Also, in many cases the user has to have admin privileges to run the setup.exe; clicking the .application doesn't (assuming someone with admin privileges has already run the setup.exe).
In conclusion, there really isn't an answer here :). But...
Make absolutely sure your reasoning is sound for not doing an offline install instead.
After running the setup.exe once, direct users to click on the .application url (or the desktop shortcut if you switch to offline) instead of the setup.exe.
As far as I know, there is no reliable way for running online only ClickOnce application than creating shortcut to that setup.exe.
I've had a scout around some answers to similar questions but they haven't really helped me much.
I have an app, into which I've embedded some resources. At launch the app checks to see if the resources exist in the appdata folder and if not copies the template files from the embedded resources to the appdata folder before loading them and then using the ones in the appdata folder as the working copies.
I have a helper class which amongst other things returns the appdata and resources subfolder as follows:
class Folders
{
static public String GetUserFolder()
{
return Application.LocalUserAppDataPath;
}
static public String GetResourcesFolder()
{
// If the resources folder does not exist then create it
String userFolder = GetUserFolder();
String resourcesFolder = userFolder + "\\Resources";
if (!Directory.Exists(resourcesFolder))
{
Directory.CreateDirectory(resourcesFolder);
}
return resourcesFolder;
}
...
So my code calls the GetResourcesFolder method which returns the path (creating the folder in the process if it needs to) checks to see if the file exists and if it doesn't tries to write to it using something like:
String filename = Helpers.IO.Folders.GetResourcesFolder() + "\\data.dat";
FileStream outFile = System.IO.File.OpenWrite(filename);
So I've set the scene and this code is working on all the machines I had in the development office. However a couple of off site colleagues have complained it "crashes" on their machines - in each case an XP machine - but otherwise not a lot of useful information coming back from them - working on trying to get something more informative from them. I have XP machines in the office that it has worked on without problems.
After digging out some really old dev machines that were "archived" a while ago, I've managed to have a crash on two xp (sp2) machines also. On both occasions the crash seems to be related to write permissions and running the app using "Run As..." has resolved the problem and it executes correctly. However once the app has been successfully run once the app no longer crashes, even if I delete the files/folders it created from the appdata folder it will still create the successfully on subsequent executions even if I don't elevate permissions.
The problem I have is that I can now no longer repeat the crash on any dev machines available to me and I don't know how to go about putting the machine back into the state where I can.
Anybody got any ideas on what might be causing the problem, or how I may be able to return the machines to a "virgin" state to be able repeat the crash and help me track it down.
One course of action is to create a Virtual Machine of XP. You can save the state of the machine before install for testing. After your install just revert back to the previous state to test again. There are a few Vendors with free Virtual Machines:
http://www.microsoft.com/windows/virtual-pc/
https://www.virtualbox.org/
As too the related problem itself, I don't know a better way than to install VS on a virtual machine for testing purposes.
+1 to Erik's VM solutions for reporducing the issue.
For tracking down permissions issues consider using ProcMon ( http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx ) - will show enverything you ever wanted (and not :) ) about file/regisstry access made by a process. I'd recommend trying it several times first on machine where you program works fine to get filtering setup for your process and get a sense of what should be happening.
I am trying to make an Outlook 2003 add-in using Visual Studio 2008 on Windows XP SP3 and Internet Explorer 7.
My add-in is using custom Folder Home Page which displays my custom form, which wraps Outlook View Control.
I get COM Exception with 'Exception from HRESULT: 0xXXXXXXXX' description every time when I try to set Folder property of the OVC. Error code is a random number, every time is different. It is not the first access to control's properties, before that, View and ViewXML properties are set already. Control is marked as Safe for Scripting.
I am using value of the CurrentFolder.FolderPath property of the active explorer, which seems to be a right one:
Outlook.Explorer currentExplorer = app.ActiveExplorer();
if (currentExplorer != null)
{
ovcWrapper.Folder = currentExplorer.CurrentFolder.FolderPath;
}
This is top of the stack trace:
System.Runtime.InteropServices.COMException (0xXXXXXXXX): Exception from HRESULT: 0xXXXXXXXX
at Microsoft.Office.Interop.OutlookViewCtl.ViewCtlClass.set_Folder(String pVal)
at AxMicrosoft.Office.Interop.OutlookViewCtl.AxViewCtl.set_Folder(String value)..
This is happening only if the folder is located in non-default PST file. Changing to folder inside default PST file will produce no exception.
I must underline that everything worked just fine before I went to holiday :). It seems that Windows XP installed some updates which changed default security of Internet Explorer or Outlook 2003 while I was absent.
On the other (virtual machine) with Office 2007 and Internet Explorer 6, without any updates, everything is working just fine.
After a while, I finally find out what is the solution: change a name of the external storage to something new.
During startup of the addin, it loads the non-default PST file, and changes its name (not the name of the pst file, but the name of the root folder) to "Documents".
This is code:
session.AddStore("C:\\test.pst"); // loads existing or creates a new one, if there is none.
storage = session.Folders.GetLast(); // grabs root folder of the new fileStorage.
if (storage.Name != storageName) // if fileStorage is brand new, it has default name.
{
storage.Name = "Documents";
session.RemoveStore(storage); // to apply new fileStorage name, it have to be removed and added again.
session.AddStore(storagePath);
}
Solution is not to use 'Documents' as a name any more, but something new. Problem is not related to specific name.
Dobri Dan, nency :)I don't know if I can really offer a "silver bullet" solution given the information here...but here are a few ideas/notes to try out:Having worked with Outlook on a few projects in the past, I can tell you that it is a funny bird sometimes when it comes to giving/granting access to outside users/processes. It sometimes requires the user to manually confirm access or log in...so make certain that you have
app.Session.Logon()
taken care of somewhere.The other thing I notice is the use of app.ActiveExplorer() Make certain that this function is returning exactly what you think it is; It takes the topmost window on the user's desktop...which is usualyy but not always the window you are trying to work with, so just doublecheck.