Not able to get Application startup path on click on setup.exe - c#

I am publishing a Windows project and on click on form I am installing another setup to install.
I am not getting the current Application Startup Path on clickevent on button.
On debug and Release it is showing the right path but after publishing it is giving
C:\Users\username\AppData\Local\Apps\2.0 path
Already I have used :
Application.StartupPath
Application.Executablepath
Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location))
System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase))
Path.Combine(Directory.GetCurrentDirectory())
But of no use it always show
C:\Users\username\AppData\Local\Apps\2.0 path

You are getting that path because it's the one used by ClickOnce. ClickOnce applications are installed under the profile of the user who installed them.
Edit :
Method 1:
Here's a way to get the path where your application was installed from (works only if your application was installed) (parts of this were written by #codeConcussion) :
// productName is name you assigned to your app in the
// Project properties -> Publish -> Publish Settings
public static string GetInstalledFromDir(string productName)
{
using (var key = Registry.CurrentUser.OpenSubKey(#"Software\Microsoft\Windows\CurrentVersion\Uninstall"))
{
if (key != null)
{
var appKey = key.GetSubKeyNames().FirstOrDefault(x => GetValue(key, x, "DisplayName") == productName);
return appKey == null ? null : GetValue(key, appKey, "UrlUpdateInfo");
}
}
return null;
}
private static string GetValue(RegistryKey key, string app, string value)
{
using (var subKey = key.OpenSubKey(app))
{
if (subKey == null || !subKey.GetValueNames().Contains(value))
{
return null;
}
return subKey.GetValue(value).ToString();
}
}
Here's how to use it :
Uri uri = new Uri(GetInstalledFromDir("ProductName"));
MessageBox.Show(Path.GetDirectoryName(HttpUtility.UrlDecode(uri.AbsolutePath)));
Method 2 :
You can also try
System.Deployment.Application.ApplicationDeployment.CurrentDeployment.ActivationUri
But I think this one works only if your app was installed from the internet

try this:
Process.GetCurrentProcess().MainModule.FileName
BTW, is it ClickOnce deployment? If so then the directory you are getting looks about right.

Related

Cross-App Keychain Access, where to configure?

I am currently developing multiple cross-plattform apps which (under iOS) use some shared keychain entries. My current project started on android and after we had a working version I continued working on the iOS version. I imported our keychain access code from earlier projects to access our shared login-data. Only this time the queries always return SecStatusCode.ItemNotFound.
I compared the provisioning profile and the entitlements and all looks the same. After some time it drove me nuts and I created a new empty app with only the keychain-code, the same bundle identifier, provisioning profiles and entitlements file as the currently-not-working-app and it works just fine and returns my data.
To my question, where else are things to be configured, that could possibly interfere with my access to keychain entries besides entitlements.plist and provisioning profile? Since the project is somewhat bigger, I don't want to copy ALL code to fresh project. I tried both Visual Studio 2017 for Windows and VS for Mac 2019. It is an internal/enterprise app, it that is of any concern...
Keychain call:
KeyChain kc = new KeyChain("USER_DATA", "de.rlp.myCompany.Shared");
var data = kc.Find("LOGIN_DATA");
Keychain-Class:
public class KeyChain
{
public string ServiceName { get; set; }
public string GroupName { get; set; }
public KeyChain(string serviceName, string groupName = null)
{
ServiceName = serviceName;
GroupName = groupName;
}
public byte[] Find(string key)
{
SecStatusCode res;
var rec = PrepareDictionary(key);
var match = SecKeyChain.QueryAsRecord(rec, out res);
if (res == SecStatusCode.Success) // ItemNotFound return-code here
{
return match.ValueData.ToArray();
}
else
{
System.Diagnostics.Debug.Write(res.ToString());
}
return null;
}
private SecRecord PrepareDictionary(string key)
{
var sr = new SecRecord(SecKind.GenericPassword)
{
Service = this.ServiceName,
Generic = NSData.FromString (key),
Account = key,
Accessible = SecAccessible.AlwaysThisDeviceOnly
};
if (string.IsNullOrEmpty(GroupName))
{
sr.AccessGroup = GroupName;
}
return sr;
}
}
Entitlements-Entry
<key>keychain-access-groups</key>
<array>
<string>$(AppIdentifierPrefix)de.rlp.myCompany.Shared</string>
</array>
Have you added both your applications to the same App Group/ Keychain Group from entitlements and enabled it.
VS might be buggy. Just check entitlements for both the apps on apple developer site.
That might be the problem.
Documentation

From where clickonce get the value used in DisplayName from regedit?

From where the clickonce get the value used in DisplayName in the register HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\XXXXXXXX ? I tried the change the application title and assembly name on VS(project -> properties -> application -> assembly information) but this neither change there changed the name used in DisplayName value.
I need this because I want to avoid hard-code my application name on this piece of code that change the unistall icon of my application on add/remove programs
RegistryKey myUninstallKey = Registry.CurrentUser.OpenSubKey(#"Software\Microsoft\Windows\CurrentVersion\Uninstall");
string[] mySubKeyNames = myUninstallKey.GetSubKeyNames();
for (int i = 0; i < mySubKeyNames.Length; i++)
{
RegistryKey myKey = myUninstallKey.OpenSubKey(mySubKeyNames[i], true);
object myValue = myKey.GetValue("DisplayName");
if (myValue != null && myValue.ToString() == applictionName) /* this must be the same used by clickonce to set DisplayName value */
{
myKey.SetValue("DisplayIcon", iconSourcePath);
break;
}
}
From where clickonce get the value used in DisplayName from regedit?
To set the display name for a ClickOnce app, you specify it in Publish Options inside Visual Studio prior to publishing. This updates the ClickOnce Manifest - information about the ClickOnce application. This information is more important and essentially veteos any details you may specify in Assembly Information.
<project>.Properties.Publish.Options
Also, there is no need to muck about in the Windows Registry for ClickOnce apps. Doing so may block automatic updates.
object myValue = myKey.GetValue("UrlUpdateInfo");
if(myValue != null)
{
string updateinfo = myValue.ToString();
string updateLocation = ApplicationDeployment.CurrentDeployment.UpdateLocation.ToString();
if (updateinfo==updateLocation)
{
myKey.SetValue("DisplayIcon", iconSourcePath);
break;
}
}

Files that are upload does not show up in the Project solution(Mvc5)

I have implement the following code to upload a file. The file is upload to the location ("../App_Data/uploads") but it does not show up in the project. I have to include the file manually in the project. Why is the file not showing up?
public ActionResult ChangeSetting(SettingViewModel setting)
{
string userId = User.Identity.GetUserId();
ApplicationUser currentUser = this._appUserRepo.Find(e => e.Id.Equals(userId)).FirstOrDefault();
if (setting.PictureUrl != null)
{
if (setting.PictureUrl.ContentLength > 0)
{
string fileName = Path.GetFileName(setting.PictureUrl.FileName);
if (fileName != null)
{
string path = Path.Combine(Server.MapPath("../App_Data/uploads"), fileName);
setting.PictureUrl.SaveAs(path);
if (currentUser != null)
{
currentUser.PictureUrl = path;
currentUser.PictureSmalUrl = path;
currentUser.PictureBigUrl = path;
}
}
}
}
if (setting.FirstName != null)
{
if (currentUser != null) currentUser.FirstName = setting.FirstName;
}
_appUserRepo.Update(currentUser);
return RedirectToAction("index", "Admin");
}
Why is the file not showing up?
Because that's how Visual Studio projects work - only files that you manually include into the project are shown in the solution explorer. Files that get added dynamically to folders afterwards by eternal processes do not show up in Visual Studio (unless you manually include them and make them part of the solution). But that's probably not something you should be worried about. The files uploaded by users won't automagically appear in your Visual Studio project. The important thing is that they are present at the expected location and that your web application is capable of accessing them at runtime. Just open the physical location of the folder in Windows Explorer to confirm that your code is working as expected.

using winform to pass installation path from winform to custom action

i am trying to create custom windows installer using windows forms.
how to create custom action which can accept installation path from windows form for installation.
i am trying to assign value from windows form to this.Context.Parameters["targetdir"] but the application is installing at default path i.e. C:\Program Files (x86)\Microsoft\Setup1.
public override void Install(IDictionary savedState)
{
base.Install(savedState);
const string key_path = "SOFTWARE\\VendorName\\MyAppName";
const string key_value_name = "InstallationDirectory";
RegistryKey key = Registry.LocalMachine.OpenSubKey(key_path, RegistryKeyPermissionCheck.ReadWriteSubTree);
if (key == null)
{
key = Registry.LocalMachine.CreateSubKey(key_path);
}
this.Context.Parameters["targetdir"] = default_installation_path;
string tgt_dir = this.Context.Parameters["targetdir"];
key.SetValue(key_value_name, tgt_dir);
}
please help me i am new to installer class.

Get file path from Visual Studio editor

I'm developing a Visual Studio Package, written in C#.
How do I get the full path of the active editor programatically?
When working macros you can use
DTE.ActiveDocument.Path + DTE.ActiveDocument.Name
to get the full path. Likely this is the same in C# when making VS packages?
This is how you get the full path of the focused (active) document in Visual Studio:
DTE dte = (DTE)GetService(typeof(DTE));
string document = dte.ActiveDocument.FullName;
I had a similar problem when developing ASP.NET Web Forms custom server controls.
In order to obtain a reference to the DTE object and create a virtual path to the directory of the file being edited I used the following code inside my custom server control file:
[Bindable(true)]
[Category("Behavior")]
[DefaultValue("")]
[Editor(typeof(System.Web.UI.Design.UrlEditor), typeof(System.Drawing.Design.UITypeEditor))]
public string Url
{
get
{
object urlObject = ViewState["Url"];
if (urlObject == null)
{
if (DesignMode)
{
// Get a reference to the Visual Studio IDE
EnvDTE.DTE dte = this.Site.GetService(typeof(EnvDTE.DTE)) as EnvDTE.DTE;
// Interface for accessing the web application in VS
IWebApplication webApplication = (IWebApplication)this.Site.GetService(typeof(IWebApplication));
// Path of document being edited (Web form in web application)
string activeDocumentPath = dte.ActiveDocument.Path;
// Physical path to the web application root
string projectPath = webApplication.RootProjectItem.PhysicalPath;
// Create virtal path
string relativePath = activeDocumentPath.Replace(projectPath, "~\\");
return relativePath.Replace('\\','/');
}
else
{
return String.Empty;
}
}
else
{
return (string)urlObject;
}
}
set
{
ViewState["Url"] = value;
}
}
This is useful quickly navigating to a file near the one being edited when using the UrlEditor
In VS 2010 and 2008, you right click the tab at the top and select "Copy Full Path" from the context menu. See my image below.

Categories