I am trying to write a custom installer for my application. I am making this installer using C#. One of the features of this is adding my app's directory to PATH.
However, when I do this, I have to reboot my computer to be able to access the updated PATH variable. When using a setup scripting tool like Inno setup, I can set it to somehow reload the environment to access the updated PATH immediately without having to reboot. How can I replicate this behaviour using C#?
I am sorry if this is a duplicate question but I am unable to find anything on this.
It turns out that I was trying to modify the registry. You can access it immediately by using System.Environment
var name = "PATH";
var scope = EnvironmentVariableTarget.User; // or User
var oldValue = Environment.GetEnvironmentVariable(name, scope);
var newValue = oldValue + #";C:\Path\To\Add";
Changing the PATH variable in Windows should not require a reboot. A simple solution is to add the directory containing your executable and any folder it uses to your PATH variable. For example:
System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86).ToString() + ""
ather for Program Files (x86) on " + System.Environment.OSVersion.Name
Related
I'm working for a client that has given me access to two specific folders and their subfolders only. The first one used to be our previous working space and now we will switch to the second one.
When I connect to the SFTP using the WinSCP GUI it connects me to the old folder. However, I can change that by clicking on settings and adding the “new” path in the remote path field. The session will then take me to the new default folder/workspace automatically when I connect.
My question is how can I do this using .NET and the respective winscpnet library?
The problem is the root directory of the session is different to remote path.
Example :
Session directory is /C/Document/.
Remote path is /C/Inetpub/ftproot/username/
When I used the following command on terminal:
winscp.com> open sftp://someone:password;fingerprint=something#ipaddress/C/Inetpub/ftproot/username
winscp.com> put some.txt /in
winscp.com> exit
it works fine! Because as we can see, my session directory is /C/Inetpub/ftproot/username/.
Is there a way to set session root path in C#?
Solved: you are right it is a virtual path so /c/Inetpub instead of c/Inetpub
WinSCP .NET assembly does not use the concept of a working directory. It always uses absolute paths.
So if you have your GUI session configured to start in /new/path, use that as an absolute path in WinSCP .NET assembly.
session.PutFiles(#"c:\local\path\*", "/new/path/", false, transferOptions);
the modern way of doing things would be, using Renci.SshNet.
Dont forget to use regular slashes and to quit your session after things are done.
you can create your Session with:
var connectionInfo = new Renci.SshNet.ConnectionInfo(host, username, new PasswordAuthenticationMethod(username, password));
using (var sftp = new SftpClient(connectionInfo))
{
sftp.Connect();
sftp.ChangeDirectory("..");
sftp.ChangeDirectory("C:\Inetpub\ftproot\username\");
}
sftp.Disconnect();
i have developed an application in a .mdb access file with tables linked to sql server
i try toput the mdb file in folder shared to all user but simultaneus access break the file very often.
so iam trying to deploy the .mdb file to every client machine and keep it update. i have created a winform app that check mdb file version and copy it to a local folder and next opens the local copy
but even in this way i have problem if too many user uses the winform launcher appat same time
so iam thinking if there is a bettere and simpler way:
can i use clickonce to deploy directly the access file and create a silly webform to launch it?
i have created the webform but how can i add the mdb file to deploy process? i have to add it to resources? and in that case embedded or not?
and in that case how clickonce detect that the access is a modified one?
If I understand correctly, your .mdb file is the front end to a SQL Server back end. In that case, yes, each user should have their own copy of that FE. If you do a web search, there are many solutions for distributing an Access FE, without having to re-invent the wheel. A favorite is Tony's Auto FE Updater http://autofeupdater.com/.
Found the solution finally:
i add the db to Resources, setting build action to "Content", then my program.cs is this:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
string nomeFile = #"\EW.accde";
string DestinationPath;
string codeBase = Assembly.GetExecutingAssembly().CodeBase;
UriBuilder uri = new UriBuilder(codeBase);
string path = Uri.UnescapeDataString(uri.Path);
DestinationPath = System.IO.Path.GetDirectoryName(path) + #"\Resources";
Process.Start(DestinationPath + nomeFile);
}
in this way i simply copy the new db in project and then deply app with clickonce
once installed app simply launch the database file
I have a C# WPF application and I am trying to find a way to get the path to the root OneDrive directory in Windows. How can I do this programmatically? I have searched online, but I couldn't find anything. I wish I could supply some code but I have no clue; I mean, I have checked system environment variables and I couldn't find anything on my machine, thinking that could be a valid solution, but it didn't turn up anything.
With latest update for windows 10, Microsoft introduced new environment variable %OneDrive%, I have checked it on April 2017 update (Creators update) and it is there.
This works for me (Windows 10 Pro, 1803):
var oneDrivePath = Environment.GetEnvironmentVariable("OneDriveConsumer");
On my Windows 8.1 computer, the registry key that holds this information is: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\SkyDrive\UserFolder
I'd try using the Registry.GetValue() method:
const string userRoot = "HKEY_CURRENT_USER";
const string subkey = #"Software\Microsoft\Windows\CurrentVersion\SkyDrive";
const string keyName = userRoot + "\\" + subkey;
string oneDrivePath = (string)Registry.GetValue(keyName,
"UserFolder",
"Return this default if NoSuchName does not exist.");
Console.WriteLine("\r\n OneDrivePath : {0}", oneDrivePath);
I also found the path under:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\SyncRootManager\SkyDrive\UserSyncRoots\S-1-5-21-2696997101-1021499815-432504798-1004
HKEY_USERS\S-1-5-21-2696997101-1021499815-432504798-1004\Software\Microsoft\Windows\CurrentVersion\SkyDrive\UserFolder
I get the location of my OneDrive folder using the constant FOLDERID_SkyDrive (https://msdn.microsoft.com/library/dd378457.aspx) and the "GetKnownFolderPath" method from the answer at // Detect the location of AppData\LocalLow.
Although the environment variable "USERPROFILE" combined with "\OneDrive" will sometimes work, if the user has moved their OneDrive folder, the environment variable will actually be a reparse point, and not the actual location.
Tested on Windows 10
Guid FOLDERID_SkyDrive = new Guid("A52BBA46-E9E1-435f-B3D9-28DAA648C0F6");
location = GetKnownFolderPath(FOLDERID_SkyDrive);
For completeness, there seem to be 3 environment variables set:
OneDrive
OneDriveConsumer
OneDriveCommercial
In my case, the first and last are the same (my OneDrive for Business account) and the middle one is my personal OneDrive. I'm seeing the same results on both a domain joined PC and a non-domain joined PC but with both OneDrive configured. On a non-domain joined PC with just my personal OneDrive then the OneDrive environment variable points to the personal OneDrive.
I can't find any Microsoft documentation for this but I think that it may be best to ignore the OneDrive variable and just use the OneDriveConsumer/OneDriveCommercial ones to find OneDrive folders.
Steve
If your are using PowerShell, you can use this :
$ENV:onedrive
private void button1_Click(object sender, EventArgs e)
{
try
{
const string userRoot = "HKEY_CURRENT_USER";
const string subkey = #"Software\Microsoft\OneDrive";
const string keyName = userRoot + "\\" + subkey;
string oneDrivePath = (string)Microsoft.Win32.Registry.GetValue(keyName,
"UserFolder",
"Return this default if NoSuchName does not exist.");
Console.WriteLine("\r\n OneDrivePath : {0}", oneDrivePath);
string Onedrivepath= string.Format(oneDrivePath);
label1 .Text = string.Format(Onedrivepath);
}
catch (Exception)
{
/// throw;
}
}
To keep track of these OneDrive environment variables (It will display all environment variables starting by "one"):
From CMD:
$>set one
OneDrive=C:\Users\my_username\OneDrive - COMPANY
OneDriveCommercial=C:\Users\my_username\OneDrive - COMPANY
OneDriveConsumer=C:\Users\my_username\OneDrive
From PowerShell:
$>dir env: | Where-Object {$_.Name -like "one*"}
OneDrive=C:\Users\my_username\OneDrive - COMPANY
OneDriveCommercial=C:\Users\my_username\OneDrive - COMPANY
OneDriveConsumer=C:\Users\my_username\OneDrive
or
$>Get-ChildItem env: | Where-Object {$_.Name -like "one*"}
OneDrive=C:\Users\my_username\OneDrive - COMPANY
OneDriveCommercial=C:\Users\my_username\OneDrive - COMPANY
OneDriveConsumer=C:\Users\my_username\OneDrive
I was thinking the registry as Smashing1978 mentioned, but I do not have a UserFolder key under HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\SkyDrive.
Could you use the %UserProfile%\SkyDrive path?
You must find path under registry ... First run regedit from search box , then under Software - Microsoft - find OneDrive
image description here
Then use that path for you subkey string
const string subkey = #"Software\Microsoft\OneDrive";
Solution source code is here
in VBA use Environ("OneDriveConsumer")
The registry didn't work for me on some PC's.
However, this worked for me:
using System;
using System.IO;
DirectoryInfo di = DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));
string path = di.Parent.FullName;
I'm guilty of only skimming this but see some issues with the questions & answers. The question asks "...I am trying to find a way to get the path to the root OneDrive directory...". I'm using Win11 & Win10 (version 10.0.19044 specifically). Both show the same details below with OneDrive settings
There are 2 paths with OneDrive to consider: The local PC path with cached files/folders & the actual OneDrive path that contains everything. Windows lets users keep all or just selected files/directories cached locally. All of the answers focus on the local path. I am giving an alternate set of details because this opens OneDrive in Explorer rather than a web page or the local cache. This also answers the question being asked but uses OneDrive not the local cache.
Get the value of HKCU\Software\Microsoft\OneDrive\Accounts\Personal value: cid (string value). This is the ID needed for a UNC path. The UNC is: \\d.docs.live.net#SSL\[whatever the registry CID is]. This will get you everything in OneDrive, not just what's cached locally on the PC. You can even map a drive to that UNC path & it works.
I have not compared this with OneDrive #work yet, but I will.
Is the poster looking for the local path or for the full OneDrive path?
For the local cache path, it's here: HKCU\Software\Microsoft\OneDrive\Accounts\Personal value: UserFolder (string value)
Relying on an OS variable ties you to specific versions of Win10 or later which might not be a good idea depending on your delivery audience. What I've described covers the local cache + entire OneDrive.
(you don't need a SID or have to convert a SID to a name & you don't need to use OS variables that won't necessarily be present)
I have the code to save a file in a folder in directory
string timestamp = DateTime.Now.ToString("MM-dd-yyyy.HH-mm-ss");
var file = File.Create("Owe-Data.txt" + timestamp);
var com = System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase + timestamp + #"\Data" + file;
MessageBox.Show(com);
if (!Directory.Exists(com))
{
Directory.CreateDirectory(com);
}
using (var sw = new StreamWriter(com))
{
sw.WriteLine(InputData);
}
}
i Displayed COM it gives path bt i cant see the Data folder or Owe-Data file at that path
Anybody can tell why this happening, or should i save the Data folder in current directory where this prgram running? bt i dnt know how to reach that path. Any solutions ??
Working on windows phone 5, visual studio 2008 .NET framwork 2.0
As per the Exceptions section of documentation,the above exception is thrown when
ArgumentException ------- folder is not a member of System.Environment.SpecialFolder.
It means the OS where you are running this command does not have Environment.SpecialFolder.CommonApplicationData as one of the special folder.
For knowledge,
Environment.SpecialFolder.ApplicationData is the most common one. This folder holds per-user, non-temporary application-specific data, other than user documents. A common example would be a settings or configuration file.
Environment.SpecialFolder.CommonApplicationData is similar, but shared across users. You could use this to store document templates, for instance.
Environment.SpecialFolder.LocalApplicationData is a non-roaming alternative for ApplicationData. As such, you'd never store important data there. However, because it's non-roaming it is a good location for temporary files, caches, etcetera. It's typically on a local disk.
I think the problem may be that Environment.SpecialFolder.CommonApplicationData is common and shared between different users and the user with which you have logged in is not having rights to access the folder or the Visual Studio has not been started in Admin mode.
EDIT Look at link and try to add a manual registry Common AppData defined in the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\
Given you are asking about a .NET Windows Phone application as per the tags
I think your problem is that a .NET Windows Phone application does not have direct access to the file system; it can only access IsolatedStorage this is by design.
I would quote a Microsoft source for this but I can't seem to find one!
EDIT
See this article from MSDN
I am working on a windows service c# program.
I need to use a file. Here is my code
const string mail_file_path = #"template\mailbody.html";
But according to my log, there is an error like this:
Error: Could not find a part of the path 'C:\Windows\system32\template\mailbody.html'.
I use the app.configuration to use another file
<add key="TimeStampFilePath" value="timestamp.ini" />
StreamReader sr = new StreamReader(ConfigurationManager.AppSettings["TimeStampFilePath"]);
But I can't read the file.
When I run this project as a simple windows console project, it works. But after I run it using windows service mode, the two problems appear.
You could try:
// dir is path where your service EXE is running
string dir = Path.GetDirectoryName(
Assembly.GetExecutingAssembly().Location);
// mail_file_path is where you need to search
string mail_file_path = Path.Combine(dir , #"\template\mailbody.html");
Take my answer as an integration to #CharithJ's post, which is definitely correct!!
If you have got template\mailbody.html in the same directory where the service exe resides. Try something like below and see. You could find the folder where the windows service .exe resides.
string mail_file_path = System.Reflection.Assembly.GetEntryAssembly().Location +
"\template\mailbody.html";
Or this also can help AppDomain.CurrentDomain.BaseDirectory
I found a way to solve the problem, thanks to the suggestion from #Macro. I get the windows service mapping directory using REGISTER API, then setting the working directory the same with it. Then I can use the relative path to get the file I need.