I am looking for a solution for this after struggling for most of the day. In short my dilemma seems simple. An effective solution appears elusive based on the Google and Stackoverflow hits I've had on this one.
(EDIT) I need to clarify the use-case. We may have 6 users needing to run certain scripts that use the "%USERNAME%" string to login to case-sensitive environments, Linux, MySQL, etc. One user-name is mixed-case. In the example I used my name: "Will" for the scripts it must-be: "will" (all lower-case).
The general question though is how can the %USERNAME% environment variable value be change when it is mis-entered?
At present my Windows 7 Professional username is "will" but the environment variable has this value:
echo. User = %USERNAME%
User = Will
I need it to come-out as:
User = will
rem * All lower-case
To be clear ...
I want to change (source) value Windows sets the USERNAME environment variable when I login.
I thought it would be easy to find the setting or config option to change that string -- Until I tried. I think this must happen frequently judging from questions related to getting a USERNAME to work with cygwin, etc.
The question
How to convert the value of %USERNAME% to lowercase within a Windows batch script?
Bothers me too, because that's a messy script to "fix" something basic in a login-environment.
I did a quick survey around the office as well. Some people have mixed case, one or two have lowercase. It seems arbitrary depending on what was typed-in when account was created or something.
Our admin guy looked up my account on the domain (no, not active directory) and is same as my login-screen, "will" (lowercase).
Finally I did a couple of experiments. I changed my username in the Users control panel
from: "will" to "xxwill"
Thinking that would surely update my USERNAME string. I logged out. I did it again and rebooted a second time. The result was extremely surprising (or maybe it shouldn't have been):
User = Will
rem * NO change for the "xxwill" name-change!
Some further grist. I created an account "dodo" and account "Dogdo" and changed the usernames to "Dodo" and "dogdo" respectively.
User = dodo
User = Dogdo
rem * NO change for name-changes!
I see that the USERNAME can't be altered that way. I can't edit the system environment variable in the Advanced options. It may be in the profile. But can you edit a profile or even look inside it with just Administrator powers? I don't know yet; I'm not sure that's my preferred route either since it is hacking with a bit of "output" from some original setting, somewhere.
I hope someone can set me straight so I don't need that script-solution.
If you want to change the windows USERNAME environment variable string, you can do this in the Advanced User Accounts Control Panel.
Open it by running netplwiz ("C:\Windows\System32\Netplwiz.exe").
Then select the name you want to change and click on the Properties button.
Now you get the properties of the selected user account: you can change the User name (, Full name & Description) here.
You'll (just) need administrator rights to do this.
Log out and log on, open a command prompt and try to output the value for %USERNAME%. You'll notice it has been changed according to your modification.
#ECHO OFF
SETLOCAL
PUSHD "%temp%"
COPY NUL "%username%" >NUL 2>NUL
FOR /f "delims=" %%a IN ('dir /L /b "%username%"') DO set "usernamelc=%%a"
del "%username%" >NUL 2>NUL
POPD
ECHO %USERNAME% --^> %usernamelc%
GOTO :EOF
Perhaps this may help. YMMV.
I don't think there is a way to do exactly what you are saying, but it might be achievable, you will know by playing around with the locations where usernames are defined.
• Firstly, there is the user folder C:\user\username1 and that is defined at user creation. This can (I think) be changed (I've only seen references to it, but there are many references, this is easy to find).
• Secondly, there is the Control Panel > User Accounts > Change My Name. This seems to tie in with your $env:USERNAME
• Finally, there is the lusrmgr.msc > Users. This is tied most closely to your "real" username, and aligns with [Security.Principal.WindowsIdentity]::GetCurrent()
I say "real" because I found this recently when trying to use ssh-keygen to create a public key and although my Display Name and $env:USERNAME were set to "Name1", ssh-keygen would only see "Name2" and I had to alter the name in lusrmgr.msc to fix this (a reboot was required).
This is an old post, but posting in case this can help anyone with similar issues.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 28 days ago.
Improve this question
Summary: I have a set of reports I must to run, and would like to create links to each report online. The problem I'm having is how to make a batch file which can successfully loop through the file containing my URLs, and make an internet shortcut for each URL with a name based on data from URL itself.
Example URL exactly as shown, each URL is a line in a text file, (one report per day of the year):
<https://app.gomotive.com/en-US/#/reports/ifta-distance/vehicle;start_date=2023-01-01;end_date=2023-01-31;vehicle_ids=1103007;report_id=25;report_type=normal>
<https://app.gomotive.com/en-US/#/reports/ifta-distance/vehicle;start_date=2023-01-02;end_date=2023-01-31;vehicle_ids=1103007;report_id=25;report_type=normal>
<https://app.gomotive.com/en-US/#/reports/ifta-distance/vehicle;start_date=2023-01-03;end_date=2023-01-31;vehicle_ids=1103007;report_id=25;report_type=normal>
Breaking the URL down to understand the static vs dynamic data and how to manipulate it.
https://app.gomotive.com/en-US/#/reports/ifta-distance/vehicle;start_date= (static data)
2023-01-01 (dynamic data - format YYYY-mm-DD)
;end_date= (static data)
2023-01-31 (dynamic data - format YYYY-mm-DD)
;vehicle_ids=1103007;report_id=25;report_type=normal (static data)
I'm trying to make the URL shortcut names based off the line itself for example, with the URL https://app.gomotive.com/en-US/#/reports/ifta-distance/vehicle;start_date=2023-01-01;end_date=2023-01-31;vehicle_ids=1103007;report_id=25;report_type=normal, I'd like to create a shortcut in directory named: C:\Users\UserName\OneDrive\Desktop\Folder for the links\01-01-2023 mileage report.URL. The filename of 01-01-2023 being dynamic based on the date stated in the URL itself.
Also I found out the hard way, the other day, this computer "%UserProfile%\Desktop\Anywhere Else" is not a valid directory, not sure if this is a new Windows 11 trait, (moved from Win 7), or a OneDrive issue. Either way, any old code I had that used the %UserProfile% variable is needing re-done, or I need to make a new environment variable.
Here are my issue(s):
I have no experience using for looping command, let alone the restrictions of batch when using special characters. I thought I'd best ask before goofing something up terribly (special characters in the text file containing all the URLS).
The URL can vary on length ,so I'm not sure how to extract the month/day/year to use in the filename correctly.
Batch is the only language I have any experience with, and that is limited too. So whilst I'm sure there are much better options to do the task I'm wanting, I don't know them, to try them.
What I have done:
I used spreadsheet to break the URL down, modify the dates for the entire year, concatenate the data in a manner which made a proper working URL for each day of the year, added a column for the filename, and Echo #Echo Off> To the filename, Echo Start (the URL)>> To the filename, Echo Exit>> To the filename.
At which point, I was able to copy the crude columns of code from the spreadsheet, and paste them into the Command Prompt, which created a batch file for each URL, (file name was based on date) like so:
#Echo OFF
Start "" "https://app.gomotive.com/en-US/#/reports/ifta-distance/vehicle;start_date=2023-01-
01;end_date=2023-01-31;vehicle_ids=1103007;report_id=25;report_type=normal"
Exit
Making a working batch file for each link but surely not the right way to do it. (It's not the first time I've used a spreadsheet to break apart a directory or URL and re-constitute it for a batch file).
However I feel making actual internet shortcuts would be a much better way to do this across all forms of devices, (I think one of the people who may look at the reports from time to time use MacOS, and I'm assuming a batch file to "start" the URL won't work on their Mac, let alone not being the most friendly way of doing the job.
What my mind is telling me so far to do, (this is the batch file in my mind at the moment):
#Echo Off
CLS
REM Batch file create URLs based on text file
REM Filenames based on URL data from line in file
REM File containing URLs C:\Users\UserName\OneDrive\Desktop\Report Creation\FileNameOfURLS.txt
REM Save directory C:\Users\UserName\OneDrive\Desktop\Report Creation\All URLS Here
for /F "tokens=*" %%A in (C:\Users\UserName\OneDrive\Desktop\Report Creation\FileNameOfURLS.txt)
do (Echo [InternetShortcut] > "C:\Users\UserName\OneDrive\Desktop\Report Creation\%Option1%.URL"
echo URL=%%A >> "C:\Users\UserName\OneDrive\Desktop\Report Creation\%Option1%.URL"
echo IconFile=C:\Program Files\Google\Chrome\Application\chrome.exe >>
"C:\Users\UserName\OneDrive\Desktop\Report Creation\%Option1%.URL"
echo IconIndex=0 >> "C:\Users\UserName\OneDrive\Desktop\Report Creation\%Option1%.URL"
)
Exit
But I'm lost on how to extract the mm-DD-YYYY from the URL in the text file, and set it as the "option1", as I feel there is need for a second for command somewhere, to make this possible.
I have not ran my potential code, as shown above, through this system yet as I'm not sure how to make the filenames based on the data in the URL of the file filenames.txt, and I'm not sure this is even possible.
I did break the URLs down (365x) in spreadsheet, re-constitute them with proper dates, and make a column for filenames based on those dates, where I was able to further concatenate lines like Echo #Echo Off>FileName(s).bat, Echo Start "" "The URL with updated dates">>FileName(s).bat and Echo Exit>>FileName(s).bat, effectively creating a crude batch file containing the proper link, and having a correct name based on the date of the URL via the Command Prompt. However, making 365 batch files per year, and being locked to only Windows OS, not able to run those batch files on my phone either, makes them half as useful as if they were a .url file which any device can open.
Here is how I would think, based upon your provided text file content, and your unattempted code, it could be done:
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "URLFile=C:\Users\UserName\OneDrive\Desktop\Report Creation\FileNameOfURLS.txt"
Set "SaveDir=C:\Users\UserName\OneDrive\Desktop\Report Creation"
For /F "UseBackQ Delims=<>" %%G In ("%URLFile%") Do (
For /F "Tokens=3 Delims=;=" %%H In ("%%~G") Do (
Echo [InternetShortcut]
Echo URL="%%~G"
Echo IconFile="C:\Program Files\Google\Chrome\Application\chrome.exe"
Echo IconIndex=0
) 1>"%SaveDir%\%%H.url"
)
As you had assumed, an additional for loop was needed.
Please be aware however, that it is not very likely that your phone, or a Mac will have a copy of chrome.exe in the location stipulated in the IconFile entry. So you may be better advised to miss out those two Icon* keys, or at least their values.
I'm a biologist, and sometimes I have to work with quite a lot of files, which are arranged not in an optimal way by someone.
Can you give me a tip on the following task?
There are folders
D:\.......\folder1\subfolder(1....)\subsubfolder(1.....) \SOMEtext_exactword(1.....)
(the last one are files without extension)
Can I create in windows cmd something like
D:\.......\folderEXACTWORD1\(subfolder1_subsubfolder1_SOMEtext_exactword1,
subfolder2_subsubfolder2_SOMEtext_exactword1,
subfolder3_subsubfolder3_SOMEtext_exactword1)
(the last one are files without extension again)
Meaning to find all files, containing "string" in their name in few sub folders, copy them into the specific folder and rename them, so they contain their parent file location in their name now.
I guess there should be a way to do it in a linux, though I am not a linux user and not a good (not at all actually) coder myself. Though I can handle some work, so I would be happy if someone can give me a tip whats the easiest way to do what I want. Or what can I search - I tried to search, but maybe I am missing some right words to look for.
Your question is very unclear, but here is more or less something that does this, you have to still define a few more items to make sure your find the correct files in locations and move them accordingly.
#echo off
setlocal enabledelayedexpansion
set mydir="D:\somedir\somedir\someotherdir\
for %%a in (%mydir%) do set "name=%%~nxa"
echo %name%
for /r %%i in (*string*) do (set "file=%%i"
echo move "!file!" "C:\somedir\!name!")
)
)
endlocal
Well. Someone elsewhere has given me advice and it worked. In total commander, you can do it with multi-rename tool and flags [P] and [G] which will allow you to add parent and grandparent directory name.
Well. I guess there is nothing wrong with having this topic with answer from myself, but I will be ok if it is deleted :)
Though I will be still interested if it can be done from cmd, just out of curiosity.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I am using WinAutomation and I am trying to point to and open a file on any computer that my software is placed on without having to hard-code the username in the path, so I am looking for a way to retrieve the logged in Username, that will be case sensitive so I can grab that variable.
Using the Windows command line, (which I can run invisible to the user in the background) if the username in the file tree is "User Name", whoami will return "user name" and then,
If I point to a file C:\Users\%pcName%\Desktop\Masterlist.xlsx with that %pcName% not correctly capitalized it will not work...
I saw a question about Pythonic way to retrieve case sensitive path but I can't use Python for this. I am open to creative ways to get the case sensitive User Name but I keep seeing people deciding to enforce lowercase usernames as a solution.
Is there a way to find the case-sensitive logged in users name for use in file path references? I'm open to being creative at this point!!
First, let me make clear that your request is probably an XY issue. You're trying to achieve something and it looks like the solution is to fix the casing in the user name. However, there are several argument against that:
Windows file names are not case sensitive. It should not matter what casing you use. Maybe some other component compares these names in a case sensitive way where it shouldn't. In that case, the component should be fixed.
User names in Windows are not case sensitive. You can log on with any casing.
You're constructing a path C:\Users\%pcname%, which looks like %USERPROFILE%. However, a user profile is not necessarily in C:\Users. It could have been moved anywhere.
It's unclear to me, what exactly "does not work" and for which reason. You don't specify an error message which could let me diagnose the root cause, so we could fix the real problem.
You say that you can't use Python, but you do not specify any other programming language that you can use, so let me treat dos as an equivalent of batch.
Whatever your real problem is, echo %username% does what you ask for:
C:\Users\For example John>echo %username%
For example John
But be warned: in 90+% of the cases, this is not the correct approach.
In C#, you would use
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)
for the user profile and
Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
for the Desktop.
Winautomation has a function, "Get Special folder" that will return the filepath to the Desktop of the current PC as a variable. That variable can then be used as the root of whatever you are trying to access.
This is the correct way to reach the Desktop file path and does not require any special DOS usage.
'Desktop' is a User Shell Folder. The value for these folders is stored in the registry, with the right case :-).
The registry can be queried from the command prompt using 'reg query'.
If you just want the data value of the Desktop property, use the following:
for /f "tokens=2*" %a in ('reg query "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v Desktop ^| findstr "REG_"') do #echo %b
I want to set path in Visual Foxpro. In such a way that I want to keep exe file on local machine and data\tables on server. How can I do so?
I personally have never liked using SET PATH, especially if you have many "paths" that your application is expecting to use.. If you have a given table / file in multiple locations that are visible with multiple paths that qualify, you may be getting the wrong table, but you won't necessarily know it since the application just runs as normal, finds a table and continues.
Instead, I would suggest one of a few things. Yes, have your application on each user's local machine, but have the person's shortcut have the "START IN" folder pointing to the path on the server where your data is. This way, your application will BE in the folder where the data resides and processes without issue. If no data is on the local machine, during your startup, you could add a messagebox about ... hey... your shortcut should be set to "Start In" setting to X:\SomeShareOnServer\MyVFPDataPath...
If not that, then another avenue I have used is to have your application during startup, add a property to the "_Screen" object which will NEVER loose scope, and set that property to the path you have the data located such as...
_Screen.AddProperty( "cDataPath" )
_Screen.cDataPath = "X:\SomeShareOnServer\MyVFPDataPath\"
Then, in your code, any of your opening tables or SQL queries, use the path variable PLUS the table... something like
if not used( "SomeTable" )
select 0
use ( _Screen.cDataPath + "SomeTable" )
endif
if doing a query, use similar approach
select ST.* ;
from ( _Screen.cDataPath + "SomeTable" ) ST ;
where ST.SomeID = 123;
into cursor C_TmpResult readwrite
So, although the second option may take more effort, especially on an existing application, the first option to make sure the "Start In" path is where the data is might help.
Again, this is my suggestion as I hate chasing down ambiguous -- sometimes it works, but not others. If I can't find a file, I WANT TO KNOW about it and fail outright.
Your call, your app, your environment. But if you DO use the "SET PATH" command, you might want to make sure you use the ADDITIVE command, just in case there are other settings, such as pointing to the a path for forms, classes, report folders... You run a SET PATH without it, and you kill your other paths...
SET PATH TO "X:\SomeShareOnServer\MyVFPDataPath\" ADDITIVE
Also, if you have any spaces in your path in question, MAKE SURE you use quotes around it, otherwise it will fail finding the path you expect and may cause compile error, such as
SET PATH TO X:\Some Share On Server\MyVFPDataPath\ ADDITIVE
You can use VFP's Set Path command
Set Path To m.lcDataFolder
early in your client startup code, i.e. in your project's "main.PRG".
Where the content of the m.lcDataFolder could for example come from something like a custom "myConfig.XML/INI/TXT" containing the desired string, e.g. \\fileServerNameOrIP\sharedDataFolder
Use 'SET DEFAULT TO' to change the current working directory or use explicit full paths as per the answer by #DRapp.
I have a process that writes log files and screenshots to a folder on a regular basis creating
between
30-50 files a week. The folder structure is ..\Year\Month\filename.ext, and it cannot be changed.
I'd like to create a shortcut to stick in my Favorites so I can get to this folder quickly but I need a variable for the YEAR and MONTH. Are there an environmental variables for this?
Any bright ideas on how I could create one that updates automatically preferably without a script or scheduled job?
The %DATE% environment variable holds the current date. You might be tempted to parse the date with %DATE:~6,4% to get the year.
But this method would not be very solid. %DATE% returns the current date using the windows settings for the "short date format". The problem is that the short date format setting is fully and endlessly customizable. One user can configure its system to show the short date as 29/06/2012; while another user (even in the same system) may choose Fri062912. It's a complete nightmare for a BAT programmer.
One possible solution is to use WMIC, instead. WMIC is the WMI command line interface to WMI. WMI Windows Management Instrumentation is the http://en.wikipedia.org/wiki/Windows_Management_Instrumentation
WMIC Path Win32_LocalTime Get Day,Hour,Minute,Month,Second,Year /Format:table
returns the date in a convenient way to directly parse it with a FOR.
Completing the parse and putting the pieces together
FOR /F "skip=1 tokens=1-6" %%A IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Month^,Second^,Year /Format:table') DO (
SET /A MONTH=%%D
SET /A YEAR=%%F
)
your shortcut can point to a BAT file that includes the above code and then opens explorer on the right folder.
start "" "D:\FOLDER\%YEAR%\%MONTH%"